@@ -550,82 +550,111 @@ impl CodegenBackend for MyBackend {
550550
551551 let mut bbs = HashMap :: new ( ) ;
552552
553- let mut to_call_invokevirtual_on = "_1" . to_string ( ) ;
553+ // Determine if this impl item is an instance method (has self receiver of this class)
554+ let is_instance_method = match oomir_function. signature . params . first ( ) {
555+ Some ( Type :: Class ( name) ) => * name == ident,
556+ Some ( Type :: MutableReference ( box Type :: Class ( name) ) ) => * name == ident,
557+ _ => false ,
558+ } ;
554559
555- if let oomir:: Operand :: Variable { ty, .. } = & args[ 0 ] {
556- // &mut self
557- if ty
558- == & oomir:: Type :: MutableReference ( Box :: new ( oomir:: Type :: Class (
559- ident. clone ( ) ,
560- ) ) )
561- {
562- instructions. push ( oomir:: Instruction :: Cast {
563- op : Operand :: Variable {
564- name : "_1" . into ( ) ,
565- ty : Type :: MutableReference ( Box :: new ( Type :: Class (
566- ident. clone ( ) ,
567- ) ) ) ,
568- } ,
569- ty : Type :: Class ( ident. clone ( ) ) ,
570- dest : "_1_mutderef" . into ( ) ,
571- } ) ;
572- to_call_invokevirtual_on = "_1_mutderef" . to_string ( ) ;
573- } else if * ty != oomir:: Type :: Class ( ident. clone ( ) ) {
574- instructions. push ( oomir:: Instruction :: ConstructObject {
575- dest : "_1_instance" . into ( ) ,
576- class_name : ident. clone ( ) ,
577- } ) ;
578- to_call_invokevirtual_on = "_1_instance" . into ( ) ;
560+ if is_instance_method {
561+ let mut to_call_invokevirtual_on = "_1" . to_string ( ) ;
562+ // args[0] exists because it's an instance method
563+ if let oomir:: Operand :: Variable { ty, .. } = & args[ 0 ] {
564+ // &mut self
565+ if ty
566+ == & oomir:: Type :: MutableReference ( Box :: new ( oomir:: Type :: Class (
567+ ident. clone ( ) ,
568+ ) ) )
569+ {
570+ instructions. push ( oomir:: Instruction :: Cast {
571+ op : Operand :: Variable {
572+ name : "_1" . into ( ) ,
573+ ty : Type :: MutableReference ( Box :: new ( Type :: Class (
574+ ident. clone ( ) ,
575+ ) ) ) ,
576+ } ,
577+ ty : Type :: Class ( ident. clone ( ) ) ,
578+ dest : "_1_mutderef" . into ( ) ,
579+ } ) ;
580+ to_call_invokevirtual_on = "_1_mutderef" . to_string ( ) ;
581+ } else if * ty != oomir:: Type :: Class ( ident. clone ( ) ) {
582+ instructions. push ( oomir:: Instruction :: ConstructObject {
583+ dest : "_1_instance" . into ( ) ,
584+ class_name : ident. clone ( ) ,
585+ } ) ;
586+ to_call_invokevirtual_on = "_1_instance" . into ( ) ;
587+ }
579588 }
580- }
581589
582- instructions. extend ( vec ! [
583- oomir:: Instruction :: InvokeVirtual {
584- operand: Operand :: Variable {
585- name: to_call_invokevirtual_on,
586- ty: Type :: Class ( ident. clone( ) ) ,
587- } ,
588- class_name: ident. to_string( ) ,
589- method_name: i. to_string( ) ,
590- method_ty: oomir_function. signature. clone( ) ,
591- args,
592- dest: if has_return {
593- Some ( "dest" . into( ) )
594- } else {
595- None
590+ instructions. extend ( vec ! [
591+ oomir:: Instruction :: InvokeVirtual {
592+ operand: Operand :: Variable {
593+ name: to_call_invokevirtual_on,
594+ ty: Type :: Class ( ident. clone( ) ) ,
595+ } ,
596+ class_name: ident. to_string( ) ,
597+ method_name: i. to_string( ) ,
598+ method_ty: oomir_function. signature. clone( ) ,
599+ args,
600+ dest: if has_return {
601+ Some ( "dest" . into( ) )
602+ } else {
603+ None
604+ } ,
596605 } ,
597- } ,
598- oomir :: Instruction :: Return {
599- operand : if has_return {
600- Some ( Operand :: Variable {
601- name : "dest" . into ( ) ,
602- ty : * oomir_function . signature . ret . clone ( ) ,
603- } )
604- } else {
605- None
606+ oomir :: Instruction :: Return {
607+ operand : if has_return {
608+ Some ( Operand :: Variable {
609+ name : "dest" . into ( ) ,
610+ ty : * oomir_function . signature . ret . clone ( ) ,
611+ } )
612+ } else {
613+ None
614+ } ,
606615 } ,
607- } ,
608- ] ) ;
616+ ] ) ;
617+ } else {
618+ // Associated function (no self receiver): no wrapper needed.
619+ // Insert the lowered function directly as a top-level function named Type_method.
620+ // Keep a clone for class metadata below with the original method name.
621+ let method_impl_for_class = oomir_function. clone ( ) ;
622+
623+ let mut top_level_func = oomir_function. clone ( ) ;
624+ top_level_func. name = i2. clone ( ) ;
625+ oomir_module
626+ . functions
627+ . insert ( i2. clone ( ) , top_level_func) ;
628+
629+ // For associated functions, skip creating a wrapper basic block.
630+ // We'll still register the method on the class using `method_impl_for_class` below.
631+
632+ // Replace oomir_function with the clone intended for class metadata for the remaining code.
633+ oomir_function = method_impl_for_class;
634+ }
609635
610- // insert a wrapper function for the trait method - calling InvokeVirtual on the class to call the actual method
611- bbs. insert (
612- "bb0" . into ( ) ,
613- oomir:: BasicBlock {
614- instructions,
615- label : "bb0" . to_string ( ) ,
616- } ,
617- ) ;
618- oomir_module. functions . insert (
619- i2. clone ( ) ,
620- Function {
621- name : i2,
622- signature : helper_sig,
623- body : CodeBlock {
624- entry : "bb0" . into ( ) ,
625- basic_blocks : bbs,
636+ // For instance methods, insert the wrapper; associated methods skipped above
637+ if is_instance_method {
638+ // insert a wrapper function for the method - calling InvokeVirtual on the class to call the actual method
639+ bbs. insert (
640+ "bb0" . into ( ) ,
641+ oomir:: BasicBlock {
642+ instructions,
643+ label : "bb0" . to_string ( ) ,
626644 } ,
627- } ,
628- ) ;
645+ ) ;
646+ oomir_module. functions . insert (
647+ i2. clone ( ) ,
648+ Function {
649+ name : i2,
650+ signature : helper_sig,
651+ body : CodeBlock {
652+ entry : "bb0" . into ( ) ,
653+ basic_blocks : bbs,
654+ } ,
655+ } ,
656+ ) ;
657+ }
629658
630659 oomir_module. merge_data_types ( & oomir_result. 1 ) ;
631660
0 commit comments