diff options
Diffstat (limited to 'py')
-rw-r--r-- | py/builtin.h | 3 | ||||
-rw-r--r-- | py/builtinevex.c | 7 | ||||
-rw-r--r-- | py/builtinimport.c | 7 | ||||
-rw-r--r-- | py/builtintables.c | 2 | ||||
-rw-r--r-- | py/compile.c | 15 | ||||
-rw-r--r-- | py/emitbc.c | 34 | ||||
-rw-r--r-- | py/emitcommon.c | 4 | ||||
-rw-r--r-- | py/emitcpy.c | 2 | ||||
-rw-r--r-- | py/emitglue.c | 159 | ||||
-rw-r--r-- | py/emitglue.h | 40 | ||||
-rw-r--r-- | py/emitinlinethumb.c | 5 | ||||
-rw-r--r-- | py/emitnative.c | 12 | ||||
-rw-r--r-- | py/emitpass1.c | 2 | ||||
-rw-r--r-- | py/modcollections.c | 4 | ||||
-rw-r--r-- | py/obj.c | 6 | ||||
-rw-r--r-- | py/objdict.c | 9 | ||||
-rw-r--r-- | py/objfun.c | 25 | ||||
-rw-r--r-- | py/objint.c | 23 | ||||
-rw-r--r-- | py/objlist.c | 40 | ||||
-rw-r--r-- | py/objset.c | 2 | ||||
-rw-r--r-- | py/opmethods.c | 20 | ||||
-rw-r--r-- | py/parsehelper.c | 22 | ||||
-rw-r--r-- | py/parsehelper.h | 2 | ||||
-rw-r--r-- | py/py.mk | 1 | ||||
-rw-r--r-- | py/qstrdefs.h | 3 | ||||
-rw-r--r-- | py/runtime.c | 2 | ||||
-rw-r--r-- | py/runtime.h | 3 | ||||
-rw-r--r-- | py/runtime0.h | 2 | ||||
-rw-r--r-- | py/scope.c | 6 | ||||
-rw-r--r-- | py/scope.h | 4 | ||||
-rw-r--r-- | py/showbc.c | 13 | ||||
-rw-r--r-- | py/vm.c | 30 |
32 files changed, 274 insertions, 235 deletions
diff --git a/py/builtin.h b/py/builtin.h index bf65b48329..743f748da0 100644 --- a/py/builtin.h +++ b/py/builtin.h @@ -35,6 +35,9 @@ MP_DECLARE_CONST_FUN_OBJ(mp_builtin_sum_obj); MP_DECLARE_CONST_FUN_OBJ(mp_namedtuple_obj); +MP_DECLARE_CONST_FUN_OBJ(mp_op_contains_obj); +MP_DECLARE_CONST_FUN_OBJ(mp_op_getitem_obj); + extern const mp_obj_module_t mp_module___main__; extern const mp_obj_module_t mp_module_array; extern const mp_obj_module_t mp_module_collections; diff --git a/py/builtinevex.c b/py/builtinevex.c index fc3a60182e..ae82537374 100644 --- a/py/builtinevex.c +++ b/py/builtinevex.c @@ -25,13 +25,16 @@ STATIC mp_obj_t parse_compile_execute(mp_obj_t o_in, mp_parse_input_kind_t parse // parse the string mp_parse_error_kind_t parse_error_kind; mp_parse_node_t pn = mp_parse(lex, parse_input_kind, &parse_error_kind); - mp_lexer_free(lex); if (pn == MP_PARSE_NODE_NULL) { // parse error; raise exception - nlr_raise(mp_parse_make_exception(parse_error_kind)); + mp_obj_t exc = mp_parse_make_exception(lex, parse_error_kind); + mp_lexer_free(lex); + nlr_raise(exc); } + mp_lexer_free(lex); + // compile the string mp_obj_t module_fun = mp_compile(pn, source_name, MP_EMIT_OPT_NONE, false); mp_parse_node_free(pn); diff --git a/py/builtinimport.c b/py/builtinimport.c index 578e73feb6..4af7dd7ed3 100644 --- a/py/builtinimport.c +++ b/py/builtinimport.c @@ -96,15 +96,18 @@ void do_load(mp_obj_t module_obj, vstr_t *file) { // parse the imported script mp_parse_error_kind_t parse_error_kind; mp_parse_node_t pn = mp_parse(lex, MP_PARSE_FILE_INPUT, &parse_error_kind); - mp_lexer_free(lex); if (pn == MP_PARSE_NODE_NULL) { // parse error; clean up and raise exception + mp_obj_t exc = mp_parse_make_exception(lex, parse_error_kind); + mp_lexer_free(lex); mp_locals_set(old_locals); mp_globals_set(old_globals); - nlr_raise(mp_parse_make_exception(parse_error_kind)); + nlr_raise(exc); } + mp_lexer_free(lex); + // compile the imported script mp_obj_t module_fun = mp_compile(pn, source_name, MP_EMIT_OPT_NONE, false); mp_parse_node_free(pn); diff --git a/py/builtintables.c b/py/builtintables.c index 23c34eda11..0115ea04b5 100644 --- a/py/builtintables.c +++ b/py/builtintables.c @@ -126,7 +126,7 @@ STATIC const mp_map_elem_t mp_builtin_module_table[] = { #if MICROPY_ENABLE_MOD_IO { MP_OBJ_NEW_QSTR(MP_QSTR_io), (mp_obj_t)&mp_module_io }, #endif - { MP_OBJ_NEW_QSTR(MP_QSTR_collections), (mp_obj_t)&mp_module_collections }, + { MP_OBJ_NEW_QSTR(MP_QSTR__collections), (mp_obj_t)&mp_module_collections }, #if MICROPY_ENABLE_MOD_STRUCT { MP_OBJ_NEW_QSTR(MP_QSTR_struct), (mp_obj_t)&mp_module_struct }, #endif diff --git a/py/compile.c b/py/compile.c index f397501f17..7a3d810f9d 100644 --- a/py/compile.c +++ b/py/compile.c @@ -10,11 +10,11 @@ #include "qstr.h" #include "lexer.h" #include "parse.h" -#include "scope.h" #include "runtime0.h" -#include "emit.h" -#include "emitglue.h" #include "obj.h" +#include "emitglue.h" +#include "scope.h" +#include "emit.h" #include "compile.h" #include "runtime.h" #include "builtin.h" @@ -283,7 +283,7 @@ STATIC void compile_decrease_except_level(compiler_t *comp) { } STATIC scope_t *scope_new_and_link(compiler_t *comp, scope_kind_t kind, mp_parse_node_t pn, uint emit_options) { - scope_t *scope = scope_new(kind, pn, comp->source_file, mp_emit_glue_get_unique_code_id(), emit_options); + scope_t *scope = scope_new(kind, pn, comp->source_file, emit_options); scope->parent = comp->scope_cur; scope->next = NULL; if (comp->scope_head == NULL) { @@ -3454,7 +3454,7 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, uint emit_opt, bool is #endif // !MICROPY_EMIT_CPYTHON // free the scopes - uint unique_code_id = module_scope->unique_code_id; + mp_raw_code_t *outer_raw_code = module_scope->raw_code; for (scope_t *s = module_scope; s;) { scope_t *next = s->next; scope_free(s); @@ -3471,12 +3471,11 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, uint emit_opt, bool is } else { #if MICROPY_EMIT_CPYTHON // can't create code, so just return true - (void)unique_code_id; // to suppress warning that unique_code_id is unused + (void)outer_raw_code; // to suppress warning that outer_raw_code is unused return mp_const_true; #else // return function that executes the outer module - // we can free the unique_code slot because no-one has reference to this unique_code_id anymore - return mp_make_function_from_id_and_free(unique_code_id, MP_OBJ_NULL, MP_OBJ_NULL); + return mp_make_function_from_raw_code(outer_raw_code, MP_OBJ_NULL, MP_OBJ_NULL); #endif } } diff --git a/py/emitbc.c b/py/emitbc.c index d1d59ef4a5..2d71d86855 100644 --- a/py/emitbc.c +++ b/py/emitbc.c @@ -9,10 +9,11 @@ #include "qstr.h" #include "lexer.h" #include "parse.h" +#include "obj.h" +#include "emitglue.h" #include "scope.h" #include "runtime0.h" #include "emit.h" -#include "emitglue.h" #include "bc0.h" struct _emit_t { @@ -65,6 +66,10 @@ STATIC byte* emit_get_cur_to_write_code_info(emit_t* emit, int num_bytes_to_writ } } +STATIC void emit_align_code_info_to_machine_word(emit_t* emit) { + emit->code_info_offset = (emit->code_info_offset + sizeof(machine_uint_t) - 1) & (~(sizeof(machine_uint_t) - 1)); +} + STATIC void emit_write_code_info_qstr(emit_t* emit, qstr qstr) { byte* c = emit_get_cur_to_write_code_info(emit, 4); // TODO variable length encoding for qstr @@ -98,6 +103,10 @@ STATIC byte* emit_get_cur_to_write_byte_code(emit_t* emit, int num_bytes_to_writ } } +STATIC void emit_align_byte_code_to_machine_word(emit_t* emit) { + emit->byte_code_offset = (emit->byte_code_offset + sizeof(machine_uint_t) - 1) & (~(sizeof(machine_uint_t) - 1)); +} + STATIC void emit_write_byte_code_byte(emit_t* emit, byte b1) { byte* c = emit_get_cur_to_write_byte_code(emit, 1); c[0] = b1; @@ -158,6 +167,14 @@ STATIC void emit_write_byte_code_byte_uint(emit_t* emit, byte b, uint num) { emit_write_byte_code_uint(emit, num); } +// aligns the pointer so it is friendly to GC +STATIC void emit_write_byte_code_byte_ptr(emit_t* emit, byte b, void *ptr) { + emit_write_byte_code_byte(emit, b); + emit_align_byte_code_to_machine_word(emit); + machine_uint_t *c = (machine_uint_t*)emit_get_cur_to_write_byte_code(emit, sizeof(machine_uint_t)); + *c = (machine_uint_t)ptr; +} + /* currently unused STATIC void emit_write_byte_code_byte_uint_uint(emit_t* emit, byte b, uint num1, uint num2) { emit_write_byte_code_byte(emit, b); @@ -178,7 +195,7 @@ STATIC void emit_write_byte_code_byte_unsigned_label(emit_t* emit, byte b1, uint } else { byte_code_offset = emit->label_offsets[label] - emit->byte_code_offset - 3; } - byte* c = emit_get_cur_to_write_byte_code(emit, 3); + byte *c = emit_get_cur_to_write_byte_code(emit, 3); c[0] = b1; c[1] = byte_code_offset; c[2] = byte_code_offset >> 8; @@ -269,19 +286,20 @@ STATIC void emit_bc_end_pass(emit_t *emit) { } emit_write_code_info_bytes_lines(emit, 0, 0); // end of line number info + emit_align_code_info_to_machine_word(emit); // align so that following byte_code is aligned if (emit->pass == PASS_2) { // calculate size of code in bytes emit->code_info_size = emit->code_info_offset; emit->byte_code_size = emit->byte_code_offset; - emit->code_base = m_new(byte, emit->code_info_size + emit->byte_code_size); + emit->code_base = m_new0(byte, emit->code_info_size + emit->byte_code_size); } else if (emit->pass == PASS_3) { qstr *arg_names = m_new(qstr, emit->scope->num_params); for (int i = 0; i < emit->scope->num_params; i++) { arg_names[i] = emit->scope->id_info[i].qstr; } - mp_emit_glue_assign_byte_code(emit->scope->unique_code_id, emit->code_base, + mp_emit_glue_assign_byte_code(emit->scope->raw_code, emit->code_base, emit->code_info_size + emit->byte_code_size, emit->scope->num_params, emit->scope->num_locals, emit->scope->scope_flags, arg_names); @@ -733,7 +751,7 @@ STATIC void emit_bc_unpack_ex(emit_t *emit, int n_left, int n_right) { STATIC void emit_bc_make_function(emit_t *emit, scope_t *scope, uint n_pos_defaults, uint n_kw_defaults) { if (n_pos_defaults == 0 && n_kw_defaults == 0) { emit_bc_pre(emit, 1); - emit_write_byte_code_byte_uint(emit, MP_BC_MAKE_FUNCTION, scope->unique_code_id); + emit_write_byte_code_byte_ptr(emit, MP_BC_MAKE_FUNCTION, scope->raw_code); } else { if (n_pos_defaults == 0) { // load dummy entry for non-existent positional default tuple @@ -744,14 +762,14 @@ STATIC void emit_bc_make_function(emit_t *emit, scope_t *scope, uint n_pos_defau emit_bc_load_null(emit); } emit_bc_pre(emit, -1); - emit_write_byte_code_byte_uint(emit, MP_BC_MAKE_FUNCTION_DEFARGS, scope->unique_code_id); + emit_write_byte_code_byte_ptr(emit, MP_BC_MAKE_FUNCTION_DEFARGS, scope->raw_code); } } STATIC void emit_bc_make_closure(emit_t *emit, scope_t *scope, uint n_pos_defaults, uint n_kw_defaults) { if (n_pos_defaults == 0 && n_kw_defaults == 0) { emit_bc_pre(emit, 0); - emit_write_byte_code_byte_uint(emit, MP_BC_MAKE_CLOSURE, scope->unique_code_id); + emit_write_byte_code_byte_ptr(emit, MP_BC_MAKE_CLOSURE, scope->raw_code); } else { if (n_pos_defaults == 0) { // load dummy entry for non-existent positional default tuple @@ -763,7 +781,7 @@ STATIC void emit_bc_make_closure(emit_t *emit, scope_t *scope, uint n_pos_defaul emit_bc_rot_two(emit); } emit_bc_pre(emit, -2); - emit_write_byte_code_byte_uint(emit, MP_BC_MAKE_CLOSURE_DEFARGS, scope->unique_code_id); + emit_write_byte_code_byte_ptr(emit, MP_BC_MAKE_CLOSURE_DEFARGS, scope->raw_code); } } diff --git a/py/emitcommon.c b/py/emitcommon.c index 30f5ace923..454ec9c5e5 100644 --- a/py/emitcommon.c +++ b/py/emitcommon.c @@ -7,8 +7,10 @@ #include "qstr.h" #include "lexer.h" #include "parse.h" -#include "scope.h" #include "runtime0.h" +#include "obj.h" +#include "emitglue.h" +#include "scope.h" #include "emit.h" #define EMIT(fun, ...) (emit_method_table->fun(emit, __VA_ARGS__)) diff --git a/py/emitcpy.c b/py/emitcpy.c index 5866d474e9..010219d12f 100644 --- a/py/emitcpy.c +++ b/py/emitcpy.c @@ -9,6 +9,8 @@ #include "qstr.h" #include "lexer.h" #include "parse.h" +#include "obj.h" +#include "emitglue.h" #include "scope.h" #include "runtime0.h" #include "emit.h" diff --git a/py/emitglue.c b/py/emitglue.c index bcc9b2cca1..ce296f4321 100644 --- a/py/emitglue.c +++ b/py/emitglue.c @@ -23,46 +23,11 @@ #define DEBUG_OP_printf(...) (void)0 #endif -typedef enum { - MP_CODE_UNUSED, - MP_CODE_RESERVED, - MP_CODE_BYTE, - MP_CODE_NATIVE, - MP_CODE_INLINE_ASM, -} mp_code_kind_t; - -typedef struct _mp_code_t { - mp_code_kind_t kind : 8; - uint scope_flags : 8; - uint n_args : 16; - union { - struct { - byte *code; - uint len; - } u_byte; - struct { - mp_fun_t fun; - } u_native; - struct { - void *fun; - } u_inline_asm; - }; - qstr *arg_names; -} mp_code_t; - -STATIC machine_uint_t unique_codes_alloc = 0; -STATIC machine_uint_t unique_codes_total = 0; // always >= unique_codes_alloc -STATIC mp_code_t *unique_codes = NULL; - #ifdef WRITE_CODE FILE *fp_write_code = NULL; #endif void mp_emit_glue_init(void) { - unique_codes_alloc = 0; - unique_codes_total = 0; - unique_codes = NULL; - #ifdef WRITE_CODE fp_write_code = fopen("out-code", "wb"); #endif @@ -74,50 +39,24 @@ void mp_emit_glue_deinit(void) { fclose(fp_write_code); } #endif - - m_del(mp_code_t, unique_codes, unique_codes_alloc); -} - -uint mp_emit_glue_get_unique_code_id(void) { - // look for an existing unused slot - for (uint i = 0; i < unique_codes_alloc; i++) { - if (unique_codes[i].kind == MP_CODE_UNUSED) { - unique_codes[i].kind = MP_CODE_RESERVED; - return i; - } - } - // no existing slot - // return next available id, memory will be allocated later - return unique_codes_total++; } -STATIC void mp_emit_glue_alloc_unique_codes(void) { - if (unique_codes_total > unique_codes_alloc) { - DEBUG_printf("allocate more unique codes: " UINT_FMT " -> %u\n", unique_codes_alloc, unique_codes_total); - // increase size of unique_codes table (all new entries are already reserved) - unique_codes = m_renew(mp_code_t, unique_codes, unique_codes_alloc, unique_codes_total); - for (uint i = unique_codes_alloc; i < unique_codes_total; i++) { - unique_codes[i].kind = MP_CODE_RESERVED; - } - unique_codes_alloc = unique_codes_total; - } +mp_raw_code_t *mp_emit_glue_new_raw_code(void) { + mp_raw_code_t *rc = m_new0(mp_raw_code_t, 1); + rc->kind = MP_CODE_RESERVED; + return rc; } -void mp_emit_glue_assign_byte_code(uint unique_code_id, byte *code, uint len, int n_args, int n_locals, uint scope_flags, qstr *arg_names) { - mp_emit_glue_alloc_unique_codes(); - - assert(unique_code_id < unique_codes_alloc && unique_codes[unique_code_id].kind == MP_CODE_RESERVED); - unique_codes[unique_code_id].kind = MP_CODE_BYTE; - unique_codes[unique_code_id].scope_flags = scope_flags; - unique_codes[unique_code_id].n_args = n_args; - unique_codes[unique_code_id].u_byte.code = code; - unique_codes[unique_code_id].u_byte.len = len; - unique_codes[unique_code_id].arg_names = arg_names; - - //printf("byte code: %d bytes\n", len); +void mp_emit_glue_assign_byte_code(mp_raw_code_t *rc, byte *code, uint len, int n_args, int n_locals, uint scope_flags, qstr *arg_names) { + rc->kind = MP_CODE_BYTE; + rc->scope_flags = scope_flags; + rc->n_args = n_args; + rc->u_byte.code = code; + rc->u_byte.len = len; + rc->arg_names = arg_names; #ifdef DEBUG_PRINT - DEBUG_printf("assign byte code: id=%d code=%p len=%u n_args=%d n_locals=%d\n", unique_code_id, code, len, n_args, n_locals); + DEBUG_printf("assign byte code: code=%p len=%u n_args=%d n_locals=%d\n", code, len, n_args, n_locals); for (int i = 0; i < 128 && i < len; i++) { if (i > 0 && i % 16 == 0) { DEBUG_printf("\n"); @@ -131,19 +70,14 @@ void mp_emit_glue_assign_byte_code(uint unique_code_id, byte *code, uint len, in #endif } -void mp_emit_glue_assign_native_code(uint unique_code_id, void *fun, uint len, int n_args) { - mp_emit_glue_alloc_unique_codes(); - - assert(unique_code_id < unique_codes_alloc && unique_codes[unique_code_id].kind == MP_CODE_RESERVED); - unique_codes[unique_code_id].kind = MP_CODE_NATIVE; - unique_codes[unique_code_id].scope_flags = 0; - unique_codes[unique_code_id].n_args = n_args; - unique_codes[unique_code_id].u_native.fun = fun; - - //printf("native code: %d bytes\n", len); +void mp_emit_glue_assign_native_code(mp_raw_code_t *rc, void *fun, uint len, int n_args) { + rc->kind = MP_CODE_NATIVE; + rc->scope_flags = 0; + rc->n_args = n_args; + rc->u_native.fun = fun; #ifdef DEBUG_PRINT - DEBUG_printf("assign native code: id=%d fun=%p len=%u n_args=%d\n", unique_code_id, fun, len, n_args); + DEBUG_printf("assign native code: fun=%p len=%u n_args=%d\n", fun, len, n_args); byte *fun_data = (byte*)(((machine_uint_t)fun) & (~1)); // need to clear lower bit in case it's thumb code for (int i = 0; i < 128 && i < len; i++) { if (i > 0 && i % 16 == 0) { @@ -162,17 +96,14 @@ void mp_emit_glue_assign_native_code(uint unique_code_id, void *fun, uint len, i #endif } -void mp_emit_glue_assign_inline_asm_code(uint unique_code_id, void *fun, uint len, int n_args) { - mp_emit_glue_alloc_unique_codes(); - - assert(unique_code_id < unique_codes_alloc && unique_codes[unique_code_id].kind == MP_CODE_RESERVED); - unique_codes[unique_code_id].kind = MP_CODE_INLINE_ASM; - unique_codes[unique_code_id].scope_flags = 0; - unique_codes[unique_code_id].n_args = n_args; - unique_codes[unique_code_id].u_inline_asm.fun = fun; +void mp_emit_glue_assign_inline_asm_code(mp_raw_code_t *rc, void *fun, uint len, int n_args) { + rc->kind = MP_CODE_INLINE_ASM; + rc->scope_flags = 0; + rc->n_args = n_args; + rc->u_inline_asm.fun = fun; #ifdef DEBUG_PRINT - DEBUG_printf("assign inline asm code: id=%d fun=%p len=%u n_args=%d\n", unique_code_id, fun, len, n_args); + DEBUG_printf("assign inline asm code: fun=%p len=%u n_args=%d\n", fun, len, n_args); byte *fun_data = (byte*)(((machine_uint_t)fun) & (~1)); // need to clear lower bit in case it's thumb code for (int i = 0; i < 128 && i < len; i++) { if (i > 0 && i % 16 == 0) { @@ -191,12 +122,9 @@ void mp_emit_glue_assign_inline_asm_code(uint unique_code_id, void *fun, uint le #endif } -mp_obj_t mp_make_function_from_id(uint unique_code_id, mp_obj_t def_args, mp_obj_t def_kw_args) { - DEBUG_OP_printf("make_function_from_id %d\n", unique_code_id); - if (unique_code_id >= unique_codes_total) { - // illegal code id - return mp_const_none; - } +mp_obj_t mp_make_function_from_raw_code(mp_raw_code_t *rc, mp_obj_t def_args, mp_obj_t def_kw_args) { + DEBUG_OP_printf("make_function_from_raw_code %p\n", rc); + assert(rc != NULL); // def_args must be MP_OBJ_NULL or a tuple assert(def_args == MP_OBJ_NULL || MP_OBJ_IS_TYPE(def_args, &mp_type_tuple)); @@ -204,49 +132,36 @@ mp_obj_t mp_make_function_from_id(uint unique_code_id, mp_obj_t def_args, mp_obj // TODO implement default kw args assert(def_kw_args == MP_OBJ_NULL); - // make the function, depending on the code kind - mp_code_t *c = &unique_codes[unique_code_id]; + // make the function, depending on the raw code kind mp_obj_t fun; - switch (c->kind) { + switch (rc->kind) { case MP_CODE_BYTE: - fun = mp_obj_new_fun_bc(c->scope_flags, c->arg_names, c->n_args, def_args, c->u_byte.code); + fun = mp_obj_new_fun_bc(rc->scope_flags, rc->arg_names, rc->n_args, def_args, rc->u_byte.code); break; case MP_CODE_NATIVE: - fun = mp_make_function_n(c->n_args, c->u_native.fun); + fun = mp_make_function_n(rc->n_args, rc->u_native.fun); break; case MP_CODE_INLINE_ASM: - fun = mp_obj_new_fun_asm(c->n_args, c->u_inline_asm.fun); + fun = mp_obj_new_fun_asm(rc->n_args, rc->u_inline_asm.fun); break; default: - // code id was never assigned (this should not happen) + // raw code was never set (this should not happen) assert(0); return mp_const_none; } // check for generator functions and if so wrap in generator object - if ((c->scope_flags & MP_SCOPE_FLAG_GENERATOR) != 0) { + if ((rc->scope_flags & MP_SCOPE_FLAG_GENERATOR) != 0) { fun = mp_obj_new_gen_wrap(fun); } return fun; } -mp_obj_t mp_make_function_from_id_and_free(uint unique_code_id, mp_obj_t def_args, mp_obj_t def_kw_args) { - mp_obj_t f = mp_make_function_from_id(unique_code_id, def_args, def_kw_args); - - // in some cases we can free the unique_code slot - // any dynamically allocated memory is now owned by the fun object - mp_code_t *c = &unique_codes[unique_code_id]; - memset(c, 0, sizeof *c); // make sure all pointers are zeroed - c->kind = MP_CODE_UNUSED; - - return f; -} - -mp_obj_t mp_make_closure_from_id(uint unique_code_id, mp_obj_t closure_tuple, mp_obj_t def_args, mp_obj_t def_kw_args) { - DEBUG_OP_printf("make_closure_from_id %d\n", unique_code_id); +mp_obj_t mp_make_closure_from_raw_code(mp_raw_code_t *rc, mp_obj_t closure_tuple, mp_obj_t def_args, mp_obj_t def_kw_args) { + DEBUG_OP_printf("make_closure_from_raw_code %p\n", rc); // make function object - mp_obj_t ffun = mp_make_function_from_id(unique_code_id, def_args, def_kw_args); + mp_obj_t ffun = mp_make_function_from_raw_code(rc, def_args, def_kw_args); // wrap function in closure object return mp_obj_new_closure(ffun, closure_tuple); } diff --git a/py/emitglue.h b/py/emitglue.h index 8f69951c21..2f9960bfa1 100644 --- a/py/emitglue.h +++ b/py/emitglue.h @@ -1,8 +1,40 @@ // These variables and functions glue the code emitters to the runtime. +typedef enum { + MP_CODE_UNUSED, + MP_CODE_RESERVED, + MP_CODE_BYTE, + MP_CODE_NATIVE, + MP_CODE_INLINE_ASM, +} mp_raw_code_kind_t; + +typedef struct _mp_code_t { + mp_raw_code_kind_t kind : 8; + uint scope_flags : 8; + uint n_args : 16; + union { + struct { + byte *code; + uint len; + } u_byte; + struct { + mp_fun_t fun; + } u_native; + struct { + void *fun; + } u_inline_asm; + }; + qstr *arg_names; +} mp_raw_code_t; + void mp_emit_glue_init(void); void mp_emit_glue_deinit(void); -uint mp_emit_glue_get_unique_code_id(void); -void mp_emit_glue_assign_byte_code(uint unique_code_id, byte *code, uint len, int n_args, int n_locals, uint scope_flags, qstr *arg_names); -void mp_emit_glue_assign_native_code(uint unique_code_id, void *f, uint len, int n_args); -void mp_emit_glue_assign_inline_asm_code(uint unique_code_id, void *f, uint len, int n_args); + +mp_raw_code_t *mp_emit_glue_new_raw_code(void); + +void mp_emit_glue_assign_byte_code(mp_raw_code_t *rc, byte *code, uint len, int n_args, int n_locals, uint scope_flags, qstr *arg_names); +void mp_emit_glue_assign_native_code(mp_raw_code_t *rc, void *f, uint len, int n_args); +void mp_emit_glue_assign_inline_asm_code(mp_raw_code_t *rc, void *f, uint len, int n_args); + +mp_obj_t mp_make_function_from_raw_code(mp_raw_code_t *rc, mp_obj_t def_args, mp_obj_t def_kw_args); +mp_obj_t mp_make_closure_from_raw_code(mp_raw_code_t *rc, mp_obj_t closure_tuple, mp_obj_t def_args, mp_obj_t def_kw_args); diff --git a/py/emitinlinethumb.c b/py/emitinlinethumb.c index fc881f3d18..812e702af6 100644 --- a/py/emitinlinethumb.c +++ b/py/emitinlinethumb.c @@ -9,10 +9,11 @@ #include "qstr.h" #include "lexer.h" #include "parse.h" +#include "obj.h" +#include "emitglue.h" #include "scope.h" #include "runtime0.h" #include "emit.h" -#include "emitglue.h" #include "asmthumb.h" #if MICROPY_EMIT_INLINE_THUMB @@ -72,7 +73,7 @@ STATIC bool emit_inline_thumb_end_pass(emit_inline_asm_t *emit) { if (emit->pass == PASS_3) { void *f = asm_thumb_get_code(emit->as); - mp_emit_glue_assign_inline_asm_code(emit->scope->unique_code_id, f, asm_thumb_get_code_size(emit->as), emit->scope->num_params); + mp_emit_glue_assign_inline_asm_code(emit->scope->raw_code, f, asm_thumb_get_code_size(emit->as), emit->scope->num_params); } return emit->success; diff --git a/py/emitnative.c b/py/emitnative.c index b5a3acc231..3046aef4d6 100644 --- a/py/emitnative.c +++ b/py/emitnative.c @@ -27,11 +27,11 @@ #include "qstr.h" #include "lexer.h" #include "parse.h" +#include "obj.h" +#include "emitglue.h" #include "scope.h" #include "runtime0.h" #include "emit.h" -#include "emitglue.h" -#include "obj.h" #include "runtime.h" #if 0 // print debugging info @@ -283,10 +283,10 @@ STATIC void emit_native_end_pass(emit_t *emit) { if (emit->pass == PASS_3) { #if N_X64 void *f = asm_x64_get_code(emit->as); - mp_emit_glue_assign_native_code(emit->scope->unique_code_id, f, asm_x64_get_code_size(emit->as), emit->scope->num_params); + mp_emit_glue_assign_native_code(emit->scope->raw_code, f, asm_x64_get_code_size(emit->as), emit->scope->num_params); #elif N_THUMB void *f = asm_thumb_get_code(emit->as); - mp_emit_glue_assign_native_code(emit->scope->unique_code_id, f, asm_thumb_get_code_size(emit->as), emit->scope->num_params); + mp_emit_glue_assign_native_code(emit->scope->raw_code, f, asm_thumb_get_code_size(emit->as), emit->scope->num_params); #endif } } @@ -1188,7 +1188,9 @@ STATIC void emit_native_make_function(emit_t *emit, scope_t *scope, uint n_pos_d // call runtime, with type info for args, or don't support dict/default params, or only support Python objects for them assert(n_pos_defaults == 0 && n_kw_defaults == 0); emit_native_pre(emit); - emit_call_with_3_imm_args(emit, MP_F_MAKE_FUNCTION_FROM_ID, mp_make_function_from_id, scope->unique_code_id, REG_ARG_1, (machine_uint_t)MP_OBJ_NULL, REG_ARG_2, (machine_uint_t)MP_OBJ_NULL, REG_ARG_3); + assert(0); + // TODO we need to store the raw_code ptr aligned within the code for the GC + emit_call_with_3_imm_args(emit, MP_F_MAKE_FUNCTION_FROM_RAW_CODE, mp_make_function_from_raw_code, (machine_uint_t)scope->raw_code, REG_ARG_1, (machine_uint_t)MP_OBJ_NULL, REG_ARG_2, (machine_uint_t)MP_OBJ_NULL, REG_ARG_3); emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); } diff --git a/py/emitpass1.c b/py/emitpass1.c index ad86588e20..01156bfbe6 100644 --- a/py/emitpass1.c +++ b/py/emitpass1.c @@ -7,6 +7,8 @@ #include "qstr.h" #include "lexer.h" #include "parse.h" +#include "obj.h" +#include "emitglue.h" #include "scope.h" #include "runtime0.h" #include "emit.h" diff --git a/py/modcollections.c b/py/modcollections.c index dbd1896f20..11845a00ce 100644 --- a/py/modcollections.c +++ b/py/modcollections.c @@ -5,7 +5,7 @@ #include "builtin.h" STATIC const mp_map_elem_t mp_module_collections_globals_table[] = { - { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_collections) }, + { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR__collections) }, { MP_OBJ_NEW_QSTR(MP_QSTR_namedtuple), (mp_obj_t)&mp_namedtuple_obj }, }; @@ -22,6 +22,6 @@ STATIC const mp_obj_dict_t mp_module_collections_globals = { const mp_obj_module_t mp_module_collections = { .base = { &mp_type_module }, - .name = MP_QSTR_collections, + .name = MP_QSTR__collections, .globals = (mp_obj_dict_t*)&mp_module_collections_globals, }; @@ -333,11 +333,11 @@ mp_obj_t mp_identity(mp_obj_t self) { MP_DEFINE_CONST_FUN_OBJ_1(mp_identity_obj, mp_identity); bool mp_get_buffer(mp_obj_t obj, buffer_info_t *bufinfo) { - mp_obj_base_t *o = (mp_obj_base_t *)obj; - if (o->type->buffer_p.get_buffer == NULL) { + mp_obj_type_t *type = mp_obj_get_type(obj); + if (type->buffer_p.get_buffer == NULL) { return false; } - o->type->buffer_p.get_buffer(o, bufinfo, BUFFER_READ); + type->buffer_p.get_buffer(obj, bufinfo, BUFFER_READ); if (bufinfo->buf == NULL) { return false; } diff --git a/py/objdict.c b/py/objdict.c index 8bdd0026a5..2c56540d15 100644 --- a/py/objdict.c +++ b/py/objdict.c @@ -10,6 +10,7 @@ #include "objtuple.h" #include "runtime0.h" #include "runtime.h" +#include "builtin.h" STATIC mp_obj_t mp_obj_new_dict_iterator(mp_obj_dict_t *dict, int cur); STATIC mp_map_elem_t *dict_it_iternext_elem(mp_obj_t self_in); @@ -137,12 +138,6 @@ STATIC bool dict_store_item(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { return true; } -STATIC mp_obj_t dict_getitem(mp_obj_t lhs_in, mp_obj_t rhs_in) { - return dict_binary_op(MP_BINARY_OP_SUBSCR, lhs_in, rhs_in); -} - -STATIC MP_DEFINE_CONST_FUN_OBJ_2(dict_getitem_obj, dict_getitem); - /******************************************************************************/ /* dict iterator */ @@ -501,7 +496,7 @@ STATIC const mp_map_elem_t dict_locals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_setdefault), (mp_obj_t)&dict_setdefault_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_update), (mp_obj_t)&dict_update_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_values), (mp_obj_t)&dict_values_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR___getitem__), (mp_obj_t)&dict_getitem_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR___getitem__), (mp_obj_t)&mp_op_getitem_obj }, }; STATIC MP_DEFINE_CONST_DICT(dict_locals_dict, dict_locals_dict_table); diff --git a/py/objfun.c b/py/objfun.c index 4ef92c0256..8fadbc6119 100644 --- a/py/objfun.c +++ b/py/objfun.c @@ -229,7 +229,8 @@ STATIC mp_obj_t fun_bc_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_o if (n_args > self->n_args) { // given more than enough arguments if (!self->takes_var_args) { - goto arg_error; + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, + "function takes %d positional arguments but %d were given", self->n_args, n_args)); } // put extra arguments in varargs tuple *extra_args = mp_obj_new_tuple(n_args - self->n_args, args + self->n_args); @@ -249,7 +250,9 @@ STATIC mp_obj_t fun_bc_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_o extra_args -= self->n_args - n_args; n_extra_args += self->n_args - n_args; } else { - goto arg_error; + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, + "function takes at least %d positional arguments but %d were given", + self->n_args - self->n_def_args, n_args)); } } } @@ -344,9 +347,6 @@ continue2:; } else { // MP_VM_RETURN_EXCEPTION nlr_raise(result); } - -arg_error: - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "function takes %d positional arguments but %d were given", self->n_args, n_args)); } const mp_obj_type_t mp_type_fun_bc = { @@ -442,14 +442,15 @@ STATIC machine_uint_t convert_obj_for_inline_asm(mp_obj_t obj) { mp_obj_t *items; mp_obj_list_get(obj, &len, &items); return (machine_uint_t)items; - } else if (type->buffer_p.get_buffer != NULL) { - // supports the buffer protocol, get a pointer to the data - buffer_info_t bufinfo; - type->buffer_p.get_buffer(obj, &bufinfo, BUFFER_READ); - return (machine_uint_t)bufinfo.buf; } else { - // just pass along a pointer to the object - return (machine_uint_t)obj; + buffer_info_t bufinfo; + if (mp_get_buffer(obj, &bufinfo)) { + // supports the buffer protocol, return a pointer to the data + return (machine_uint_t)bufinfo.buf; + } else { + // just pass along a pointer to the object + return (machine_uint_t)obj; + } } } } diff --git a/py/objint.c b/py/objint.c index 69954168de..2eabff8d4e 100644 --- a/py/objint.c +++ b/py/objint.c @@ -265,18 +265,27 @@ mp_obj_t mp_obj_int_binary_op_extra_cases(int op, mp_obj_t lhs_in, mp_obj_t rhs_ return MP_OBJ_NULL; } +// this is a classmethod STATIC mp_obj_t int_from_bytes(uint n_args, const mp_obj_t *args) { + // TODO: Support long ints + // TODO: Support byteorder param (assumes 'little' at the moment) + // TODO: Support signed param (assumes signed=False at the moment) + + // get the buffer info buffer_info_t bufinfo; - mp_get_buffer_raise(args[0], &bufinfo); + mp_get_buffer_raise(args[1], &bufinfo); - assert(bufinfo.len >= sizeof(machine_int_t)); - // TODO: Support long ints - // TODO: Support byteorder param - // TODO: Support signed param - return mp_obj_new_int_from_uint(*(machine_uint_t*)bufinfo.buf); + // convert the bytes to an integer + machine_uint_t value = 0; + for (const byte* buf = bufinfo.buf + bufinfo.len - 1; buf >= (byte*)bufinfo.buf; buf--) { + value = (value << 8) | *buf; + } + + return mp_obj_new_int_from_uint(value); } -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(int_from_bytes_obj, 1, 3, int_from_bytes); +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(int_from_bytes_fun_obj, 2, 3, int_from_bytes); +STATIC MP_DEFINE_CONST_CLASSMETHOD_OBJ(int_from_bytes_obj, (const mp_obj_t)&int_from_bytes_fun_obj); STATIC mp_obj_t int_to_bytes(uint n_args, const mp_obj_t *args) { machine_int_t val = mp_obj_int_get_checked(args[0]); diff --git a/py/objlist.c b/py/objlist.c index 538cba71fd..fa7d2bc1c7 100644 --- a/py/objlist.c +++ b/py/objlist.c @@ -33,6 +33,15 @@ STATIC void list_print(void (*print)(void *env, const char *fmt, ...), void *env print(env, "]"); } +STATIC mp_obj_t list_extend_from_iter(mp_obj_t list, mp_obj_t iterable) { + mp_obj_t iter = mp_getiter(iterable); + mp_obj_t item; + while ((item = mp_iternext(iter)) != MP_OBJ_NULL) { + mp_obj_list_append(list, item); + } + return list; +} + STATIC mp_obj_t list_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { // TODO check n_kw == 0 @@ -44,13 +53,9 @@ STATIC mp_obj_t list_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp case 1: { // make list from iterable - mp_obj_t iterable = mp_getiter(args[0]); + // TODO: optimize list/tuple mp_obj_t list = mp_obj_new_list(0, NULL); - mp_obj_t item; - while ((item = mp_iternext(iterable)) != MP_OBJ_NULL) { - mp_obj_list_append(list, item); - } - return list; + return list_extend_from_iter(list, args[0]); } default: @@ -167,18 +172,21 @@ mp_obj_t mp_obj_list_append(mp_obj_t self_in, mp_obj_t arg) { STATIC mp_obj_t list_extend(mp_obj_t self_in, mp_obj_t arg_in) { assert(MP_OBJ_IS_TYPE(self_in, &mp_type_list)); - assert(MP_OBJ_IS_TYPE(arg_in, &mp_type_list)); - mp_obj_list_t *self = self_in; - mp_obj_list_t *arg = arg_in; + if (MP_OBJ_IS_TYPE(arg_in, &mp_type_list)) { + mp_obj_list_t *self = self_in; + mp_obj_list_t *arg = arg_in; + + if (self->len + arg->len > self->alloc) { + // TODO: use alloc policy for "4" + self->items = m_renew(mp_obj_t, self->items, self->alloc, self->len + arg->len + 4); + self->alloc = self->len + arg->len + 4; + } - if (self->len + arg->len > self->alloc) { - // TODO: use alloc policy for "4" - self->items = m_renew(mp_obj_t, self->items, self->alloc, self->len + arg->len + 4); - self->alloc = self->len + arg->len + 4; + memcpy(self->items + self->len, arg->items, sizeof(mp_obj_t) * arg->len); + self->len += arg->len; + } else { + list_extend_from_iter(self_in, arg_in); } - - memcpy(self->items + self->len, arg->items, sizeof(mp_obj_t) * arg->len); - self->len += arg->len; return mp_const_none; // return None, as per CPython } diff --git a/py/objset.c b/py/objset.c index 05d064a047..bdc8d7f382 100644 --- a/py/objset.c +++ b/py/objset.c @@ -9,6 +9,7 @@ #include "obj.h" #include "runtime.h" #include "runtime0.h" +#include "builtin.h" typedef struct _mp_obj_set_t { mp_obj_base_t base; @@ -445,6 +446,7 @@ STATIC const mp_map_elem_t set_locals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_symmetric_difference_update), (mp_obj_t)&set_symmetric_difference_update_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_union), (mp_obj_t)&set_union_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_update), (mp_obj_t)&set_update_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR___contains__), (mp_obj_t)&mp_op_contains_obj }, }; STATIC MP_DEFINE_CONST_DICT(set_locals_dict, set_locals_dict_table); diff --git a/py/opmethods.c b/py/opmethods.c new file mode 100644 index 0000000000..af2524cf20 --- /dev/null +++ b/py/opmethods.c @@ -0,0 +1,20 @@ +#include "nlr.h" +#include "misc.h" +#include "mpconfig.h" +#include "qstr.h" +#include "obj.h" +#include "runtime.h" +#include "runtime0.h" +#include "builtin.h" + +STATIC mp_obj_t op_getitem(mp_obj_t lhs_in, mp_obj_t rhs_in) { + mp_obj_type_t *type = mp_obj_get_type(lhs_in); + return type->binary_op(MP_BINARY_OP_SUBSCR, lhs_in, rhs_in); +} +MP_DEFINE_CONST_FUN_OBJ_2(mp_op_getitem_obj, op_getitem); + +STATIC mp_obj_t op_contains(mp_obj_t lhs_in, mp_obj_t rhs_in) { + mp_obj_type_t *type = mp_obj_get_type(lhs_in); + return type->binary_op(MP_BINARY_OP_IN, lhs_in, rhs_in); +} +MP_DEFINE_CONST_FUN_OBJ_2(mp_op_contains_obj, op_contains); diff --git a/py/parsehelper.c b/py/parsehelper.c index e069657b1d..d467399a17 100644 --- a/py/parsehelper.c +++ b/py/parsehelper.c @@ -38,20 +38,30 @@ void mp_parse_show_exception(mp_lexer_t *lex, mp_parse_error_kind_t parse_error_ } } -mp_obj_t mp_parse_make_exception(mp_parse_error_kind_t parse_error_kind) { - // TODO add source file and line number to exception? +mp_obj_t mp_parse_make_exception(mp_lexer_t *lex, mp_parse_error_kind_t parse_error_kind) { + // make exception object + mp_obj_t exc; switch (parse_error_kind) { case MP_PARSE_ERROR_MEMORY: - return mp_obj_new_exception_msg(&mp_type_MemoryError, STR_MEMORY); + exc = mp_obj_new_exception_msg(&mp_type_MemoryError, STR_MEMORY); + break; case MP_PARSE_ERROR_UNEXPECTED_INDENT: - return mp_obj_new_exception_msg(&mp_type_IndentationError, STR_UNEXPECTED_INDENT); + exc = mp_obj_new_exception_msg(&mp_type_IndentationError, STR_UNEXPECTED_INDENT); + break; case MP_PARSE_ERROR_UNMATCHED_UNINDENT: - return mp_obj_new_exception_msg(&mp_type_IndentationError, STR_UNMATCHED_UNINDENT); + exc = mp_obj_new_exception_msg(&mp_type_IndentationError, STR_UNMATCHED_UNINDENT); + break; case MP_PARSE_ERROR_INVALID_SYNTAX: default: - return mp_obj_new_exception_msg(&mp_type_SyntaxError, STR_INVALID_SYNTAX); + exc = mp_obj_new_exception_msg(&mp_type_SyntaxError, STR_INVALID_SYNTAX); + break; } + + // add traceback to give info about file name and location + mp_obj_exception_add_traceback(exc, mp_lexer_source_name(lex), mp_lexer_cur(lex)->src_line, mp_lexer_cur(lex)->src_column); + + return exc; } diff --git a/py/parsehelper.h b/py/parsehelper.h index 1de70d19d6..b8f8c106dd 100644 --- a/py/parsehelper.h +++ b/py/parsehelper.h @@ -1,2 +1,2 @@ void mp_parse_show_exception(mp_lexer_t *lex, mp_parse_error_kind_t parse_error_kind); -mp_obj_t mp_parse_make_exception(mp_parse_error_kind_t parse_error_kind); +mp_obj_t mp_parse_make_exception(mp_lexer_t *lex, mp_parse_error_kind_t parse_error_kind); @@ -69,6 +69,7 @@ PY_O_BASENAME = \ objtuple.o \ objtype.o \ objzip.o \ + opmethods.o \ sequence.o \ stream.o \ binary.o \ diff --git a/py/qstrdefs.h b/py/qstrdefs.h index 6075000166..b332e22fa2 100644 --- a/py/qstrdefs.h +++ b/py/qstrdefs.h @@ -17,6 +17,7 @@ Q(__path__) Q(__repl_print__) Q(__bool__) +Q(__contains__) Q(__enter__) Q(__exit__) Q(__len__) @@ -90,7 +91,7 @@ Q(calcsize) #endif Q(chr) Q(classmethod) -Q(collections) +Q(_collections) Q(complex) Q(dict) Q(dir) diff --git a/py/runtime.c b/py/runtime.c index ed01193628..a507f97f36 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -1132,7 +1132,7 @@ void *const mp_fun_table[MP_F_NUMBER_OF] = { mp_obj_dict_store, mp_obj_new_set, mp_obj_set_store, - mp_make_function_from_id, + mp_make_function_from_raw_code, mp_call_function_n_kw_for_native, mp_call_method_n_kw, mp_getiter, diff --git a/py/runtime.h b/py/runtime.h index bf3d3da3ca..1d60181e7f 100644 --- a/py/runtime.h +++ b/py/runtime.h @@ -29,12 +29,9 @@ mp_obj_t mp_load_const_dec(qstr qstr); mp_obj_t mp_load_const_str(qstr qstr); mp_obj_t mp_load_const_bytes(qstr qstr); -mp_obj_t mp_make_function_from_id(uint unique_code_id, mp_obj_t def_args, mp_obj_t def_kw_args); -mp_obj_t mp_make_function_from_id_and_free(uint unique_code_id, mp_obj_t def_args, mp_obj_t def_kw_args); mp_obj_t mp_make_function_n(int n_args, void *fun); // fun must have the correct signature for n_args fixed arguments mp_obj_t mp_make_function_var(int n_args_min, mp_fun_var_t fun); mp_obj_t mp_make_function_var_between(int n_args_min, int n_args_max, mp_fun_var_t fun); // min and max are inclusive -mp_obj_t mp_make_closure_from_id(uint unique_code_id, mp_obj_t closure_tuple, mp_obj_t def_args, mp_obj_t def_kw_args); mp_obj_t mp_call_function_0(mp_obj_t fun); mp_obj_t mp_call_function_1(mp_obj_t fun, mp_obj_t arg); diff --git a/py/runtime0.h b/py/runtime0.h index 6ee70aa01d..eef3706794 100644 --- a/py/runtime0.h +++ b/py/runtime0.h @@ -86,7 +86,7 @@ typedef enum { MP_F_STORE_MAP, MP_F_BUILD_SET, MP_F_STORE_SET, - MP_F_MAKE_FUNCTION_FROM_ID, + MP_F_MAKE_FUNCTION_FROM_RAW_CODE, MP_F_CALL_FUNCTION_N_KW_FOR_NATIVE, MP_F_CALL_METHOD_N_KW, MP_F_GETITER, diff --git a/py/scope.c b/py/scope.c index 51701727e6..391ad5da87 100644 --- a/py/scope.c +++ b/py/scope.c @@ -6,10 +6,12 @@ #include "misc.h" #include "mpconfig.h" #include "qstr.h" +#include "obj.h" #include "parse.h" +#include "emitglue.h" #include "scope.h" -scope_t *scope_new(scope_kind_t kind, mp_parse_node_t pn, qstr source_file, uint unique_code_id, uint emit_options) { +scope_t *scope_new(scope_kind_t kind, mp_parse_node_t pn, qstr source_file, uint emit_options) { scope_t *scope = m_new0(scope_t, 1); scope->kind = kind; scope->pn = pn; @@ -41,7 +43,7 @@ scope_t *scope_new(scope_kind_t kind, mp_parse_node_t pn, qstr source_file, uint default: assert(0); } - scope->unique_code_id = unique_code_id; + scope->raw_code = mp_emit_glue_new_raw_code(); scope->emit_options = emit_options; scope->id_info_alloc = 8; scope->id_info = m_new(id_info_t, scope->id_info_alloc); diff --git a/py/scope.h b/py/scope.h index 07b41fe721..6e0990ea9c 100644 --- a/py/scope.h +++ b/py/scope.h @@ -29,7 +29,7 @@ typedef struct _scope_t { mp_parse_node_t pn; qstr source_file; qstr simple_name; - uint unique_code_id; + mp_raw_code_t *raw_code; uint8_t scope_flags; // see runtime0.h uint8_t emit_options; // see compile.h uint16_t num_params; @@ -41,7 +41,7 @@ typedef struct _scope_t { id_info_t *id_info; } scope_t; -scope_t *scope_new(scope_kind_t kind, mp_parse_node_t pn, qstr source_file, uint unique_code_id, uint emit_options); +scope_t *scope_new(scope_kind_t kind, mp_parse_node_t pn, qstr source_file, uint emit_options); void scope_free(scope_t *scope); id_info_t *scope_find_or_add_id(scope_t *scope, qstr qstr, bool *added); id_info_t *scope_find(scope_t *scope, qstr qstr); diff --git a/py/showbc.c b/py/showbc.c index 615d1fe0de..25b1b2ffb6 100644 --- a/py/showbc.c +++ b/py/showbc.c @@ -22,6 +22,11 @@ qstr = (qstr << 7) + (*ip & 0x7f); \ } while ((*ip++ & 0x80) != 0); \ } +#define DECODE_PTR do { \ + ip = (byte*)(((machine_uint_t)ip + sizeof(machine_uint_t) - 1) & (~(sizeof(machine_uint_t) - 1))); /* align ip */ \ + unum = *(machine_uint_t*)ip; \ + ip += sizeof(machine_uint_t); \ +} while (0) void mp_byte_code_print(const byte *ip, int len) { const byte *ip_start = ip; @@ -389,22 +394,22 @@ void mp_byte_code_print(const byte *ip, int len) { break; case MP_BC_MAKE_FUNCTION: - DECODE_UINT; + DECODE_PTR; printf("MAKE_FUNCTION " UINT_FMT, unum); break; case MP_BC_MAKE_FUNCTION_DEFARGS: - DECODE_UINT; + DECODE_PTR; printf("MAKE_FUNCTION_DEFARGS " UINT_FMT, unum); break; case MP_BC_MAKE_CLOSURE: - DECODE_UINT; + DECODE_PTR; printf("MAKE_CLOSURE " UINT_FMT, unum); break; case MP_BC_MAKE_CLOSURE_DEFARGS: - DECODE_UINT; + DECODE_PTR; printf("MAKE_CLOSURE_DEFARGS " UINT_FMT, unum); break; @@ -7,6 +7,7 @@ #include "mpconfig.h" #include "qstr.h" #include "obj.h" +#include "emitglue.h" #include "runtime.h" #include "bc0.h" #include "bc.h" @@ -29,20 +30,25 @@ typedef enum { UNWIND_JUMP, } mp_unwind_reason_t; -#define DECODE_UINT { \ +#define DECODE_UINT do { \ unum = 0; \ do { \ unum = (unum << 7) + (*ip & 0x7f); \ } while ((*ip++ & 0x80) != 0); \ -} +} while (0) #define DECODE_ULABEL do { unum = (ip[0] | (ip[1] << 8)); ip += 2; } while (0) #define DECODE_SLABEL do { unum = (ip[0] | (ip[1] << 8)) - 0x8000; ip += 2; } while (0) -#define DECODE_QSTR { \ +#define DECODE_QSTR do { \ qst = 0; \ do { \ qst = (qst << 7) + (*ip & 0x7f); \ } while ((*ip++ & 0x80) != 0); \ -} +} while (0) +#define DECODE_PTR do { \ + ip = (byte*)(((machine_uint_t)ip + sizeof(machine_uint_t) - 1) & (~(sizeof(machine_uint_t) - 1))); /* align ip */ \ + unum = *(machine_uint_t*)ip; \ + ip += sizeof(machine_uint_t); \ +} while (0) #define PUSH(val) *++sp = (val) #define POP() (*sp--) #define TOP() (*sp) @@ -704,29 +710,29 @@ unwind_jump: break; case MP_BC_MAKE_FUNCTION: - DECODE_UINT; - PUSH(mp_make_function_from_id(unum, MP_OBJ_NULL, MP_OBJ_NULL)); + DECODE_PTR; + PUSH(mp_make_function_from_raw_code((mp_raw_code_t*)unum, MP_OBJ_NULL, MP_OBJ_NULL)); break; case MP_BC_MAKE_FUNCTION_DEFARGS: - DECODE_UINT; + DECODE_PTR; // Stack layout: def_tuple def_dict <- TOS obj1 = POP(); - SET_TOP(mp_make_function_from_id(unum, TOP(), obj1)); + SET_TOP(mp_make_function_from_raw_code((mp_raw_code_t*)unum, TOP(), obj1)); break; case MP_BC_MAKE_CLOSURE: - DECODE_UINT; + DECODE_PTR; // Stack layout: closure_tuple <- TOS - SET_TOP(mp_make_closure_from_id(unum, TOP(), MP_OBJ_NULL, MP_OBJ_NULL)); + SET_TOP(mp_make_closure_from_raw_code((mp_raw_code_t*)unum, TOP(), MP_OBJ_NULL, MP_OBJ_NULL)); break; case MP_BC_MAKE_CLOSURE_DEFARGS: - DECODE_UINT; + DECODE_PTR; // Stack layout: def_tuple def_dict closure_tuple <- TOS obj1 = POP(); obj2 = POP(); - SET_TOP(mp_make_closure_from_id(unum, obj1, TOP(), obj2)); + SET_TOP(mp_make_closure_from_raw_code((mp_raw_code_t*)unum, obj1, TOP(), obj2)); break; case MP_BC_CALL_FUNCTION: |