-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Open
Labels
RFCRequest for commentsRequest for comments
Description
Summary
Introduce a new AnyOparg enum & make Instruction + PseudoInstruction enums to not hold the oparg type.
Detailed Explanation
The current Instruction enum couples the opcode and its oparg type together. In practice, this creates friction and many boilerplate code that can be avoided.
Suggested API
New pure Opcode enum that will have only the mapping between the opcode name and it's ID, like this:
enum Opcode {
Nop = 0,
IsOp = 1,
BinaryOp = 2,
...
}A new AnyOparg enum that will have all oparg types as it's variants:
enum AnyOparg {
NameIdx(oparg::NameIdx),
IntristicFunction1(oparg::IntristicFunction1),
Invert(oparg::Invert),
...
}An Instruction struct that is like a typed version of the CodeUnit struct:
struct Instruction {
opcode: AnyOpcode,
oparg: AnyOparg,
}
impl Instruction {
pub fn new<T: Into<AnyOpcode>>(opcode: T, oparg: Option<i32>) -> Result<Self, MarshalError> {
let oparg = match opcode.into() {
AnyOpcode::Real(Opcode::Nop) => None,
AnyOpcode::Real(Opcode::IsOp) => Some(oparg::Invert::try_from(oparg.unwrap())?),
...
};
Ok(Self { opcode: opcode.into(), oparg: oparg.map(Into::into) })
}
}Drawbacks, Rationale, and Alternatives
Drawbacks
- Will require a serious refactoring to the code
Rational
- Reduce boilerplate code (use
num_enumcrate for example). - Easier to auto-generate the opcodes (and their IDs) in the future.
- Simplify
opcode -> opargmapping.
Unresolved Questions
Performance implifications?
- Will probably increase performance because we will validate the oparg once instead of doing so every time we need to do an operation on the opcode.
Implementation & refactoring efforts?
Metadata
Metadata
Assignees
Labels
RFCRequest for commentsRequest for comments