@@ -31,6 +31,7 @@ use rustpython_compiler_core::{
3131 self , AnyInstruction , Arg as OpArgMarker , BinaryOperator , BuildSliceArgCount , CodeObject ,
3232 ComparisonOperator , ConstantData , ConvertValueOparg , Instruction , IntrinsicFunction1 ,
3333 Invert , OpArg , OpArgType , PseudoInstruction , SpecialMethod , UnpackExArgs ,
34+ encode_load_attr_arg, encode_load_super_attr_arg,
3435 } ,
3536} ;
3637use rustpython_wtf8:: Wtf8Buf ;
@@ -2108,7 +2109,7 @@ impl Compiler {
21082109 if let Some ( alias) = & name. asname {
21092110 for part in name. name . split ( '.' ) . skip ( 1 ) {
21102111 let idx = self . name ( part) ;
2111- emit ! ( self , Instruction :: LoadAttr { idx } ) ;
2112+ self . emit_load_attr ( idx) ;
21122113 }
21132114 self . store_name ( alias. as_str ( ) ) ?
21142115 } else {
@@ -6280,7 +6281,7 @@ impl Compiler {
62806281 self . compile_expression ( value) ?;
62816282 emit ! ( self , Instruction :: Copy { index: 1_u32 } ) ;
62826283 let idx = self . name ( attr) ;
6283- emit ! ( self , Instruction :: LoadAttr { idx } ) ;
6284+ self . emit_load_attr ( idx) ;
62846285 AugAssignKind :: Attr { idx }
62856286 }
62866287 _ => {
@@ -6615,19 +6616,17 @@ impl Compiler {
66156616 let idx = self . name ( attr. as_str ( ) ) ;
66166617 match super_type {
66176618 SuperCallType :: TwoArg { .. } => {
6618- // LoadSuperAttr (pseudo) - will be converted to real LoadSuperAttr
6619- // with flags=0b10 (has_class=true, load_method=false) in ir.rs
6620- emit ! ( self , Instruction :: LoadSuperAttr { arg: idx } ) ;
6619+ self . emit_load_super_attr ( idx) ;
66216620 }
66226621 SuperCallType :: ZeroArg => {
6623- emit ! ( self , PseudoInstruction :: LoadZeroSuperAttr { idx } ) ;
6622+ self . emit_load_zero_super_attr ( idx) ;
66246623 }
66256624 }
66266625 } else {
66276626 // Normal attribute access
66286627 self . compile_expression ( value) ?;
66296628 let idx = self . name ( attr. as_str ( ) ) ;
6630- emit ! ( self , Instruction :: LoadAttr { idx } ) ;
6629+ self . emit_load_attr ( idx) ;
66316630 }
66326631 }
66336632 ast:: Expr :: Compare ( ast:: ExprCompare {
@@ -7070,19 +7069,19 @@ impl Compiler {
70707069 let idx = self . name ( attr. as_str ( ) ) ;
70717070 match super_type {
70727071 SuperCallType :: TwoArg { .. } => {
7073- emit ! ( self , PseudoInstruction :: LoadSuperMethod { idx } ) ;
7072+ self . emit_load_super_method ( idx) ;
70747073 }
70757074 SuperCallType :: ZeroArg => {
7076- emit ! ( self , PseudoInstruction :: LoadZeroSuperMethod { idx } ) ;
7075+ self . emit_load_zero_super_method ( idx) ;
70777076 }
70787077 }
70797078 self . codegen_call_helper ( 0 , args) ?;
70807079 } else {
7081- // Normal method call: compile object, then LOAD_ATTR_METHOD
7082- // LOAD_ATTR_METHOD pushes [method, self_or_null] on stack
7080+ // Normal method call: compile object, then LOAD_ATTR with method flag
7081+ // LOAD_ATTR(method=1) pushes [method, self_or_null] on stack
70837082 self . compile_expression ( value) ?;
70847083 let idx = self . name ( attr. as_str ( ) ) ;
7085- emit ! ( self , PseudoInstruction :: LoadAttrMethod { idx } ) ;
7084+ self . emit_load_attr_method ( idx) ;
70867085 self . codegen_call_helper ( 0 , args) ?;
70877086 }
70887087 } else {
@@ -7782,6 +7781,48 @@ impl Compiler {
77827781 emit ! ( self , Instruction :: ReturnValue )
77837782 }
77847783
7784+ /// Emit LOAD_ATTR for attribute access (method=false).
7785+ /// Encodes: (name_idx << 1) | 0
7786+ fn emit_load_attr ( & mut self , name_idx : u32 ) {
7787+ let encoded = encode_load_attr_arg ( name_idx, false ) ;
7788+ self . emit_arg ( encoded, |arg| Instruction :: LoadAttr { idx : arg } )
7789+ }
7790+
7791+ /// Emit LOAD_ATTR with method flag set (for method calls).
7792+ /// Encodes: (name_idx << 1) | 1
7793+ fn emit_load_attr_method ( & mut self , name_idx : u32 ) {
7794+ let encoded = encode_load_attr_arg ( name_idx, true ) ;
7795+ self . emit_arg ( encoded, |arg| Instruction :: LoadAttr { idx : arg } )
7796+ }
7797+
7798+ /// Emit LOAD_SUPER_ATTR for 2-arg super().attr access.
7799+ /// Encodes: (name_idx << 2) | 0b10 (method=0, class=1)
7800+ fn emit_load_super_attr ( & mut self , name_idx : u32 ) {
7801+ let encoded = encode_load_super_attr_arg ( name_idx, false , true ) ;
7802+ self . emit_arg ( encoded, |arg| Instruction :: LoadSuperAttr { arg } )
7803+ }
7804+
7805+ /// Emit LOAD_SUPER_ATTR for 2-arg super().method() call.
7806+ /// Encodes: (name_idx << 2) | 0b11 (method=1, class=1)
7807+ fn emit_load_super_method ( & mut self , name_idx : u32 ) {
7808+ let encoded = encode_load_super_attr_arg ( name_idx, true , true ) ;
7809+ self . emit_arg ( encoded, |arg| Instruction :: LoadSuperAttr { arg } )
7810+ }
7811+
7812+ /// Emit LOAD_SUPER_ATTR for 0-arg super().attr access.
7813+ /// Encodes: (name_idx << 2) | 0b00 (method=0, class=0)
7814+ fn emit_load_zero_super_attr ( & mut self , name_idx : u32 ) {
7815+ let encoded = encode_load_super_attr_arg ( name_idx, false , false ) ;
7816+ self . emit_arg ( encoded, |arg| Instruction :: LoadSuperAttr { arg } )
7817+ }
7818+
7819+ /// Emit LOAD_SUPER_ATTR for 0-arg super().method() call.
7820+ /// Encodes: (name_idx << 2) | 0b01 (method=1, class=0)
7821+ fn emit_load_zero_super_method ( & mut self , name_idx : u32 ) {
7822+ let encoded = encode_load_super_attr_arg ( name_idx, true , false ) ;
7823+ self . emit_arg ( encoded, |arg| Instruction :: LoadSuperAttr { arg } )
7824+ }
7825+
77857826 fn emit_return_value ( & mut self ) {
77867827 emit ! ( self , Instruction :: ReturnValue )
77877828 }
0 commit comments