Skip to content

Commit 3d61ff1

Browse files
committed
stack is [Option<PyObjectRef>]
1 parent e191864 commit 3d61ff1

File tree

8 files changed

+355
-316
lines changed

8 files changed

+355
-316
lines changed

Lib/test/test_xml_etree.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2301,7 +2301,6 @@ def test_bug_xmltoolkit62(self):
23012301
self.assertEqual(t.find('.//paragraph').text,
23022302
'A new cultivar of Begonia plant named \u2018BCT9801BEG\u2019.')
23032303

2304-
@unittest.expectedFailure # TODO: RUSTPYTHON
23052304
@unittest.skipIf(sys.gettrace(), "Skips under coverage.")
23062305
def test_bug_xmltoolkit63(self):
23072306
# Check reference leak.

crates/codegen/src/compile.rs

Lines changed: 64 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,10 +1037,11 @@ impl Compiler {
10371037

10381038
// Call __exit__(None, None, None) - compiler_call_exit_with_nones
10391039
// Stack: [..., __exit__] or [..., return_value, __exit__]
1040+
emit!(self, Instruction::PushNull);
10401041
self.emit_load_const(ConstantData::None);
10411042
self.emit_load_const(ConstantData::None);
10421043
self.emit_load_const(ConstantData::None);
1043-
emit!(self, Instruction::CallFunctionPositional { nargs: 3 });
1044+
emit!(self, Instruction::Call { nargs: 3 });
10441045

10451046
// For async with, await the result
10461047
if matches!(info.fb_type, FBlockType::AsyncWith) {
@@ -1875,13 +1876,14 @@ impl Compiler {
18751876

18761877
let assertion_error = self.name("AssertionError");
18771878
emit!(self, Instruction::LoadGlobal(assertion_error));
1879+
emit!(self, Instruction::PushNull);
18781880
match msg {
18791881
Some(e) => {
18801882
self.compile_expression(e)?;
1881-
emit!(self, Instruction::CallFunctionPositional { nargs: 1 });
1883+
emit!(self, Instruction::Call { nargs: 1 });
18821884
}
18831885
None => {
1884-
emit!(self, Instruction::CallFunctionPositional { nargs: 0 });
1886+
emit!(self, Instruction::Call { nargs: 0 });
18851887
}
18861888
}
18871889
emit!(
@@ -2095,14 +2097,16 @@ impl Compiler {
20952097
fn prepare_decorators(&mut self, decorator_list: &[Decorator]) -> CompileResult<()> {
20962098
for decorator in decorator_list {
20972099
self.compile_expression(&decorator.expression)?;
2100+
// PUSH_NULL for self_or_null slot (decorator is not a method call)
2101+
emit!(self, Instruction::PushNull);
20982102
}
20992103
Ok(())
21002104
}
21012105

21022106
fn apply_decorators(&mut self, decorator_list: &[Decorator]) {
2103-
// Apply decorators:
2107+
// Apply decorators - each pops [decorator, NULL, arg] and pushes result
21042108
for _ in decorator_list {
2105-
emit!(self, Instruction::CallFunctionPositional { nargs: 1 });
2109+
emit!(self, Instruction::Call { nargs: 1 });
21062110
}
21072111
}
21082112

@@ -2142,9 +2146,10 @@ impl Compiler {
21422146

21432147
// Create type params function with closure
21442148
self.make_closure(code, bytecode::MakeFunctionFlags::empty())?;
2149+
emit!(self, Instruction::PushNull);
21452150

21462151
// Call the function immediately
2147-
emit!(self, Instruction::CallFunctionPositional { nargs: 0 });
2152+
emit!(self, Instruction::Call { nargs: 0 });
21482153

21492154
Ok(())
21502155
}
@@ -3308,22 +3313,42 @@ impl Compiler {
33083313
self.make_closure(type_params_code, bytecode::MakeFunctionFlags::empty())?;
33093314

33103315
// Call the closure
3316+
// Call expects stack: [callable, self_or_null, arg1, ..., argN]
33113317
if num_typeparam_args > 0 {
3318+
// Stack: [arg1, ..., argN, closure]
3319+
// Need: [closure, NULL, arg1, ..., argN]
3320+
emit!(self, Instruction::PushNull);
3321+
// Stack: [arg1, ..., argN, closure, NULL]
33123322
emit!(
33133323
self,
3314-
Instruction::Swap {
3315-
index: (num_typeparam_args + 1) as u32
3324+
Instruction::Reverse {
3325+
amount: (num_typeparam_args + 2) as u32
33163326
}
33173327
);
3328+
// Stack: [NULL, closure, argN, ..., arg1]
3329+
emit!(self, Instruction::Swap { index: 2 });
3330+
// Stack: [closure, NULL, argN, ..., arg1]
3331+
if num_typeparam_args > 1 {
3332+
emit!(
3333+
self,
3334+
Instruction::Reverse {
3335+
amount: num_typeparam_args as u32
3336+
}
3337+
);
3338+
}
3339+
// Stack: [closure, NULL, arg1, ..., argN]
33183340
emit!(
33193341
self,
3320-
Instruction::CallFunctionPositional {
3342+
Instruction::Call {
33213343
nargs: num_typeparam_args as u32
33223344
}
33233345
);
33243346
} else {
3325-
// No arguments, just call the closure
3326-
emit!(self, Instruction::CallFunctionPositional { nargs: 0 });
3347+
// Stack: [closure]
3348+
emit!(self, Instruction::PushNull);
3349+
// Stack: [closure, NULL] - already correct layout
3350+
// Call pops: args (0), then self_or_null (NULL), then callable (closure)
3351+
emit!(self, Instruction::Call { nargs: 0 });
33273352
}
33283353
}
33293354

@@ -3691,6 +3716,7 @@ impl Compiler {
36913716

36923717
// Generate class creation code
36933718
emit!(self, Instruction::LoadBuildClass);
3719+
emit!(self, Instruction::PushNull);
36943720

36953721
// Set up the class function with type params
36963722
let mut func_flags = bytecode::MakeFunctionFlags::empty();
@@ -3720,24 +3746,30 @@ impl Compiler {
37203746
if let Some(arguments) = arguments
37213747
&& !arguments.keywords.is_empty()
37223748
{
3749+
let mut kwarg_names = vec![];
37233750
for keyword in &arguments.keywords {
37243751
if let Some(name) = &keyword.arg {
3725-
self.emit_load_const(ConstantData::Str {
3752+
kwarg_names.push(ConstantData::Str {
37263753
value: name.as_str().into(),
37273754
});
3755+
} else {
3756+
panic!("keyword argument name must be set");
37283757
}
37293758
self.compile_expression(&keyword.value)?;
37303759
}
3760+
self.emit_load_const(ConstantData::Tuple {
3761+
elements: kwarg_names,
3762+
});
37313763
emit!(
37323764
self,
3733-
Instruction::CallFunctionKeyword {
3765+
Instruction::CallKw {
37343766
nargs: nargs
37353767
+ u32::try_from(arguments.keywords.len())
37363768
.expect("too many keyword arguments")
37373769
}
37383770
);
37393771
} else {
3740-
emit!(self, Instruction::CallFunctionPositional { nargs });
3772+
emit!(self, Instruction::Call { nargs });
37413773
}
37423774

37433775
// Return the created class
@@ -3748,10 +3780,12 @@ impl Compiler {
37483780

37493781
// Execute the type params function
37503782
self.make_closure(type_params_code, bytecode::MakeFunctionFlags::empty())?;
3751-
emit!(self, Instruction::CallFunctionPositional { nargs: 0 });
3783+
emit!(self, Instruction::PushNull);
3784+
emit!(self, Instruction::Call { nargs: 0 });
37523785
} else {
37533786
// Non-generic class: standard path
37543787
emit!(self, Instruction::LoadBuildClass);
3788+
emit!(self, Instruction::PushNull);
37553789

37563790
// Create class function with closure
37573791
self.make_closure(class_code, bytecode::MakeFunctionFlags::empty())?;
@@ -3762,7 +3796,7 @@ impl Compiler {
37623796
} else {
37633797
CallType::Positional { nargs: 2 }
37643798
};
3765-
self.compile_normal_call(call);
3799+
self.compile_call_with_self(call);
37663800
}
37673801

37683802
// Step 4: Apply decorators and store (common to both paths)
@@ -3912,10 +3946,11 @@ impl Compiler {
39123946
// Stack: [..., __exit__]
39133947
// Call __exit__(None, None, None)
39143948
self.set_source_range(with_range);
3949+
emit!(self, Instruction::PushNull);
39153950
self.emit_load_const(ConstantData::None);
39163951
self.emit_load_const(ConstantData::None);
39173952
self.emit_load_const(ConstantData::None);
3918-
emit!(self, Instruction::CallFunctionPositional { nargs: 3 });
3953+
emit!(self, Instruction::Call { nargs: 3 });
39193954
if is_async {
39203955
emit!(self, Instruction::GetAwaitable);
39213956
self.emit_load_const(ConstantData::None);
@@ -6088,41 +6123,33 @@ impl Compiler {
60886123

60896124
fn compile_call(&mut self, func: &Expr, args: &Arguments) -> CompileResult<()> {
60906125
// Method call: obj → LOAD_ATTR_METHOD → [method, self_or_null] → args → CALL_WITH_SELF
6091-
// Regular call: func → args → CALL
6126+
// Regular call: func → PUSH_NULL → args → CALL_WITH_SELF
60926127
if let Expr::Attribute(ExprAttribute { value, attr, .. }) = &func {
60936128
// Method call: compile object, then LOAD_ATTR_METHOD
60946129
// LOAD_ATTR_METHOD pushes [method, self_or_null] on stack
60956130
self.compile_expression(value)?;
60966131
let idx = self.name(attr.as_str());
60976132
emit!(self, Instruction::LoadAttrMethod { idx });
6098-
// Compile args, then use CallWithSelf which handles self_or_null
6133+
// Compile args, then use Call which handles self_or_null
60996134
let call = self.compile_call_inner(0, args)?;
61006135
self.compile_call_with_self(call);
61016136
} else {
6102-
// Regular call: just compile function and args
6137+
// Regular call: push func, then NULL for self_or_null slot
6138+
// Stack layout: [func, NULL, args...] - same as method call [func, self, args...]
61036139
self.compile_expression(func)?;
6140+
emit!(self, Instruction::PushNull);
61046141
let call = self.compile_call_inner(0, args)?;
6105-
self.compile_normal_call(call);
6142+
self.compile_call_with_self(call);
61066143
}
61076144
Ok(())
61086145
}
61096146

61106147
fn compile_call_with_self(&mut self, ty: CallType) {
61116148
match ty {
61126149
CallType::Positional { nargs } => {
6113-
emit!(self, Instruction::CallWithSelf { nargs })
6114-
}
6115-
CallType::Keyword { nargs } => emit!(self, Instruction::CallWithSelfKw { nargs }),
6116-
CallType::Ex { has_kwargs } => emit!(self, Instruction::CallWithSelfEx { has_kwargs }),
6117-
}
6118-
}
6119-
6120-
fn compile_normal_call(&mut self, ty: CallType) {
6121-
match ty {
6122-
CallType::Positional { nargs } => {
6123-
emit!(self, Instruction::CallFunctionPositional { nargs })
6150+
emit!(self, Instruction::Call { nargs })
61246151
}
6125-
CallType::Keyword { nargs } => emit!(self, Instruction::CallFunctionKeyword { nargs }),
6152+
CallType::Keyword { nargs } => emit!(self, Instruction::CallKw { nargs }),
61266153
CallType::Ex { has_kwargs } => emit!(self, Instruction::CallFunctionEx { has_kwargs }),
61276154
}
61286155
}
@@ -6412,6 +6439,7 @@ impl Compiler {
64126439

64136440
// Create comprehension function with closure
64146441
self.make_closure(code, bytecode::MakeFunctionFlags::empty())?;
6442+
emit!(self, Instruction::PushNull);
64156443

64166444
// Evaluate iterated item:
64176445
self.compile_expression(&generators[0].iter)?;
@@ -6425,7 +6453,7 @@ impl Compiler {
64256453
};
64266454

64276455
// Call just created <listcomp> function:
6428-
emit!(self, Instruction::CallFunctionPositional { nargs: 1 });
6456+
emit!(self, Instruction::Call { nargs: 1 });
64296457
if is_async_list_set_dict_comprehension {
64306458
emit!(self, Instruction::GetAwaitable);
64316459
self.emit_load_const(ConstantData::None);
@@ -6841,10 +6869,11 @@ impl Compiler {
68416869
match action {
68426870
UnwindAction::With { is_async } => {
68436871
// compiler_call_exit_with_nones
6872+
emit!(self, Instruction::PushNull);
68446873
self.emit_load_const(ConstantData::None);
68456874
self.emit_load_const(ConstantData::None);
68466875
self.emit_load_const(ConstantData::None);
6847-
emit!(self, Instruction::CallFunctionPositional { nargs: 3 });
6876+
emit!(self, Instruction::Call { nargs: 3 });
68486877

68496878
if is_async {
68506879
emit!(self, Instruction::GetAwaitable);

0 commit comments

Comments
 (0)