@@ -63,50 +63,53 @@ impl<'a, 'cp> FunctionTranslator<'a, 'cp> {
6363
6464 // Assign JVM local slots 0, 1, 2... to MIR argument names _1, _2, _3...
6565 // Assumes static methods where args start at slot 0.
66- // Assumes OOMIR uses MIR's _1, _2 naming convention for args passed from lower1.rs.
66+ // Note: For synthetic parameters (like main's String[] args), we allocate the slot
67+ // but don't map it to MIR locals since MIR doesn't reference them.
6768 let num_params = oomir_func. signature . params . len ( ) ;
6869 for i in 0 ..num_params {
69- // Internal name for translator logic (optional, but helps clarity if complex logic added later)
7070 let param_translator_name = format ! ( "param_{}" , i) ;
71- // The name used in the OOMIR body, corresponding to MIR convention (_1, _2, ...)
72- let param_oomir_name = format ! ( "_{}" , i + 1 ) ;
73- let ( _param_name, param_ty) = & oomir_func. signature . params [ i] ;
71+ let ( param_name, param_ty) = & oomir_func. signature . params [ i] ;
7472
75- // Use assign_local to allocate the slot using the *translator* name first.
76- // This ensures the slot is reserved and next_local_index advances correctly.
73+ // Allocate the slot for this parameter
7774 let assigned_index = translator. assign_local ( param_translator_name. as_str ( ) , param_ty) ;
7875
79- // Now, explicitly map the OOMIR name (_1, _2, ...) to the *same* slot index
80- // and store its type information using the OOMIR name as the key.
81- // This allows instructions in the body using "_1" to find the correct slot.
82- if translator
83- . local_var_map
84- . insert ( param_oomir_name. clone ( ) , assigned_index)
85- . is_some ( )
86- {
87- // This shouldn't happen if MIR locals truly start after parameters
88- breadcrumbs:: log!(
89- breadcrumbs:: LogLevel :: Warn ,
90- "bytecode-gen" ,
91- format!(
92- "Warning: OOMIR parameter name '{}' potentially clashed with an existing mapping during parameter assignment." ,
93- param_oomir_name
94- )
95- ) ;
96- }
97- if translator
98- . local_var_types
99- . insert ( param_oomir_name. clone ( ) , param_ty. clone ( ) )
100- . is_some ( )
101- {
102- breadcrumbs:: log!(
103- breadcrumbs:: LogLevel :: Warn ,
104- "bytecode-gen" ,
105- format!(
106- "Warning: OOMIR parameter name '{}' potentially clashed with an existing type mapping during parameter assignment." ,
107- param_oomir_name
108- )
109- ) ;
76+ // Only create MIR local mapping (_1, _2, ...) if this is a real MIR parameter,
77+ // not a synthetic one added for JVM compatibility (like main's args).
78+ // We detect synthetic params by checking if the param name matches the pattern
79+ // used by the MIR-to-OOMIR lowering vs. names added by signature overrides.
80+ // Real MIR params would have been numbered, synthetic ones have descriptive names.
81+ if param_name != "args" && !( oomir_func. name == "main" && i == 0 ) {
82+ // This looks like a real MIR parameter, map it to _1, _2, etc.
83+ let param_oomir_name = format ! ( "_{}" , i + 1 ) ;
84+
85+ if translator
86+ . local_var_map
87+ . insert ( param_oomir_name. clone ( ) , assigned_index)
88+ . is_some ( )
89+ {
90+ breadcrumbs:: log!(
91+ breadcrumbs:: LogLevel :: Warn ,
92+ "bytecode-gen" ,
93+ format!(
94+ "Warning: OOMIR parameter name '{}' potentially clashed with an existing mapping during parameter assignment." ,
95+ param_oomir_name
96+ )
97+ ) ;
98+ }
99+ if translator
100+ . local_var_types
101+ . insert ( param_oomir_name. clone ( ) , param_ty. clone ( ) )
102+ . is_some ( )
103+ {
104+ breadcrumbs:: log!(
105+ breadcrumbs:: LogLevel :: Warn ,
106+ "bytecode-gen" ,
107+ format!(
108+ "Warning: OOMIR parameter name '{}' potentially clashed with an existing type mapping during parameter assignment." ,
109+ param_oomir_name
110+ )
111+ ) ;
112+ }
110113 }
111114 }
112115
@@ -402,10 +405,23 @@ impl<'a, 'cp> FunctionTranslator<'a, 'cp> {
402405 load_constant ( & mut self . jvm_instructions , & mut self . constant_pool , c) ?
403406 }
404407 oomir:: Operand :: Variable { name : var_name, ty } => {
405- // Use the provided type directly - OOMIR variables should have correct types
406- let index = self . get_or_assign_local ( var_name, ty) ;
407- let load_instr = get_load_instruction ( ty, index) ?;
408- self . jvm_instructions . push ( load_instr) ;
408+ // Special case: If this is an uninitialized Object variable (likely a dead closure reference),
409+ // just push null instead of trying to load from an uninitialized local
410+ if !self . local_var_map . contains_key ( var_name)
411+ && matches ! ( ty, oomir:: Type :: Class ( name) if name == "java/lang/Object" )
412+ {
413+ breadcrumbs:: log!(
414+ breadcrumbs:: LogLevel :: Info ,
415+ "bytecode-gen" ,
416+ format!( "Loading uninitialized closure placeholder '{}' as null" , var_name)
417+ ) ;
418+ self . jvm_instructions . push ( Instruction :: Aconst_null ) ;
419+ } else {
420+ // Use the provided type directly - OOMIR variables should have correct types
421+ let index = self . get_or_assign_local ( var_name, ty) ;
422+ let load_instr = get_load_instruction ( ty, index) ?;
423+ self . jvm_instructions . push ( load_instr) ;
424+ }
409425 }
410426 }
411427 Ok ( ( ) )
@@ -2133,6 +2149,7 @@ impl<'a, 'cp> FunctionTranslator<'a, 'cp> {
21332149
21342150 // Check for diverging (can use shim_info if available)
21352151 if function_name == "panic_fmt"
2152+ || function_name == "std_rt_panic_fmt"
21362153 || function_name == "core_panicking_panic"
21372154 || function_name == "core_assert_failed"
21382155 // Or check shim_info.diverges
0 commit comments