diff options
-rw-r--r-- | py/compile.c | 37 | ||||
-rw-r--r-- | py/emitinlinethumb.c | 2 | ||||
-rw-r--r-- | py/parse.c | 47 | ||||
-rw-r--r-- | tests/cmdline/cmd_parsetree.py.exp | 4 |
4 files changed, 24 insertions, 66 deletions
diff --git a/py/compile.c b/py/compile.c index 15e757d464..ca21d8294c 100644 --- a/py/compile.c +++ b/py/compile.c @@ -47,8 +47,6 @@ typedef enum { #include "py/grammar.h" #undef DEF_RULE #undef DEF_RULE_NC - PN_string, // special node for non-interned string - PN_bytes, // special node for non-interned bytes PN_const_object, // special node for a constant, generic Python object // define rules without a compile function #define DEF_RULE(rule, comp, kind, ...) @@ -1880,8 +1878,6 @@ STATIC void compile_expr_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) { } else { // for non-REPL, evaluate then discard the expression if ((MP_PARSE_NODE_IS_LEAF(pns->nodes[0]) && !MP_PARSE_NODE_IS_ID(pns->nodes[0])) - || MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_string) - || MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_bytes) || MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_const_object)) { // do nothing with a lonely constant } else { @@ -2600,33 +2596,19 @@ STATIC void compile_atom_expr_await(compiler_t *comp, mp_parse_node_struct_t *pn } #endif -STATIC void compile_string(compiler_t *comp, mp_parse_node_struct_t *pns) { - // only create and load the actual str object on the last pass - if (comp->pass != MP_PASS_EMIT) { - EMIT_ARG(load_const_obj, mp_const_none); - } else { - EMIT_ARG(load_const_obj, mp_obj_new_str((const char*)pns->nodes[0], pns->nodes[1], false)); - } -} - -STATIC void compile_bytes(compiler_t *comp, mp_parse_node_struct_t *pns) { - // only create and load the actual bytes object on the last pass - if (comp->pass != MP_PASS_EMIT) { - EMIT_ARG(load_const_obj, mp_const_none); - } else { - EMIT_ARG(load_const_obj, mp_obj_new_bytes((const byte*)pns->nodes[0], pns->nodes[1])); - } -} - -STATIC void compile_const_object(compiler_t *comp, mp_parse_node_struct_t *pns) { +STATIC mp_obj_t get_const_object(mp_parse_node_struct_t *pns) { #if MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_D // nodes are 32-bit pointers, but need to extract 64-bit object - EMIT_ARG(load_const_obj, (uint64_t)pns->nodes[0] | ((uint64_t)pns->nodes[1] << 32)); + return (uint64_t)pns->nodes[0] | ((uint64_t)pns->nodes[1] << 32); #else - EMIT_ARG(load_const_obj, (mp_obj_t)pns->nodes[0]); + return (mp_obj_t)pns->nodes[0]; #endif } +STATIC void compile_const_object(compiler_t *comp, mp_parse_node_struct_t *pns) { + EMIT_ARG(load_const_obj, get_const_object(pns)); +} + typedef void (*compile_function_t)(compiler_t*, mp_parse_node_struct_t*); STATIC const compile_function_t compile_function[] = { // only define rules with a compile function @@ -2637,8 +2619,6 @@ STATIC const compile_function_t compile_function[] = { #undef c #undef DEF_RULE #undef DEF_RULE_NC - compile_string, - compile_bytes, compile_const_object, }; @@ -2891,7 +2871,8 @@ STATIC void check_for_doc_string(compiler_t *comp, mp_parse_node_t pn) { mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)pn; if ((MP_PARSE_NODE_IS_LEAF(pns->nodes[0]) && MP_PARSE_NODE_LEAF_KIND(pns->nodes[0]) == MP_PARSE_NODE_STRING) - || MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_string)) { + || (MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[0], PN_const_object) + && MP_OBJ_IS_STR(get_const_object((mp_parse_node_struct_t*)pns->nodes[0])))) { // compile the doc string compile_node(comp, pns->nodes[0]); // store the doc string diff --git a/py/emitinlinethumb.c b/py/emitinlinethumb.c index 89bcebfead..c1a4eac5d0 100644 --- a/py/emitinlinethumb.c +++ b/py/emitinlinethumb.c @@ -42,8 +42,6 @@ typedef enum { #include "py/grammar.h" #undef DEF_RULE #undef DEF_RULE_NC - PN_string, // special node for non-interned string - PN_bytes, // special node for non-interned bytes PN_const_object, // special node for a constant, generic Python object // define rules without a compile function #define DEF_RULE(rule, comp, kind, ...) diff --git a/py/parse.c b/py/parse.c index 7280f74870..5a5adc6093 100644 --- a/py/parse.c +++ b/py/parse.c @@ -38,6 +38,7 @@ #include "py/runtime0.h" #include "py/runtime.h" #include "py/objint.h" +#include "py/objstr.h" #include "py/builtin.h" #if MICROPY_ENABLE_COMPILER @@ -75,8 +76,6 @@ enum { #include "py/grammar.h" #undef DEF_RULE #undef DEF_RULE_NC - RULE_string, // special node for non-interned string - RULE_bytes, // special node for non-interned bytes RULE_const_object, // special node for a constant, generic Python object // define rules without a compile function @@ -123,8 +122,6 @@ STATIC const rule_t *const rules[] = { #include "py/grammar.h" #undef DEF_RULE #undef DEF_RULE_NC - NULL, // RULE_string - NULL, // RULE_bytes NULL, // RULE_const_object // define rules without a compile function @@ -326,11 +323,7 @@ void mp_parse_node_print(mp_parse_node_t pn, size_t indent) { } else { // node must be a mp_parse_node_struct_t mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)pn; - if (MP_PARSE_NODE_STRUCT_KIND(pns) == RULE_string) { - printf("literal str(%.*s)\n", (int)pns->nodes[1], (char*)pns->nodes[0]); - } else if (MP_PARSE_NODE_STRUCT_KIND(pns) == RULE_bytes) { - printf("literal bytes(%.*s)\n", (int)pns->nodes[1], (char*)pns->nodes[0]); - } else if (MP_PARSE_NODE_STRUCT_KIND(pns) == RULE_const_object) { + if (MP_PARSE_NODE_STRUCT_KIND(pns) == RULE_const_object) { #if MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_D printf("literal const(%016llx)\n", (uint64_t)pns->nodes[0] | ((uint64_t)pns->nodes[1] << 32)); #else @@ -392,21 +385,6 @@ STATIC void push_result_node(parser_t *parser, mp_parse_node_t pn) { parser->result_stack[parser->result_stack_top++] = pn; } -STATIC mp_parse_node_t make_node_string_bytes(parser_t *parser, size_t src_line, size_t rule_kind, const char *str, size_t len) { - mp_parse_node_struct_t *pn = parser_alloc(parser, sizeof(mp_parse_node_struct_t) + sizeof(mp_parse_node_t) * 2); - if (pn == NULL) { - parser->parse_error = PARSE_ERROR_MEMORY; - return MP_PARSE_NODE_NULL; - } - pn->source_line = src_line; - pn->kind_num_nodes = rule_kind | (2 << 8); - char *p = m_new(char, len); - memcpy(p, str, len); - pn->nodes[0] = (uintptr_t)p; - pn->nodes[1] = len; - return (mp_parse_node_t)pn; -} - STATIC mp_parse_node_t make_node_const_object(parser_t *parser, size_t src_line, mp_obj_t obj) { mp_parse_node_struct_t *pn = parser_alloc(parser, sizeof(mp_parse_node_struct_t) + sizeof(mp_obj_t)); if (pn == NULL) { @@ -473,8 +451,11 @@ STATIC void push_result_token(parser_t *parser, const rule_t *rule) { // qstr exists, make a leaf node pn = mp_parse_node_new_leaf(lex->tok_kind == MP_TOKEN_STRING ? MP_PARSE_NODE_STRING : MP_PARSE_NODE_BYTES, qst); } else { - // not interned, make a node holding a pointer to the string/bytes data - pn = make_node_string_bytes(parser, lex->tok_line, lex->tok_kind == MP_TOKEN_STRING ? RULE_string : RULE_bytes, lex->vstr.buf, lex->vstr.len); + // not interned, make a node holding a pointer to the string/bytes object + mp_obj_t o = mp_obj_new_str_of_type( + lex->tok_kind == MP_TOKEN_STRING ? &mp_type_str : &mp_type_bytes, + (const byte*)lex->vstr.buf, lex->vstr.len); + pn = make_node_const_object(parser, lex->tok_line, o); } } else { pn = mp_parse_node_new_leaf(MP_PARSE_NODE_TOKEN, lex->tok_kind); @@ -934,15 +915,13 @@ mp_parse_tree_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind) { // this code discards lonely statements, such as doc strings if (input_kind != MP_PARSE_SINGLE_INPUT && rule->rule_id == RULE_expr_stmt && peek_result(&parser, 0) == MP_PARSE_NODE_NULL) { mp_parse_node_t p = peek_result(&parser, 1); - if ((MP_PARSE_NODE_IS_LEAF(p) && !MP_PARSE_NODE_IS_ID(p)) || MP_PARSE_NODE_IS_STRUCT_KIND(p, RULE_string)) { + if ((MP_PARSE_NODE_IS_LEAF(p) && !MP_PARSE_NODE_IS_ID(p)) + || MP_PARSE_NODE_IS_STRUCT_KIND(p, RULE_const_object)) { pop_result(&parser); // MP_PARSE_NODE_NULL - mp_parse_node_t pn = pop_result(&parser); // possibly RULE_string - if (MP_PARSE_NODE_IS_STRUCT(pn)) { - mp_parse_node_struct_t *pns = (mp_parse_node_struct_t *)pn; - if (MP_PARSE_NODE_STRUCT_KIND(pns) == RULE_string) { - m_del(char, (char*)pns->nodes[0], (size_t)pns->nodes[1]); - } - } + pop_result(&parser); // const expression (leaf or RULE_const_object) + // Pushing the "pass" rule here will overwrite any RULE_const_object + // entry that was on the result stack, allowing the GC to reclaim + // the memory from the const object when needed. push_result_rule(&parser, rule_src_line, rules[RULE_pass_stmt], 0); break; } diff --git a/tests/cmdline/cmd_parsetree.py.exp b/tests/cmdline/cmd_parsetree.py.exp index 36f1f1b271..17fecaf960 100644 --- a/tests/cmdline/cmd_parsetree.py.exp +++ b/tests/cmdline/cmd_parsetree.py.exp @@ -15,13 +15,13 @@ str(str) [ 8] rule(5) (n=2) id(c) -[ 8] literal str(a very long str that will not be interned) +[ 8] literal \.\+ [ 9] rule(5) (n=2) id(d) bytes(bytes) [ 10] rule(5) (n=2) id(e) -[ 10] literal bytes(a very long bytes that will not be interned) +[ 10] literal \.\+ [ 11] rule(5) (n=2) id(f) [ 11] literal \.\+ |