py: Add module/function/class name to exceptions.
Exceptions know source file, line and block name. Also tidy up some debug printing functions and provide a global flag to enable/disable them.
This commit is contained in:
parent
e02b2d4391
commit
cbd2f7482c
1
py/bc.h
1
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);
|
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);
|
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);
|
||||||
|
12
py/compile.c
12
py/compile.c
@ -39,6 +39,7 @@ typedef enum {
|
|||||||
#define EMIT_OPT_ASM_THUMB (4)
|
#define EMIT_OPT_ASM_THUMB (4)
|
||||||
|
|
||||||
typedef struct _compiler_t {
|
typedef struct _compiler_t {
|
||||||
|
qstr source_file;
|
||||||
bool is_repl;
|
bool is_repl;
|
||||||
pass_kind_t pass;
|
pass_kind_t pass;
|
||||||
bool had_error; // try to keep compiler clean from nlr
|
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) {
|
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->parent = comp->scope_cur;
|
||||||
scope->next = NULL;
|
scope->next = NULL;
|
||||||
if (comp->scope_head == 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)];
|
compile_function_t f = compile_function[MP_PARSE_NODE_STRUCT_KIND(pns)];
|
||||||
if (f == NULL) {
|
if (f == NULL) {
|
||||||
printf("node %u cannot be compiled\n", (uint)MP_PARSE_NODE_STRUCT_KIND(pns));
|
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);
|
assert(0);
|
||||||
} else {
|
} else {
|
||||||
f(comp, pns);
|
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;
|
mp_parse_node_t *nodes;
|
||||||
int num = list_get(&pn_body, PN_suite_block_stmts, &nodes);
|
int num = list_get(&pn_body, PN_suite_block_stmts, &nodes);
|
||||||
|
|
||||||
|
/*
|
||||||
if (comp->pass == PASS_3) {
|
if (comp->pass == PASS_3) {
|
||||||
//printf("----\n");
|
//printf("----\n");
|
||||||
scope_print_info(scope);
|
scope_print_info(scope);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
for (int i = 0; i < num; i++) {
|
for (int i = 0; i < num; i++) {
|
||||||
assert(MP_PARSE_NODE_IS_STRUCT(nodes[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) {
|
mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, bool is_repl) {
|
||||||
compiler_t *comp = m_new(compiler_t, 1);
|
compiler_t *comp = m_new(compiler_t, 1);
|
||||||
|
|
||||||
|
comp->source_file = source_file;
|
||||||
comp->is_repl = is_repl;
|
comp->is_repl = is_repl;
|
||||||
comp->had_error = false;
|
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:
|
default:
|
||||||
if (emit_bc == NULL) {
|
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 = emit_bc;
|
||||||
comp->emit_method_table = &emit_bc_method_table;
|
comp->emit_method_table = &emit_bc_method_table;
|
||||||
|
@ -120,7 +120,7 @@ extern const emit_method_table_t emit_native_thumb_method_table;
|
|||||||
emit_t *emit_pass1_new(qstr qstr___class__);
|
emit_t *emit_pass1_new(qstr qstr___class__);
|
||||||
void emit_pass1_free(emit_t *emit);
|
void emit_pass1_free(emit_t *emit);
|
||||||
emit_t *emit_cpython_new(uint max_num_labels);
|
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_x64_new(uint max_num_labels);
|
||||||
emit_t *emit_native_thumb_new(uint max_num_labels);
|
emit_t *emit_native_thumb_new(uint max_num_labels);
|
||||||
|
|
||||||
|
@ -21,7 +21,6 @@ struct _emit_t {
|
|||||||
|
|
||||||
scope_t *scope;
|
scope_t *scope;
|
||||||
|
|
||||||
qstr source_file;
|
|
||||||
uint last_source_line_offset;
|
uint last_source_line_offset;
|
||||||
uint last_source_line;
|
uint last_source_line;
|
||||||
|
|
||||||
@ -36,9 +35,8 @@ struct _emit_t {
|
|||||||
byte dummy_data[8];
|
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_t *emit = m_new0(emit_t, 1);
|
||||||
emit->source_file = source_file;
|
|
||||||
emit->max_num_labels = max_num_labels;
|
emit->max_num_labels = max_num_labels;
|
||||||
emit->label_offsets = m_new(uint, emit->max_num_labels);
|
emit->label_offsets = m_new(uint, emit->max_num_labels);
|
||||||
return emit;
|
return emit;
|
||||||
@ -187,7 +185,8 @@ static void emit_bc_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// code info
|
// 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
|
// prelude for initialising closed over variables
|
||||||
int num_cell = 0;
|
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) {
|
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) {
|
if (source_line > emit->last_source_line) {
|
||||||
int bytes_to_skip = emit->byte_code_offset - emit->last_source_line_offset;
|
int bytes_to_skip = emit->byte_code_offset - emit->last_source_line_offset;
|
||||||
for (; bytes_to_skip > 255; bytes_to_skip -= 255) {
|
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, 0, 255);
|
||||||
}
|
}
|
||||||
emit_write_code_info_byte_byte(emit, bytes_to_skip, lines_to_skip);
|
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_offset = emit->byte_code_offset;
|
||||||
emit->last_source_line = source_line;
|
emit->last_source_line = source_line;
|
||||||
}
|
}
|
||||||
|
@ -39,9 +39,11 @@
|
|||||||
#define MICROPY_MEM_STATS (0)
|
#define MICROPY_MEM_STATS (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Whether to build code to show byte code
|
// Whether to build functions that print debugging info:
|
||||||
#ifndef MICROPY_SHOW_BC
|
// mp_byte_code_print
|
||||||
#define MICROPY_SHOW_BC (0)
|
// mp_parse_node_print
|
||||||
|
#ifndef MICROPY_DEBUG_PRINTERS
|
||||||
|
#define MICROPY_DEBUG_PRINTERS (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
4
py/obj.h
4
py/obj.h
@ -273,8 +273,8 @@ machine_int_t mp_obj_int_get_checked(mp_obj_t self_in);
|
|||||||
// exception
|
// exception
|
||||||
extern const mp_obj_type_t exception_type;
|
extern const mp_obj_type_t exception_type;
|
||||||
qstr mp_obj_exception_get_type(mp_obj_t self_in);
|
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_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);
|
void mp_obj_exception_get_source_info(mp_obj_t self_in, qstr *file, machine_uint_t *line, qstr *block);
|
||||||
|
|
||||||
// str
|
// str
|
||||||
extern const mp_obj_type_t str_type;
|
extern const mp_obj_type_t str_type;
|
||||||
|
@ -19,6 +19,7 @@ typedef struct mp_obj_exception_t {
|
|||||||
mp_obj_base_t base;
|
mp_obj_base_t base;
|
||||||
qstr source_file;
|
qstr source_file;
|
||||||
machine_uint_t source_line;
|
machine_uint_t source_line;
|
||||||
|
qstr source_block;
|
||||||
qstr id;
|
qstr id;
|
||||||
qstr msg;
|
qstr msg;
|
||||||
mp_obj_tuple_t args;
|
mp_obj_tuple_t args;
|
||||||
@ -114,7 +115,7 @@ qstr mp_obj_exception_get_type(mp_obj_t self_in) {
|
|||||||
return self->id;
|
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));
|
assert(MP_OBJ_IS_TYPE(self_in, &exception_type));
|
||||||
mp_obj_exception_t *self = self_in;
|
mp_obj_exception_t *self = self_in;
|
||||||
// TODO make a list of file/line pairs for the traceback
|
// 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) {
|
if (line != 0 && self->source_line == 0) {
|
||||||
self->source_line = line;
|
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));
|
assert(MP_OBJ_IS_TYPE(self_in, &exception_type));
|
||||||
mp_obj_exception_t *self = self_in;
|
mp_obj_exception_t *self = self_in;
|
||||||
*file = self->source_file;
|
*file = self->source_file;
|
||||||
*line = self->source_line;
|
*line = self->source_line;
|
||||||
|
*block = self->source_block;
|
||||||
}
|
}
|
||||||
|
@ -135,7 +135,8 @@ mp_parse_node_struct_t *parse_node_new_struct(int src_line, int rule_id, int num
|
|||||||
return pn;
|
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)) {
|
if (MP_PARSE_NODE_IS_STRUCT(pn)) {
|
||||||
printf("[% 4d] ", (int)((mp_parse_node_struct_t*)pn)->source_line);
|
printf("[% 4d] ", (int)((mp_parse_node_struct_t*)pn)->source_line);
|
||||||
} else {
|
} 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);
|
printf("rule(%u) (n=%d)\n", (uint)MP_PARSE_NODE_STRUCT_KIND(pns2), n);
|
||||||
#endif
|
#endif
|
||||||
for (int i = 0; i < n; i++) {
|
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) {
|
static void result_stack_show(parser_t *parser) {
|
||||||
printf("result stack, most recent first\n");
|
printf("result stack, most recent first\n");
|
||||||
for (int i = parser->result_stack_top - 1; i >= 0; i--) {
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
@ -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);
|
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 {
|
typedef enum {
|
||||||
MP_PARSE_SINGLE_INPUT,
|
MP_PARSE_SINGLE_INPUT,
|
||||||
|
@ -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(" %02x", code[i]);
|
||||||
}
|
}
|
||||||
DEBUG_printf("\n");
|
DEBUG_printf("\n");
|
||||||
#if MICROPY_SHOW_BC
|
#if MICROPY_DEBUG_PRINTERS
|
||||||
extern void mp_show_byte_code(const byte *code, int len);
|
mp_byte_code_print(code, len);
|
||||||
mp_show_byte_code(code, len);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WRITE_CODE
|
#ifdef WRITE_CODE
|
||||||
|
38
py/scope.c
38
py/scope.c
@ -8,15 +8,16 @@
|
|||||||
#include "parse.h"
|
#include "parse.h"
|
||||||
#include "scope.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_t *scope = m_new(scope_t, 1);
|
||||||
scope->kind = kind;
|
scope->kind = kind;
|
||||||
scope->parent = NULL;
|
scope->parent = NULL;
|
||||||
scope->next = NULL;
|
scope->next = NULL;
|
||||||
scope->pn = pn;
|
scope->pn = pn;
|
||||||
|
scope->source_file = source_file;
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
case SCOPE_MODULE:
|
case SCOPE_MODULE:
|
||||||
scope->simple_name = 0;
|
scope->simple_name = qstr_from_str_static("<module>");
|
||||||
break;
|
break;
|
||||||
case SCOPE_FUNCTION:
|
case SCOPE_FUNCTION:
|
||||||
case SCOPE_CLASS:
|
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;
|
scope->id_info_alloc *= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
id_info_t *id_info;
|
// 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++];
|
||||||
// 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++];
|
|
||||||
}
|
|
||||||
|
|
||||||
id_info->param = false;
|
id_info->param = false;
|
||||||
id_info->kind = 0;
|
id_info->kind = 0;
|
||||||
@ -213,6 +191,7 @@ void scope_declare_nonlocal(scope_t *scope, qstr qstr) {
|
|||||||
scope_close_over_in_parents(scope, qstr);
|
scope_close_over_in_parents(scope, qstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if MICROPY_EMIT_CPYTHON
|
||||||
void scope_print_info(scope_t *s) {
|
void scope_print_info(scope_t *s) {
|
||||||
if (s->kind == SCOPE_MODULE) {
|
if (s->kind == SCOPE_MODULE) {
|
||||||
printf("code <module>\n");
|
printf("code <module>\n");
|
||||||
@ -264,3 +243,4 @@ void scope_print_info(scope_t *s) {
|
|||||||
printf(" nlocals %d\n", s->num_locals);
|
printf(" nlocals %d\n", s->num_locals);
|
||||||
printf(" stacksize %d\n", s->stack_size);
|
printf(" stacksize %d\n", s->stack_size);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
@ -38,6 +38,7 @@ typedef struct _scope_t {
|
|||||||
struct _scope_t *parent;
|
struct _scope_t *parent;
|
||||||
struct _scope_t *next;
|
struct _scope_t *next;
|
||||||
mp_parse_node_t pn;
|
mp_parse_node_t pn;
|
||||||
|
qstr source_file;
|
||||||
qstr simple_name;
|
qstr simple_name;
|
||||||
int id_info_alloc;
|
int id_info_alloc;
|
||||||
int id_info_len;
|
int id_info_len;
|
||||||
@ -54,7 +55,7 @@ typedef struct _scope_t {
|
|||||||
uint emit_options;
|
uint emit_options;
|
||||||
} scope_t;
|
} 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_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(scope_t *scope, qstr qstr);
|
||||||
id_info_t *scope_find_global(scope_t *scope, qstr qstr);
|
id_info_t *scope_find_global(scope_t *scope, qstr qstr);
|
||||||
|
@ -8,14 +8,14 @@
|
|||||||
#include "mpconfig.h"
|
#include "mpconfig.h"
|
||||||
#include "bc0.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_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_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_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 { 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;
|
const byte *ip_start = ip;
|
||||||
|
|
||||||
// get code info size
|
// 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
|
||||||
|
41
py/vm.c
41
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_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_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_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 PUSH(val) *++sp = (val)
|
||||||
#define POP() (*sp--)
|
#define POP() (*sp--)
|
||||||
#define TOP() (*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;
|
const byte *ip = *ip_in_out;
|
||||||
mp_obj_t *sp = *sp_in_out;
|
mp_obj_t *sp = *sp_in_out;
|
||||||
machine_uint_t unum;
|
machine_uint_t unum;
|
||||||
qstr qstr;
|
qstr qst;
|
||||||
mp_obj_t obj1, obj2;
|
mp_obj_t obj1, obj2;
|
||||||
mp_obj_t fast0 = fastn[0], fast1 = fastn[-1], fast2 = fastn[-2];
|
mp_obj_t fast0 = fastn[0], fast1 = fastn[-1], fast2 = fastn[-2];
|
||||||
nlr_buf_t nlr;
|
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:
|
case MP_BC_LOAD_CONST_INT:
|
||||||
DECODE_QSTR;
|
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;
|
break;
|
||||||
|
|
||||||
case MP_BC_LOAD_CONST_DEC:
|
case MP_BC_LOAD_CONST_DEC:
|
||||||
DECODE_QSTR;
|
DECODE_QSTR;
|
||||||
PUSH(rt_load_const_dec(qstr));
|
PUSH(rt_load_const_dec(qst));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MP_BC_LOAD_CONST_ID:
|
case MP_BC_LOAD_CONST_ID:
|
||||||
DECODE_QSTR;
|
DECODE_QSTR;
|
||||||
PUSH(rt_load_const_str(qstr)); // TODO
|
PUSH(rt_load_const_str(qst)); // TODO
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MP_BC_LOAD_CONST_BYTES:
|
case MP_BC_LOAD_CONST_BYTES:
|
||||||
DECODE_QSTR;
|
DECODE_QSTR;
|
||||||
PUSH(rt_load_const_str(qstr)); // TODO
|
PUSH(rt_load_const_str(qst)); // TODO
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MP_BC_LOAD_CONST_STRING:
|
case MP_BC_LOAD_CONST_STRING:
|
||||||
DECODE_QSTR;
|
DECODE_QSTR;
|
||||||
PUSH(rt_load_const_str(qstr));
|
PUSH(rt_load_const_str(qst));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MP_BC_LOAD_FAST_0:
|
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:
|
case MP_BC_LOAD_NAME:
|
||||||
DECODE_QSTR;
|
DECODE_QSTR;
|
||||||
PUSH(rt_load_name(qstr));
|
PUSH(rt_load_name(qst));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MP_BC_LOAD_GLOBAL:
|
case MP_BC_LOAD_GLOBAL:
|
||||||
DECODE_QSTR;
|
DECODE_QSTR;
|
||||||
PUSH(rt_load_global(qstr));
|
PUSH(rt_load_global(qst));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MP_BC_LOAD_ATTR:
|
case MP_BC_LOAD_ATTR:
|
||||||
DECODE_QSTR;
|
DECODE_QSTR;
|
||||||
SET_TOP(rt_load_attr(TOP(), qstr));
|
SET_TOP(rt_load_attr(TOP(), qst));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MP_BC_LOAD_METHOD:
|
case MP_BC_LOAD_METHOD:
|
||||||
DECODE_QSTR;
|
DECODE_QSTR;
|
||||||
rt_load_method(*sp, qstr, sp);
|
rt_load_method(*sp, qst, sp);
|
||||||
sp += 1;
|
sp += 1;
|
||||||
break;
|
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:
|
case MP_BC_STORE_NAME:
|
||||||
DECODE_QSTR;
|
DECODE_QSTR;
|
||||||
rt_store_name(qstr, POP());
|
rt_store_name(qst, POP());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MP_BC_STORE_GLOBAL:
|
case MP_BC_STORE_GLOBAL:
|
||||||
DECODE_QSTR;
|
DECODE_QSTR;
|
||||||
rt_store_global(qstr, POP());
|
rt_store_global(qst, POP());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MP_BC_STORE_ATTR:
|
case MP_BC_STORE_ATTR:
|
||||||
DECODE_QSTR;
|
DECODE_QSTR;
|
||||||
rt_store_attr(sp[0], qstr, sp[-1]);
|
rt_store_attr(sp[0], qst, sp[-1]);
|
||||||
sp -= 2;
|
sp -= 2;
|
||||||
break;
|
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:
|
case MP_BC_IMPORT_NAME:
|
||||||
DECODE_QSTR;
|
DECODE_QSTR;
|
||||||
obj1 = POP();
|
obj1 = POP();
|
||||||
SET_TOP(rt_import_name(qstr, obj1, TOP()));
|
SET_TOP(rt_import_name(qst, obj1, TOP()));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MP_BC_IMPORT_FROM:
|
case MP_BC_IMPORT_FROM:
|
||||||
DECODE_QSTR;
|
DECODE_QSTR;
|
||||||
obj1 = rt_import_from(TOP(), qstr);
|
obj1 = rt_import_from(TOP(), qst);
|
||||||
PUSH(obj1);
|
PUSH(obj1);
|
||||||
break;
|
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
|
// set file and line number that the exception occurred at
|
||||||
if (MP_OBJ_IS_TYPE(nlr.ret_val, &exception_type)) {
|
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);
|
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 source_line = 1;
|
||||||
machine_uint_t bc = save_ip - code_info - code_info_size;
|
machine_uint_t bc = save_ip - code_info - code_info_size;
|
||||||
//printf("find %lu %d %d\n", bc, code_info[8], code_info[9]);
|
//printf("find %lu %d %d\n", bc, code_info[12], code_info[13]);
|
||||||
for (const byte* ci = code_info + 8; bc > ci[0]; ci += 2) {
|
for (const byte* ci = code_info + 12; bc >= ci[0]; ci += 2) {
|
||||||
bc -= ci[0];
|
bc -= ci[0];
|
||||||
source_line += ci[1];
|
source_line += ci[1];
|
||||||
if (ci[0] == 0 && ci[1] == 0) {
|
if (ci[0] == 0 && ci[1] == 0) {
|
||||||
break;
|
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) {
|
while (currently_in_except_block) {
|
||||||
|
@ -44,7 +44,7 @@ void do_file(const char *file) {
|
|||||||
|
|
||||||
if (pn != MP_PARSE_NODE_NULL) {
|
if (pn != MP_PARSE_NODE_NULL) {
|
||||||
//printf("----------------\n");
|
//printf("----------------\n");
|
||||||
//parse_node_show(pn, 0);
|
//mp_parse_node_print(pn, 0);
|
||||||
//printf("----------------\n");
|
//printf("----------------\n");
|
||||||
|
|
||||||
// compile
|
// compile
|
||||||
|
14
unix/main.c
14
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);
|
qstr source_name = mp_lexer_source_name(lex);
|
||||||
mp_lexer_free(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);
|
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
|
// uncaught exception
|
||||||
mp_obj_t exc = (mp_obj_t)nlr.ret_val;
|
mp_obj_t exc = (mp_obj_t)nlr.ret_val;
|
||||||
if (MP_OBJ_IS_TYPE(exc, &exception_type)) {
|
if (MP_OBJ_IS_TYPE(exc, &exception_type)) {
|
||||||
qstr file;
|
qstr file, block;
|
||||||
machine_uint_t line;
|
machine_uint_t line;
|
||||||
mp_obj_exception_get_source_info(exc, &file, &line);
|
mp_obj_exception_get_source_info(exc, &file, &line, &block);
|
||||||
printf("File \"%s\", line %d\n", qstr_str(file), (int)line);
|
printf("File \"%s\", line %d, in %s\n", qstr_str(file), (int)line, qstr_str(block));
|
||||||
}
|
}
|
||||||
mp_obj_print(exc, PRINT_REPR);
|
mp_obj_print(exc, PRINT_REPR);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
@ -9,11 +9,11 @@
|
|||||||
#define MICROPY_EMIT_THUMB (0)
|
#define MICROPY_EMIT_THUMB (0)
|
||||||
#define MICROPY_EMIT_INLINE_THUMB (0)
|
#define MICROPY_EMIT_INLINE_THUMB (0)
|
||||||
#define MICROPY_MEM_STATS (1)
|
#define MICROPY_MEM_STATS (1)
|
||||||
|
#define MICROPY_DEBUG_PRINTERS (1)
|
||||||
#define MICROPY_ENABLE_REPL_HELPERS (1)
|
#define MICROPY_ENABLE_REPL_HELPERS (1)
|
||||||
#define MICROPY_ENABLE_LEXER_UNIX (1)
|
#define MICROPY_ENABLE_LEXER_UNIX (1)
|
||||||
#define MICROPY_ENABLE_FLOAT (1)
|
#define MICROPY_ENABLE_FLOAT (1)
|
||||||
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_LONGLONG)
|
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_LONGLONG)
|
||||||
#define MICROPY_SHOW_BC (0)
|
|
||||||
|
|
||||||
// type definitions for the specific machine
|
// type definitions for the specific machine
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user