diff --git a/py/bc.h b/py/bc.h index 6a7b91690f..17f71553e8 100644 --- a/py/bc.h +++ b/py/bc.h @@ -1,2 +1,3 @@ mp_obj_t mp_execute_byte_code(const byte *code, const mp_obj_t *args, uint n_args, uint n_state); bool mp_execute_byte_code_2(const byte *code_info, const byte **ip_in_out, mp_obj_t *fastn, mp_obj_t **sp_in_out); +void mp_byte_code_print(const byte *code, int len); diff --git a/py/compile.c b/py/compile.c index cf87e018d9..27b2439639 100644 --- a/py/compile.c +++ b/py/compile.c @@ -39,6 +39,7 @@ typedef enum { #define EMIT_OPT_ASM_THUMB (4) typedef struct _compiler_t { + qstr source_file; bool is_repl; pass_kind_t pass; bool had_error; // try to keep compiler clean from nlr @@ -189,7 +190,7 @@ static int comp_next_label(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, rt_get_unique_code_id(), emit_options); + scope_t *scope = scope_new(kind, pn, comp->source_file, rt_get_unique_code_id(), emit_options); scope->parent = comp->scope_cur; scope->next = NULL; if (comp->scope_head == NULL) { @@ -2509,7 +2510,9 @@ void compile_node(compiler_t *comp, mp_parse_node_t pn) { compile_function_t f = compile_function[MP_PARSE_NODE_STRUCT_KIND(pns)]; if (f == NULL) { printf("node %u cannot be compiled\n", (uint)MP_PARSE_NODE_STRUCT_KIND(pns)); - mp_parse_node_show(pn, 0); +#if MICROPY_DEBUG_PRINTERS + mp_parse_node_print(pn, 0); +#endif assert(0); } else { f(comp, pns); @@ -2875,10 +2878,12 @@ void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind_t pass mp_parse_node_t *nodes; int num = list_get(&pn_body, PN_suite_block_stmts, &nodes); + /* if (comp->pass == PASS_3) { //printf("----\n"); scope_print_info(scope); } + */ for (int i = 0; i < num; i++) { assert(MP_PARSE_NODE_IS_STRUCT(nodes[i])); @@ -3028,6 +3033,7 @@ void compile_scope_compute_things(compiler_t *comp, scope_t *scope) { mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, bool is_repl) { compiler_t *comp = m_new(compiler_t, 1); + comp->source_file = source_file; comp->is_repl = is_repl; comp->had_error = false; @@ -3132,7 +3138,7 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, bool is_repl) { default: if (emit_bc == NULL) { - emit_bc = emit_bc_new(source_file, max_num_labels); + emit_bc = emit_bc_new(max_num_labels); } comp->emit = emit_bc; comp->emit_method_table = &emit_bc_method_table; diff --git a/py/emit.h b/py/emit.h index 521b43cae2..309d4740b9 100644 --- a/py/emit.h +++ b/py/emit.h @@ -120,7 +120,7 @@ extern const emit_method_table_t emit_native_thumb_method_table; emit_t *emit_pass1_new(qstr qstr___class__); void emit_pass1_free(emit_t *emit); emit_t *emit_cpython_new(uint max_num_labels); -emit_t *emit_bc_new(qstr source_file, uint max_num_labels); +emit_t *emit_bc_new(uint max_num_labels); emit_t *emit_native_x64_new(uint max_num_labels); emit_t *emit_native_thumb_new(uint max_num_labels); diff --git a/py/emitbc.c b/py/emitbc.c index e1a81adac1..1f034e9df1 100644 --- a/py/emitbc.c +++ b/py/emitbc.c @@ -21,7 +21,6 @@ struct _emit_t { scope_t *scope; - qstr source_file; uint last_source_line_offset; uint last_source_line; @@ -36,9 +35,8 @@ struct _emit_t { byte dummy_data[8]; }; -emit_t *emit_bc_new(qstr source_file, uint max_num_labels) { +emit_t *emit_bc_new(uint max_num_labels) { emit_t *emit = m_new0(emit_t, 1); - emit->source_file = source_file; emit->max_num_labels = max_num_labels; emit->label_offsets = m_new(uint, emit->max_num_labels); return emit; @@ -187,7 +185,8 @@ static void emit_bc_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope) { } // code info - emit_write_code_info_qstr(emit, emit->source_file); + emit_write_code_info_qstr(emit, scope->source_file); + emit_write_code_info_qstr(emit, scope->simple_name); // prelude for initialising closed over variables int num_cell = 0; @@ -239,6 +238,7 @@ static void emit_bc_set_stack_size(emit_t *emit, int size) { } static void emit_bc_set_source_line(emit_t *emit, int source_line) { + //printf("source: line %d -> %d offset %d -> %d\n", emit->last_source_line, source_line, emit->last_source_line_offset, emit->byte_code_offset); if (source_line > emit->last_source_line) { int bytes_to_skip = emit->byte_code_offset - emit->last_source_line_offset; for (; bytes_to_skip > 255; bytes_to_skip -= 255) { @@ -249,6 +249,7 @@ static void emit_bc_set_source_line(emit_t *emit, int source_line) { emit_write_code_info_byte_byte(emit, 0, 255); } emit_write_code_info_byte_byte(emit, bytes_to_skip, lines_to_skip); + //printf(" %d %d\n", bytes_to_skip, lines_to_skip); emit->last_source_line_offset = emit->byte_code_offset; emit->last_source_line = source_line; } diff --git a/py/mpconfig.h b/py/mpconfig.h index 505b1b2d18..97e4b13875 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -39,9 +39,11 @@ #define MICROPY_MEM_STATS (0) #endif -// Whether to build code to show byte code -#ifndef MICROPY_SHOW_BC -#define MICROPY_SHOW_BC (0) +// Whether to build functions that print debugging info: +// mp_byte_code_print +// mp_parse_node_print +#ifndef MICROPY_DEBUG_PRINTERS +#define MICROPY_DEBUG_PRINTERS (0) #endif /*****************************************************************************/ diff --git a/py/obj.h b/py/obj.h index 8c32de789d..44d2858aee 100644 --- a/py/obj.h +++ b/py/obj.h @@ -273,8 +273,8 @@ machine_int_t mp_obj_int_get_checked(mp_obj_t self_in); // exception extern const mp_obj_type_t exception_type; qstr mp_obj_exception_get_type(mp_obj_t self_in); -void mp_obj_exception_set_source_info(mp_obj_t self_in, qstr file, machine_uint_t line); -void mp_obj_exception_get_source_info(mp_obj_t self_in, qstr *file, machine_uint_t *line); +void mp_obj_exception_set_source_info(mp_obj_t self_in, qstr file, machine_uint_t line, qstr block); +void mp_obj_exception_get_source_info(mp_obj_t self_in, qstr *file, machine_uint_t *line, qstr *block); // str extern const mp_obj_type_t str_type; diff --git a/py/objexcept.c b/py/objexcept.c index 7f87478a89..326d320d52 100644 --- a/py/objexcept.c +++ b/py/objexcept.c @@ -19,6 +19,7 @@ typedef struct mp_obj_exception_t { mp_obj_base_t base; qstr source_file; machine_uint_t source_line; + qstr source_block; qstr id; qstr msg; mp_obj_tuple_t args; @@ -114,7 +115,7 @@ qstr mp_obj_exception_get_type(mp_obj_t self_in) { return self->id; } -void mp_obj_exception_set_source_info(mp_obj_t self_in, qstr file, machine_uint_t line) { +void mp_obj_exception_set_source_info(mp_obj_t self_in, qstr file, machine_uint_t line, qstr block) { assert(MP_OBJ_IS_TYPE(self_in, &exception_type)); mp_obj_exception_t *self = self_in; // TODO make a list of file/line pairs for the traceback @@ -125,11 +126,15 @@ void mp_obj_exception_set_source_info(mp_obj_t self_in, qstr file, machine_uint_ if (line != 0 && self->source_line == 0) { self->source_line = line; } + if (block != 0 && self->source_block == 0) { + self->source_block = block; + } } -void mp_obj_exception_get_source_info(mp_obj_t self_in, qstr *file, machine_uint_t *line) { +void mp_obj_exception_get_source_info(mp_obj_t self_in, qstr *file, machine_uint_t *line, qstr *block) { assert(MP_OBJ_IS_TYPE(self_in, &exception_type)); mp_obj_exception_t *self = self_in; *file = self->source_file; *line = self->source_line; + *block = self->source_block; } diff --git a/py/parse.c b/py/parse.c index fc74a5fa50..93d75424ac 100644 --- a/py/parse.c +++ b/py/parse.c @@ -135,7 +135,8 @@ mp_parse_node_struct_t *parse_node_new_struct(int src_line, int rule_id, int num return pn; } -void mp_parse_node_show(mp_parse_node_t pn, int indent) { +#if MICROPY_DEBUG_PRINTERS +void mp_parse_node_print(mp_parse_node_t pn, int indent) { if (MP_PARSE_NODE_IS_STRUCT(pn)) { printf("[% 4d] ", (int)((mp_parse_node_struct_t*)pn)->source_line); } else { @@ -167,16 +168,17 @@ void mp_parse_node_show(mp_parse_node_t pn, int indent) { printf("rule(%u) (n=%d)\n", (uint)MP_PARSE_NODE_STRUCT_KIND(pns2), n); #endif for (int i = 0; i < n; i++) { - mp_parse_node_show(pns2->nodes[i], indent + 2); + mp_parse_node_print(pns2->nodes[i], indent + 2); } } } +#endif // MICROPY_DEBUG_PRINTERS /* static void result_stack_show(parser_t *parser) { printf("result stack, most recent first\n"); for (int i = parser->result_stack_top - 1; i >= 0; i--) { - mp_parse_node_show(parser->result_stack[i], 0); + mp_parse_node_print(parser->result_stack[i], 0); } } */ diff --git a/py/parse.h b/py/parse.h index e1e7f73022..2801f414ee 100644 --- a/py/parse.h +++ b/py/parse.h @@ -54,7 +54,7 @@ typedef struct _mp_parse_node_struct_t { mp_parse_node_t mp_parse_node_new_leaf(machine_int_t kind, machine_int_t arg); -void mp_parse_node_show(mp_parse_node_t pn, int indent); +void mp_parse_node_print(mp_parse_node_t pn, int indent); typedef enum { MP_PARSE_SINGLE_INPUT, diff --git a/py/runtime.c b/py/runtime.c index fbcc983ab7..e0d76a517a 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -215,9 +215,8 @@ void rt_assign_byte_code(int unique_code_id, byte *code, uint len, int n_args, i DEBUG_printf(" %02x", code[i]); } DEBUG_printf("\n"); -#if MICROPY_SHOW_BC - extern void mp_show_byte_code(const byte *code, int len); - mp_show_byte_code(code, len); +#if MICROPY_DEBUG_PRINTERS + mp_byte_code_print(code, len); #endif #ifdef WRITE_CODE diff --git a/py/scope.c b/py/scope.c index 5d97393ae3..5cc0bda068 100644 --- a/py/scope.c +++ b/py/scope.c @@ -8,15 +8,16 @@ #include "parse.h" #include "scope.h" -scope_t *scope_new(scope_kind_t kind, mp_parse_node_t pn, uint unique_code_id, uint emit_options) { +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 = m_new(scope_t, 1); scope->kind = kind; scope->parent = NULL; scope->next = NULL; scope->pn = pn; + scope->source_file = source_file; switch (kind) { case SCOPE_MODULE: - scope->simple_name = 0; + scope->simple_name = qstr_from_str_static(""); break; case SCOPE_FUNCTION: case SCOPE_CLASS: @@ -72,33 +73,10 @@ id_info_t *scope_find_or_add_id(scope_t *scope, qstr qstr, bool *added) { scope->id_info_alloc *= 2; } - id_info_t *id_info; - - { - /* - // just pick next slot in array - id_info = &scope->id_info[scope->id_info_len++]; - */ - } - - if (0) { - // sort insert into id_info array, so we are equivalent to CPython (no other reason to do it) - // actually, seems that this is not what CPython does... - scope->id_info_len += 1; - for (int i = scope->id_info_len - 1;; i--) { - if (i == 0 || strcmp(qstr_str(scope->id_info[i - 1].qstr), qstr_str(qstr)) < 0) { - id_info = &scope->id_info[i]; - break; - } else { - scope->id_info[i] = scope->id_info[i - 1]; - } - } - } else { - // just add new id to end of array of all ids; this seems to match CPython - // important thing is that function arguments are first, but that is - // handled by the compiler because it adds arguments before compiling the body - id_info = &scope->id_info[scope->id_info_len++]; - } + // add new id to end of array of all ids; this seems to match CPython + // important thing is that function arguments are first, but that is + // handled by the compiler because it adds arguments before compiling the body + id_info_t *id_info = &scope->id_info[scope->id_info_len++]; id_info->param = false; id_info->kind = 0; @@ -213,6 +191,7 @@ void scope_declare_nonlocal(scope_t *scope, qstr qstr) { scope_close_over_in_parents(scope, qstr); } +#if MICROPY_EMIT_CPYTHON void scope_print_info(scope_t *s) { if (s->kind == SCOPE_MODULE) { printf("code \n"); @@ -264,3 +243,4 @@ void scope_print_info(scope_t *s) { printf(" nlocals %d\n", s->num_locals); printf(" stacksize %d\n", s->stack_size); } +#endif diff --git a/py/scope.h b/py/scope.h index 761a4d7119..718ce46ecc 100644 --- a/py/scope.h +++ b/py/scope.h @@ -38,6 +38,7 @@ typedef struct _scope_t { struct _scope_t *parent; struct _scope_t *next; mp_parse_node_t pn; + qstr source_file; qstr simple_name; int id_info_alloc; int id_info_len; @@ -54,7 +55,7 @@ typedef struct _scope_t { uint emit_options; } scope_t; -scope_t *scope_new(scope_kind_t kind, mp_parse_node_t pn, uint unique_code_id, uint emit_options); +scope_t *scope_new(scope_kind_t kind, mp_parse_node_t pn, qstr source_file, uint unique_code_id, uint emit_options); 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); id_info_t *scope_find_global(scope_t *scope, qstr qstr); diff --git a/py/showbc.c b/py/showbc.c index 9a7ff9e3be..f34449ed10 100644 --- a/py/showbc.c +++ b/py/showbc.c @@ -8,14 +8,14 @@ #include "mpconfig.h" #include "bc0.h" -#if MICROPY_SHOW_BC +#if MICROPY_DEBUG_PRINTERS #define DECODE_UINT do { unum = *ip++; if (unum > 127) { unum = ((unum & 0x3f) << 8) | (*ip++); } } 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 do { qstr = *ip++; if (qstr > 127) { qstr = ((qstr & 0x3f) << 8) | (*ip++); } } while (0) -void mp_show_byte_code(const byte *ip, int len) { +void mp_byte_code_print(const byte *ip, int len) { const byte *ip_start = ip; // get code info size @@ -367,4 +367,4 @@ void mp_show_byte_code(const byte *ip, int len) { } } -#endif // MICROPY_SHOW_BC +#endif // MICROPY_DEBUG_PRINTERS diff --git a/py/vm.c b/py/vm.c index 750c7431b7..44cbd9f359 100644 --- a/py/vm.c +++ b/py/vm.c @@ -18,7 +18,7 @@ #define DECODE_UINT do { unum = *ip++; if (unum > 127) { unum = ((unum & 0x3f) << 8) | (*ip++); } } 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 do { qstr = *ip++; if (qstr > 127) { qstr = ((qstr & 0x3f) << 8) | (*ip++); } } while (0) +#define DECODE_QSTR do { qst = *ip++; if (qst > 127) { qst = ((qst & 0x3f) << 8) | (*ip++); } } while (0) #define PUSH(val) *++sp = (val) #define POP() (*sp--) #define TOP() (*sp) @@ -78,7 +78,7 @@ bool mp_execute_byte_code_2(const byte *code_info, const byte **ip_in_out, mp_ob const byte *ip = *ip_in_out; mp_obj_t *sp = *sp_in_out; machine_uint_t unum; - qstr qstr; + qstr qst; mp_obj_t obj1, obj2; mp_obj_t fast0 = fastn[0], fast1 = fastn[-1], fast2 = fastn[-2]; nlr_buf_t nlr; @@ -122,27 +122,27 @@ bool mp_execute_byte_code_2(const byte *code_info, const byte **ip_in_out, mp_ob case MP_BC_LOAD_CONST_INT: DECODE_QSTR; - PUSH(mp_obj_new_int_from_long_str(qstr_str(qstr))); + PUSH(mp_obj_new_int_from_long_str(qstr_str(qst))); break; case MP_BC_LOAD_CONST_DEC: DECODE_QSTR; - PUSH(rt_load_const_dec(qstr)); + PUSH(rt_load_const_dec(qst)); break; case MP_BC_LOAD_CONST_ID: DECODE_QSTR; - PUSH(rt_load_const_str(qstr)); // TODO + PUSH(rt_load_const_str(qst)); // TODO break; case MP_BC_LOAD_CONST_BYTES: DECODE_QSTR; - PUSH(rt_load_const_str(qstr)); // TODO + PUSH(rt_load_const_str(qst)); // TODO break; case MP_BC_LOAD_CONST_STRING: DECODE_QSTR; - PUSH(rt_load_const_str(qstr)); + PUSH(rt_load_const_str(qst)); break; case MP_BC_LOAD_FAST_0: @@ -178,22 +178,22 @@ bool mp_execute_byte_code_2(const byte *code_info, const byte **ip_in_out, mp_ob case MP_BC_LOAD_NAME: DECODE_QSTR; - PUSH(rt_load_name(qstr)); + PUSH(rt_load_name(qst)); break; case MP_BC_LOAD_GLOBAL: DECODE_QSTR; - PUSH(rt_load_global(qstr)); + PUSH(rt_load_global(qst)); break; case MP_BC_LOAD_ATTR: DECODE_QSTR; - SET_TOP(rt_load_attr(TOP(), qstr)); + SET_TOP(rt_load_attr(TOP(), qst)); break; case MP_BC_LOAD_METHOD: DECODE_QSTR; - rt_load_method(*sp, qstr, sp); + rt_load_method(*sp, qst, sp); sp += 1; break; @@ -234,17 +234,17 @@ bool mp_execute_byte_code_2(const byte *code_info, const byte **ip_in_out, mp_ob case MP_BC_STORE_NAME: DECODE_QSTR; - rt_store_name(qstr, POP()); + rt_store_name(qst, POP()); break; case MP_BC_STORE_GLOBAL: DECODE_QSTR; - rt_store_global(qstr, POP()); + rt_store_global(qst, POP()); break; case MP_BC_STORE_ATTR: DECODE_QSTR; - rt_store_attr(sp[0], qstr, sp[-1]); + rt_store_attr(sp[0], qst, sp[-1]); sp -= 2; break; @@ -509,12 +509,12 @@ bool mp_execute_byte_code_2(const byte *code_info, const byte **ip_in_out, mp_ob case MP_BC_IMPORT_NAME: DECODE_QSTR; obj1 = POP(); - SET_TOP(rt_import_name(qstr, obj1, TOP())); + SET_TOP(rt_import_name(qst, obj1, TOP())); break; case MP_BC_IMPORT_FROM: DECODE_QSTR; - obj1 = rt_import_from(TOP(), qstr); + obj1 = rt_import_from(TOP(), qst); PUSH(obj1); break; @@ -532,18 +532,19 @@ bool mp_execute_byte_code_2(const byte *code_info, const byte **ip_in_out, mp_ob // set file and line number that the exception occurred at if (MP_OBJ_IS_TYPE(nlr.ret_val, &exception_type)) { machine_uint_t code_info_size = code_info[0] | (code_info[1] << 8) | (code_info[2] << 16) | (code_info[3] << 24); - qstr = code_info[4] | (code_info[5] << 8) | (code_info[6] << 16) | (code_info[7] << 24); + qstr source_file = code_info[4] | (code_info[5] << 8) | (code_info[6] << 16) | (code_info[7] << 24); + qstr block_name = code_info[8] | (code_info[9] << 8) | (code_info[10] << 16) | (code_info[11] << 24); machine_uint_t source_line = 1; machine_uint_t bc = save_ip - code_info - code_info_size; - //printf("find %lu %d %d\n", bc, code_info[8], code_info[9]); - for (const byte* ci = code_info + 8; bc > ci[0]; ci += 2) { + //printf("find %lu %d %d\n", bc, code_info[12], code_info[13]); + for (const byte* ci = code_info + 12; bc >= ci[0]; ci += 2) { bc -= ci[0]; source_line += ci[1]; if (ci[0] == 0 && ci[1] == 0) { break; } } - mp_obj_exception_set_source_info(nlr.ret_val, qstr, source_line); + mp_obj_exception_set_source_info(nlr.ret_val, source_file, source_line, block_name); } while (currently_in_except_block) { diff --git a/unix-cpy/main.c b/unix-cpy/main.c index 1f54b6f479..0da1fca291 100644 --- a/unix-cpy/main.c +++ b/unix-cpy/main.c @@ -44,7 +44,7 @@ void do_file(const char *file) { if (pn != MP_PARSE_NODE_NULL) { //printf("----------------\n"); - //parse_node_show(pn, 0); + //mp_parse_node_print(pn, 0); //printf("----------------\n"); // compile diff --git a/unix/main.c b/unix/main.c index 39a772d1eb..35fca2059a 100644 --- a/unix/main.c +++ b/unix/main.c @@ -53,9 +53,11 @@ static void execute_from_lexer(mp_lexer_t *lex, mp_parse_input_kind_t input_kind qstr source_name = mp_lexer_source_name(lex); mp_lexer_free(lex); - //printf("----------------\n"); - //mp_parse_node_show(pn, 0); - //printf("----------------\n"); + /* + printf("----------------\n"); + mp_parse_node_print(pn, 0); + printf("----------------\n"); + */ mp_obj_t module_fun = mp_compile(pn, source_name, is_repl); @@ -73,10 +75,10 @@ static void execute_from_lexer(mp_lexer_t *lex, mp_parse_input_kind_t input_kind // uncaught exception mp_obj_t exc = (mp_obj_t)nlr.ret_val; if (MP_OBJ_IS_TYPE(exc, &exception_type)) { - qstr file; + qstr file, block; machine_uint_t line; - mp_obj_exception_get_source_info(exc, &file, &line); - printf("File \"%s\", line %d\n", qstr_str(file), (int)line); + mp_obj_exception_get_source_info(exc, &file, &line, &block); + printf("File \"%s\", line %d, in %s\n", qstr_str(file), (int)line, qstr_str(block)); } mp_obj_print(exc, PRINT_REPR); printf("\n"); diff --git a/unix/mpconfigport.h b/unix/mpconfigport.h index b36c171969..10abb8ce75 100644 --- a/unix/mpconfigport.h +++ b/unix/mpconfigport.h @@ -9,11 +9,11 @@ #define MICROPY_EMIT_THUMB (0) #define MICROPY_EMIT_INLINE_THUMB (0) #define MICROPY_MEM_STATS (1) +#define MICROPY_DEBUG_PRINTERS (1) #define MICROPY_ENABLE_REPL_HELPERS (1) #define MICROPY_ENABLE_LEXER_UNIX (1) #define MICROPY_ENABLE_FLOAT (1) #define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_LONGLONG) -#define MICROPY_SHOW_BC (0) // type definitions for the specific machine