@@ -30,7 +30,7 @@ use rustpython_compiler_core::{
3030 bytecode:: {
3131 self , AnyInstruction , Arg as OpArgMarker , BinaryOperator , BuildSliceArgCount , CodeObject ,
3232 ComparisonOperator , ConstantData , ConvertValueOparg , Instruction , IntrinsicFunction1 ,
33- Invert , OpArg , OpArgType , PseudoInstruction , UnpackExArgs ,
33+ Invert , OpArg , OpArgType , PseudoInstruction , SpecialMethod , UnpackExArgs ,
3434 } ,
3535} ;
3636use rustpython_wtf8:: Wtf8Buf ;
@@ -489,7 +489,12 @@ impl Compiler {
489489 match ctx {
490490 ast:: ExprContext :: Load => {
491491 emit ! ( self , Instruction :: BuildSlice { argc } ) ;
492- emit ! ( self , Instruction :: BinarySubscr ) ;
492+ emit ! (
493+ self ,
494+ Instruction :: BinaryOp {
495+ op: BinaryOperator :: Subscr
496+ }
497+ ) ;
493498 }
494499 ast:: ExprContext :: Store => {
495500 emit ! ( self , Instruction :: BuildSlice { argc } ) ;
@@ -503,7 +508,12 @@ impl Compiler {
503508
504509 // Emit appropriate instruction based on context
505510 match ctx {
506- ast:: ExprContext :: Load => emit ! ( self , Instruction :: BinarySubscr ) ,
511+ ast:: ExprContext :: Load => emit ! (
512+ self ,
513+ Instruction :: BinaryOp {
514+ op: BinaryOperator :: Subscr
515+ }
516+ ) ,
507517 ast:: ExprContext :: Store => emit ! ( self , Instruction :: StoreSubscr ) ,
508518 ast:: ExprContext :: Del => emit ! ( self , Instruction :: DeleteSubscr ) ,
509519 ast:: ExprContext :: Invalid => {
@@ -4680,20 +4690,55 @@ impl Compiler {
46804690 let exc_handler_block = self . new_block ( ) ;
46814691 let after_block = self . new_block ( ) ;
46824692
4683- // Compile context expression and BEFORE_WITH
4693+ // Compile context expression and load __enter__/__exit__ methods
46844694 self . compile_expression ( & item. context_expr ) ?;
46854695 self . set_source_range ( with_range) ;
46864696
4697+ // Stack: [cm]
4698+ emit ! ( self , Instruction :: Copy { index: 1_u32 } ) ; // [cm, cm]
4699+
46874700 if is_async {
46884701 if self . ctx . func != FunctionContext :: AsyncFunction {
46894702 return Err ( self . error ( CodegenErrorType :: InvalidAsyncWith ) ) ;
46904703 }
4691- emit ! ( self , Instruction :: BeforeAsyncWith ) ;
4704+ // Load __aexit__ and __aenter__, then call __aenter__
4705+ emit ! (
4706+ self ,
4707+ Instruction :: LoadSpecial {
4708+ method: SpecialMethod :: AExit
4709+ }
4710+ ) ; // [cm, bound_aexit]
4711+ emit ! ( self , Instruction :: Swap { index: 2_u32 } ) ; // [bound_aexit, cm]
4712+ emit ! (
4713+ self ,
4714+ Instruction :: LoadSpecial {
4715+ method: SpecialMethod :: AEnter
4716+ }
4717+ ) ; // [bound_aexit, bound_aenter]
4718+ // bound_aenter is already bound, call with NULL self_or_null
4719+ emit ! ( self , Instruction :: PushNull ) ; // [bound_aexit, bound_aenter, NULL]
4720+ emit ! ( self , Instruction :: Call { nargs: 0 } ) ; // [bound_aexit, awaitable]
46924721 emit ! ( self , Instruction :: GetAwaitable ) ;
46934722 self . emit_load_const ( ConstantData :: None ) ;
46944723 self . compile_yield_from_sequence ( true ) ?;
46954724 } else {
4696- emit ! ( self , Instruction :: BeforeWith ) ;
4725+ // Load __exit__ and __enter__, then call __enter__
4726+ emit ! (
4727+ self ,
4728+ Instruction :: LoadSpecial {
4729+ method: SpecialMethod :: Exit
4730+ }
4731+ ) ; // [cm, bound_exit]
4732+ emit ! ( self , Instruction :: Swap { index: 2_u32 } ) ; // [bound_exit, cm]
4733+ emit ! (
4734+ self ,
4735+ Instruction :: LoadSpecial {
4736+ method: SpecialMethod :: Enter
4737+ }
4738+ ) ; // [bound_exit, bound_enter]
4739+ // bound_enter is already bound, call with NULL self_or_null
4740+ emit ! ( self , Instruction :: PushNull ) ; // [bound_exit, bound_enter, NULL]
4741+ emit ! ( self , Instruction :: Call { nargs: 0 } ) ; // [bound_exit, enter_result]
46974742 }
46984743
46994744 // Stack: [..., __exit__, enter_result]
@@ -5179,7 +5224,12 @@ impl Compiler {
51795224 ) ;
51805225 }
51815226 // Use BINARY_OP/NB_SUBSCR to extract the element.
5182- emit ! ( self , Instruction :: BinarySubscr ) ;
5227+ emit ! (
5228+ self ,
5229+ Instruction :: BinaryOp {
5230+ op: BinaryOperator :: Subscr
5231+ }
5232+ ) ;
51835233 // Compile the subpattern in irrefutable mode.
51845234 self . compile_pattern_subpattern ( pattern, pc) ?;
51855235 }
@@ -6206,7 +6256,12 @@ impl Compiler {
62066256 self . compile_expression ( slice) ?;
62076257 emit ! ( self , Instruction :: Copy { index: 2_u32 } ) ;
62086258 emit ! ( self , Instruction :: Copy { index: 2_u32 } ) ;
6209- emit ! ( self , Instruction :: BinarySubscr ) ;
6259+ emit ! (
6260+ self ,
6261+ Instruction :: BinaryOp {
6262+ op: BinaryOperator :: Subscr
6263+ }
6264+ ) ;
62106265 AugAssignKind :: Subscript
62116266 }
62126267 ast:: Expr :: Attribute ( ast:: ExprAttribute { value, attr, .. } ) => {
0 commit comments