- Notifications
You must be signed in to change notification settings - Fork1.4k
Opcode metadata auto generation#6174
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
base:main
Are you sure you want to change the base?
Uh oh!
There was an error while loading.Please reload this page.
Conversation
coderabbitaibot commentedSep 23, 2025 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
WalkthroughAdds generated opcode enums (RealOpcode, PseudoOpcode) and an Opcode wrapper to compiler/core, a Python generator script to emit the generated file, stdlib and VM updates to use the new opcode types, marks the generated file in .gitattributes, adds dependencies, and updates a spelling dictionary token. Changes
Sequence Diagram(s)sequenceDiagram autonumber actor Caller participant Std as stdlib::opcode::stack_effect participant Core as compiler_core::opcode::Opcode participant Real as compiler_core::opcodes::RealOpcode participant Pseudo as compiler_core::opcodes::PseudoOpcode Caller->>Std: stack_effect(raw_id, oparg) Std->>Core: Opcode::try_from(raw_id) alt Pseudo (u16) Core->>Pseudo: PseudoOpcode::try_from(raw) Pseudo-->>Std: PseudoOpcode Std->>Std: apply pseudo-specific stack logic Std-->>Caller: stack delta else Real (u8) Core->>Real: RealOpcode::try_from(raw_u8) Real-->>Std: RealOpcode Std->>Std: use RealOpcode::num_popped/num_pushed/deopt Std-->>Caller: stack delta else Invalid Std-->>Caller: invalid / error endsequenceDiagram autonumber actor Dev participant Script as scripts/gen_opcodes.py participant Output as compiler/core/src/opcodes.rs participant Repo as Git Dev->>Script: run generator (analyze CPython) Script->>Output: emit enums, predicates, TryFrom impls, helpers Script->>Repo: write file & run cargo fmt Repo-->>Output: file added (marked in .gitattributes)Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: Path: .coderabbit.yml Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
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. Comment |
ShaharNaveh commentedOct 5, 2025
I have updated the main PR comment |
There was a problem hiding this 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 (3)
compiler/core/src/opcode.rs (3)
7-8:Consider adding accessor and additional trait implementations.The
OpcodeIdnewtype lacks a public accessor for the inneru16value. Additionally, consider implementingHash,Display, and potentiallyFromStrfor better ergonomics.Apply this diff to add an accessor:
#[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct OpcodeId(u16); impl OpcodeId {+ /// Returns the raw opcode ID value.+ #[must_use]+ pub const fn get(self) -> u16 {+ self.0+ }+For
Hash, update the derives:-#[derive(Clone, Copy, Debug, Eq, PartialEq)]+#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] pub struct OpcodeId(u16);
235-243:Enhance safety documentation.The safety documentation for
new_uncheckedshould reference theis_validmethod to clarify what constitutes a valid opcode ID.Apply this diff:
/// Creates a new opcode ID without checking the value is a valid opcode ID. /// /// # Safety ///- /// The value should be a valid opcode ID.+ /// The caller must ensure that `id` satisfies `Self::is_valid(id)`. #[must_use] pub const unsafe fn new_unchecked(id: u16) -> Self {
545-560:Consider a more descriptive error type for TryFrom.The
TryFromimplementations use()as the error type, providing no information about why a conversion failed. While this is acceptable, a custom error type could improve debuggability.Consider defining an error type:
/// Error type for invalid opcode ID conversions.#[derive(Clone,Copy,Debug,Eq,PartialEq)]pubstructInvalidOpcodeId;impl std::fmt::DisplayforInvalidOpcodeId{fnfmt(&self,f:&mut std::fmt::Formatter<'_>) -> std::fmt::Result{write!(f,"invalid opcode ID")}}impl std::error::ErrorforInvalidOpcodeId{}Then update the macro:
macro_rules! opcode_id_try_from_impl { ($t:ty) => { impl TryFrom<$t> for OpcodeId {- type Error = ();+ type Error = InvalidOpcodeId; fn try_from(value: $t) -> Result<Self, Self::Error> {- let id = value.try_into().map_err(|_| ())?;+ let id = value.try_into().map_err(|_| InvalidOpcodeId)?; if Self::is_valid(id) { Ok(Self(id)) } else {- Err(())+ Err(InvalidOpcodeId) } } }
📜 Review details
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (6)
.gitattributes(1 hunks)compiler/core/src/lib.rs(1 hunks)compiler/core/src/opcode.rs(1 hunks)scripts/gen_opcodes.py(1 hunks)stdlib/src/opcode.rs(3 hunks)vm/src/lib.rs(1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.rs
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.rs: Format Rust code with the default rustfmt style (runcargo fmt)
Run clippy and fix any warnings or lints introduced by your changes
Follow Rust best practices for error handling and memory management
Files:
vm/src/lib.rscompiler/core/src/lib.rscompiler/core/src/opcode.rsstdlib/src/opcode.rs
{vm,stdlib}/**/*.rs
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use RustPython macros (
pyclass,pymodule,pyfunction, etc.) when implementing Python functionality in Rust
Files:
vm/src/lib.rsstdlib/src/opcode.rs
🧬 Code graph analysis (3)
scripts/gen_opcodes.py (2)
compiler/core/src/opcode.rs (9)
is_pseudo(253-269)is_valid(247-249)has_arg(273-426)has_const(430-435)has_name(439-465)has_jump(469-487)has_free(491-500)has_local(504-519)has_exc(523-542)stdlib/src/opcode.rs (8)
is_valid(70-72)has_arg(75-77)has_const(80-82)has_name(85-87)has_jump(90-92)has_free(95-97)has_local(100-102)has_exc(105-107)
compiler/core/src/opcode.rs (1)
stdlib/src/opcode.rs (8)
is_valid(70-72)has_arg(75-77)has_const(80-82)has_name(85-87)has_jump(90-92)has_free(95-97)has_local(100-102)has_exc(105-107)
stdlib/src/opcode.rs (3)
scripts/gen_opcodes.py (1)
Instruction(81-119)compiler/core/src/bytecode.rs (1)
try_from(814-820)compiler/core/src/opcode.rs (8)
is_valid(247-249)has_arg(273-426)has_const(430-435)has_name(439-465)has_jump(469-487)has_free(491-500)has_local(504-519)has_exc(523-542)
🪛 Flake8 (7.3.0)
scripts/gen_opcodes.py
[error] 256-256: indentation contains mixed spaces and tabs
(E101)
[error] 257-257: indentation contains mixed spaces and tabs
(E101)
[error] 258-258: indentation contains mixed spaces and tabs
(E101)
[error] 259-259: indentation contains mixed spaces and tabs
(E101)
[error] 260-260: indentation contains mixed spaces and tabs
(E101)
[error] 261-261: indentation contains mixed spaces and tabs
(E101)
[error] 262-262: indentation contains mixed spaces and tabs
(E101)
[error] 263-263: indentation contains mixed spaces and tabs
(E101)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Run snippets and cpython tests (windows-2025)
🔇 Additional comments (3)
scripts/gen_opcodes.py (2)
75-78: ...
75-78: ...compiler/core/src/opcode.rs (1)
11-233:Refine opcode verification scope
Adaptive and instrumented opcodes (e.g. CALL_ALLOC_AND_ENTER_INIT, INSTRUMENTED_*, etc.) are RustPython-specific and must not be removed; only verify that the standard CPython 3.13.7 opcodes (those without ADAPTIVE_ or INSTRUMENTED_ prefixes) match their CPython values.Likely an incorrect or invalid review comment.
compiler/core/src/opcode.rs Outdated
| /// Whether opcode ID have 'HAS_PURE_FLAG' set. | ||
| #[must_use] | ||
| pubconstfnhas_exc(&self) ->bool{ |
coderabbitaibotOct 5, 2025 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Fix misleading documentation comment.
The documentation comment says "Whether opcode ID have 'HAS_PURE_FLAG' set" but the method is namedhas_exc. This appears to be a copy-paste error.
Apply this diff to fix the comment:
- /// Whether opcode ID have 'HAS_PURE_FLAG' set.+ /// Whether opcode ID have 'HAS_EXC_FLAG' set. #[must_use] pub const fn has_exc(&self) -> bool {
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| /// Whether opcode ID have 'HAS_PURE_FLAG' set. | |
| #[must_use] | |
| pubconstfn has_exc(&self) ->bool{ | |
| /// Whether opcode ID have 'HAS_EXC_FLAG' set. | |
| #[must_use] | |
| pubconstfn has_exc(&self) ->bool{ |
🤖 Prompt for AI Agents
In compiler/core/src/opcode.rs around lines 521 to 523, the doc comment abovepub const fn has_exc(&self) -> bool is incorrect and looks copy-pasted fromanother method; update the comment to correctly describe this method (e.g.,"Whether opcode ID has 'HAS_EXC_FLAG' set.") and fix grammar ("has" instead of"have") so the comment matches the method name and purpose.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
this is intended
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash# Check the generation script to see how has_exc method is generatedcat scripts/gen_opcodes.py | grep -A 10 -B 5 "has_exc\|HAS_PURE"Length of output: 1411
🏁 Script executed:
#!/bin/bash# Search for any references to HAS_PURE_FLAG or has_exc in the codebaserg -n "HAS_PURE|has_exc" --type=py --type=rust -C 3Length of output: 5081
@ShaharNaveh, understood! I can see from the generation script that this is intentional:
defgenerate_has_exc(self)->str:returnself._generate_has_attr("exc",flag_override="HAS_PURE_FLAG")
The method namehas_exc() reflects the semantic meaning (opcodes related to exception handling), while the doc comment accurately documents which CPython flag is actually being checked (HAS_PURE_FLAG). This design choice maintains alignment with CPython's internal flag naming while providing a more descriptive API method name.
Thank you for the clarification!
Uh oh!
There was an error while loading.Please reload this page.
There was a problem hiding this 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
🧹 Nitpick comments (1)
stdlib/src/opcode.rs (1)
26-26:Track the TODO for auto-generated Instruction enum.This TODO references future work to leverage the auto-generated
Instructionenum. Consider tracking this as a follow-up task.Do you want me to open a new issue to track this task?
📜 Review details
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
stdlib/src/opcode.rs(3 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.rs
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.rs: Format Rust code with the default rustfmt style (runcargo fmt)
Run clippy and fix any warnings or lints introduced by your changes
Follow Rust best practices for error handling and memory management
Files:
stdlib/src/opcode.rs
{vm,stdlib}/**/*.rs
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use RustPython macros (
pyclass,pymodule,pyfunction, etc.) when implementing Python functionality in Rust
Files:
stdlib/src/opcode.rs
🧬 Code graph analysis (1)
stdlib/src/opcode.rs (3)
scripts/gen_opcodes.py (1)
Instruction(81-119)compiler/core/src/bytecode.rs (1)
try_from(814-820)compiler/core/src/opcode.rs (8)
is_valid(247-249)has_arg(273-426)has_const(430-435)has_name(439-465)has_jump(469-487)has_free(491-500)has_local(504-519)has_exc(523-542)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
- GitHub Check: Check Rust code with rustfmt and clippy
- GitHub Check: Run snippets and cpython tests (ubuntu-latest)
- GitHub Check: Run snippets and cpython tests (windows-2025)
- GitHub Check: Run snippets and cpython tests (macos-latest)
- GitHub Check: Run snippets and cpython tests on wasm-wasi
- GitHub Check: Ensure compilation on various targets
- GitHub Check: Run rust tests (ubuntu-latest)
- GitHub Check: Run rust tests (windows-2025)
- GitHub Check: Run rust tests (macos-latest)
- GitHub Check: Check the WASM package and demo
🔇 Additional comments (3)
stdlib/src/opcode.rs (3)
57-59:LGTM! TypeError preservation implemented correctly.The error handling now correctly preserves
TypeErrorwhen the opcode argument is not an integer, while only convertingInstruction::try_fromfailures toValueError. This directly addresses the feedback from the previous review.
14-14:LGTM! Correct type for the flag.Changing
ENABLE_SPECIALIZATIONfromi8tou8is appropriate for a boolean-like flag constant.
71-101:LGTM! Consistent pattern across all predicates.The
has_*functions follow a consistent pattern usingOpcodeId::try_from(opcode).is_ok_and(|oid| !oid.is_pseudo() && oid.has_*()), which correctly filters out pseudo-opcodes and delegates to the generated predicates.
stdlib/src/opcode.rs Outdated
| #[pyfunction] | ||
| fnis_valid(opcode:i32) ->bool{ | ||
| Opcode::is_valid(opcode) | ||
| OpcodeId::try_from(opcode).is_ok() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Consider filtering pseudo-opcodes inis_valid for consistency.
All thehas_* predicates (lines 71-101) explicitly filter out pseudo-opcodes with!oid.is_pseudo(), butis_valid does not. Pseudo-opcodes are typically not valid for runtime bytecode execution. For consistency with the other predicates and to match typical CPython semantics,is_valid should likely also exclude pseudo-opcodes.
Apply this diff to filter pseudo-opcodes:
fn is_valid(opcode: i32) -> bool {- OpcodeId::try_from(opcode).is_ok()+ OpcodeId::try_from(opcode).is_ok_and(|oid| !oid.is_pseudo()) }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| OpcodeId::try_from(opcode).is_ok() | |
| fn is_valid(opcode:i32) ->bool{ | |
| OpcodeId::try_from(opcode).is_ok_and(|oid| !oid.is_pseudo()) | |
| } |
🤖 Prompt for AI Agents
In stdlib/src/opcode.rs around line 66, update the is_valid implementation toexclude pseudo-opcodes like the other has_* predicates: after converting opcodeto an OpcodeId via try_from, return true only if the conversion succeeds and theresulting OpcodeId is not a pseudo-opcode (i.e., check !oid.is_pseudo()); ensureyou handle the Err case from try_from by returning false.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
stdlib/src/opcode.rs (1)
31-41:Preserve the CPython TypeError message.Line 39 wraps
PyInt::try_to_primitive::<i32>in an emptyTypeError(""); CPython raisesTypeError("'int' object cannot be interpreted as an integer"). Emitting an empty message is misleading for users. Please propagate the original conversion error (or at least set a meaningful message matching CPython).
📜 Review details
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (3)
Cargo.lockis excluded by!**/*.lockLib/dis.pyis excluded by!Lib/**Lib/test/test__opcode.pyis excluded by!Lib/**
📒 Files selected for processing (8)
.cspell.dict/cpython.txt(1 hunks).gitattributes(1 hunks)compiler/core/src/lib.rs(1 hunks)compiler/core/src/opcode.rs(1 hunks)compiler/core/src/opcodes.rs(1 hunks)scripts/gen_opcodes.py(1 hunks)stdlib/src/opcode.rs(3 hunks)vm/src/lib.rs(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- .cspell.dict/cpython.txt
🚧 Files skipped from review as they are similar to previous changes (3)
- compiler/core/src/lib.rs
- .gitattributes
- vm/src/lib.rs
🧰 Additional context used
📓 Path-based instructions (2)
**/*.rs
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.rs: Format Rust code with the default rustfmt style (runcargo fmt)
Run clippy and fix any warnings or lints introduced by your changes
Follow Rust best practices for error handling and memory management
Files:
stdlib/src/opcode.rscompiler/core/src/opcodes.rscompiler/core/src/opcode.rs
{vm,stdlib}/**/*.rs
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use RustPython macros (
pyclass,pymodule,pyfunction, etc.) when implementing Python functionality in Rust
Files:
stdlib/src/opcode.rs
🧬 Code graph analysis (4)
stdlib/src/opcode.rs (2)
compiler/core/src/bytecode.rs (1)
stack_effect(1391-1516)compiler/core/src/opcodes.rs (32)
try_from(993-1001)try_from(1007-1015)try_from(1021-1029)try_from(1035-1043)try_from(1049-1057)try_from(1063-1071)try_from(1077-1084)try_from(1090-1098)try_from(1104-1112)try_from(1118-1126)try_from(1132-1140)try_from(1146-1154)try_from(1250-1258)try_from(1264-1272)try_from(1278-1286)try_from(1292-1300)is_valid(549-551)is_valid(1242-1244)has_arg(299-441)has_arg(1177-1189)has_const(445-450)has_const(1193-1195)has_name(523-545)has_name(1230-1238)has_jump(486-502)has_jump(1218-1220)has_free(473-482)has_free(1212-1214)has_local(506-519)has_local(1224-1226)has_exc(454-469)has_exc(1199-1208)
compiler/core/src/opcodes.rs (1)
stdlib/src/opcode.rs (8)
has_arg(120-122)has_const(125-127)has_exc(150-152)has_free(140-142)has_jump(135-137)has_local(145-147)has_name(130-132)is_valid(115-117)
compiler/core/src/opcode.rs (1)
compiler/core/src/opcodes.rs (16)
try_from(993-1001)try_from(1007-1015)try_from(1021-1029)try_from(1035-1043)try_from(1049-1057)try_from(1063-1071)try_from(1077-1084)try_from(1090-1098)try_from(1104-1112)try_from(1118-1126)try_from(1132-1140)try_from(1146-1154)try_from(1250-1258)try_from(1264-1272)try_from(1278-1286)try_from(1292-1300)
scripts/gen_opcodes.py (1)
compiler/core/src/opcodes.rs (1)
deopt(224-295)
🪛 Flake8 (7.3.0)
scripts/gen_opcodes.py
[error] 24-24: 'opcode_metadata_generator.cflags' imported but unused
(F401)
[error] 329-329: do not assign a lambda expression, use a def
(E731)
[error] 329-329: ambiguous variable name 'l'
(E741)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
- GitHub Check: Run snippets and cpython tests (windows-2025)
- GitHub Check: Run snippets and cpython tests (macos-latest)
- GitHub Check: Check Rust code with rustfmt and clippy
- GitHub Check: Run rust tests (windows-2025)
- GitHub Check: Run rust tests (macos-latest)
- GitHub Check: Run snippets and cpython tests (ubuntu-latest)
- GitHub Check: Run rust tests (ubuntu-latest)
- GitHub Check: Ensure compilation on various targets
- GitHub Check: Check the WASM package and demo
- GitHub Check: Run snippets and cpython tests on wasm-wasi
🔇 Additional comments (5)
stdlib/src/opcode.rs (1)
52-110:Opcode::try_fromaccepts pseudocode IDs—mirrors CPython’s ValueError.Great job aligning error handling and stack effect logic with the new opcode split. Using
Opcode::try_fromhere cleanly differentiates real and pseudo opcodes and keeps CPython-compatible validation.compiler/core/src/opcode.rs (2)
9-27:impl_try_from!drops pseudo-only values silently.The macro tries
RealOpcode::try_fromfirst; if that succeeds we never see pseudos. ButRealOpcode::try_fromreturnsErr(())for pseudo IDs, so the fallback works—no issue. Confirmed.
9-27:Macro-generated TryFrom keeps conversions DRY.Nice reuse of the macro to wire every integer type into
Opcode; keeps parity with CPython-style APIs with minimal duplication.compiler/core/src/opcodes.rs (2)
452-469:Confirm flag mapping forhas_exc.Using CPython’s HAS_PURE flag to back RustPython’s
has_excis intentional per prior discussion—thanks for preserving the semantics.
547-551:is_validexcludes pseudo-opcodes.The real-opcode
is_validstops at 0..=118 | 149..=222 | 236..=254, so pseudos are properly filtered here; consistent with stdlib predicates once patched.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
There was a problem hiding this 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
♻️ Duplicate comments (3)
scripts/gen_opcodes.py (3)
24-24:Drop the unusedcflagsimport.The import triggers flake8 F401 and is never referenced in the script.
Apply this diff:
-from opcode_metadata_generator import cflags
53-54:Replace lambda assignments with proper methods.Assigning lambdas to class attributes violates PEP 8 E731 and reduces maintainability. These monkey-patch
StackOffsetmethods used by CPython's stack analyzer.Apply this diff to define proper functions:
-StackOffset.pop = lambda self, item: self.popped.append(_var_size(item))-StackOffset.push = lambda self, item: self.pushed.append(_var_size(item))+def _stack_offset_pop(self, item):+ self.popped.append(_var_size(item))++def _stack_offset_push(self, item):+ self.pushed.append(_var_size(item))++StackOffset.pop = _stack_offset_pop+StackOffset.push = _stack_offset_push
344-344:Replace lambda and rename the ambiguous parameter.The lambda assigned to
fviolates flake8 E731, and its parameterlis ambiguous (E741). Use a descriptive name likedeopt_listand define a proper function.Apply this diff:
- f = lambda l: "|".join(f"Self::{x}" for x in l)+ def format_deopt_variants(deopt_list):+ return "|".join(f"Self::{x}" for x in deopt_list)+ branches = ",\n".join(- f"{f(deopt)} => Self::{name}" for name, deopt in sorted(deopts.items())+ f"{format_deopt_variants(deopt)} => Self::{name}" for name, deopt in sorted(deopts.items()) )
🧹 Nitpick comments (1)
scripts/gen_opcodes.py (1)
234-279:Document the TryFrom generation logic.The
impl_try_from_numsproperty contains complex branching logic (lines 245-256) that determines whether narrowing/widening conversions require.try_into(),.into(), or direct use. A brief comment explaining the four cases (sign mismatch, widen, exact match, narrow) would aid future maintainers.Consider adding a docstring or inline comments like:
deffn_prefix(typ:str):""" Generate the TryFrom prefix based on type compatibility. Cases: 1. Sign mismatch (u8 vs i8): requires try_into 2. Widening (u8 to u16): requires try_into for safety 3. Exact match (u8 to u8): use directly 4. Narrowing (u16 to u8): use into (infallible) """s_val=int(self.typ[1:])# ... rest of implementation
📜 Review details
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
compiler/core/src/opcodes.rs(1 hunks)scripts/gen_opcodes.py(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- compiler/core/src/opcodes.rs
🧰 Additional context used
🧬 Code graph analysis (1)
scripts/gen_opcodes.py (1)
compiler/core/src/opcodes.rs (1)
deopt(224-295)
🪛 Flake8 (7.3.0)
scripts/gen_opcodes.py
[error] 24-24: 'opcode_metadata_generator.cflags' imported but unused
(F401)
[error] 344-344: do not assign a lambda expression, use a def
(E731)
[error] 344-344: ambiguous variable name 'l'
(E741)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
- GitHub Check: Run snippets and cpython tests (windows-2025)
- GitHub Check: Ensure compilation on various targets
- GitHub Check: Check the WASM package and demo
- GitHub Check: Run snippets and cpython tests (ubuntu-latest)
- GitHub Check: Check Rust code with rustfmt and clippy
- GitHub Check: Run snippets and cpython tests (macos-latest)
- GitHub Check: Run rust tests (ubuntu-latest)
- GitHub Check: Run rust tests (windows-2025)
- GitHub Check: Run snippets and cpython tests on wasm-wasi
- GitHub Check: Run rust tests (macos-latest)
🔇 Additional comments (2)
scripts/gen_opcodes.py (2)
295-321:No action needed:.to_c()produces valid Rust expressions
383-386:Regex substitution is safe; no unintended replacements detected
The existingcompiler/core/src/opcodes.rsshows only intended enum variants (RealOpcode,PseudoOpcode, etc.) in comments and code, and all Rust keywords (impl,fn,pub,const,match,Self) remain intact.
Uh oh!
There was an error while loading.Please reload this page.
youknowone left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
@coolreader18 What will be the best way to solve it?
@ShaharNaveh Do we need to have different type for Instruction and RealOpCode? Otherwise, just in case, can it be defined like:
struct RealOpCode(bytecode::Instruction);compiler/core/src/opcodes.rs Outdated
| implTryFrom<i8>forRealOpcode{ | ||
| typeError =(); | ||
| fntry_from(raw:i8) ->Result<Self,Self::Error>{ | ||
| let id = raw.try_into().map_err(|_|())?; | ||
| ifSelf::is_valid(id){ | ||
| // SAFETY: We just validated that we have a valid opcode id. | ||
| Ok(unsafe{Self::new_unchecked(id)}) | ||
| }else{ | ||
| Err(()) | ||
| } | ||
| } | ||
| } | ||
| implTryFrom<i16>forRealOpcode{ | ||
| typeError =(); | ||
| fntry_from(raw:i16) ->Result<Self,Self::Error>{ | ||
| let id = raw.try_into().map_err(|_|())?; | ||
| ifSelf::is_valid(id){ | ||
| // SAFETY: We just validated that we have a valid opcode id. | ||
| Ok(unsafe{Self::new_unchecked(id)}) | ||
| }else{ | ||
| Err(()) | ||
| } | ||
| } | ||
| } | ||
| implTryFrom<i32>forRealOpcode{ | ||
| typeError =(); | ||
| fntry_from(raw:i32) ->Result<Self,Self::Error>{ | ||
| let id = raw.try_into().map_err(|_|())?; | ||
| ifSelf::is_valid(id){ | ||
| // SAFETY: We just validated that we have a valid opcode id. | ||
| Ok(unsafe{Self::new_unchecked(id)}) | ||
| }else{ | ||
| Err(()) | ||
| } | ||
| } | ||
| } | ||
| implTryFrom<i64>forRealOpcode{ | ||
| typeError =(); | ||
| fntry_from(raw:i64) ->Result<Self,Self::Error>{ | ||
| let id = raw.try_into().map_err(|_|())?; | ||
| ifSelf::is_valid(id){ | ||
| // SAFETY: We just validated that we have a valid opcode id. | ||
| Ok(unsafe{Self::new_unchecked(id)}) | ||
| }else{ | ||
| Err(()) | ||
| } | ||
| } | ||
| } | ||
| implTryFrom<i128>forRealOpcode{ | ||
| typeError =(); | ||
| fntry_from(raw:i128) ->Result<Self,Self::Error>{ | ||
| let id = raw.try_into().map_err(|_|())?; | ||
| ifSelf::is_valid(id){ | ||
| // SAFETY: We just validated that we have a valid opcode id. | ||
| Ok(unsafe{Self::new_unchecked(id)}) | ||
| }else{ | ||
| Err(()) | ||
| } | ||
| } | ||
| } | ||
| implTryFrom<isize>forRealOpcode{ | ||
| typeError =(); | ||
| fntry_from(raw:isize) ->Result<Self,Self::Error>{ | ||
| let id = raw.try_into().map_err(|_|())?; | ||
| ifSelf::is_valid(id){ | ||
| // SAFETY: We just validated that we have a valid opcode id. | ||
| Ok(unsafe{Self::new_unchecked(id)}) | ||
| }else{ | ||
| Err(()) | ||
| } | ||
| } | ||
| } | ||
| implTryFrom<u8>forRealOpcode{ | ||
| typeError =(); | ||
| fntry_from(id:u8) ->Result<Self,Self::Error>{ | ||
| ifSelf::is_valid(id){ | ||
| // SAFETY: We just validated that we have a valid opcode id. | ||
| Ok(unsafe{Self::new_unchecked(id)}) | ||
| }else{ | ||
| Err(()) | ||
| } | ||
| } | ||
| } | ||
| implTryFrom<u16>forRealOpcode{ | ||
| typeError =(); | ||
| fntry_from(raw:u16) ->Result<Self,Self::Error>{ | ||
| let id = raw.try_into().map_err(|_|())?; | ||
| ifSelf::is_valid(id){ | ||
| // SAFETY: We just validated that we have a valid opcode id. | ||
| Ok(unsafe{Self::new_unchecked(id)}) | ||
| }else{ | ||
| Err(()) | ||
| } | ||
| } | ||
| } | ||
| implTryFrom<u32>forRealOpcode{ | ||
| typeError =(); | ||
| fntry_from(raw:u32) ->Result<Self,Self::Error>{ | ||
| let id = raw.try_into().map_err(|_|())?; | ||
| ifSelf::is_valid(id){ | ||
| // SAFETY: We just validated that we have a valid opcode id. | ||
| Ok(unsafe{Self::new_unchecked(id)}) | ||
| }else{ | ||
| Err(()) | ||
| } | ||
| } | ||
| } | ||
| implTryFrom<u64>forRealOpcode{ | ||
| typeError =(); | ||
| fntry_from(raw:u64) ->Result<Self,Self::Error>{ | ||
| let id = raw.try_into().map_err(|_|())?; | ||
| ifSelf::is_valid(id){ | ||
| // SAFETY: We just validated that we have a valid opcode id. | ||
| Ok(unsafe{Self::new_unchecked(id)}) | ||
| }else{ | ||
| Err(()) | ||
| } | ||
| } | ||
| } | ||
| implTryFrom<u128>forRealOpcode{ | ||
| typeError =(); | ||
| fntry_from(raw:u128) ->Result<Self,Self::Error>{ | ||
| let id = raw.try_into().map_err(|_|())?; | ||
| ifSelf::is_valid(id){ | ||
| // SAFETY: We just validated that we have a valid opcode id. | ||
| Ok(unsafe{Self::new_unchecked(id)}) | ||
| }else{ | ||
| Err(()) | ||
| } | ||
| } | ||
| } | ||
| implTryFrom<usize>forRealOpcode{ | ||
| typeError =(); | ||
| fntry_from(raw:usize) ->Result<Self,Self::Error>{ | ||
| let id = raw.try_into().map_err(|_|())?; | ||
| ifSelf::is_valid(id){ | ||
| // SAFETY: We just validated that we have a valid opcode id. | ||
| Ok(unsafe{Self::new_unchecked(id)}) | ||
| }else{ | ||
| Err(()) | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
is this applicable?
https://docs.rs/num_enum/latest/num_enum/derive.TryFromPrimitive.html
Also for the psuedo opcode
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Yeah, this is great!
will modify the code
ShaharNaveh commentedOct 13, 2025
Yes, because imo opcode should be it's own enum. An instruction should contain a where
For impl<T:OpargType>Instruction<T>{pubfnnew(opcode:RealOpcode,raw_oparg:u32) ->Result<Self,MarshalError>{if !opcode.has_arg(){returnOk(Self{opcode,oparg:None});}let oparg =match opcode{RealOpcode::Resume =>ResumeOpcode::try_from(raw_oparg)?,// More typed oparg checks for specific opcodes _ =>Oparg(raw_oparg)};Ok(Self{ opcode,oparg:Some(oparg)})}} |
There was a problem hiding this 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
♻️ Duplicate comments (2)
stdlib/src/opcode.rs (1)
131-133:Filter pseudo-opcodes inis_validto match CPython semantics.Past review comments correctly noted that
is_validshould reject pseudo-opcodes, as they are not valid for runtime bytecode execution and CPython'sopcode.is_validexcludes them. Currently,Opcode::try_from(opcode).is_ok()returnstruefor pseudo-opcodes.Apply this diff to filter pseudo-opcodes:
#[pyfunction] fn is_valid(opcode: i32) -> bool {- Opcode::try_from(opcode).is_ok()+ matches!(Opcode::try_from(opcode), Ok(Opcode::Real(_))) }scripts/gen_opcodes.py (1)
53-78:Guard against empty input ingroup_ranges.The function unconditionally accesses
nums[0]on line 73, raisingIndexErrorif the input iterable is empty. While CPython's opcode metadata likely never produces empty ranges in practice, defensive coding would prevent potential future issues.Apply this diff to add an early return:
def group_ranges(it: "Iterable[int]") -> "Iterator[range]": """ Group consecutive numbers into ranges. Parameters ---------- it : Iterable[int] Numbers to group into ranges. Notes ----- Numbers in `it` must be sorted in ascending order. Examples -------- >>> nums = [0, 1, 2, 3, 17, 18, 42, 50, 51] >>> list(group_ranges(nums)) [range(0, 4), range(17, 19), range(42, 43), range(50, 52)] """ nums = list(it)+ if not nums:+ return start = prev = nums[0]
📜 Review details
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (5)
compiler/core/Cargo.toml(1 hunks)compiler/core/src/opcode.rs(1 hunks)compiler/core/src/opcodes.rs(1 hunks)scripts/gen_opcodes.py(1 hunks)stdlib/src/opcode.rs(3 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.rs
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.rs: Format Rust code with the default rustfmt style (runcargo fmt)
Run clippy and fix any warnings or lints introduced by your changes
Follow Rust best practices for error handling and memory management
Files:
stdlib/src/opcode.rscompiler/core/src/opcode.rscompiler/core/src/opcodes.rs
{vm,stdlib}/**/*.rs
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Use RustPython macros (
pyclass,pymodule,pyfunction, etc.) when implementing Python functionality in Rust
Files:
stdlib/src/opcode.rs
🧬 Code graph analysis (3)
stdlib/src/opcode.rs (3)
compiler/core/src/bytecode.rs (2)
stack_effect(1391-1516)try_from(814-820)compiler/core/src/opcode.rs (2)
try_from(13-20)try_from(26-29)compiler/core/src/opcodes.rs (14)
has_arg(303-445)has_arg(1026-1038)has_const(449-454)has_const(1042-1044)has_name(527-549)has_name(1079-1087)has_jump(490-506)has_jump(1067-1069)has_free(477-486)has_free(1061-1063)has_local(510-523)has_local(1073-1075)has_exc(458-473)has_exc(1048-1057)
scripts/gen_opcodes.py (1)
compiler/core/src/opcodes.rs (1)
deopt(228-299)
compiler/core/src/opcodes.rs (1)
stdlib/src/opcode.rs (8)
has_arg(136-138)has_const(141-143)has_exc(166-168)has_free(156-158)has_jump(151-153)has_local(161-163)has_name(146-148)is_valid(131-133)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
- GitHub Check: Run snippets and cpython tests (windows-latest)
- GitHub Check: Run snippets and cpython tests (ubuntu-latest)
- GitHub Check: Run rust tests (windows-latest)
- GitHub Check: Run rust tests (macos-latest)
- GitHub Check: Run snippets and cpython tests (macos-latest)
- GitHub Check: Run rust tests (ubuntu-latest)
- GitHub Check: Ensure compilation on various targets
- GitHub Check: Run snippets and cpython tests on wasm-wasi
- GitHub Check: Check the WASM package and demo
- GitHub Check: Check Rust code with rustfmt and clippy
🔇 Additional comments (8)
compiler/core/Cargo.toml (1)
20-21:LGTM! Dependencies align with the new opcode system.The addition of
num_enumandnum-traitsappropriately supports the generated opcode infrastructure.num_enumprovides theTryFromPrimitivederive macro used inopcodes.rs, andnum-traitssupplies thePrimInttrait bound for the error constructor.stdlib/src/opcode.rs (3)
7-11:LGTM! Updated imports and type change.The imports now correctly reference the new
Opcode,PseudoOpcode, andRealOpcodetypes from thevm::opcodemodule. The change ofENABLE_SPECIALIZATIONfromi8tou8aligns with CPython's unsigned value and removes unnecessary signedness.
23-117:Stack effect implementation aligns well with CPython.The refactored
stack_effectcorrectly handlesRealOpcodeandPseudoOpcodeseparately, mirrors CPython's special-case treatment ofExitInitCheck, rejects specialized opcodes viadeopt(), and properly computes stack effects for pseudo-opcodes with jump-dependent logic.
119-168:LGTM! Macro-based real opcode checks.The
real_opcode_check!macro correctly filters out pseudo-opcodes by attempting conversion toRealOpcodeviau8::try_fromand delegates to the appropriatehas_*predicate. This ensures allhas_arg,has_const,has_name,has_jump,has_free,has_local, andhas_excfunctions only operate on real opcodes, consistent with CPython semantics.scripts/gen_opcodes.py (1)
112-343:Well-structured generator design.The abstraction via
InstructionsMeta,RealInstructions, andPseudoInstructionscleanly separates concerns and generates comprehensive Rust opcode scaffolding including predicates, stack effects, deoptimization mappings, and TryFrom conversions. The CPython variant-to-Rust identifier substitution and automaticcargo fmtinvocation are nice touches for maintainability.compiler/core/src/opcodes.rs (1)
1-1109:Generated opcode definitions are comprehensive and correct.The auto-generated
RealOpcode(repr(u8), 223 variants) andPseudoOpcode(repr(u16), 12 variants) enums provide exhaustive CPython 3.13.7 opcode coverage. The implementation includes:
deopt()mappings for specialized opcodes- Predicate methods (
has_arg,has_const,has_exc,has_free,has_jump,has_local,has_name)- Stack effect calculations (
num_popped,num_pushed) with oparg-dependent logicis_valid()range checks- TryFromPrimitive conversions with custom MarshalError constructor
The generated code follows Rust best practices (const methods where possible, exhaustive matching, proper repr annotations).
compiler/core/src/opcode.rs (2)
1-8:LGTM! Clean opcode wrapper design.The
Opcodeenum unifiesRealOpcodeandPseudoOpcodeunder a single type, enabling unified handling while preserving type safety. The public re-export ofRealOpcodeandPseudoOpcodemaintains flexibility for code that needs direct access to the underlying types.
32-48:LGTM! Macro reduces TryFrom boilerplate.The
impl_try_from!macro generates consistentTryFromimplementations for signed and unsigned integer types by first converting tou16and delegating to the existingTryFrom<u16>implementation. This reduces code duplication and ensures uniform error handling.
Uh oh!
There was an error while loading.Please reload this page.
There was a problem hiding this 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
♻️ Duplicate comments (1)
scripts/gen_opcodes.py (1)
49-50:Avoid assigning lambdas to methods (E731); use named defs.Define helpers and assign them to
StackOffsetfor clarity and lint compliance. (Similar to prior feedback.)-StackOffset.pop = lambda self, item: self.popped.append(_var_size(item))-StackOffset.push = lambda self, item: self.pushed.append(_var_size(item))+def _stackoffset_pop(self, item):+ self.popped.append(_var_size(item))++def _stackoffset_push(self, item):+ self.pushed.append(_var_size(item))++StackOffset.pop = _stackoffset_pop+StackOffset.push = _stackoffset_push
🧹 Nitpick comments (4)
scripts/gen_opcodes.py (3)
14-21:Make CPython path configurable and fail with a clear message.Hardcoding
CPYTHON_PATHrisks opaque failures. Allow an env override and validate the path.-CPYTHON_PATH = (- pathlib.Path(__file__).parents[2] / "cpython"-)+CPYTHON_PATH = pathlib.Path(+ sys.environ.get("RUSTPYTHON_CPYTHON_PATH", "")+) or (pathlib.Path(__file__).parents[2] / "cpython")++if not CPYTHON_PATH.exists():+ sys.exit(f"cpython checkout not found at: {CPYTHON_PATH}. "+ "Set RUSTPYTHON_CPYTHON_PATH to override.")
253-256:Escape and order tokens in the regex replacement.Unescaped alternation can mis-match; ordering prevents short-name shadowing.
- replacements = {name: enum_variant_name(name) for name in analysis.opmap}- inner_pattern = "|".join(replacements)+ replacements = {name: enum_variant_name(name) for name in analysis.opmap}+ # Longest-first to avoid partial matches (e.g., LOAD vs LOAD_CONST)+ names = sorted(replacements.keys(), key=len, reverse=True)+ inner_pattern = "|".join(re.escape(n) for n in names) pattern = re.compile(rf"\b({inner_pattern})\b") out = pattern.sub(lambda m: replacements[m.group(0)], out)
258-259:Surface formatting failures and keep output consistent.Use
check=Trueto fail fast; ifcargois missing, at least warn.- print("Running `cargo fmt`")- subprocess.run(["cargo", "fmt"], cwd=ROOT)+ print("Running `cargo fmt`")+ try:+ subprocess.run(["cargo", "fmt"], cwd=ROOT, check=True)+ except Exception as e:+ print(f"Warning: `cargo fmt` failed: {e}", file=sys.stderr)compiler/core/src/opcodes.rs (1)
227-299:Optional: simplify deopt for readability.Current
Some(match ... _ => return None)works; consider a directmatchto avoid early return inside the expression.- pub const fn deopt(&self) -> Option<Self> {- Some(match *self {+ pub const fn deopt(&self) -> Option<Self> {+ match *self { /* arms unchanged */- _ => return None,- })+ _ => return None,+ } }
📜 Review details
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
compiler/core/src/opcodes.rs(1 hunks)scripts/gen_opcodes.py(1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rs
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
**/*.rs: Format Rust code with the default rustfmt style (runcargo fmt)
Run clippy and fix any warnings or lints introduced by your changes
Follow Rust best practices for error handling and memory management
Files:
compiler/core/src/opcodes.rs
🧬 Code graph analysis (2)
compiler/core/src/opcodes.rs (1)
stdlib/src/opcode.rs (7)
has_arg(136-138)has_const(141-143)has_exc(166-168)has_free(156-158)has_jump(151-153)has_local(161-163)has_name(146-148)
scripts/gen_opcodes.py (2)
compiler/core/src/marshal.rs (1)
instructions(188-195)compiler/core/src/opcodes.rs (1)
deopt(228-299)
🪛 Flake8 (7.3.0)
scripts/gen_opcodes.py
[error] 12-12: 'collections.abc.Iterable' imported but unused
(F401)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
- GitHub Check: Run snippets and cpython tests (ubuntu-latest)
- GitHub Check: Run rust tests (ubuntu-latest)
- GitHub Check: Run snippets and cpython tests (windows-latest)
- GitHub Check: Run rust tests (macos-latest)
- GitHub Check: Run rust tests (windows-latest)
- GitHub Check: Ensure compilation on various targets
- GitHub Check: Run snippets and cpython tests on wasm-wasi
- GitHub Check: Run snippets and cpython tests (macos-latest)
- GitHub Check: Check the WASM package and demo
- GitHub Check: Check Rust code with rustfmt and clippy
🔇 Additional comments (2)
compiler/core/src/opcodes.rs (2)
9-12:Good use of num_enum for fallible conversions.Derive + error_type hook is clean and const-friendly. LGTM.
988-1005:Approve PseudoOpcode derivation; num_enum dependency confirmed
repr(u16) + TryFromPrimitive matches design and num_enum is declared in Cargo.toml.
| importtyping | ||
| iftyping.TYPE_CHECKING: | ||
| fromcollections.abcimportIterable,Iterator |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Fix unused import (flake8 F401).
Iterable isn’t used. Keep onlyIterator.
-if typing.TYPE_CHECKING:- from collections.abc import Iterable, Iterator+if typing.TYPE_CHECKING:+ from collections.abc import Iterator
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| fromcollections.abcimportIterable,Iterator | |
| iftyping.TYPE_CHECKING: | |
| fromcollections.abcimportIterator |
🧰 Tools
🪛 Flake8 (7.3.0)
[error] 12-12: 'collections.abc.Iterable' imported but unused
(F401)
🤖 Prompt for AI Agents
In scripts/gen_opcodes.py around line 12, the import statement brings in bothIterable and Iterator but Iterable is unused; remove Iterable from the importand keep only Iterator so the line imports Iterator from collections.abc tosatisfy flake8 F401.| const fn new_invalid_bytecode<T: num_traits::int::PrimInt>(_: T) -> MarshalError {{ | ||
| MarshalError::InvalidBytecode | ||
| }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
🧩 Analysis chain
Confirm num_traits is declared for generated code.
new_invalid_bytecode usesnum_traits::int::PrimInt; ensurecompiler/core/Cargo.toml includesnum_traits.
You can verify with:
🏁 Script executed:
#!/bin/bashrg -nP'^\s*num_traits\s*=' -g'compiler/**/Cargo.toml'
Length of output: 0
🏁 Script executed:
#!/bin/bash# List all Cargo.toml files under compiler/find compiler -type f -name Cargo.toml# Search for any num_traits references in those toml filesrg -n'num_traits' -g'compiler/**/*.toml'
Length of output: 127
Add num_traits dependency to compiler/core/Cargo.toml: Generated code invokesnum_traits::int::PrimInt but nonum_traits entry exists in any compiler/*.toml—add it under[dependencies].
🤖 Prompt for AI Agents
In scripts/gen_opcodes.py around lines 248 to 250, the generated Rust usesnum_traits::int::PrimInt but compiler/core/Cargo.toml has no num-traitsdependency; add num-traits to the [dependencies] section (e.g. num-traits ="0.2") in compiler/core/Cargo.toml, run cargo update/build to ensure the crateresolves, and regenerate/verify the generated code compiles.youknowone commentedOct 14, 2025
Somehow, our Instruction is a u8 backed type because Arg is a zero-sized type. This is a trick to type the argument but not actually owning a value. |
ShaharNaveh commentedOct 14, 2025 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
So, if I understand it correctly we must keep |
youknowone commentedOct 15, 2025
I am currently not perfectly understanding how they are different in Python. |
ShaharNaveh commentedOct 15, 2025
Some opcodes that we have does not exist in Cpython & Some were changed. I thought it would be better if we would use CPython
Completely agree. Using Rust safety features is better than forcing rust to behave like C. For now, I'll convert this PR to draft and try to see if I'm able to auto-generate the |
youknowone commentedOct 15, 2025
I agree it will be great if dis.py perfectly work.
I agree here too. But it may not be always possible especially when CPython is updated. Because CPython doesn't guarantee bytecode compatibility, every python version can have different bytecode. We can patch bytecode to be aligned to CPython. But if we have incompatibility, |
ShaharNaveh commentedOct 15, 2025
Sounds good. I'll invest more time to see how we can auto generate the |
youknowone commentedOct 23, 2025
Now Python has exception table for code object, which is related to the newer except instructions. |
ShaharNaveh commentedOct 23, 2025
Are we aiming now for Python 3.14? what are the steps to achieve it? Updating the Instructions can't be only thing needed, right? |
youknowone commentedOct 23, 2025
If you are interested in 3.14 support,#5484 is the guideline |
youknowone commentedOct 24, 2025
Oh, to prevent miscommunication, the exception table is not related to 3.14. It is probably a 3.11 feature which we didn't implement yet. |
ShaharNaveh commentedOct 24, 2025
No worries. I think that this PR will stay open for a while as the changes required to use the updated instructions is very large. meanwhile I'll open small PRs to get us there slowly but surely |
Uh oh!
There was an error while loading.Please reload this page.
This PR's original goal was to auto generate an enum that will replace:
RustPython/compiler/core/src/bytecode.rs
Lines 539 to 795 in3a6fda4
RustPython/compiler/core/src/bytecode.rs
Lines 1335 to 1697 in3a6fda4
But turned out to be more work than originally anticipated.
From what I see ATM our largest gaps are that we have opcodes that doesn't exist in Cpython (3.13.7) such as
RustPython/compiler/core/src/bytecode.rs
Lines 620 to 625 in3a6fda4
So, I have converted this PR to address#6156 (review)
cc:@youknowone@coolreader18
Followup for#6156 (comment)Summary by CodeRabbit
New Features
Bug Fixes
Chores