Thanks to visit codestin.com
Credit goes to GitHub.com

Skip to content

[RFC] Split oparg type from the opcode enum #6746

@ShaharNaveh

Description

@ShaharNaveh

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_enum crate for example).
  • Easier to auto-generate the opcodes (and their IDs) in the future.
  • Simplify opcode -> oparg mapping.

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 comments

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions