Skip to content

Commit

Permalink
WIP: Make mp_module_context_t derive from mp_obj_module_t.
Browse files Browse the repository at this point in the history
Signed-off-by: Damien George <damien@micropython.org>
  • Loading branch information
dpgeorge committed Jan 22, 2022
1 parent de42a94 commit 0f6a102
Show file tree
Hide file tree
Showing 23 changed files with 152 additions and 109 deletions.
3 changes: 2 additions & 1 deletion mpy-cross/main.c
Expand Up @@ -72,7 +72,8 @@ STATIC int compile_and_save(const char *file, const char *output_file, const cha
#endif

mp_parse_tree_t parse_tree = mp_parse(lex, MP_PARSE_FILE_INPUT);
mp_compiled_module_t cm = mp_compile_to_raw_code(&parse_tree, source_name, false);
mp_module_context_t *ctx = m_new_obj(mp_module_context_t);
mp_compiled_module_t cm = mp_compile_to_raw_code(&parse_tree, source_name, false, ctx);

vstr_t vstr;
vstr_init(&vstr, 16);
Expand Down
4 changes: 3 additions & 1 deletion ports/unix/main.c
Expand Up @@ -138,7 +138,9 @@ STATIC int execute_from_lexer(int source_kind, const void *source, mp_parse_inpu
}
#endif

mp_obj_t module_fun = mp_compile(&parse_tree, source_name, is_repl);
mp_module_context_t *ctx = m_new_obj(mp_module_context_t);
ctx->module.globals = mp_globals_get();
mp_obj_t module_fun = mp_compile(&parse_tree, source_name, is_repl, ctx);

if (!compile_only) {
// execute it
Expand Down
4 changes: 2 additions & 2 deletions py/bc.c
Expand Up @@ -202,7 +202,7 @@ void mp_setup_code_state(mp_code_state_t *code_state, size_t n_args, size_t n_kw
for (size_t j = 0; j < n_pos_args + n_kwonly_args; j++) {
qstr arg_qstr = mp_decode_uint(&arg_names);
#if MICROPY_PERSISTENT_CODE
arg_qstr = self->mc->qstr_table[arg_qstr];
arg_qstr = self->ctx->constants.qstr_table[arg_qstr];
#endif
if (wanted_arg_name == MP_OBJ_NEW_QSTR(arg_qstr)) {
if (code_state->state[n_state - 1 - j] != MP_OBJ_NULL) {
Expand Down Expand Up @@ -258,7 +258,7 @@ void mp_setup_code_state(mp_code_state_t *code_state, size_t n_args, size_t n_kw
for (size_t i = 0; i < n_kwonly_args; i++) {
qstr arg_qstr = mp_decode_uint(&arg_names);
#if MICROPY_PERSISTENT_CODE
arg_qstr = self->mc->qstr_table[arg_qstr];
arg_qstr = self->ctx->constants.qstr_table[arg_qstr];
#endif
if (code_state->state[n_state - 1 - n_pos_args - i] == MP_OBJ_NULL) {
mp_map_elem_t *elem = NULL;
Expand Down
32 changes: 25 additions & 7 deletions py/bc.h
Expand Up @@ -197,15 +197,21 @@ typedef struct _mp_exc_stack_t {
} mp_exc_stack_t;

// State associated with a module, to interface bytecode with runtime.
// Outer level struct defining a compiled module.
typedef struct _mp_module_constants_t {
qstr_short_t *qstr_table;
mp_obj_t *obj_table;
} mp_module_constants_t;

// State associated with a module, to interface bytecode with runtime.
typedef struct _mp_module_context_t {
mp_obj_dict_t **globals_ref;
mp_obj_t *const_table;
qstr_short_t qstr_table[];
mp_obj_module_t module;
mp_module_constants_t constants;
} mp_module_context_t;

// Outer level struct defining a compiled module.
typedef struct _mp_compiled_module_t {
const mp_module_context_t *ctx;
const struct _mp_raw_code_t *rc;
const mp_module_context_t *mc;
#if MICROPY_PERSISTENT_CODE
// placed here, this is part of the ABI b/c native code assumes offsets of entries below
bool has_native;
Expand All @@ -214,6 +220,18 @@ typedef struct _mp_compiled_module_t {
#endif
} mp_compiled_module_t;

// Outer level struct defining a compiled module.
typedef struct _mp_frozen_module_t {
const mp_module_constants_t constants;
const struct _mp_raw_code_t *rc;
#if MICROPY_PERSISTENT_CODE
// placed here, this is part of the ABI b/c native code assumes offsets of entries below
bool has_native;
size_t n_qstr;
size_t n_obj;
#endif
} mp_frozen_module_t;

typedef struct _mp_code_state_t {
// The fun_bc entry points to the underlying function object that is being executed.
// It is needed to access the start of bytecode and the const_table.
Expand Down Expand Up @@ -245,8 +263,8 @@ const byte *mp_decode_uint_skip(const byte *ptr);
mp_vm_return_kind_t mp_execute_bytecode(mp_code_state_t *code_state, volatile mp_obj_t inject_exc);
mp_code_state_t *mp_obj_fun_bc_prepare_codestate(mp_obj_t func, size_t n_args, size_t n_kw, const mp_obj_t *args);
void mp_setup_code_state(mp_code_state_t *code_state, size_t n_args, size_t n_kw, const mp_obj_t *args);
void mp_bytecode_print(const mp_print_t *print, const void *descr, const byte *code, mp_uint_t len, const mp_module_context_t *cm);
void mp_bytecode_print2(const mp_print_t *print, const byte *code, size_t len, const mp_module_context_t *cm);
void mp_bytecode_print(const mp_print_t *print, const void *descr, const byte *code, mp_uint_t len, const mp_module_constants_t *cm);
void mp_bytecode_print2(const mp_print_t *print, const byte *code, size_t len, const mp_module_constants_t *cm);
const byte *mp_bytecode_print_str(const mp_print_t *print, const byte *ip);
#define mp_bytecode_print_inst(print, code, x_table) mp_bytecode_print2(print, code, 1, x_table)

Expand Down
2 changes: 1 addition & 1 deletion py/builtinevex.c
Expand Up @@ -54,7 +54,7 @@ STATIC mp_obj_t code_execute(mp_obj_code_t *self, mp_obj_dict_t *globals, mp_obj
// the correct one
if (mp_obj_is_type(self->module_fun, &mp_type_fun_bc)) {
mp_obj_fun_bc_t *fun_bc = MP_OBJ_TO_PTR(self->module_fun);
*((const mp_module_context_t *)fun_bc->mc)->globals_ref = globals;
((mp_module_context_t *)fun_bc->ctx)->module.globals = globals;
}

// execute code
Expand Down
17 changes: 9 additions & 8 deletions py/builtinimport.c
Expand Up @@ -168,7 +168,6 @@ STATIC void do_execute_raw_code(mp_obj_t module_obj, const mp_raw_code_t *rc, co

// execute the module in its context
mp_obj_dict_t *mod_globals = mp_obj_module_get_globals(module_obj);
*mc->globals_ref = mod_globals;

// save context
mp_obj_dict_t *volatile old_globals = mp_globals_get();
Expand Down Expand Up @@ -196,7 +195,7 @@ STATIC void do_execute_raw_code(mp_obj_t module_obj, const mp_raw_code_t *rc, co
}
#endif

STATIC void do_load(mp_obj_t module_obj, vstr_t *file) {
STATIC void do_load(mp_module_context_t *module_obj, vstr_t *file) {
#if MICROPY_MODULE_FROZEN || MICROPY_ENABLE_COMPILER || (MICROPY_PERSISTENT_CODE_LOAD && MICROPY_HAS_FILE_READER)
const char *file_str = vstr_null_terminated_str(file);
#endif
Expand All @@ -223,8 +222,10 @@ STATIC void do_load(mp_obj_t module_obj, vstr_t *file) {
// its data) in the list of frozen files, execute it.
#if MICROPY_MODULE_FROZEN_MPY
if (frozen_type == MP_FROZEN_MPY) {
const mp_compiled_module_t *cm = modref;
do_execute_raw_code(module_obj, cm->rc, cm->mc, file_str + frozen_path_prefix_len);
const mp_frozen_module_t *frozen = modref;
module_obj->constants = frozen->constants;
module_obj->module.globals = mp_obj_module_get_globals(module_obj);
do_execute_raw_code(module_obj, frozen->rc, module_obj, file_str + frozen_path_prefix_len);
return;
}
#endif
Expand All @@ -236,8 +237,8 @@ STATIC void do_load(mp_obj_t module_obj, vstr_t *file) {
// the correct format and, if so, load and execute the file.
#if MICROPY_HAS_FILE_READER && MICROPY_PERSISTENT_CODE_LOAD
if (file_str[file->len - 3] == 'm') {
mp_compiled_module_t cm = mp_raw_code_load_file(file_str);
do_execute_raw_code(module_obj, cm.rc, cm.mc, file_str);
mp_compiled_module_t cm = mp_raw_code_load_file(file_str, module_obj);
do_execute_raw_code(module_obj, cm.rc, cm.ctx, file_str);
return;
}
#endif
Expand Down Expand Up @@ -436,7 +437,7 @@ STATIC mp_obj_t process_import_at_level(qstr full_mod_name, qstr level_mod_name,
size_t orig_path_len = path->len;
vstr_add_str(path, PATH_SEP_CHAR "__init__.py");
if (stat_file_py_or_mpy(path) == MP_IMPORT_STAT_FILE) {
do_load(module_obj, path);
do_load(MP_OBJ_TO_PTR(module_obj), path);
} else {
// No-op. Nothing to load.
// mp_warning("%s is imported as namespace package", vstr_str(&path));
Expand All @@ -445,7 +446,7 @@ STATIC mp_obj_t process_import_at_level(qstr full_mod_name, qstr level_mod_name,
path->len = orig_path_len;
} else { // MP_IMPORT_STAT_FILE
// File -- execute "path.(m)py".
do_load(module_obj, path);
do_load(MP_OBJ_TO_PTR(module_obj), path);
// Note: This should be the last component in the import path. If
// there are remaining components then it's an ImportError
// because the current path(the module that was just loaded) is
Expand Down
14 changes: 7 additions & 7 deletions py/compile.c
Expand Up @@ -3417,7 +3417,7 @@ STATIC void scope_compute_things(scope_t *scope, mp_emit_common_t *emit_common)
#if !MICROPY_PERSISTENT_CODE_SAVE
STATIC
#endif
mp_compiled_module_t mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr source_file, bool is_repl) {
mp_compiled_module_t mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr source_file, bool is_repl, mp_module_context_t *ctx) {
// put compiler state on the stack, it's relatively small
compiler_t comp_state = {0};
compiler_t *comp = &comp_state;
Expand Down Expand Up @@ -3567,17 +3567,17 @@ mp_compiled_module_t mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr so
// Construct the global qstr/const table for this module.
mp_compiled_module_t cm;
cm.rc = module_scope->raw_code;
cm.mc = NULL;
cm.ctx = ctx;
#if MICROPY_PERSISTENT_CODE_SAVE
cm.has_native = has_native_code;
#endif
if (comp->compile_error == MP_OBJ_NULL) {
mp_emit_common_create_module_context(&comp->emit_common, &cm);
mp_emit_common_create_module_context(&comp->emit_common, &cm, ctx);
#if MICROPY_DEBUG_PRINTERS
if (mp_verbose_flag >= 2) {
for (scope_t *s = comp->scope_head; s != NULL && comp->compile_error == MP_OBJ_NULL; s = s->next) {
mp_raw_code_t *rc = s->raw_code;
mp_bytecode_print(&mp_plat_print, rc, rc->fun_data, rc->fun_data_len, cm.mc);
mp_bytecode_print(&mp_plat_print, rc, rc->fun_data, rc->fun_data_len, &cm.ctx->constants);
}
}
#endif
Expand Down Expand Up @@ -3614,10 +3614,10 @@ mp_compiled_module_t mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr so
return cm;
}

mp_obj_t mp_compile(mp_parse_tree_t *parse_tree, qstr source_file, bool is_repl) {
mp_compiled_module_t cm = mp_compile_to_raw_code(parse_tree, source_file, is_repl);
mp_obj_t mp_compile(mp_parse_tree_t *parse_tree, qstr source_file, bool is_repl, mp_module_context_t *ctx) {
mp_compiled_module_t cm = mp_compile_to_raw_code(parse_tree, source_file, is_repl, ctx);
// return function that executes the outer module
return mp_make_function_from_raw_code(cm.rc, cm.mc, NULL);
return mp_make_function_from_raw_code(cm.rc, cm.ctx, NULL);
}

#endif // MICROPY_ENABLE_COMPILER
4 changes: 2 additions & 2 deletions py/compile.h
Expand Up @@ -32,11 +32,11 @@

// the compiler will raise an exception if an error occurred
// the compiler will clear the parse tree before it returns
mp_obj_t mp_compile(mp_parse_tree_t *parse_tree, qstr source_file, bool is_repl);
mp_obj_t mp_compile(mp_parse_tree_t *parse_tree, qstr source_file, bool is_repl, mp_module_context_t *globals);

#if MICROPY_PERSISTENT_CODE_SAVE
// this has the same semantics as mp_compile
mp_compiled_module_t mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr source_file, bool is_repl);
mp_compiled_module_t mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr source_file, bool is_repl, mp_module_context_t *globals);
#endif

// this is implemented in runtime.c
Expand Down
27 changes: 15 additions & 12 deletions py/emit.h
Expand Up @@ -229,36 +229,39 @@ static inline void mp_emit_common_finalise(mp_emit_common_t *emit, bool has_nati
}

#include <string.h>
static inline mp_module_context_t *mp_module_context_new(size_t n_qstr, size_t n_obj) {
static inline mp_module_context_t *mp_module_context_new(mp_module_context_t *ctx, size_t n_qstr, size_t n_obj) {
//size_t nctx = (sizeof(mp_module_context_t) + sizeof(mp_uint_t) - 1) / sizeof(mp_uint_t);
size_t nctx = 0;
size_t nq = (n_qstr * sizeof(qstr_short_t) + sizeof(mp_uint_t) - 1) / sizeof(mp_uint_t);
size_t nc = n_obj;
mp_module_context_t *mc = m_new_obj_var(mp_module_context_t, mp_uint_t, nq + 1 + nc);
mc->globals_ref = (mp_obj_dict_t **)&((mp_uint_t *)&mc->qstr_table[0])[nq];
*mc->globals_ref = mp_globals_get();
mc->const_table = (mp_obj_t *)&((mp_uint_t *)&mc->qstr_table[0])[nq + 1];
return mc;
size_t no = n_obj;
mp_uint_t *mem = m_new(mp_uint_t, nctx + nq + no);
//mp_module_context_t *ctx = (void *)mem;
ctx->constants.qstr_table = (void *)(mem + nctx);
ctx->constants.obj_table = (void *)(mem + nctx + nq);
//ctx->globals = globals;
return ctx;
}
static inline void mp_emit_common_create_module_context(mp_emit_common_t *emit, mp_compiled_module_t *cm) {
static inline void mp_emit_common_create_module_context(mp_emit_common_t *emit, mp_compiled_module_t *cm, mp_module_context_t *ctx) {
assert(emit->ct_cur_obj == emit->ct_num_obj);

size_t qstr_map_used = emit->qstr_map.used;
mp_module_context_t *mc = mp_module_context_new(qstr_map_used, emit->ct_cur_obj);
mp_module_context_new(ctx, qstr_map_used, emit->ct_cur_obj);
for (size_t i = 0; i < emit->qstr_map.alloc; ++i) {
if (mp_map_slot_is_filled(&emit->qstr_map, i)) {
size_t idx = MP_OBJ_SMALL_INT_VALUE(emit->qstr_map.table[i].value);
qstr qst = MP_OBJ_QSTR_VALUE(emit->qstr_map.table[i].key);
mc->qstr_table[idx] = qst;
ctx->constants.qstr_table[idx] = qst;
}
}
memcpy(mc->const_table, emit->const_table, emit->ct_cur_obj * sizeof(mp_uint_t));
memcpy(ctx->constants.obj_table, emit->const_table, emit->ct_cur_obj * sizeof(mp_uint_t));
#if 0
printf("table %d\n", (int)emit->ct_cur_obj);
printf(" %p\n", mc->const_table[0]);
printf(" %p\n", mc->const_table[1]);
printf(" %p\n", mc->const_table[2]);
#endif

cm->mc = mc;
cm->ctx = ctx;
#if MICROPY_PERSISTENT_CODE_SAVE
cm->n_qstr = emit->qstr_map.used;
cm->n_obj = emit->ct_cur_obj;
Expand Down
9 changes: 4 additions & 5 deletions py/emitnative.c
Expand Up @@ -95,10 +95,10 @@
#define OFFSETOF_CODE_STATE_SP (offsetof(mp_code_state_t, sp) / sizeof(uintptr_t))
//#define OFFSETOF_OBJ_FUN_BC_GLOBALS (offsetof(mp_obj_fun_bc_t, globals) / sizeof(uintptr_t))
#define OFFSETOF_OBJ_FUN_BC_BYTECODE (offsetof(mp_obj_fun_bc_t, bytecode) / sizeof(uintptr_t))
#define OFFSETOF_OBJ_FUN_BC_MC (offsetof(mp_obj_fun_bc_t, mc) / sizeof(uintptr_t))
#define OFFSETOF_OBJ_FUN_BC_MC (offsetof(mp_obj_fun_bc_t, ctx) / sizeof(uintptr_t))
#define OFFSETOF_OBJ_FUN_BC_RAW_CODE_TABLE (offsetof(mp_obj_fun_bc_t, raw_code_table) / sizeof(uintptr_t))
#define OFFSETOF_MODULE_CONTEXT_CONST_TABLE (offsetof(mp_module_context_t, const_table) / sizeof(uintptr_t))
#define OFFSETOF_MODULE_CONTEXT_GLOBALS_REF (offsetof(mp_module_context_t, globals_ref) / sizeof(uintptr_t))
#define OFFSETOF_MODULE_CONTEXT_CONST_TABLE (offsetof(mp_module_context_t, constants.obj_table) / sizeof(uintptr_t))
#define OFFSETOF_MODULE_CONTEXT_GLOBALS (offsetof(mp_module_context_t, module.globals) / sizeof(uintptr_t))
#define INDEX_OF_MP_FUN_TABLE_IN_CONST_TABLE (0)

// If not already defined, set parent args to same as child call registers
Expand Down Expand Up @@ -1185,8 +1185,7 @@ STATIC void emit_native_global_exc_entry(emit_t *emit) {
// Set new globals
emit_native_mov_reg_state(emit, REG_ARG_1, LOCAL_IDX_FUN_OBJ(emit));
ASM_LOAD_REG_REG_OFFSET(emit->as, REG_ARG_1, REG_ARG_1, OFFSETOF_OBJ_FUN_BC_MC);
ASM_LOAD_REG_REG_OFFSET(emit->as, REG_ARG_1, REG_ARG_1, OFFSETOF_MODULE_CONTEXT_GLOBALS_REF);
ASM_LOAD_REG_REG_OFFSET(emit->as, REG_ARG_1, REG_ARG_1, 0);
ASM_LOAD_REG_REG_OFFSET(emit->as, REG_ARG_1, REG_ARG_1, OFFSETOF_MODULE_CONTEXT_GLOBALS);
emit_call(emit, MP_F_NATIVE_SWAP_GLOBALS);

// Save old globals (or NULL if globals didn't change)
Expand Down
2 changes: 1 addition & 1 deletion py/frozenmod.c
Expand Up @@ -57,7 +57,7 @@ extern const char mp_frozen_str_content[];

#include "py/emitglue.h"

extern const mp_compiled_module_t *const mp_frozen_mpy_content[];
extern const mp_frozen_module_t *const mp_frozen_mpy_content[];

#endif // MICROPY_MODULE_FROZEN_MPY

Expand Down
2 changes: 2 additions & 0 deletions py/gc.c
Expand Up @@ -339,12 +339,14 @@ void gc_collect_start(void) {
size_t root_end = offsetof(mp_state_ctx_t, vm.qstr_last_chunk);
gc_collect_root(ptrs + root_start / sizeof(void *), (root_end - root_start) / sizeof(void *));

#if 0
#if MICROPY_MODULE_FROZEN_MPY
// Trace root pointers from frozen modules.
extern void *mp_frozen_root_pointers[];
extern size_t mp_frozen_root_pointers_len;
gc_collect_root(mp_frozen_root_pointers, mp_frozen_root_pointers_len);
#endif
#endif

#if MICROPY_ENABLE_PYSTACK
// Trace root pointers from the Python stack.
Expand Down
10 changes: 5 additions & 5 deletions py/objfun.c
Expand Up @@ -167,7 +167,7 @@ qstr mp_obj_fun_get_name(mp_const_obj_t fun_in) {

const byte *bc = fun->bytecode;
MP_BC_PRELUDE_SIG_DECODE(bc);
return mp_obj_code_get_name(bc, fun->mc->qstr_table);
return mp_obj_code_get_name(bc, fun->ctx->constants.qstr_table);
}

#if MICROPY_CPYTHON_COMPAT
Expand Down Expand Up @@ -285,7 +285,7 @@ STATIC mp_obj_t fun_bc_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const
INIT_CODESTATE(code_state, self, n_state, n_args, n_kw, args);

// execute the byte code with the correct globals context
mp_globals_set(*self->mc->globals_ref);
mp_globals_set(self->ctx->module.globals);
mp_vm_return_kind_t vm_return_kind = mp_execute_bytecode(code_state, MP_OBJ_NULL);
mp_globals_set(code_state->old_globals);

Expand Down Expand Up @@ -358,7 +358,7 @@ void mp_obj_fun_bc_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
}
if (attr == MP_QSTR___globals__) {
mp_obj_fun_bc_t *self = MP_OBJ_TO_PTR(self_in);
dest[0] = MP_OBJ_FROM_PTR(*self->mc->globals_ref);
dest[0] = MP_OBJ_FROM_PTR(self->ctx->module.globals);
}
}
#endif
Expand All @@ -377,7 +377,7 @@ const mp_obj_type_t mp_type_fun_bc = {
#endif
};

mp_obj_t mp_obj_new_fun_bc(const mp_obj_t *def_args, const byte *code, const mp_module_context_t *mc, struct _mp_raw_code_t *const *raw_code_table) {
mp_obj_t mp_obj_new_fun_bc(const mp_obj_t *def_args, const byte *code, const mp_module_context_t *ctx, struct _mp_raw_code_t *const *raw_code_table) {
size_t n_def_args = 0;
size_t n_extra_args = 0;
mp_obj_tuple_t *def_pos_args = NULL;
Expand All @@ -396,7 +396,7 @@ mp_obj_t mp_obj_new_fun_bc(const mp_obj_t *def_args, const byte *code, const mp_
mp_obj_fun_bc_t *o = m_new_obj_var(mp_obj_fun_bc_t, mp_obj_t, n_extra_args);
o->base.type = &mp_type_fun_bc;
o->bytecode = code;
o->mc = mc;
o->ctx = ctx;
o->raw_code_table = raw_code_table;
if (def_pos_args != NULL) {
memcpy(o->extra_args, def_pos_args->items, n_def_args * sizeof(mp_obj_t));
Expand Down
2 changes: 1 addition & 1 deletion py/objfun.h
Expand Up @@ -31,7 +31,7 @@

typedef struct _mp_obj_fun_bc_t {
mp_obj_base_t base;
const mp_module_context_t *mc; // the context within which this function was defined
const mp_module_context_t *ctx; // the context within which this function was defined
struct _mp_raw_code_t *const *raw_code_table;
const byte *bytecode; // bytecode for the function
#if MICROPY_PY_SYS_SETTRACE
Expand Down
4 changes: 2 additions & 2 deletions py/objgenerator.c
Expand Up @@ -95,7 +95,7 @@ STATIC mp_obj_t native_gen_wrap_call(mp_obj_t self_in, size_t n_args, size_t n_k
uintptr_t prelude_offset = ((uintptr_t *)self_fun->bytecode)[0];
#if MICROPY_EMIT_NATIVE_PRELUDE_AS_BYTES_OBJ
// Prelude is in bytes object in const_table, at index prelude_offset
mp_obj_str_t *prelude_bytes = MP_OBJ_TO_PTR(self_fun->mc->const_table[prelude_offset]);
mp_obj_str_t *prelude_bytes = MP_OBJ_TO_PTR(self_fun->ctx->constants.obj_table[prelude_offset]);
prelude_offset = (const byte *)prelude_bytes->data - self_fun->bytecode;
#endif
const uint8_t *ip = self_fun->bytecode + prelude_offset;
Expand Down Expand Up @@ -184,7 +184,7 @@ mp_vm_return_kind_t mp_obj_gen_resume(mp_obj_t self_in, mp_obj_t send_value, mp_

// Set up the correct globals context for the generator and execute it
self->code_state.old_globals = mp_globals_get();
mp_globals_set(*self->code_state.fun_bc->mc->globals_ref);
mp_globals_set(self->code_state.fun_bc->ctx->module.globals);

mp_vm_return_kind_t ret_kind;

Expand Down

0 comments on commit 0f6a102

Please sign in to comment.