| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
📝 Walkthrough
WalkthroughRefactors stack-effect handling by introducing a new StackEffect type (pushed/popped + effect), extends InstructionMetadata with stack_effect_info (returning StackEffect) while keeping a default stack_effect delegating to it, adds From<OpArg> for u32, re-exports StackEffect, and updates call sites in codegen and stdlib to use the new API (plus a minor local import removal). Changes
Sequence Diagram(s)sequenceDiagram
participant Codegen as Codegen (crates/codegen)
participant Stdlib as Stdlib (_opcode)
participant Compiler as Compiler-core (AnyInstruction / Instruction)
participant OpArg as OpArg (converter)
Note over Codegen,Stdlib: Obtain numeric oparg and request stack effect
Codegen->>OpArg: convert/forward oparg -> u32 (use `.into()` where needed)
Stdlib->>OpArg: use oparg as u32 / forward as-is
Codegen->>Compiler: call stack_effect_info(u32) or stack_effect(u32)
Stdlib->>Compiler: call stack_effect(u32)
Compiler-->>Codegen: return StackEffect (pushed,popped) / .effect()
Compiler-->>Stdlib: return StackEffect (pushed,popped) / .effect()
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
Poem🚥 Pre-merge checks | ✅ 3 ✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
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. ❤️ ShareComment @coderabbitai help to get the list of available commands and usage tips. |
Sorry, something went wrong.
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)crates/stdlib/src/_opcode.rs (1)169-201: Add validation to reject negative oparg values.
CPython's dis.stack_effect treats oparg as an unsigned bytecode argument and raises ValueError("invalid opcode or oparg") if oparg is negative. Your change from u32 to i32 allows negatives to pass through unchecked, creating a compatibility divergence. Add a guard:
if oparg < 0 { return Err(vm.new_value_error("oparg must be non-negative")); }
In `@crates/codegen/src/ir.rs`:
- Line 734: Replace the unchecked cast u32::from(info.arg) as i32 with a checked
conversion using i32::try_from(u32::from(info.arg)) and handle the Err case
instead of allowing silent wraparound; specifically, call
instr.stack_effect(i32::try_from(u32::from(info.arg)).expect("OpArg out of i32
range")) or propagate an error if appropriate for your context, and make the
same replacement for the other occurrence noted (the second use of
instr.stack_effect with info.arg).
In `@crates/compiler-core/src/bytecode/instruction.rs`:
- Around line 900-906: The match arm for the opcode BinaryOpInplaceAddUnicode
currently returns 0 pushes which contradicts the IR treatment (pop 2 / push 1)
and causes stack_effect = -2; update the implementation that computes pushes
(e.g., num_pushed or the match in instruction.rs where BinaryOpInplaceAddUnicode
is handled) to return 1 like the other binary ops
(BinaryOpAddFloat/Int/Unicode/Extend/Multiply) so the stack depth calculation
matches the IR semantics.
Sorry, something went wrong.
| /// How many items this instruction is popping from the stack. | ||
| fn num_popped(&self, oparg: i32) -> i32; | ||
|
|
||
| /// How many items this instruction is pushing on the stack. | ||
| fn num_pushed(&self, oparg: i32) -> i32; |
There was a problem hiding this comment.
I like this idea. How do you think about stack_popped_and_pushed(&self, oparg: i32) -> (i32, i32) to avoid a whole instruction match twice
Sorry, something went wrong.
There was a problem hiding this comment.
Sure, I can do it as a followup improvement if this is fine by you
Sorry, something went wrong.
There was a problem hiding this comment.
I've made StackEffect into a struct, this will be clearer than returning an unnamed tuple
Sorry, something went wrong.
There was a problem hiding this comment.
oh, i meant not about changing stack_effect return type but merging num_popped and num_pushed into single function returning a tuple (or StackEffect, that's looking better!) to avoid full instruciton match for each function.
if we are going to use stack_effect as a single number for most of places, keeping current -> i32 will be easier for user side.
Sorry, something went wrong.
| } | ||
|
|
||
| pub trait InstructionMetadata { | ||
| pub trait StackEffect { |
There was a problem hiding this comment.
What's good if we split this trait? It seems required to implement for the all types implementing InstructionMetadata
Sorry, something went wrong.
There was a problem hiding this comment.
No need really, it made more sense for me to split it. but it can be part of InstructionMetadata. I'm fine with whatever you want:)
Sorry, something went wrong.
There was a problem hiding this comment.
Splitting traits as grouping is looking attractive while defining and implementing traits, but it usually leads to import hell for user side. I'd like to keep a single trait if all InstructionMetadata and StackEffect has manual implementation requirements. It can be splitted when one has manual implementation but the other one has blanket implementation (or any kind of different implementation strategy)
Sorry, something went wrong.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agentsIn `@crates/compiler-core/src/bytecode/instruction.rs`: - Around line 1396-1435: The From<StackEffect> for i32 impl uses unsafe unwrap_unchecked on conversions of StackEffect.pushed() and .popped(), which can UB if values exceed i32::MAX; replace the unsafe block by performing safe conversions (use i32::try_from(...) and propagate or panic with expect including the offending value), e.g. convert pushed and popped to i32 via try_from and subtract normally, and update StackEffect::effect() to rely on this safe conversion; also fix the "SAFTEY" typo to "SAFETY" in the comment to avoid confusion.
Sorry, something went wrong.
| fn stack_effect_info(&self, oparg: u32) -> StackEffect; | ||
|
|
||
| /// Stack effect of [`Self::stack_effect_info`]. | ||
| fn stack_effect(&self, oparg: u32) -> i32 { |
There was a problem hiding this comment.
👍
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
Auto generated both num_popped and num_pushed, and then compared the result with the current stack_effect impl. This will make it easier to auto-generate this in the future, and gets us 1 step closer to #6746 as imo it's better to construct the instruction once instead of validate that the oparg is valid at every operation. Also, it's easier to see if we differences in our opcode impls from CPython (if the stack_effect does not match)
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.