@@ -287,7 +287,7 @@ STATIC void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop
287287 emit -> pass = pass ;
288288 emit -> do_viper_types = scope -> emit_options == MP_EMIT_OPT_VIPER ;
289289 emit -> stack_size = 0 ;
290- emit -> const_table_cur_obj = 0 ;
290+ emit -> const_table_cur_obj = 1 ; // first entry is for mp_fun_table
291291 emit -> const_table_cur_raw_code = 0 ;
292292 emit -> last_emit_was_return_value = false;
293293 emit -> scope = scope ;
@@ -372,24 +372,16 @@ STATIC void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop
372372 // Entry to function
373373 ASM_ENTRY (emit -> as , emit -> stack_start + emit -> n_state - num_locals_in_regs );
374374
375- // TODO don't load r7 if we don't need it
376- #if N_THUMB
377- asm_thumb_mov_reg_i32 (emit -> as , ASM_THUMB_REG_R7 , (mp_uint_t )mp_fun_table );
378- #elif N_ARM
379- asm_arm_mov_reg_i32 (emit -> as , ASM_ARM_REG_R7 , (mp_uint_t )mp_fun_table );
380- #elif N_XTENSA
381- ASM_MOV_REG_IMM (emit -> as , ASM_XTENSA_REG_A15 , (uint32_t )mp_fun_table );
382- #elif N_X86
383- asm_x86_mov_i32_to_r32 (emit -> as , (intptr_t )mp_fun_table , ASM_X86_REG_EBP );
384- #elif N_X64
385- asm_x64_mov_i64_to_r64_optimised (emit -> as , (intptr_t )mp_fun_table , ASM_X64_REG_RBP );
375+ #if N_X86
376+ asm_x86_mov_arg_to_r32 (emit -> as , 0 , REG_ARG_1 );
386377 #endif
387378
379+ // Load REG_FUN_TABLE with a pointer to mp_fun_table, found in the const_table
380+ ASM_LOAD_REG_REG_OFFSET (emit -> as , REG_LOCAL_3 , REG_ARG_1 , offsetof(mp_obj_fun_bc_t , const_table ) / sizeof (uintptr_t ));
381+ ASM_LOAD_REG_REG_OFFSET (emit -> as , REG_FUN_TABLE , REG_LOCAL_3 , 0 );
382+
388383 // Store function object (passed as first arg) to stack if needed
389384 if (NEED_FUN_OBJ (emit )) {
390- #if N_X86
391- asm_x86_mov_arg_to_r32 (emit -> as , 0 , REG_ARG_1 );
392- #endif
393385 ASM_MOV_LOCAL_REG (emit -> as , LOCAL_IDX_FUN_OBJ (emit ), REG_ARG_1 );
394386 }
395387
@@ -458,28 +450,18 @@ STATIC void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop
458450 asm_x86_mov_arg_to_r32 (emit -> as , 1 , REG_ARG_2 );
459451 #endif
460452 ASM_MOV_LOCAL_REG (emit -> as , LOCAL_IDX_EXC_VAL (emit ), REG_ARG_2 );
453+
454+ // Load REG_FUN_TABLE with a pointer to mp_fun_table, found in the const_table
455+ ASM_LOAD_REG_REG_OFFSET (emit -> as , REG_TEMP0 , REG_GENERATOR_STATE , LOCAL_IDX_FUN_OBJ (emit ));
456+ ASM_LOAD_REG_REG_OFFSET (emit -> as , REG_TEMP0 , REG_TEMP0 , offsetof(mp_obj_fun_bc_t , const_table ) / sizeof (uintptr_t ));
457+ ASM_LOAD_REG_REG_OFFSET (emit -> as , REG_FUN_TABLE , REG_TEMP0 , emit -> scope -> num_pos_args + emit -> scope -> num_kwonly_args );
461458 } else {
462459 // The locals and stack start after the code_state structure
463460 emit -> stack_start = emit -> code_state_start + sizeof (mp_code_state_t ) / sizeof (mp_uint_t );
464461
465462 // Allocate space on C-stack for code_state structure, which includes state
466463 ASM_ENTRY (emit -> as , emit -> stack_start + emit -> n_state );
467- }
468-
469- // TODO don't load r7 if we don't need it
470- #if N_THUMB
471- asm_thumb_mov_reg_i32 (emit -> as , ASM_THUMB_REG_R7 , (mp_uint_t )mp_fun_table );
472- #elif N_ARM
473- asm_arm_mov_reg_i32 (emit -> as , ASM_ARM_REG_R7 , (mp_uint_t )mp_fun_table );
474- #elif N_XTENSA
475- ASM_MOV_REG_IMM (emit -> as , ASM_XTENSA_REG_A15 , (uint32_t )mp_fun_table );
476- #elif N_X86
477- asm_x86_mov_i32_to_r32 (emit -> as , (intptr_t )mp_fun_table , ASM_X86_REG_EBP );
478- #elif N_X64
479- asm_x64_mov_i64_to_r64_optimised (emit -> as , (intptr_t )mp_fun_table , ASM_X64_REG_RBP );
480- #endif
481464
482- if (!(emit -> scope -> scope_flags & MP_SCOPE_FLAG_GENERATOR )) {
483465 // Prepare incoming arguments for call to mp_setup_code_state
484466
485467 #if N_X86
@@ -489,6 +471,10 @@ STATIC void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop
489471 asm_x86_mov_arg_to_r32 (emit -> as , 3 , REG_ARG_4 );
490472 #endif
491473
474+ // Load REG_FUN_TABLE with a pointer to mp_fun_table, found in the const_table
475+ ASM_LOAD_REG_REG_OFFSET (emit -> as , REG_LOCAL_3 , REG_ARG_1 , offsetof(mp_obj_fun_bc_t , const_table ) / sizeof (uintptr_t ));
476+ ASM_LOAD_REG_REG_OFFSET (emit -> as , REG_FUN_TABLE , REG_LOCAL_3 , emit -> scope -> num_pos_args + emit -> scope -> num_kwonly_args );
477+
492478 // Set code_state.fun_bc
493479 ASM_MOV_LOCAL_REG (emit -> as , LOCAL_IDX_FUN_OBJ (emit ), REG_ARG_1 );
494480
@@ -591,11 +577,15 @@ STATIC void emit_native_end_pass(emit_t *emit) {
591577 emit -> const_table_num_obj = emit -> const_table_cur_obj ;
592578 if (emit -> pass == MP_PASS_CODE_SIZE ) {
593579 size_t const_table_alloc = emit -> const_table_num_obj + emit -> const_table_cur_raw_code ;
580+ size_t nqstr = 0 ;
594581 if (!emit -> do_viper_types ) {
595582 // Add room for qstr names of arguments
596- const_table_alloc += emit -> scope -> num_pos_args + emit -> scope -> num_kwonly_args ;
583+ nqstr = emit -> scope -> num_pos_args + emit -> scope -> num_kwonly_args ;
584+ const_table_alloc += nqstr ;
597585 }
598586 emit -> const_table = m_new (mp_uint_t , const_table_alloc );
587+ // Store mp_fun_table pointer just after qstrs
588+ emit -> const_table [nqstr ] = (mp_uint_t )(uintptr_t )mp_fun_table ;
599589 }
600590
601591 if (emit -> pass == MP_PASS_EMIT ) {
0 commit comments