diff --git a/py/compile2.c b/py/compile2.c index 935c50f52f..8e6d76edbe 100644 --- a/py/compile2.c +++ b/py/compile2.c @@ -34,6 +34,7 @@ #include "py/emit.h" #include "py/compile.h" #include "py/runtime.h" +#include "py/asmbase.h" #if MICROPY_ENABLE_COMPILER && MICROPY_USE_SMALL_HEAP_COMPILER @@ -81,6 +82,19 @@ typedef enum { #endif +#if MICROPY_EMIT_INLINE_ASM +// define macros for inline assembler +#if MICROPY_EMIT_INLINE_THUMB +#define ASM_DECORATOR_QSTR MP_QSTR_asm_thumb +#define ASM_EMITTER(f) emit_inline_thumb_##f +#elif MICROPY_EMIT_INLINE_XTENSA +#define ASM_DECORATOR_QSTR MP_QSTR_asm_xtensa +#define ASM_EMITTER(f) emit_inline_xtensa_##f +#else +#error "unknown asm emitter" +#endif +#endif + #define EMIT_INLINE_ASM(fun) (comp->emit_inline_asm_method_table->fun(comp->emit_inline_asm)) #define EMIT_INLINE_ASM_ARG(fun, ...) (comp->emit_inline_asm_method_table->fun(comp->emit_inline_asm, __VA_ARGS__)) @@ -117,7 +131,7 @@ typedef struct _compiler_t { const emit_method_table_t *emit_method_table; // current emit method table #endif - #if MICROPY_EMIT_INLINE_THUMB + #if MICROPY_EMIT_INLINE_ASM emit_inline_asm_t *emit_inline_asm; // current emitter for inline asm const emit_inline_asm_method_table_t *emit_inline_asm_method_table; // current emit method table for inline asm #endif @@ -790,10 +804,10 @@ STATIC bool compile_built_in_decorator(compiler_t *comp, const byte *p, const by } else if (attr == MP_QSTR_viper) { *emit_options = MP_EMIT_OPT_VIPER; #endif -#if MICROPY_EMIT_INLINE_THUMB - } else if (attr == MP_QSTR_asm_thumb) { - *emit_options = MP_EMIT_OPT_ASM_THUMB; -#endif + #if MICROPY_EMIT_INLINE_ASM + } else if (attr == ASM_DECORATOR_QSTR) { + *emit_options = MP_EMIT_OPT_ASM; + #endif } else { compile_syntax_error(comp, NULL, "invalid micropython decorator"); } @@ -3016,7 +3030,7 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) { assert(comp->cur_except_level == 0); } -#if MICROPY_EMIT_INLINE_THUMB +#if MICROPY_EMIT_INLINE_ASM // requires 3 passes: SCOPE, CODE_SIZE, EMIT STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind_t pass) { comp->pass = pass; @@ -3029,7 +3043,7 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind } if (comp->pass > MP_PASS_SCOPE) { - EMIT_INLINE_ASM_ARG(start_pass, comp->pass, comp->scope_cur, &comp->compile_error); + EMIT_INLINE_ASM_ARG(start_pass, comp->pass, &comp->compile_error); } // get the function definition parse node @@ -3134,7 +3148,8 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind return; } if (pass > MP_PASS_SCOPE) { - EMIT_INLINE_ASM_ARG(align, pt_small_int_value(p_args)); + mp_asm_base_align((mp_asm_base_t*)comp->emit_inline_asm, + pt_small_int_value(p_args)); } } else if (op == MP_QSTR_data) { if (!(n_args >= 2 && pt_is_small_int(p_args))) { @@ -3151,7 +3166,8 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind } mp_int_t val; p_args = pt_get_small_int(p_args, &val); - EMIT_INLINE_ASM_ARG(data, bytesize, val); + mp_asm_base_data((mp_asm_base_t*)comp->emit_inline_asm, + bytesize, val); } } } else { @@ -3174,6 +3190,13 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind if (comp->pass > MP_PASS_SCOPE) { EMIT_INLINE_ASM_ARG(end_pass, type_sig); + + if (comp->pass == MP_PASS_EMIT) { + void *f = mp_asm_base_get_code((mp_asm_base_t*)comp->emit_inline_asm); + mp_emit_glue_assign_native(comp->scope_cur->raw_code, MP_CODE_NATIVE_ASM, + f, mp_asm_base_get_code_size((mp_asm_base_t*)comp->emit_inline_asm), + NULL, comp->scope_cur->num_pos_args, 0, type_sig); + } } if (comp->compile_error != MP_OBJ_NULL) { @@ -3309,10 +3332,10 @@ mp_raw_code_t *mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr source_f keep_going = true; s->raw_code = mp_emit_glue_new_raw_code(); if (false) { -#if MICROPY_EMIT_INLINE_THUMB - } else if (s->emit_options == MP_EMIT_OPT_ASM_THUMB) { + #if MICROPY_EMIT_INLINE_ASM + } else if (s->emit_options == MP_EMIT_OPT_ASM) { compile_scope_inline_asm(comp, s, MP_PASS_SCOPE); -#endif + #endif } else { compile_scope(comp, s, MP_PASS_SCOPE); } @@ -3337,9 +3360,6 @@ mp_raw_code_t *mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr source_f // compile pass 2 and 3 #if MICROPY_EMIT_NATIVE emit_t *emit_native = NULL; -#endif -#if MICROPY_EMIT_INLINE_THUMB - emit_inline_asm_t *emit_inline_thumb = NULL; #endif for (uint i = 0; i < comp->num_scopes && comp->compile_error == MP_OBJ_NULL; ++i) { scope_t *s = comp->scopes[i]; @@ -3347,20 +3367,25 @@ mp_raw_code_t *mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr source_f if (false) { // dummy -#if MICROPY_EMIT_INLINE_THUMB - } else if (s->emit_options == MP_EMIT_OPT_ASM_THUMB) { - // inline assembly for thumb - if (emit_inline_thumb == NULL) { - emit_inline_thumb = emit_inline_thumb_new(max_num_labels); + #if MICROPY_EMIT_INLINE_ASM + } else if (s->emit_options == MP_EMIT_OPT_ASM) { + // inline assembly + if (comp->emit_inline_asm == NULL) { + comp->emit_inline_asm = ASM_EMITTER(new)(comp->co_data, max_num_labels); } comp->emit = NULL; - comp->emit_inline_asm = emit_inline_thumb; - comp->emit_inline_asm_method_table = &emit_inline_thumb_method_table; + comp->emit_inline_asm_method_table = &ASM_EMITTER(method_table); compile_scope_inline_asm(comp, s, MP_PASS_CODE_SIZE); + #if MICROPY_EMIT_INLINE_XTENSA + // Xtensa requires an extra pass to compute size of l32r const table + // TODO this can be improved by calculating it during SCOPE pass + // but that requires some other structural changes to the asm emitters + compile_scope_inline_asm(comp, s, MP_PASS_CODE_SIZE); + #endif if (comp->compile_error == MP_OBJ_NULL) { compile_scope_inline_asm(comp, s, MP_PASS_EMIT); } -#endif + #endif } else { @@ -3445,11 +3470,11 @@ mp_raw_code_t *mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr source_f #endif } #endif -#if MICROPY_EMIT_INLINE_THUMB - if (emit_inline_thumb != NULL) { - emit_inline_thumb_free(emit_inline_thumb); + #if MICROPY_EMIT_INLINE_ASM + if (comp->emit_inline_asm != NULL) { + ASM_EMITTER(free)(comp->emit_inline_asm); } -#endif + #endif // free the parse tree mp_parse_tree_clear(parse_tree); diff --git a/py/emit.h b/py/emit.h index 9d5726e6ef..cdeedd5b55 100644 --- a/py/emit.h +++ b/py/emit.h @@ -271,7 +271,7 @@ typedef struct _emit_inline_asm_method_table_t { extern const emit_inline_asm_method_table_t emit_inline_thumb_method_table; extern const emit_inline_asm_method_table_t emit_inline_xtensa_method_table; -emit_inline_asm_t *emit_inline_thumb_new(mp_uint_t max_num_labels); +emit_inline_asm_t *emit_inline_thumb_new(mp_uint_t *co_data, mp_uint_t max_num_labels); emit_inline_asm_t *emit_inline_xtensa_new(mp_uint_t max_num_labels); void emit_inline_thumb_free(emit_inline_asm_t *emit); diff --git a/py/emitinlinethumb.c b/py/emitinlinethumb.c index a695b92b85..4e5b545e1a 100644 --- a/py/emitinlinethumb.c +++ b/py/emitinlinethumb.c @@ -55,6 +55,7 @@ struct _emit_inline_asm_t { asm_thumb_t as; uint16_t pass; mp_obj_t *error_slot; + mp_uint_t *co_data; mp_uint_t max_num_labels; qstr *label_lookup; }; @@ -67,10 +68,11 @@ STATIC void emit_inline_thumb_error_exc(emit_inline_asm_t *emit, mp_obj_t exc) { *emit->error_slot = exc; } -emit_inline_asm_t *emit_inline_thumb_new(mp_uint_t max_num_labels) { +emit_inline_asm_t *emit_inline_thumb_new(mp_uint_t *co_data, mp_uint_t max_num_labels) { emit_inline_asm_t *emit = m_new_obj(emit_inline_asm_t); memset(&emit->as, 0, sizeof(emit->as)); mp_asm_base_init(&emit->as.base, max_num_labels); + emit->co_data = co_data; emit->max_num_labels = max_num_labels; emit->label_lookup = m_new(qstr, max_num_labels); return emit; @@ -97,21 +99,21 @@ STATIC void emit_inline_thumb_end_pass(emit_inline_asm_t *emit, mp_uint_t type_s asm_thumb_end_pass(&emit->as); } -STATIC mp_uint_t emit_inline_thumb_count_params(emit_inline_asm_t *emit, const byte *p, const byte *ptop) { - mp_uint_t n_params = 0; - while (p != ptop) { - if (++n_params > 4) { - emit_inline_thumb_error_msg(emit, "can only have up to 4 parameters to Thumb assembly"); - return 0; - } - if (!pt_is_any_id(p)) { +STATIC mp_uint_t emit_inline_thumb_count_params(emit_inline_asm_t *emit, const byte *pn, const byte *ptop) { + mp_uint_t n_params = pt_num_nodes(pn, ptop); + if (n_params > 4) { + emit_inline_thumb_error_msg(emit, "can only have up to 4 parameters to Thumb assembly"); + return 0; + } + for (mp_uint_t i = 0; i < n_params; i++) { + if (!MP_PARSE_NODE_IS_ID(pn)) { emit_inline_thumb_error_msg(emit, "parameters must be registers in sequence r0 to r3"); return 0; } qstr qst; - p = pt_extract_id(p, &qst); - const char *param = qstr_str(qst); - if (!(strlen(param) == 2 && param[0] == 'r' && param[1] == '0' + n_params - 1)) { + pn = pt_extract_id(pn, &qst); + const char *p = qstr_str(qst); + if (!(strlen(p) == 2 && p[0] == 'r' && p[1] == '0' + i)) { emit_inline_thumb_error_msg(emit, "parameters must be registers in sequence r0 to r3"); return 0; } @@ -168,8 +170,8 @@ STATIC const special_reg_name_t special_reg_name_table[] = { // return empty string in case of error, so we can attempt to parse the string // without a special check if it was in fact a string -STATIC const char *get_arg_str(const byte *pn) { - if (pt_is_any_id(pn)) { +STATIC const char *get_arg_str(mp_parse_node_t pn) { + if (MP_PARSE_NODE_IS_ID(pn)) { qstr qst; pt_extract_id(pn, &qst); return qstr_str(qst); @@ -178,7 +180,7 @@ STATIC const char *get_arg_str(const byte *pn) { } } -STATIC mp_uint_t get_arg_reg(emit_inline_asm_t *emit, const char *op, const byte *pn, mp_uint_t max_reg) { +STATIC mp_uint_t get_arg_reg(emit_inline_asm_t *emit, const char *op, mp_parse_node_t pn, mp_uint_t max_reg) { const char *reg_str = get_arg_str(pn); for (mp_uint_t i = 0; i < MP_ARRAY_SIZE(reg_name_table); i++) { const reg_name_t *r = ®_name_table[i]; @@ -202,7 +204,7 @@ STATIC mp_uint_t get_arg_reg(emit_inline_asm_t *emit, const char *op, const byte return 0; } -STATIC mp_uint_t get_arg_special_reg(emit_inline_asm_t *emit, const char *op, const byte *pn) { +STATIC mp_uint_t get_arg_special_reg(emit_inline_asm_t *emit, const char *op, mp_parse_node_t pn) { const char *reg_str = get_arg_str(pn); for (mp_uint_t i = 0; i < MP_ARRAY_SIZE(special_reg_name_table); i++) { const special_reg_name_t *r = &special_reg_name_table[i]; @@ -217,7 +219,7 @@ STATIC mp_uint_t get_arg_special_reg(emit_inline_asm_t *emit, const char *op, co } #if MICROPY_EMIT_INLINE_THUMB_FLOAT -STATIC mp_uint_t get_arg_vfpreg(emit_inline_asm_t *emit, const char *op, const byte *pn) { +STATIC mp_uint_t get_arg_vfpreg(emit_inline_asm_t *emit, const char *op, mp_parse_node_t pn) { const char *reg_str = get_arg_str(pn); if (reg_str[0] == 's' && reg_str[1] != '\0') { mp_uint_t regno = 0; @@ -245,31 +247,32 @@ malformed: } #endif -STATIC mp_uint_t get_arg_reglist(emit_inline_asm_t *emit, const char *op, const byte *p) { +STATIC mp_uint_t get_arg_reglist(emit_inline_asm_t *emit, const char *op, mp_parse_node_t pn) { // a register list looks like {r0, r1, r2} and is parsed as a Python set - if (!pt_is_rule(p, PN_atom_brace)) { + if (!pt_is_rule(pn, PN_atom_brace)) { goto bad_arg; } const byte *ptop; - p = pt_rule_extract_top(p, &ptop); + pn = pt_rule_extract_top(pn, &ptop); mp_uint_t reglist = 0; - if (p == ptop) { + if (pn == ptop) { goto bad_arg; - } else if (pt_is_any_id(p)) { + } + if (MP_PARSE_NODE_IS_ID(pn)) { // set with one element - reglist |= 1 << get_arg_reg(emit, op, p, 15); - } else if (pt_is_rule(p, PN_dictorsetmaker)) { - p = pt_rule_first(p); - const byte *p1 = pt_next(p); + reglist |= 1 << get_arg_reg(emit, op, pn, 15); + } else if (pt_is_rule(pn, PN_dictorsetmaker)) { + pn = pt_rule_first(pn); + const byte *p1 = pt_next(pn); if (pt_is_rule(p1, PN_dictorsetmaker_list)) { // set with multiple elements // get first element of set (we rely on get_arg_reg to catch syntax errors) - reglist |= 1 << get_arg_reg(emit, op, p, 15); + reglist |= 1 << get_arg_reg(emit, op, pn, 15); // get tail elements (2nd, 3rd, ...) const byte *p1_top; @@ -296,9 +299,9 @@ bad_arg: return 0; } -STATIC uint32_t get_arg_i(emit_inline_asm_t *emit, const char *op, const byte *pn, uint32_t fit_mask) { +STATIC uint32_t get_arg_i(emit_inline_asm_t *emit, const char *op, mp_parse_node_t pn, uint32_t fit_mask) { mp_obj_t o; - if (!mp_parse_node_get_int_maybe(pn, &o)) { + if (!mp_parse_node_get_int_maybe(pn, &o, emit->co_data)) { emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "'%s' expects an integer", op)); return 0; } @@ -310,25 +313,25 @@ STATIC uint32_t get_arg_i(emit_inline_asm_t *emit, const char *op, const byte *p return i; } -STATIC bool get_arg_addr(emit_inline_asm_t *emit, const char *op, const byte *p, const byte **p_base, const byte **p_offset) { - if (!pt_is_rule(p, PN_atom_bracket)) { +STATIC bool get_arg_addr(emit_inline_asm_t *emit, const char *op, mp_parse_node_t pn, mp_parse_node_t *pn_base, mp_parse_node_t *pn_offset) { + if (!pt_is_rule(pn, PN_atom_bracket)) { goto bad_arg; } - if (pt_is_rule_empty(p)) { + if (pt_is_rule_empty(pn)) { goto bad_arg; } - p = pt_rule_first(p); - if (!pt_is_rule(p, PN_testlist_comp)) { + pn = pt_rule_first(pn); + if (!pt_is_rule(pn, PN_testlist_comp)) { goto bad_arg; } const byte *ptop; - p = pt_rule_extract_top(p, &ptop); - if (pt_num_nodes(p, ptop) != 2) { + pn = pt_rule_extract_top(pn, &ptop); + if (pt_num_nodes(pn, ptop) != 2) { goto bad_arg; } - *p_base = p; - *p_offset = pt_next(p); + *pn_base = pn; + *pn_offset = pt_next(pn); return true; bad_arg: @@ -336,13 +339,13 @@ bad_arg: return false; } -STATIC int get_arg_label(emit_inline_asm_t *emit, const char *op, const byte *p) { - if (!pt_is_any_id(p)) { +STATIC int get_arg_label(emit_inline_asm_t *emit, const char *op, mp_parse_node_t pn) { + if (!MP_PARSE_NODE_IS_ID(pn)) { emit_inline_thumb_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, "'%s' expects a label", op)); return 0; } qstr label_qstr; - pt_extract_id(p, &label_qstr); + pt_extract_id(pn, &label_qstr); for (uint i = 0; i < emit->max_num_labels; i++) { if (emit->label_lookup[i] == label_qstr) { return i; @@ -421,7 +424,7 @@ STATIC const format_vfp_op_t format_vfp_op_table[] = { // shorthand alias for whether we allow ARMv7-M instructions #define ARMV7M MICROPY_EMIT_INLINE_THUMB_ARMV7M -STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_args, const byte **pn_args) { +STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_args, mp_parse_node_t *pn_args) { // TODO perhaps make two tables: // one_args = // "b", LAB, asm_thumb_b_n, @@ -495,7 +498,7 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a op_code_hi = 0xed90; op_vldr_vstr:; mp_uint_t vd = get_arg_vfpreg(emit, op_str, pn_args[0]); - const byte *pn_base, *pn_offset; + mp_parse_node_t pn_base, pn_offset; if (get_arg_addr(emit, op_str, pn_args[1], &pn_base, &pn_offset)) { mp_uint_t rlo_base = get_arg_reg(emit, op_str, pn_base, 7); mp_uint_t i8; @@ -634,7 +637,7 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a } } else if (n_args == 2) { - if (pt_is_any_id(pn_args[1])) { + if (MP_PARSE_NODE_IS_ID(pn_args[1])) { // second arg is a register (or should be) mp_uint_t op_code, op_code_hi; if (op == MP_QSTR_mov) { @@ -713,7 +716,7 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a asm_thumb_mov_reg_i16(&emit->as, ASM_THUMB_OP_MOVT, reg_dest, (i_src >> 16) & 0xffff); } else if (ARMV7M && op == MP_QSTR_ldrex) { mp_uint_t r_dest = get_arg_reg(emit, op_str, pn_args[0], 15); - const byte *pn_base, *pn_offset; + mp_parse_node_t pn_base, pn_offset; if (get_arg_addr(emit, op_str, pn_args[1], &pn_base, &pn_offset)) { mp_uint_t r_base = get_arg_reg(emit, op_str, pn_base, 15); mp_uint_t i8 = get_arg_i(emit, op_str, pn_offset, 0xff) >> 2; @@ -724,7 +727,7 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a for (mp_uint_t i = 0; i < MP_ARRAY_SIZE(format_9_10_op_table); i++) { if (op == format_9_10_op_table[i].name) { op_code = format_9_10_op_table[i].op; - const byte *pn_base, *pn_offset; + mp_parse_node_t pn_base, pn_offset; mp_uint_t rlo_dest = get_arg_reg(emit, op_str, pn_args[0], 7); if (get_arg_addr(emit, op_str, pn_args[1], &pn_base, &pn_offset)) { mp_uint_t rlo_base = get_arg_reg(emit, op_str, pn_base, 7); @@ -769,7 +772,7 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a rlo_dest = get_arg_reg(emit, op_str, pn_args[0], 7); rlo_src = get_arg_reg(emit, op_str, pn_args[1], 7); int src_b; - if (pt_is_any_id(pn_args[2])) { + if (MP_PARSE_NODE_IS_ID(pn_args[2])) { op_code |= ASM_THUMB_FORMAT_2_REG_OPERAND; src_b = get_arg_reg(emit, op_str, pn_args[2], 7); } else { @@ -794,7 +797,7 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_a } else if (ARMV7M && op == MP_QSTR_strex) { mp_uint_t r_dest = get_arg_reg(emit, op_str, pn_args[0], 15); mp_uint_t r_src = get_arg_reg(emit, op_str, pn_args[1], 15); - const byte *pn_base, *pn_offset; + mp_parse_node_t pn_base, pn_offset; if (get_arg_addr(emit, op_str, pn_args[2], &pn_base, &pn_offset)) { mp_uint_t r_base = get_arg_reg(emit, op_str, pn_base, 15); mp_uint_t i8 = get_arg_i(emit, op_str, pn_offset, 0xff) >> 2; diff --git a/py/parse2.c b/py/parse2.c index bcd35bd9d0..0356274ded 100644 --- a/py/parse2.c +++ b/py/parse2.c @@ -294,21 +294,15 @@ STATIC byte *pt_advance(const byte *p, bool full_rule) { return (byte*)p; } -bool mp_parse_node_get_int_maybe(const byte *p, mp_obj_t *o) { +bool mp_parse_node_get_int_maybe(const byte *p, mp_obj_t *o, mp_uint_t *co_data) { if (pt_is_small_int(p)) { *o = MP_OBJ_NEW_SMALL_INT(pt_small_int_value(p)); return true; - #if 0 // TODO - } else if (MP_PARSE_NODE_IS_STRUCT_KIND(pn, RULE_const_object)) { - mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)pn; - #if MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_D - // nodes are 32-bit pointers, but need to extract 64-bit object - *o = (uint64_t)pns->nodes[0] | ((uint64_t)pns->nodes[1] << 32); - #else - *o = (mp_obj_t)pns->nodes[0]; - #endif - return MP_OBJ_IS_INT(*o); - #endif + } else if (*p == MP_PT_CONST_OBJECT) { + size_t idx; + p = pt_extract_const_obj(p, &idx); + *o = (mp_obj_t)co_data[idx]; + return true; } else { return false; } @@ -481,9 +475,9 @@ STATIC const byte *pt_del_byte(pt_t *pt, const byte *p) { #if MICROPY_COMP_MODULE_CONST #include "py/builtin.h" -STATIC const mp_map_elem_t mp_constants_table[] = { +STATIC const mp_rom_map_elem_t mp_constants_table[] = { #if MICROPY_PY_UCTYPES - { MP_OBJ_NEW_QSTR(MP_QSTR_uctypes), (mp_obj_t)&mp_module_uctypes }, + { MP_ROM_QSTR(MP_QSTR_uctypes), MP_ROM_PTR(&mp_module_uctypes) }, #endif // Extra constants as defined by a port MICROPY_PORT_CONSTANTS diff --git a/py/parse2.h b/py/parse2.h index 55b05e062d..2e363a7795 100644 --- a/py/parse2.h +++ b/py/parse2.h @@ -44,6 +44,9 @@ struct _mp_lexer_t; #define MP_PT_ID_BASE (10) // +16 #define MP_PT_RULE_BASE (26) // +173-ish +// macro to eliminate differences between original parser and this one +#define MP_PARSE_NODE_IS_ID(pn) pt_is_any_id(pn) + typedef const byte *mp_parse_node_t; extern const byte pt_const_int0[]; @@ -114,7 +117,7 @@ const byte *pt_rule_extract_top(const byte *p, const byte **ptop); const byte *pt_rule_extract(const byte *p, mp_uint_t *rule_id, size_t *src_line, const byte **ptop); bool pt_is_rule_empty(const byte *p); -bool mp_parse_node_get_int_maybe(const byte *p, mp_obj_t *o); +bool mp_parse_node_get_int_maybe(const byte *p, mp_obj_t *o, mp_uint_t *co_data); const byte *mp_parse_node_extract_list(const byte **p, mp_uint_t pn_kind); typedef enum {