@@ -882,8 +882,9 @@ fn exec_call_lua_function(
882882 // Extract chunk info from ObjectPool - use unchecked for hot path
883883 let func_ref = unsafe { vm. object_pool . get_function_unchecked ( func_id) } ;
884884
885- let ( max_stack_size, is_vararg, code_ptr, constants_ptr) = (
885+ let ( max_stack_size, num_params , is_vararg, code_ptr, constants_ptr) = (
886886 func_ref. chunk . max_stack_size ,
887+ func_ref. chunk . param_count ,
887888 func_ref. chunk . is_vararg ,
888889 func_ref. chunk . code . as_ptr ( ) ,
889890 func_ref. chunk . constants . as_ptr ( ) ,
@@ -914,13 +915,14 @@ fn exec_call_lua_function(
914915 vm. register_stack . resize ( required_capacity, LuaValue :: nil ( ) ) ;
915916 }
916917
917- // Initialize locals beyond arguments (rare for simple functions)
918- // Only if there are more locals than arguments
919- if arg_count < max_stack_size {
918+ // LIKE LUA C: Only fill missing arguments (arg_count < num_params)
919+ // NOT all stack slots! This is the key optimization.
920+ // For add(a,b) called with add(1,5): arg_count=2, num_params=2 → no fill!
921+ if arg_count < num_params {
920922 unsafe {
921923 let reg_ptr = vm. register_stack . as_mut_ptr ( ) . add ( new_base) ;
922924 let nil_val = LuaValue :: nil ( ) ;
923- for i in arg_count..max_stack_size {
925+ for i in arg_count..num_params {
924926 * reg_ptr. add ( i) = nil_val;
925927 }
926928 }
0 commit comments