@@ -767,7 +767,12 @@ void close_over_variables_etc(compiler_t *comp, scope_t *this_scope, int n_dict_
767767 for (int j = 0 ; j < this_scope -> id_info_len ; j ++ ) {
768768 id_info_t * id2 = & this_scope -> id_info [j ];
769769 if (id2 -> kind == ID_INFO_KIND_FREE && id -> qstr == id2 -> qstr ) {
770+ #if MICROPY_EMIT_CPYTHON
770771 EMIT (load_closure , id -> qstr , id -> local_num );
772+ #else
773+ // in Micro Python we load closures using LOAD_FAST
774+ EMIT (load_fast , id -> qstr , id -> local_num );
775+ #endif
771776 nfree += 1 ;
772777 }
773778 }
@@ -2806,7 +2811,11 @@ void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
28062811 if (id -> kind == ID_INFO_KIND_LOCAL ) {
28072812 EMIT (load_const_tok , MP_TOKEN_KW_NONE );
28082813 } else {
2814+ #if MICROPY_EMIT_CPYTHON
28092815 EMIT (load_closure , comp -> qstr___class__ , 0 ); // XXX check this is the correct local num
2816+ #else
2817+ EMIT (load_fast , comp -> qstr___class__ , 0 ); // XXX check this is the correct local num
2818+ #endif
28102819 }
28112820 EMIT (return_value );
28122821 }
@@ -2894,7 +2903,7 @@ void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind_t pass
28942903
28952904void compile_scope_compute_things (compiler_t * comp , scope_t * scope ) {
28962905 // in functions, turn implicit globals into explicit globals
2897- // compute num_locals, and the index of each local
2906+ // compute the index of each local
28982907 scope -> num_locals = 0 ;
28992908 for (int i = 0 ; i < scope -> id_info_len ; i ++ ) {
29002909 id_info_t * id = & scope -> id_info [i ];
@@ -2913,19 +2922,27 @@ void compile_scope_compute_things(compiler_t *comp, scope_t *scope) {
29132922 }
29142923
29152924 // compute the index of cell vars (freevars[idx] in CPython)
2916- int num_closed = 0 ;
2925+ #if MICROPY_EMIT_CPYTHON
2926+ int num_cell = 0 ;
2927+ #endif
29172928 for (int i = 0 ; i < scope -> id_info_len ; i ++ ) {
29182929 id_info_t * id = & scope -> id_info [i ];
2930+ #if MICROPY_EMIT_CPYTHON
2931+ // in CPython the cells are numbered starting from 0
29192932 if (id -> kind == ID_INFO_KIND_CELL ) {
2920- id -> local_num = num_closed ;
2921- #if !MICROPY_EMIT_CPYTHON
2922- // the cells come right after the fast locals (CPython doesn't add this offset)
2923- id -> local_num += scope -> num_locals ;
2924- #endif
2925- num_closed += 1 ;
2933+ id -> local_num = num_cell ;
2934+ num_cell += 1 ;
2935+ }
2936+ #else
2937+ // in Micro Python the cells come right after the fast locals
2938+ // parameters are not counted here, since they remain at the start
2939+ // of the locals, even if they are cell vars
2940+ if (!id -> param && id -> kind == ID_INFO_KIND_CELL ) {
2941+ id -> local_num = scope -> num_locals ;
2942+ scope -> num_locals += 1 ;
29262943 }
2944+ #endif
29272945 }
2928- scope -> num_cells = num_closed ;
29292946
29302947 // compute the index of free vars (freevars[idx] in CPython)
29312948 // make sure they are in the order of the parent scope
@@ -2937,16 +2954,32 @@ void compile_scope_compute_things(compiler_t *comp, scope_t *scope) {
29372954 for (int j = 0 ; j < scope -> id_info_len ; j ++ ) {
29382955 id_info_t * id2 = & scope -> id_info [j ];
29392956 if (id2 -> kind == ID_INFO_KIND_FREE && id -> qstr == id2 -> qstr ) {
2940- id2 -> local_num = num_closed + num_free ;
2941- #if !MICROPY_EMIT_CPYTHON
2942- // the frees come right after the cells (CPython doesn't add this offset)
2943- id2 -> local_num += scope -> num_locals ;
2957+ assert (!id2 -> param ); // free vars should not be params
2958+ #if MICROPY_EMIT_CPYTHON
2959+ // in CPython the frees are numbered after the cells
2960+ id2 -> local_num = num_cell + num_free ;
2961+ #else
2962+ // in Micro Python the frees come first, before the params
2963+ id2 -> local_num = num_free ;
29442964#endif
29452965 num_free += 1 ;
29462966 }
29472967 }
29482968 }
29492969 }
2970+ #if !MICROPY_EMIT_CPYTHON
2971+ // in Micro Python shift all other locals after the free locals
2972+ if (num_free > 0 ) {
2973+ for (int i = 0 ; i < scope -> id_info_len ; i ++ ) {
2974+ id_info_t * id = & scope -> id_info [i ];
2975+ if (id -> param || id -> kind != ID_INFO_KIND_FREE ) {
2976+ id -> local_num += num_free ;
2977+ }
2978+ }
2979+ scope -> num_params += num_free ; // free vars are counted as params for passing them into the function
2980+ scope -> num_locals += num_free ;
2981+ }
2982+ #endif
29502983 }
29512984
29522985 // compute flags
0 commit comments