Skip to content

Opcode name#7433

Open
ShaharNaveh wants to merge 6 commits intoRustPython:mainfrom
ShaharNaveh:opcode-name
Open

Opcode name#7433
ShaharNaveh wants to merge 6 commits intoRustPython:mainfrom
ShaharNaveh:opcode-name

Conversation

@ShaharNaveh
Copy link
Contributor

@ShaharNaveh ShaharNaveh commented Mar 14, 2026

Summary by CodeRabbit

  • Refactor
    • Unified opcode naming so instruction names render consistently across the compiler and tooling.
    • Reworked formatting/display paths to use the unified opcode name source, replacing hard-coded opcode strings.
    • Standardized rendering for attribute/global/super and instrumented vs. base instruction views so opcode names appear consistently to users.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 14, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a public name(&self) -> &str accessor to InstructionMetadata, implements it for Instruction, PseudoInstruction, and AnyInstruction, and updates disassembly/display rendering to use this accessor instead of hard-coded opcode name literals.

Changes

Cohort / File(s) Summary
Opcode naming & display refactor
crates/compiler-core/src/bytecode/instruction.rs
Adds fn name(&self) -> &str to the InstructionMetadata trait and implements it for Instruction, PseudoInstruction, and AnyInstruction. Replaces many hard-coded opcode name strings in fmt_dis/display/instrumented rendering paths to call the new accessor and consolidates name propagation.
Manifest edits
Cargo.toml
Large manifest changes recorded (+401/-183 lines). Likely dependency/version/feature adjustments accompanying the crate changes.

Sequence Diagram(s)

(omitted)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • youknowone

Poem

🐰 I hop through bytes and stitch a name,

One tiny tag for every frame,
No scattered strings left on the floor,
Opcodes sing as I explore,
I nibble bugs and bounce some more.

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 28.57% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'Opcode name' is vague and generic, using non-descriptive terms that don't clearly convey what changed in the changeset. Consider a more descriptive title like 'Add public opcode name accessor to InstructionMetadata' that clearly explains the main change.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
crates/compiler-core/src/bytecode/instruction.rs (1)

1713-1713: Minor style inconsistency: PopBlock has no fields.

PopBlock is defined as a unit variant (line 1608), so the { .. } pattern is unnecessary. Other unit-like matches in this block don't use this pattern.

Proposed fix
-            Self::PopBlock { .. } => "POP_BLOCK",
+            Self::PopBlock => "POP_BLOCK",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/compiler-core/src/bytecode/instruction.rs` at line 1713, The match arm
for the enum variant PopBlock unnecessarily uses a struct pattern with `{ .. }`;
update the pattern in the match (the arm mapping to "POP_BLOCK") from
Self::PopBlock { .. } to the unit pattern Self::PopBlock so it matches the unit
variant definition of PopBlock in the Instruction enum.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@crates/compiler-core/src/bytecode/instruction.rs`:
- Line 1248: The match arm for Self::CallMethodDescriptorO returns the wrong
opcode name; update the returned string from "CALL_METHOD_DESCRIPTOR" to
"CALL_METHOD_DESCRIPTOR_O" so the name matches the enum variant
CallMethodDescriptorO and CPython 3.14 naming; locate the mapping in
instruction.rs where CallMethodDescriptorO is handled and change the string
literal accordingly.
- Line 1236: The match arm for the opcode name is returning the wrong string for
the enum variant Self::CallBuiltinO; update the returned name from
"CALL_BUILTIN" to "CALL_BUILTIN_O" in the function that maps instructions to
their names (the match arm handling Self::CallBuiltinO) so the opcode string
matches the enum variant and CPython 3.14 naming.

---

Nitpick comments:
In `@crates/compiler-core/src/bytecode/instruction.rs`:
- Line 1713: The match arm for the enum variant PopBlock unnecessarily uses a
struct pattern with `{ .. }`; update the pattern in the match (the arm mapping
to "POP_BLOCK") from Self::PopBlock { .. } to the unit pattern Self::PopBlock so
it matches the unit variant definition of PopBlock in the Instruction enum.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: f06d764e-9e82-49fb-9879-9fd028212ffa

📥 Commits

Reviewing files that changed from the base of the PR and between 005860c and edf5793.

📒 Files selected for processing (1)
  • crates/compiler-core/src/bytecode/instruction.rs

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@crates/compiler-core/src/bytecode/instruction.rs`:
- Line 1248: The returned opcode name mismatches the enum variant
Self::CallMethodDescriptorO by using a digit "0" instead of letter "O"; update
the string literal "CALL_METHOD_DESCRIPTOR_0" to "CALL_METHOD_DESCRIPTOR_O" in
the match arm for CallMethodDescriptorO so the opcode name matches the enum
variant and CPython 3.14 naming convention.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: e0bbe3dc-727e-40f5-aec1-8953371dc951

📥 Commits

Reviewing files that changed from the base of the PR and between edf5793 and ebbcc89.

📒 Files selected for processing (1)
  • crates/compiler-core/src/bytecode/instruction.rs

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
crates/compiler-core/src/bytecode/instruction.rs (1)

1705-1719: Minor style inconsistency in pattern matching.

Line 1713 uses Self::PopBlock { .. } but PopBlock is a unit variant (no fields). While valid Rust, this is inconsistent with line 1707 where Self::AnnotationsPlaceholder (also a unit variant) uses no braces.

Optional: Use consistent pattern style
-            Self::PopBlock { .. } => "POP_BLOCK",
+            Self::PopBlock => "POP_BLOCK",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/compiler-core/src/bytecode/instruction.rs` around lines 1705 - 1719,
The pattern match in the name() method mixes unit-variant style and struct-like
style; change the unit variant match Self::PopBlock { .. } to the consistent
unit pattern Self::PopBlock (same style as Self::AnnotationsPlaceholder) inside
the name() function so all unit variants use the same pattern form.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@crates/compiler-core/src/bytecode/instruction.rs`:
- Around line 1705-1719: The pattern match in the name() method mixes
unit-variant style and struct-like style; change the unit variant match
Self::PopBlock { .. } to the consistent unit pattern Self::PopBlock (same style
as Self::AnnotationsPlaceholder) inside the name() function so all unit variants
use the same pattern form.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: cbbc07cf-671c-4202-9a08-e334c4503173

📥 Commits

Reviewing files that changed from the base of the PR and between ebbcc89 and ffe1708.

📒 Files selected for processing (1)
  • crates/compiler-core/src/bytecode/instruction.rs

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
crates/compiler-core/src/bytecode/instruction.rs (1)

1479-1508: Consider extracting common LoadGlobal* formatting logic.

The formatting logic for LoadGlobal, LoadGlobalBuiltin, and LoadGlobalModule is nearly identical. Per coding guidelines, when branches share common logic differing only in value, consider extracting to avoid duplication.

♻️ Suggested refactor
-            Self::LoadGlobal { namei } => {
-                let oparg = namei.get(arg);
-                let name_idx = oparg >> 1;
-                let opname = self.name();
-                if (oparg & 1) != 0 {
-                    write!(f, "{:pad$}({}, NULL + {})", opname, oparg, name(name_idx))
-                } else {
-                    write!(f, "{:pad$}({}, {})", opname, oparg, name(name_idx))
-                }
-            }
-            Self::LoadGlobalBuiltin => {
-                let oparg = u32::from(arg);
-                let name_idx = oparg >> 1;
-                let opname = self.name();
-                if (oparg & 1) != 0 {
-                    write!(f, "{:pad$}({}, NULL + {})", opname, oparg, name(name_idx))
-                } else {
-                    write!(f, "{:pad$}({}, {})", opname, oparg, name(name_idx))
-                }
-            }
-            Self::LoadGlobalModule => {
-                let oparg = u32::from(arg);
-                let name_idx = oparg >> 1;
-                let opname = self.name();
-                if (oparg & 1) != 0 {
-                    write!(f, "{:pad$}({}, NULL + {})", opname, oparg, name(name_idx))
-                } else {
-                    write!(f, "{:pad$}({}, {})", opname, oparg, name(name_idx))
-                }
-            }
+            Self::LoadGlobal { namei } => {
+                let oparg = namei.get(arg);
+                fmt_load_global(f, self.name(), oparg, name(oparg >> 1), pad)
+            }
+            Self::LoadGlobalBuiltin | Self::LoadGlobalModule => {
+                let oparg = u32::from(arg);
+                fmt_load_global(f, self.name(), oparg, name(oparg >> 1), pad)
+            }

Where fmt_load_global is a local closure or helper:

let fmt_load_global = |f: &mut fmt::Formatter<'_>, opname: &str, oparg: u32, resolved_name: &str, pad: usize| -> fmt::Result {
    if (oparg & 1) != 0 {
        write!(f, "{:pad$}({}, NULL + {})", opname, oparg, resolved_name)
    } else {
        write!(f, "{:pad$}({}, {})", opname, oparg, resolved_name)
    }
};

As per coding guidelines: "When branches differ only in a value but share common logic, extract the differing value first, then call the common logic once to avoid duplicate code."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/compiler-core/src/bytecode/instruction.rs` around lines 1479 - 1508,
The three match arms Self::LoadGlobal, Self::LoadGlobalBuiltin, and
Self::LoadGlobalModule duplicate identical formatting logic; extract the shared
formatting into a small helper or closure (e.g., fmt_load_global) that accepts
opname (from self.name()), oparg (u32 from arg), resolved_name (result of
name(name_idx)) and pad, then call that helper from each arm after computing
name_idx and converting arg as needed; ensure you reuse the existing write!(f,
...) calls inside the helper so each arm only computes its specific inputs and
invokes fmt_load_global.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@crates/compiler-core/src/bytecode/instruction.rs`:
- Around line 1479-1508: The three match arms Self::LoadGlobal,
Self::LoadGlobalBuiltin, and Self::LoadGlobalModule duplicate identical
formatting logic; extract the shared formatting into a small helper or closure
(e.g., fmt_load_global) that accepts opname (from self.name()), oparg (u32 from
arg), resolved_name (result of name(name_idx)) and pad, then call that helper
from each arm after computing name_idx and converting arg as needed; ensure you
reuse the existing write!(f, ...) calls inside the helper so each arm only
computes its specific inputs and invokes fmt_load_global.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 9e29d217-1308-40ca-acf8-648f6853f03e

📥 Commits

Reviewing files that changed from the base of the PR and between ffe1708 and 1ff97e5.

📒 Files selected for processing (1)
  • crates/compiler-core/src/bytecode/instruction.rs

Copy link
Member

@youknowone youknowone left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you explain more about the motivation? The metadata seems to be described in a single function before. Now we have to edit 2 places to edit the instruction. There must be benefits to justify this inconvenience

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@crates/compiler-core/src/bytecode/instruction.rs`:
- Around line 1552-1556: The StoreFastLoadFast display arm currently writes an
extra leading space and prints raw indices; change it to match the other arms by
removing the extra leading space in the format string (use "{:pad$}" instead of
" {:pad$}") and resolve the indices to variable names before printing (use the
same resolution helper used by LoadFastLoadFast/StoreFastStoreFast on
var_nums.get(arg) to obtain store_name and load_name, then write them as
"opname{:pad$}({store_name}, {load_name})"). Ensure you still call
var_nums.get(arg) and extract the two positions but format the output with
names, not numeric indexes.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 9da50c58-8802-4a52-9193-6060e6fa4226

📥 Commits

Reviewing files that changed from the base of the PR and between 1ff97e5 and e9c0911.

📒 Files selected for processing (1)
  • crates/compiler-core/src/bytecode/instruction.rs

Comment on lines 1552 to 1556
Self::StoreFastLoadFast { var_nums } => {
let oparg = var_nums.get(arg);
let (store_idx, load_idx) = oparg.indexes();
write!(f, "STORE_FAST_LOAD_FAST")?;
write!(f, " ({}, {})", store_idx, load_idx)
write!(f, " {:pad$}({}, {})", opname, store_idx, load_idx)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Formatting inconsistencies in StoreFastLoadFast display.

Two issues:

  1. Extra leading space in {:pad$} causes misaligned disassembly output.
  2. Outputs raw indices instead of resolved variable names, unlike LoadFastLoadFast and StoreFastStoreFast.
Proposed fix
             Self::StoreFastLoadFast { var_nums } => {
                 let oparg = var_nums.get(arg);
                 let (store_idx, load_idx) = oparg.indexes();
-                write!(f, " {:pad$}({}, {})", opname, store_idx, load_idx)
+                write!(f, "{:pad$}({}, {})", opname, varname(store_idx), varname(load_idx))
             }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@crates/compiler-core/src/bytecode/instruction.rs` around lines 1552 - 1556,
The StoreFastLoadFast display arm currently writes an extra leading space and
prints raw indices; change it to match the other arms by removing the extra
leading space in the format string (use "{:pad$}" instead of " {:pad$}") and
resolve the indices to variable names before printing (use the same resolution
helper used by LoadFastLoadFast/StoreFastStoreFast on var_nums.get(arg) to
obtain store_name and load_name, then write them as "opname{:pad$}({store_name},
{load_name})"). Ensure you still call var_nums.get(arg) and extract the two
positions but format the output with names, not numeric indexes.

@ShaharNaveh
Copy link
Contributor Author

Could you explain more about the motivation? The metadata seems to be described in a single function before. Now we have to edit 2 places to edit the instruction. There must be benefits to justify this inconvenience

ofc, I was working on auto-generating the rust code for the opcodes (and methods). This change is extracted from those changes so the final PR wouldn't be that big. I guess it would have made more sense to implement fmt::Display instead. LMK what you think

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants