diff options
-rw-r--r-- | compile.c | 19 | ||||
-rw-r--r-- | iseq.c | 38 | ||||
-rw-r--r-- | prism_compile.c | 319 | ||||
-rw-r--r-- | test/ruby/test_compile_prism.rb | 11 |
4 files changed, 183 insertions, 204 deletions
@@ -968,17 +968,10 @@ rb_iseq_compile_node(rb_iseq_t *iseq, const NODE *node) return iseq_setup(iseq, ret); } -typedef struct pm_compile_context { - pm_parser_t *parser; - struct pm_compile_context *previous; - ID *constants; - st_table *index_lookup_table; -} pm_compile_context_t; - -static VALUE rb_translate_prism(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, pm_compile_context_t *compile_context); +static VALUE rb_translate_prism(rb_iseq_t *iseq, const pm_scope_node_t node, LINK_ANCHOR *const ret); VALUE -rb_iseq_compile_prism_node(rb_iseq_t * iseq, const pm_node_t *node, pm_parser_t *parser) +rb_iseq_compile_prism_node(rb_iseq_t * iseq, pm_scope_node_t scope_node, pm_parser_t *parser) { DECL_ANCHOR(ret); INIT_ANCHOR(ret); @@ -991,13 +984,9 @@ rb_iseq_compile_prism_node(rb_iseq_t * iseq, const pm_node_t *node, pm_parser_t constants[index] = rb_intern3((const char *) constant->start, constant->length, encoding); } - pm_compile_context_t compile_context = { - .parser = parser, - .previous = NULL, - .constants = constants - }; + scope_node.constants = (void *)constants; - CHECK(rb_translate_prism(iseq, node, ret, &compile_context)); + CHECK(rb_translate_prism(iseq, scope_node, ret)); free(constants); CHECK(iseq_setup_insn(iseq, ret)); @@ -941,10 +941,10 @@ rb_iseq_new_with_opt(const rb_ast_body_t *ast, VALUE name, VALUE path, VALUE rea return iseq_translate(iseq); } -VALUE rb_iseq_compile_prism_node(rb_iseq_t * iseq, const pm_node_t *node, pm_parser_t *parser); +VALUE rb_iseq_compile_prism_node(rb_iseq_t * iseq, pm_scope_node_t scope_node, pm_parser_t *parser); rb_iseq_t * -pm_iseq_new_with_opt(pm_node_t *node, pm_parser_t *parser, VALUE name, VALUE path, VALUE realpath, +pm_iseq_new_with_opt(pm_scope_node_t scope_node, pm_parser_t *parser, VALUE name, VALUE path, VALUE realpath, int first_lineno, const rb_iseq_t *parent, int isolated_depth, enum rb_iseq_type type, const rb_compile_option_t *option) { @@ -954,28 +954,26 @@ pm_iseq_new_with_opt(pm_node_t *node, pm_parser_t *parser, VALUE name, VALUE pat if (!option) option = &COMPILE_OPTION_DEFAULT; - if (node) { - pm_line_column_t start_line_col = pm_newline_list_line_column(&parser->newline_list, node->location.start); - pm_line_column_t end_line_col = pm_newline_list_line_column(&parser->newline_list, node->location.end); - - code_loc = (rb_code_location_t) { - .beg_pos = { - .lineno = (int) start_line_col.line, - .column = (int) start_line_col.column - }, - .end_pos = { - .lineno = (int) end_line_col.line, - .column = (int) end_line_col.column - }, - }; - } + pm_line_column_t start_line_col = pm_newline_list_line_column(&parser->newline_list, scope_node.base.location.start); + pm_line_column_t end_line_col = pm_newline_list_line_column(&parser->newline_list, scope_node.base.location.end); + + code_loc = (rb_code_location_t) { + .beg_pos = { + .lineno = (int) start_line_col.line, + .column = (int) start_line_col.column + }, + .end_pos = { + .lineno = (int) end_line_col.line, + .column = (int) end_line_col.column + }, + }; // TODO: node_id int node_id = -1; prepare_iseq_build(iseq, name, path, realpath, first_lineno, &code_loc, node_id, parent, isolated_depth, type, script_lines, option); - rb_iseq_compile_prism_node(iseq, node, parser); + rb_iseq_compile_prism_node(iseq, scope_node, parser); finish_iseq_build(iseq); @@ -1446,7 +1444,9 @@ iseqw_s_compile_prism(int argc, VALUE *argv, VALUE self) prepare_iseq_build(iseq, name, file, path, first_lineno, &node_location, node_id, parent, 0, (enum rb_iseq_type)iseq_type, Qnil, &option); - rb_iseq_compile_prism_node(iseq, node, &parser); + pm_scope_node_t scope_node; + pm_scope_node_init(node, &scope_node, NULL, &parser); + rb_iseq_compile_prism_node(iseq, scope_node, &parser); finish_iseq_build(iseq); pm_node_destroy(&parser, node); diff --git a/prism_compile.c b/prism_compile.c index b2173608b4..f7634e1e96 100644 --- a/prism_compile.c +++ b/prism_compile.c @@ -13,13 +13,13 @@ pm_new_child_iseq(iseq, (node), parser, rb_fstring(name), iseq, (type), (line_no)) #define PM_COMPILE(node) \ - pm_compile_node(iseq, (node), ret, src, popped, compile_context) + pm_compile_node(iseq, (node), ret, src, popped, scope_node) #define PM_COMPILE_POPPED(node) \ - pm_compile_node(iseq, (node), ret, src, true, compile_context) + pm_compile_node(iseq, (node), ret, src, true, scope_node) #define PM_COMPILE_NOT_POPPED(node) \ - pm_compile_node(iseq, (node), ret, src, false, compile_context) + pm_compile_node(iseq, (node), ret, src, false, scope_node) #define PM_POP_IF_POPPED \ if (popped) ADD_INSN(ret, &dummy_line_node, pop); @@ -213,7 +213,7 @@ pm_static_literal_p(const pm_node_t *node) * literal values can be compiled into a literal array. */ static inline VALUE -pm_static_literal_value(const pm_node_t *node, pm_compile_context_t *compile_context) +pm_static_literal_value(const pm_node_t *node, pm_scope_node_t *scope_node) { // Every node that comes into this function should already be marked as // static literal. If it's not, then we have a bug somewhere. @@ -226,7 +226,7 @@ pm_static_literal_value(const pm_node_t *node, pm_compile_context_t *compile_con VALUE value = rb_ary_hidden_new(elements->size); for (size_t index = 0; index < elements->size; index++) { - rb_ary_push(value, pm_static_literal_value(elements->nodes[index], compile_context)); + rb_ary_push(value, pm_static_literal_value(elements->nodes[index], scope_node)); } OBJ_FREEZE(value); @@ -244,7 +244,7 @@ pm_static_literal_value(const pm_node_t *node, pm_compile_context_t *compile_con for (size_t index = 0; index < elements->size; index++) { assert(PM_NODE_TYPE_P(elements->nodes[index], PM_ASSOC_NODE)); pm_assoc_node_t *cast = (pm_assoc_node_t *) elements->nodes[index]; - VALUE pair[2] = { pm_static_literal_value(cast->key, compile_context), pm_static_literal_value(cast->value, compile_context) }; + VALUE pair[2] = { pm_static_literal_value(cast->key, scope_node), pm_static_literal_value(cast->value, scope_node) }; rb_ary_cat(array, pair, 2); } @@ -270,7 +270,7 @@ pm_static_literal_value(const pm_node_t *node, pm_compile_context_t *compile_con return rb_reg_new(RSTRING_PTR(string), RSTRING_LEN(string), pm_reg_flags(node)); } case PM_SOURCE_ENCODING_NODE: { - rb_encoding *encoding = rb_find_encoding(rb_str_new_cstr(compile_context->parser->encoding.name)); + rb_encoding *encoding = rb_find_encoding(rb_str_new_cstr(scope_node->parser->encoding.name)); if (!encoding) rb_bug("Encoding not found!"); return rb_enc_from_encoding(encoding); } @@ -279,7 +279,7 @@ pm_static_literal_value(const pm_node_t *node, pm_compile_context_t *compile_con return cast->filepath.length ? parse_string(&cast->filepath) : rb_fstring_lit("<compiled>"); } case PM_SOURCE_LINE_NODE: - return INT2FIX((int) pm_newline_list_line_column(&compile_context->parser->newline_list, node->location.start).line); + return INT2FIX((int) pm_newline_list_line_column(&scope_node->parser->newline_list, node->location.start).line); case PM_STRING_NODE: return parse_string(&((pm_string_node_t *) node)->unescaped); case PM_SYMBOL_NODE: @@ -294,13 +294,13 @@ pm_static_literal_value(const pm_node_t *node, pm_compile_context_t *compile_con static void pm_compile_branch_condition(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const pm_node_t *cond, - LABEL *then_label, LABEL *else_label, const uint8_t *src, bool popped, pm_compile_context_t *compile_context); + LABEL *then_label, LABEL *else_label, const uint8_t *src, bool popped, pm_scope_node_t *scope_node); static void pm_compile_logical(rb_iseq_t *iseq, LINK_ANCHOR *const ret, pm_node_t *cond, - LABEL *then_label, LABEL *else_label, const uint8_t *src, bool popped, pm_compile_context_t *compile_context) + LABEL *then_label, LABEL *else_label, const uint8_t *src, bool popped, pm_scope_node_t *scope_node) { - pm_parser_t *parser = compile_context->parser; + pm_parser_t *parser = scope_node->parser; pm_newline_list_t newline_list = parser->newline_list; int lineno = (int)pm_newline_list_line_column(&newline_list, cond->location.start).line; NODE dummy_line_node = generate_dummy_line_node(lineno, lineno); @@ -311,7 +311,7 @@ pm_compile_logical(rb_iseq_t *iseq, LINK_ANCHOR *const ret, pm_node_t *cond, if (!then_label) then_label = label; else if (!else_label) else_label = label; - pm_compile_branch_condition(iseq, seq, cond, then_label, else_label, src, popped, compile_context); + pm_compile_branch_condition(iseq, seq, cond, then_label, else_label, src, popped, scope_node); if (LIST_INSN_SIZE_ONE(seq)) { INSN *insn = (INSN *)ELEM_FIRST_INSN(FIRST_ELEMENT(seq)); @@ -328,13 +328,13 @@ pm_compile_logical(rb_iseq_t *iseq, LINK_ANCHOR *const ret, pm_node_t *cond, return; } -static void pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, const uint8_t *src, bool popped, pm_compile_context_t *context); +static void pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, const uint8_t *src, bool popped, pm_scope_node_t *scope_node); static void pm_compile_branch_condition(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const pm_node_t *cond, - LABEL *then_label, LABEL *else_label, const uint8_t *src, bool popped, pm_compile_context_t *compile_context) + LABEL *then_label, LABEL *else_label, const uint8_t *src, bool popped, pm_scope_node_t *scope_node) { - pm_parser_t *parser = compile_context->parser; + pm_parser_t *parser = scope_node->parser; pm_newline_list_t newline_list = parser->newline_list; int lineno = (int) pm_newline_list_line_column(&newline_list, cond->location.start).line; NODE dummy_line_node = generate_dummy_line_node(lineno, lineno); @@ -343,13 +343,13 @@ again: switch (PM_NODE_TYPE(cond)) { case PM_AND_NODE: { pm_and_node_t *and_node = (pm_and_node_t *)cond; - pm_compile_logical(iseq, ret, and_node->left, NULL, else_label, src, popped, compile_context); + pm_compile_logical(iseq, ret, and_node->left, NULL, else_label, src, popped, scope_node); cond = and_node->right; goto again; } case PM_OR_NODE: { pm_or_node_t *or_node = (pm_or_node_t *)cond; - pm_compile_logical(iseq, ret, or_node->left, then_label, NULL, src, popped, compile_context); + pm_compile_logical(iseq, ret, or_node->left, then_label, NULL, src, popped, scope_node); cond = or_node->right; goto again; } @@ -373,7 +373,7 @@ again: DECL_ANCHOR(cond_seq); INIT_ANCHOR(cond_seq); - pm_compile_node(iseq, cond, cond_seq, src, false, compile_context); + pm_compile_node(iseq, cond, cond_seq, src, false, scope_node); ADD_SEQ(ret, cond_seq); break; } @@ -384,7 +384,7 @@ again: } static void -pm_compile_if(rb_iseq_t *iseq, const int line, pm_statements_node_t *node_body, pm_node_t *node_else, pm_node_t *predicate, LINK_ANCHOR *const ret, const uint8_t *src, bool popped, pm_compile_context_t *compile_context) +pm_compile_if(rb_iseq_t *iseq, const int line, pm_statements_node_t *node_body, pm_node_t *node_else, pm_node_t *predicate, LINK_ANCHOR *const ret, const uint8_t *src, bool popped, pm_scope_node_t *scope_node) { NODE dummy_line_node = generate_dummy_line_node(line, line); @@ -397,7 +397,7 @@ pm_compile_if(rb_iseq_t *iseq, const int line, pm_statements_node_t *node_body, else_label = NEW_LABEL(line); end_label = 0; - pm_compile_branch_condition(iseq, cond_seq, predicate, then_label, else_label, src, popped, compile_context); + pm_compile_branch_condition(iseq, cond_seq, predicate, then_label, else_label, src, popped, scope_node); ADD_SEQ(ret, cond_seq); if (then_label->refcnt) { @@ -406,7 +406,7 @@ pm_compile_if(rb_iseq_t *iseq, const int line, pm_statements_node_t *node_body, DECL_ANCHOR(then_seq); INIT_ANCHOR(then_seq); if (node_body) { - pm_compile_node(iseq, (pm_node_t *)node_body, then_seq, src, popped, compile_context); + pm_compile_node(iseq, (pm_node_t *)node_body, then_seq, src, popped, scope_node); } else { PM_PUTNIL_UNLESS_POPPED; } @@ -424,7 +424,7 @@ pm_compile_if(rb_iseq_t *iseq, const int line, pm_statements_node_t *node_body, DECL_ANCHOR(else_seq); INIT_ANCHOR(else_seq); if (node_else) { - pm_compile_node(iseq, (pm_node_t *)node_else, else_seq, src, popped, compile_context); + pm_compile_node(iseq, (pm_node_t *)node_else, else_seq, src, popped, scope_node); } else { PM_PUTNIL_UNLESS_POPPED; @@ -441,7 +441,7 @@ pm_compile_if(rb_iseq_t *iseq, const int line, pm_statements_node_t *node_body, } static void -pm_compile_while(rb_iseq_t *iseq, int lineno, pm_node_flags_t flags, enum pm_node_type type, pm_statements_node_t *statements, pm_node_t *predicate, LINK_ANCHOR *const ret, const uint8_t *src, bool popped, pm_compile_context_t *compile_context) +pm_compile_while(rb_iseq_t *iseq, int lineno, pm_node_flags_t flags, enum pm_node_type type, pm_statements_node_t *statements, pm_node_t *predicate, LINK_ANCHOR *const ret, const uint8_t *src, bool popped, pm_scope_node_t *scope_node) { NODE dummy_line_node = generate_dummy_line_node(lineno, lineno); @@ -484,9 +484,9 @@ pm_compile_while(rb_iseq_t *iseq, int lineno, pm_node_flags_t flags, enum pm_nod ADD_LABEL(ret, next_label); if (type == PM_WHILE_NODE) { - pm_compile_branch_condition(iseq, ret, predicate, redo_label, end_label, src, popped, compile_context); + pm_compile_branch_condition(iseq, ret, predicate, redo_label, end_label, src, popped, scope_node); } else if (type == PM_UNTIL_NODE) { - pm_compile_branch_condition(iseq, ret, predicate, end_label, redo_label, src, popped, compile_context); + pm_compile_branch_condition(iseq, ret, predicate, end_label, redo_label, src, popped, scope_node); } ADD_LABEL(ret, end_label); @@ -512,7 +512,7 @@ pm_compile_while(rb_iseq_t *iseq, int lineno, pm_node_flags_t flags, enum pm_nod } static void -pm_interpolated_node_compile(pm_node_list_t parts, rb_iseq_t *iseq, NODE dummy_line_node, LINK_ANCHOR *const ret, const uint8_t *src, bool popped, pm_compile_context_t *compile_context) +pm_interpolated_node_compile(pm_node_list_t parts, rb_iseq_t *iseq, NODE dummy_line_node, LINK_ANCHOR *const ret, const uint8_t *src, bool popped, pm_scope_node_t *scope_node) { size_t parts_size = parts.size; @@ -537,13 +537,13 @@ pm_interpolated_node_compile(pm_node_list_t parts, rb_iseq_t *iseq, NODE dummy_l } } static int -pm_lookup_local_index(rb_iseq_t *iseq, pm_compile_context_t *compile_context, pm_constant_id_t constant_id) +pm_lookup_local_index(rb_iseq_t *iseq, pm_scope_node_t *scope_node, pm_constant_id_t constant_id) { st_data_t local_index; int num_params = ISEQ_BODY(iseq)->param.size; - if (!st_lookup(compile_context->index_lookup_table, constant_id, &local_index)) { + if (!st_lookup(scope_node->index_lookup_table, constant_id, &local_index)) { rb_bug("This local does not exist"); } @@ -551,26 +551,26 @@ pm_lookup_local_index(rb_iseq_t *iseq, pm_compile_context_t *compile_context, pm } static int -pm_lookup_local_index_with_depth(rb_iseq_t *iseq, pm_compile_context_t *compile_context, pm_constant_id_t constant_id, uint32_t depth) +pm_lookup_local_index_with_depth(rb_iseq_t *iseq, pm_scope_node_t *scope_node, pm_constant_id_t constant_id, uint32_t depth) { for(uint32_t i = 0; i < depth; i++) { - compile_context = compile_context->previous; + scope_node = scope_node->previous; iseq = (rb_iseq_t *)ISEQ_BODY(iseq)->parent_iseq; } - return pm_lookup_local_index(iseq, compile_context, constant_id); + return pm_lookup_local_index(iseq, scope_node, constant_id); } // This returns the CRuby ID which maps to the pm_constant_id_t // // Constant_ids in prism are indexes of the constants in prism's constant pool. -// We add a constants mapping on the compile_context which is a mapping from +// We add a constants mapping on the scope_node which is a mapping from // these constant_id indexes to the CRuby IDs that they represent. // This helper method allows easy access to those IDs static ID -pm_constant_id_lookup(pm_compile_context_t *compile_context, pm_constant_id_t constant_id) +pm_constant_id_lookup(pm_scope_node_t *scope_node, pm_constant_id_t constant_id) { - return compile_context->constants[constant_id - 1]; + return ((ID *)scope_node->constants)[constant_id - 1]; } static rb_iseq_t * @@ -589,7 +589,7 @@ pm_new_child_iseq(rb_iseq_t *iseq, pm_scope_node_t * node, pm_parser_t *parser, } static int -pm_compile_class_path(LINK_ANCHOR *const ret, rb_iseq_t *iseq, const pm_node_t *constant_path_node, const NODE *line_node, const uint8_t * src, bool popped, pm_compile_context_t *compile_context) +pm_compile_class_path(LINK_ANCHOR *const ret, rb_iseq_t *iseq, const pm_node_t *constant_path_node, const NODE *line_node, const uint8_t * src, bool popped, pm_scope_node_t *scope_node) { if (PM_NODE_TYPE_P(constant_path_node, PM_CONSTANT_PATH_NODE)) { pm_node_t *parent = ((pm_constant_path_node_t *)constant_path_node)->parent; @@ -620,13 +620,13 @@ pm_compile_class_path(LINK_ANCHOR *const ret, rb_iseq_t *iseq, const pm_node_t * * path). */ static uint8_t -pm_compile_multi_write_lhs(rb_iseq_t *iseq, NODE dummy_line_node, const pm_node_t *node, LINK_ANCHOR *const ret, pm_compile_context_t *compile_context, uint8_t pushed, bool nested) +pm_compile_multi_write_lhs(rb_iseq_t *iseq, NODE dummy_line_node, const pm_node_t *node, LINK_ANCHOR *const ret, pm_scope_node_t *scope_node, uint8_t pushed, bool nested) { switch (PM_NODE_TYPE(node)) { case PM_MULTI_TARGET_NODE: { pm_multi_target_node_t *cast = (pm_multi_target_node_t *) node; for (size_t index = 0; index < cast->targets.size; index++) { - pushed = pm_compile_multi_write_lhs(iseq, dummy_line_node, cast->targets.nodes[index], ret, compile_context, pushed, false); + pushed = pm_compile_multi_write_lhs(iseq, dummy_line_node, cast->targets.nodes[index], ret, scope_node, pushed, false); } break; } @@ -634,7 +634,7 @@ pm_compile_multi_write_lhs(rb_iseq_t *iseq, NODE dummy_line_node, const pm_node_ pm_constant_path_target_node_t *cast = (pm_constant_path_target_node_t *)node; if (cast->parent) { ADD_INSN(ret, &dummy_line_node, putnil); - pushed = pm_compile_multi_write_lhs(iseq, dummy_line_node, cast->parent, ret, compile_context, pushed, false); + pushed = pm_compile_multi_write_lhs(iseq, dummy_line_node, cast->parent, ret, scope_node, pushed, false); } else { ADD_INSN1(ret, &dummy_line_node, putobject, rb_cObject); } @@ -643,18 +643,18 @@ pm_compile_multi_write_lhs(rb_iseq_t *iseq, NODE dummy_line_node, const pm_node_ case PM_CONSTANT_PATH_NODE: { pm_constant_path_node_t *cast = (pm_constant_path_node_t *) node; if (cast->parent) { - pushed = pm_compile_multi_write_lhs(iseq, dummy_line_node, cast->parent, ret, compile_context, pushed, false); + pushed = pm_compile_multi_write_lhs(iseq, dummy_line_node, cast->parent, ret, scope_node, pushed, false); } else { ADD_INSN(ret, &dummy_line_node, pop); ADD_INSN1(ret, &dummy_line_node, putobject, rb_cObject); } - pushed = pm_compile_multi_write_lhs(iseq, dummy_line_node, cast->child, ret, compile_context, pushed, cast->parent); + pushed = pm_compile_multi_write_lhs(iseq, dummy_line_node, cast->child, ret, scope_node, pushed, cast->parent); break; } case PM_CONSTANT_READ_NODE: { pm_constant_read_node_t *cast = (pm_constant_read_node_t *) node; ADD_INSN1(ret, &dummy_line_node, putobject, RBOOL(!nested)); - ADD_INSN1(ret, &dummy_line_node, getconstant, ID2SYM(pm_constant_id_lookup(compile_context, cast->name))); + ADD_INSN1(ret, &dummy_line_node, getconstant, ID2SYM(pm_constant_id_lookup(scope_node, cast->name))); pushed = pushed + 2; break; } @@ -669,9 +669,9 @@ pm_compile_multi_write_lhs(rb_iseq_t *iseq, NODE dummy_line_node, const pm_node_ * Compile a pattern matching expression. */ static int -pm_compile_pattern(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, const uint8_t *src, pm_compile_context_t *compile_context, LABEL *matched_label, LABEL *unmatched_label, bool in_alternation_pattern) +pm_compile_pattern(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, const uint8_t *src, pm_scope_node_t *scope_node, LABEL *matched_label, LABEL *unmatched_label, bool in_alternation_pattern) { - int lineno = (int) pm_newline_list_line_column(&compile_context->parser->newline_list, node->location.start).line; + int lineno = (int) pm_newline_list_line_column(&scope_node->parser->newline_list, node->location.start).line; NODE dummy_line_node = generate_dummy_line_node(lineno, lineno); switch (PM_NODE_TYPE(node)) { @@ -697,7 +697,7 @@ pm_compile_pattern(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const re // pm_if_node_t *cast = (pm_if_node_t *) node; - pm_compile_pattern(iseq, cast->statements->body.nodes[0], ret, src, compile_context, matched_label, unmatched_label, in_alternation_pattern); + pm_compile_pattern(iseq, cast->statements->body.nodes[0], ret, src, scope_node, matched_label, unmatched_label, in_alternation_pattern); PM_COMPILE_NOT_POPPED(cast->predicate); ADD_INSNL(ret, &dummy_line_node, branchunless, unmatched_label); @@ -714,7 +714,7 @@ pm_compile_pattern(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const re // pm_unless_node_t *cast = (pm_unless_node_t *) node; - pm_compile_pattern(iseq, cast->statements->body.nodes[0], ret, src, compile_context, matched_label, unmatched_label, in_alternation_pattern); + pm_compile_pattern(iseq, cast->statements->body.nodes[0], ret, src, scope_node, matched_label, unmatched_label, in_alternation_pattern); PM_COMPILE_NOT_POPPED(cast->predicate); ADD_INSNL(ret, &dummy_line_node, branchif, unmatched_label); @@ -726,14 +726,14 @@ pm_compile_pattern(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const re // of a pattern. For example, foo in bar. This results in the value // being matched being written to that local variable. pm_local_variable_target_node_t *cast = (pm_local_variable_target_node_t *) node; - int index = pm_lookup_local_index(iseq, compile_context, cast->name); + int index = pm_lookup_local_index(iseq, scope_node, cast->name); // If this local variable is being written from within an alternation // pattern, then it cannot actually be added to the local table since // it's ambiguous which value should be used. So instead we indicate // this with a compile error. if (in_alternation_pattern) { - ID id = pm_constant_id_lookup(compile_context, cast->name); + ID id = pm_constant_id_lookup(scope_node, cast->name); const char *name = rb_id2name(id); if (name && strlen(name) > 0 && name[0] != '_') { @@ -757,7 +757,7 @@ pm_compile_pattern(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const re // First, we're going to attempt to match against the left pattern. If // that pattern matches, then we'll skip matching the right pattern. ADD_INSN(ret, &dummy_line_node, dup); - pm_compile_pattern(iseq, cast->left, ret, src, compile_context, matched_left_label, unmatched_left_label, true); + pm_compile_pattern(iseq, cast->left, ret, src, scope_node, matched_left_label, unmatched_left_label, true); // If we get here, then we matched on the left pattern. In this case we // should pop out the duplicate value that we preemptively added to @@ -770,7 +770,7 @@ pm_compile_pattern(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const re // If we get here, then we didn't match on the left pattern. In this // case we attempt to match against the right pattern. ADD_LABEL(ret, unmatched_left_label); - pm_compile_pattern(iseq, cast->right, ret, src, compile_context, matched_label, unmatched_label, true); + pm_compile_pattern(iseq, cast->right, ret, src, scope_node, matched_label, unmatched_label, true); break; } case PM_ARRAY_NODE: @@ -812,7 +812,7 @@ pm_compile_pattern(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const re // looks like: foo in ^@bar. To compile these, we compile the variable // that they hold. pm_pinned_variable_node_t *cast = (pm_pinned_variable_node_t *) node; - pm_compile_pattern(iseq, cast->variable, ret, src, compile_context, matched_label, unmatched_label, false); + pm_compile_pattern(iseq, cast->variable, ret, src, scope_node, matched_label, unmatched_label, false); break; } case PM_PINNED_EXPRESSION_NODE: { @@ -821,7 +821,7 @@ pm_compile_pattern(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const re // foo in ^(bar). To compile these, we compile the expression that they // hold. pm_pinned_expression_node_t *cast = (pm_pinned_expression_node_t *) node; - pm_compile_pattern(iseq, cast->expression, ret, src, compile_context, matched_label, unmatched_label, false); + pm_compile_pattern(iseq, cast->expression, ret, src, scope_node, matched_label, unmatched_label, false); break; } default: @@ -843,12 +843,12 @@ pm_compile_pattern(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const re * ret - The linked list of instruction sequences to append instructions onto * popped - True if compiling something with no side effects, so instructions don't * need to be added - * compile_context - Stores parser and local information + * scope_node - Stores parser and local information */ static void -pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, const uint8_t *src, bool popped, pm_compile_context_t *compile_context) +pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, const uint8_t *src, bool popped, pm_scope_node_t *scope_node) { - pm_parser_t *parser = compile_context->parser; + pm_parser_t *parser = scope_node->parser; pm_newline_list_t newline_list = parser->newline_list; int lineno = (int)pm_newline_list_line_column(&newline_list, node->location.start).line; NODE dummy_line_node = generate_dummy_line_node(lineno, lineno); @@ -911,7 +911,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, // is popped, then we know we don't need to do anything since it's // statically known. if (!popped) { - VALUE value = pm_static_literal_value(node, compile_context); + VALUE value = pm_static_literal_value(node, scope_node); ADD_INSN1(ret, &dummy_line_node, duparray, value); RB_OBJ_WRITTEN(iseq, Qundef, value); } @@ -1003,7 +1003,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, case PM_CALL_NODE: { pm_call_node_t *call_node = (pm_call_node_t *) node; - ID method_id = pm_constant_id_lookup(compile_context, call_node->name); + ID method_id = pm_constant_id_lookup(scope_node, call_node->name); int flags = 0; int orig_argc = 0; @@ -1026,10 +1026,10 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, VALUE block_iseq = Qnil; if (call_node->block != NULL && PM_NODE_TYPE_P(call_node->block, PM_BLOCK_NODE)) { // Scope associated with the block - pm_scope_node_t scope_node; - pm_scope_node_init(call_node->block, &scope_node); + pm_scope_node_t next_scope_node; + pm_scope_node_init(call_node->block, &next_scope_node, scope_node, parser); - const rb_iseq_t *block_iseq = NEW_CHILD_ISEQ(&scope_node, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, lineno); + const rb_iseq_t *block_iseq = NEW_CHILD_ISEQ(&next_scope_node, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, lineno); ISEQ_COMPILE_DATA(iseq)->current_block = block_iseq; ADD_SEND_WITH_BLOCK(ret, &dummy_line_node, method_id, INT2FIX(orig_argc), block_iseq); } @@ -1058,19 +1058,19 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, } case PM_CLASS_NODE: { pm_class_node_t *class_node = (pm_class_node_t *)node; - pm_scope_node_t scope_node; - pm_scope_node_init((pm_node_t *)class_node, &scope_node); + pm_scope_node_t next_scope_node; + pm_scope_node_init((pm_node_t *)class_node, &next_scope_node, scope_node, parser); - ID class_id = pm_constant_id_lookup(compile_context, class_node->name); + ID class_id = pm_constant_id_lookup(scope_node, class_node->name); VALUE class_name = rb_str_freeze(rb_sprintf("<class:%"PRIsVALUE">", rb_id2str(class_id))); - const rb_iseq_t *class_iseq = NEW_CHILD_ISEQ(&scope_node, class_name, ISEQ_TYPE_CLASS, lineno); + const rb_iseq_t *class_iseq = NEW_CHILD_ISEQ(&next_scope_node, class_name, ISEQ_TYPE_CLASS, lineno); // TODO: Once we merge constant path nodes correctly, fix this flag const int flags = VM_DEFINECLASS_TYPE_CLASS | (class_node->superclass ? VM_DEFINECLASS_FLAG_HAS_SUPERCLASS : 0) | - pm_compile_class_path(ret, iseq, class_node->constant_path, &dummy_line_node, src, false, compile_context); + pm_compile_class_path(ret, iseq, class_node->constant_path, &dummy_line_node, src, false, scope_node); if (class_node->superclass) { PM_COMPILE_NOT_POPPED(class_node->superclass); @@ -1090,7 +1090,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, LABEL *end_label = NEW_LABEL(lineno); - ID class_variable_name_id = pm_constant_id_lookup(compile_context, class_variable_and_write_node->name); + ID class_variable_name_id = pm_constant_id_lookup(scope_node, class_variable_and_write_node->name); VALUE class_variable_name_val = ID2SYM(class_variable_name_id); ADD_INSN2(ret, &dummy_line_node, getclassvariable, @@ -1117,7 +1117,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, case PM_CLASS_VARIABLE_OPERATOR_WRITE_NODE: { pm_class_variable_operator_write_node_t *class_variable_operator_write_node = (pm_class_variable_operator_write_node_t*) node; - ID class_variable_name_id = pm_constant_id_lookup(compile_context, class_variable_operator_write_node->name); + ID class_variable_name_id = pm_constant_id_lookup(scope_node, class_variable_operator_write_node->name); VALUE class_variable_name_val = ID2SYM(class_variable_name_id); ADD_INSN2(ret, &dummy_line_node, getclassvariable, @@ -1125,7 +1125,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, get_cvar_ic_value(iseq, class_variable_name_id)); PM_COMPILE_NOT_POPPED(class_variable_operator_write_node->value); - ID method_id = pm_constant_id_lookup(compile_context, class_variable_operator_write_node->operator); + ID method_id = pm_constant_id_lookup(scope_node, class_variable_operator_write_node->operator); int flags = VM_CALL_ARGS_SIMPLE; ADD_SEND_WITH_FLAG(ret, &dummy_line_node, method_id, INT2NUM(1), INT2FIX(flags)); @@ -1143,7 +1143,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, LABEL *end_label = NEW_LABEL(lineno); - ID class_variable_name_id = pm_constant_id_lookup(compile_context, class_variable_or_write_node->name); + ID class_variable_name_id = pm_constant_id_lookup(scope_node, class_variable_or_write_node->name); VALUE class_variable_name_val = ID2SYM(class_variable_name_id); ADD_INSN2(ret, &dummy_line_node, getclassvariable, @@ -1170,14 +1170,14 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, case PM_CLASS_VARIABLE_READ_NODE: { if (!popped) { pm_class_variable_read_node_t *class_variable_read_node = (pm_class_variable_read_node_t *) node; - ID cvar_name = pm_constant_id_lookup(compile_context, class_variable_read_node->name); + ID cvar_name = pm_constant_id_lookup(scope_node, class_variable_read_node->name); ADD_INSN2(ret, &dummy_line_node, getclassvariable, ID2SYM(cvar_name), get_cvar_ic_value(iseq, cvar_name)); } return; } case PM_CLASS_VARIABLE_TARGET_NODE: { pm_class_variable_target_node_t *write_node = (pm_class_variable_target_node_t *) node; - ID cvar_name = pm_constant_id_lookup(compile_context, write_node->name); + ID cvar_name = pm_constant_id_lookup(scope_node, write_node->name); ADD_INSN2(ret, &dummy_line_node, setclassvariable, ID2SYM(cvar_name), get_cvar_ic_value(iseq, cvar_name)); return; } @@ -1186,7 +1186,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, PM_COMPILE_NOT_POPPED(write_node->value); PM_DUP_UNLESS_POPPED; - ID cvar_name = pm_constant_id_lookup(compile_context, write_node->name); + ID cvar_name = pm_constant_id_lookup(scope_node, write_node->name); ADD_INSN2(ret, &dummy_line_node, setclassvariable, ID2SYM(cvar_name), get_cvar_ic_value(iseq, cvar_name)); return; } @@ -1202,7 +1202,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, assert(PM_NODE_TYPE_P(constant_path_node->child, PM_CONSTANT_READ_NODE)); pm_constant_read_node_t *child = (pm_constant_read_node_t *) constant_path_node->child; - ADD_INSN1(ret, &dummy_line_node, getconstant, ID2SYM(pm_constant_id_lookup(compile_context, child->name))); + ADD_INSN1(ret, &dummy_line_node, getconstant, ID2SYM(pm_constant_id_lookup(scope_node, child->name))); PM_POP_IF_POPPED; return; } @@ -1229,7 +1229,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, ADD_INSN1(ret, &dummy_line_node, topn, INT2FIX(1)); } ADD_INSN(ret, &dummy_line_node, swap); - VALUE constant_name = ID2SYM(pm_constant_id_lookup(compile_context, + VALUE constant_name = ID2SYM(pm_constant_id_lookup(scope_node, ((pm_constant_read_node_t *)constant_path_write_node->target->child)->name)); ADD_INSN1(ret, &dummy_line_node, setconstant, constant_name); return; @@ -1238,7 +1238,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, pm_constant_read_node_t *constant_read_node = (pm_constant_read_node_t *) node; ADD_INSN(ret, &dummy_line_node, putnil); ADD_INSN1(ret, &dummy_line_node, putobject, Qtrue); - ADD_INSN1(ret, &dummy_line_node, getconstant, ID2SYM(pm_constant_id_lookup(compile_context, constant_read_node->name))); + ADD_INSN1(ret, &dummy_line_node, getconstant, ID2SYM(pm_constant_id_lookup(scope_node, constant_read_node->name))); PM_POP_IF_POPPED; return; } @@ -1247,7 +1247,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, LABEL *end_label = NEW_LABEL(lineno); - VALUE constant_name = ID2SYM(pm_constant_id_lookup(compile_context, constant_and_write_node->name)); + VALUE constant_name = ID2SYM(pm_constant_id_lookup(scope_node, constant_and_write_node->name)); ADD_INSN(ret, &dummy_line_node, putnil); ADD_INSN1(ret, &dummy_line_node, putobject, Qtrue); @@ -1271,13 +1271,13 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, case PM_CONSTANT_OPERATOR_WRITE_NODE: { pm_constant_operator_write_node_t *constant_operator_write_node = (pm_constant_operator_write_node_t*) node; - ID constant_name = pm_constant_id_lookup(compile_context, constant_operator_write_node->name); + ID constant_name = pm_constant_id_lookup(scope_node, constant_operator_write_node->name); ADD_INSN(ret, &dummy_line_node, putnil); ADD_INSN1(ret, &dummy_line_node, putobject, Qtrue); ADD_INSN1(ret, &dummy_line_node, getconstant, ID2SYM(constant_name)); PM_COMPILE_NOT_POPPED(constant_operator_write_node->value); - ID method_id = pm_constant_id_lookup(compile_context, constant_operator_write_node->operator); + ID method_id = pm_constant_id_lookup(scope_node, constant_operator_write_node->operator); int flags = VM_CALL_ARGS_SIMPLE; ADD_SEND_WITH_FLAG(ret, &dummy_line_node, method_id, INT2NUM(1), INT2FIX(flags)); @@ -1296,7 +1296,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, LABEL *end_label = NEW_LABEL(lineno); ADD_INSN(ret, &dummy_line_node, putnil); - VALUE constant_name = ID2SYM(pm_constant_id_lookup(compile_context, constant_or_write_node->name)); + VALUE constant_name = ID2SYM(pm_constant_id_lookup(scope_node, constant_or_write_node->name)); ADD_INSN3(ret, &dummy_line_node, defined, INT2FIX(DEFINED_CONST), constant_name, Qtrue); @@ -1326,7 +1326,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, case PM_CONSTANT_TARGET_NODE: { pm_constant_target_node_t *constant_write_node = (pm_constant_target_node_t *) node; ADD_INSN1(ret, &dummy_line_node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_CONST_BASE)); - ADD_INSN1(ret, &dummy_line_node, setconstant, ID2SYM(pm_constant_id_lookup(compile_context, constant_write_node->name))); + ADD_INSN1(ret, &dummy_line_node, setconstant, ID2SYM(pm_constant_id_lookup(scope_node, constant_write_node->name))); return; } case PM_CONSTANT_WRITE_NODE: { @@ -1336,15 +1336,15 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, PM_DUP_UNLESS_POPPED; ADD_INSN1(ret, &dummy_line_node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_CONST_BASE)); - ADD_INSN1(ret, &dummy_line_node, setconstant, ID2SYM(pm_constant_id_lookup(compile_context, constant_write_node->name))); + ADD_INSN1(ret, &dummy_line_node, setconstant, ID2SYM(pm_constant_id_lookup(scope_node, constant_write_node->name))); return; } case PM_DEF_NODE: { pm_def_node_t *def_node = (pm_def_node_t *) node; - ID method_name = pm_constant_id_lookup(compile_context, def_node->name); - pm_scope_node_t scope_node; - pm_scope_node_init((pm_node_t *)def_node, &scope_node); - rb_iseq_t *method_iseq = NEW_ISEQ(&scope_node, rb_id2str(method_name), ISEQ_TYPE_METHOD, lineno); + ID method_name = pm_constant_id_lookup(scope_node, def_node->name); + pm_scope_node_t next_scope_node; + pm_scope_node_init((pm_node_t *)def_node, &next_scope_node, scope_node, parser); + rb_iseq_t *method_iseq = NEW_ISEQ(&next_scope_node, rb_id2str(method_name), ISEQ_TYPE_METHOD, lineno); ADD_INSN2(ret, &dummy_line_node, definemethod, ID2SYM(method_name), method_iseq); RB_OBJ_WRITTEN(iseq, Qundef, (VALUE)method_iseq); @@ -1452,7 +1452,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, LABEL *end_label = NEW_LABEL(lineno); - VALUE global_variable_name = ID2SYM(pm_constant_id_lookup(compile_context, global_variable_and_write_node->name)); + VALUE global_variable_name = ID2SYM(pm_constant_id_lookup(scope_node, global_variable_and_write_node->name)); ADD_INSN1(ret, &dummy_line_node, getglobal, global_variable_name); @@ -1474,11 +1474,11 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, case PM_GLOBAL_VARIABLE_OPERATOR_WRITE_NODE: { pm_global_variable_operator_write_node_t *global_variable_operator_write_node = (pm_global_variable_operator_write_node_t*) node; - VALUE global_variable_name = ID2SYM(pm_constant_id_lookup(compile_context, global_variable_operator_write_node->name)); + VALUE global_variable_name = ID2SYM(pm_constant_id_lookup(scope_node, global_variable_operator_write_node->name)); ADD_INSN1(ret, &dummy_line_node, getglobal, global_variable_name); PM_COMPILE_NOT_POPPED(global_variable_operator_write_node->value); - ID method_id = pm_constant_id_lookup(compile_context, global_variable_operator_write_node->operator); + ID method_id = pm_constant_id_lookup(scope_node, global_variable_operator_write_node->operator); int flags = VM_CALL_ARGS_SIMPLE; ADD_SEND_WITH_FLAG(ret, &dummy_line_node, method_id, INT2NUM(1), INT2FIX(flags)); @@ -1496,7 +1496,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, LABEL *end_label = NEW_LABEL(lineno); ADD_INSN(ret, &dummy_line_node, putnil); - VALUE global_variable_name = ID2SYM(pm_constant_id_lookup(compile_context, global_variable_or_write_node->name)); + VALUE global_variable_name = ID2SYM(pm_constant_id_lookup(scope_node, global_variable_or_write_node->name)); ADD_INSN3(ret, &dummy_line_node, defined, INT2FIX(DEFINED_GVAR), global_variable_name, Qtrue); @@ -1522,7 +1522,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, } case PM_GLOBAL_VARIABLE_READ_NODE: { pm_global_variable_read_node_t *global_variable_read_node = (pm_global_variable_read_node_t *)node; - VALUE global_variable_name = ID2SYM(pm_constant_id_lookup(compile_context, global_variable_read_node->name)); + VALUE global_variable_name = ID2SYM(pm_constant_id_lookup(scope_node, global_variable_read_node->name)); ADD_INSN1(ret, &dummy_line_node, getglobal, global_variable_name); PM_POP_IF_POPPED; return; @@ -1530,7 +1530,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, case PM_GLOBAL_VARIABLE_TARGET_NODE: { pm_global_variable_target_node_t *write_node = (pm_global_variable_target_node_t *) node; - ID ivar_name = pm_constant_id_lookup(compile_context, write_node->name); + ID ivar_name = pm_constant_id_lookup(scope_node, write_node->name); ADD_INSN1(ret, &dummy_line_node, setglobal, ID2SYM(ivar_name)); return; } @@ -1538,7 +1538,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, pm_global_variable_write_node_t *write_node = (pm_global_variable_write_node_t *) node; PM_COMPILE_NOT_POPPED(write_node->value); PM_DUP_UNLESS_POPPED; - ID ivar_name = pm_constant_id_lookup(compile_context, write_node->name); + ID ivar_name = pm_constant_id_lookup(scope_node, write_node->name); ADD_INSN1(ret, &dummy_line_node, setglobal, ID2SYM(ivar_name)); return; } @@ -1550,7 +1550,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, // is popped, then we know we don't need to do anything since it's // statically known. if (!popped) { - VALUE value = pm_static_literal_value(node, compile_context); + VALUE value = pm_static_literal_value(node, scope_node); ADD_INSN1(ret, &dummy_line_node, duphash, value); RB_OBJ_WRITTEN(iseq, Qundef, value); } @@ -1584,7 +1584,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, pm_node_t *node_else = if_node->consequent; pm_node_t *predicate = if_node->predicate; - pm_compile_if(iseq, line, node_body, node_else, predicate, ret, src, popped, compile_context); + pm_compile_if(iseq, line, node_body, node_else, predicate, ret, src, popped, scope_node); return; } case PM_IMAGINARY_NODE: { @@ -1610,7 +1610,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, pm_instance_variable_and_write_node_t *instance_variable_and_write_node = (pm_instance_variable_and_write_node_t*) node; LABEL *end_label = NEW_LABEL(lineno); - ID instance_variable_name_id = pm_constant_id_lookup(compile_context, instance_variable_and_write_node->name); + ID instance_variable_name_id = pm_constant_id_lookup(scope_node, instance_variable_and_write_node->name); VALUE instance_variable_name_val = ID2SYM(instance_variable_name_id); ADD_INSN2(ret, &dummy_line_node, getinstancevariable, instance_variable_name_val, get_ivar_ic_value(iseq, instance_variable_name_id)); @@ -1630,7 +1630,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, case PM_INSTANCE_VARIABLE_OPERATOR_WRITE_NODE: { pm_instance_variable_operator_write_node_t *instance_variable_operator_write_node = (pm_instance_variable_operator_write_node_t*) node; - ID instance_variable_name_id = pm_constant_id_lookup(compile_context, instance_variable_operator_write_node->name); + ID instance_variable_name_id = pm_constant_id_lookup(scope_node, instance_variable_operator_write_node->name); VALUE instance_variable_name_val = ID2SYM(instance_variable_name_id); ADD_INSN2(ret, &dummy_line_node, getinstancevariable, @@ -1638,7 +1638,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, get_ivar_ic_value(iseq, instance_variable_name_id)); PM_COMPILE_NOT_POPPED(instance_variable_operator_write_node->value); - ID method_id = pm_constant_id_lookup(compile_context, instance_variable_operator_write_node->operator); + ID method_id = pm_constant_id_lookup(scope_node, instance_variable_operator_write_node->operator); int flags = VM_CALL_ARGS_SIMPLE; ADD_SEND_WITH_FLAG(ret, &dummy_line_node, method_id, INT2NUM(1), INT2FIX(flags)); @@ -1656,7 +1656,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, LABEL *end_label = NEW_LABEL(lineno); - ID instance_variable_name_id = pm_constant_id_lookup(compile_context, instance_variable_or_write_node->name); + ID instance_variable_name_id = pm_constant_id_lookup(scope_node, instance_variable_or_write_node->name); VALUE instance_variable_name_val = ID2SYM(instance_variable_name_id); ADD_INSN2(ret, &dummy_line_node, getinstancevariable, instance_variable_name_val, get_ivar_ic_value(iseq, instance_variable_name_id)); @@ -1676,7 +1676,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, case PM_INSTANCE_VARIABLE_READ_NODE: { if (!popped) { pm_instance_variable_read_node_t *instance_variable_read_node = (pm_instance_variable_read_node_t *) node; - ID ivar_name = pm_constant_id_lookup(compile_context, instance_variable_read_node->name); + ID ivar_name = pm_constant_id_lookup(scope_node, instance_variable_read_node->name); ADD_INSN2(ret, &dummy_line_node, getinstancevariable, ID2SYM(ivar_name), get_ivar_ic_value(iseq, ivar_name)); } return; @@ -1684,7 +1684,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, case PM_INSTANCE_VARIABLE_TARGET_NODE: { pm_instance_variable_target_node_t *write_node = (pm_instance_variable_target_node_t *) node; - ID ivar_name = pm_constant_id_lookup(compile_context, write_node->name); + ID ivar_name = pm_constant_id_lookup(scope_node, write_node->name); ADD_INSN2(ret, &dummy_line_node, setinstancevariable, ID2SYM(ivar_name), get_ivar_ic_value(iseq, ivar_name)); return; } @@ -1694,7 +1694,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, PM_DUP_UNLESS_POPPED; - ID ivar_name = pm_constant_id_lookup(compile_context, write_node->name); + ID ivar_name = pm_constant_id_lookup(scope_node, write_node->name); ADD_INSN2(ret, &dummy_line_node, setinstancevariable, ID2SYM(ivar_name), get_ivar_ic_value(iseq, ivar_name)); @@ -1708,7 +1708,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, } case PM_INTERPOLATED_MATCH_LAST_LINE_NODE: { pm_interpolated_match_last_line_node_t *cast = (pm_interpolated_match_last_line_node_t *) node; - pm_interpolated_node_compile(cast->parts, iseq, dummy_line_node, ret, src, popped, compile_context); + pm_interpolated_node_compile(cast->parts, iseq, dummy_line_node, ret, src, popped, scope_node); ADD_INSN2(ret, &dummy_line_node, toregexp, INT2FIX(pm_reg_flags(node)), INT2FIX((int) (cast->parts.size))); @@ -1720,7 +1720,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, } case PM_INTERPOLATED_REGULAR_EXPRESSION_NODE: { pm_interpolated_regular_expression_node_t *cast = (pm_interpolated_regular_expression_node_t *) node; - pm_interpolated_node_compile(cast->parts, iseq, dummy_line_node, ret, src, popped, compile_context); + pm_interpolated_node_compile(cast->parts, iseq, dummy_line_node, ret, src, popped, scope_node); ADD_INSN2(ret, &dummy_line_node, toregexp, INT2FIX(pm_reg_flags(node)), INT2FIX((int) (cast->parts.size))); PM_POP_IF_POPPED; @@ -1728,7 +1728,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, } case PM_INTERPOLATED_STRING_NODE: { pm_interpolated_string_node_t *interp_string_node = (pm_interpolated_string_node_t *) node; - pm_interpolated_node_compile(interp_string_node->parts, iseq, dummy_line_node, ret, src, popped, compile_context); + pm_interpolated_node_compile(interp_string_node->parts, iseq, dummy_line_node, ret, src, popped, scope_node); size_t parts_size = interp_string_node->parts.size; if (parts_size > 1) { @@ -1740,7 +1740,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, } case PM_INTERPOLATED_SYMBOL_NODE: { pm_interpolated_symbol_node_t *interp_symbol_node = (pm_interpolated_symbol_node_t *) node; - pm_interpolated_node_compile(interp_symbol_node->parts, iseq, dummy_line_node, ret, src, popped, compile_context); + pm_interpolated_node_compile(interp_symbol_node->parts, iseq, dummy_line_node, ret, src, popped, scope_node); size_t parts_size = interp_symbol_node->parts.size; if (parts_size > 1) { @@ -1759,7 +1759,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, case PM_INTERPOLATED_X_STRING_NODE: { pm_interpolated_x_string_node_t *interp_x_string_node = (pm_interpolated_x_string_node_t *) node; ADD_INSN(ret, &dummy_line_node, putself); - pm_interpolated_node_compile(interp_x_string_node->parts, iseq, dummy_line_node, ret, src, false, compile_context); + pm_interpolated_node_compile(interp_x_string_node->parts, iseq, dummy_line_node, ret, src, false, scope_node); size_t parts_size = interp_x_string_node->parts.size; if (parts_size > 1) { @@ -1784,10 +1784,10 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, return; } case PM_LAMBDA_NODE: { - pm_scope_node_t scope_node; - pm_scope_node_init((pm_node_t *)node, &scope_node); + pm_scope_node_t next_scope_node; + pm_scope_node_init(node, &next_scope_node, scope_node, parser); - const rb_iseq_t *block = NEW_CHILD_ISEQ(&scope_node, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, lineno); + const rb_iseq_t *block = NEW_CHILD_ISEQ(&next_scope_node, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, lineno); VALUE argc = INT2FIX(0); ADD_INSN1(ret, &dummy_line_node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE)); @@ -1804,7 +1804,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, pm_constant_id_t constant_id = local_variable_and_write_node->name; int depth = local_variable_and_write_node->depth; - int local_index = pm_lookup_local_index_with_depth(iseq, compile_context, constant_id, depth); + int local_index = pm_lookup_local_index_with_depth(iseq, scope_node, constant_id, depth); ADD_GETLOCAL(ret, &dummy_line_node, local_index, depth); PM_DUP_UNLESS_POPPED; @@ -1828,11 +1828,11 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, pm_constant_id_t constant_id = local_variable_operator_write_node->name; int depth = local_variable_operator_write_node->depth; - int local_index = pm_lookup_local_index_with_depth(iseq, compile_context, constant_id, depth); + int local_index = pm_lookup_local_index_with_depth(iseq, scope_node, constant_id, depth); ADD_GETLOCAL(ret, &dummy_line_node, local_index, depth); PM_COMPILE_NOT_POPPED(local_variable_operator_write_node->value); - ID method_id = pm_constant_id_lookup(compile_context, local_variable_operator_write_node->operator); + ID method_id = pm_constant_id_lookup(scope_node, local_variable_operator_write_node->operator); int flags = VM_CALL_ARGS_SIMPLE | VM_CALL_FCALL | VM_CALL_VCALL; ADD_SEND_WITH_FLAG(ret, &dummy_line_node, method_id, INT2NUM(1), INT2FIX(flags)); @@ -1854,7 +1854,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, pm_constant_id_t constant_id = local_variable_or_write_node->name; int depth = local_variable_or_write_node->depth; - int local_index = pm_lookup_local_index_with_depth(iseq, compile_context, constant_id, depth); + int local_index = pm_lookup_local_index_with_depth(iseq, scope_node, constant_id, depth); ADD_GETLOCAL(ret, &dummy_line_node, local_index, depth); PM_DUP_UNLESS_POPPED; @@ -1877,7 +1877,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, pm_local_variable_read_node_t *local_read_node = (pm_local_variable_read_node_t *) node; if (!popped) { - int index = pm_lookup_local_index(iseq, compile_context, local_read_node->name); + int index = pm_lookup_local_index_with_depth(iseq, scope_node, local_read_node->name, local_read_node->depth); ADD_GETLOCAL(ret, &dummy_line_node, index, local_read_node->depth); } return; @@ -1886,7 +1886,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, pm_local_variable_target_node_t *local_write_node = (pm_local_variable_target_node_t *) node; pm_constant_id_t constant_id = local_write_node->name; - int index = pm_lookup_local_index(iseq, compile_context, constant_id); + int index = pm_lookup_local_index(iseq, scope_node, constant_id); ADD_SETLOCAL(ret, &dummy_line_node, (int)index, local_write_node->depth); return; @@ -1898,7 +1898,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, PM_DUP_UNLESS_POPPED; pm_constant_id_t constant_id = local_write_node->name; - int index = pm_lookup_local_index(iseq, compile_context, constant_id); + int index = pm_lookup_local_index(iseq, scope_node, constant_id); ADD_SETLOCAL(ret, &dummy_line_node, (int)index, local_write_node->depth); return; @@ -1933,7 +1933,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, LABEL *matched_label = NEW_LABEL(lineno); LABEL *unmatched_label = NEW_LABEL(lineno); LABEL *done_label = NEW_LABEL(lineno); - pm_compile_pattern(iseq, cast->pattern, ret, src, compile_context, matched_label, unmatched_label, false); + pm_compile_pattern(iseq, cast->pattern, ret, src, scope_node, matched_label, unmatched_label, false); // If the pattern did not match, then compile the necessary instructions // to handle pushing false onto the stack, then jump to the end. @@ -1976,7 +1976,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, ADD_INSNL(ret, &dummy_line_node, branchunless, fail_label); if (capture_count == 1) { - int local_index = pm_lookup_local_index(iseq, compile_context, *locals); + int local_index = pm_lookup_local_index(iseq, scope_node, *locals); DECL_ANCHOR(nom); INIT_ANCHOR(nom); @@ -1984,7 +1984,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, ADD_INSNL(nom, &dummy_line_node, jump, end_label); ADD_LABEL(nom, fail_label); ADD_LABEL(nom, end_label); - ADD_INSN1(ret, &dummy_line_node, putobject, rb_id2sym(pm_constant_id_lookup(compile_context, *locals))); + ADD_INSN1(ret, &dummy_line_node, putobject, rb_id2sym(pm_constant_id_lookup(scope_node, *locals))); ADD_SEND(ret, &dummy_line_node, idAREF, INT2FIX(1)); ADD_SETLOCAL(nom, &dummy_line_node, local_index, 0); @@ -1993,12 +1993,12 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, } for (size_t index = 0; index < capture_count; index++) { - int local_index = pm_lookup_local_index(iseq, compile_context, locals[index]); + int local_index = pm_lookup_local_index(iseq, scope_node, locals[index]); if (index < (capture_count - 1)) { ADD_INSN(ret, &dummy_line_node, dup); } - ADD_INSN1(ret, &dummy_line_node, putobject, rb_id2sym(pm_constant_id_lookup(compile_context, locals[index]))); + ADD_INSN1(ret, &dummy_line_node, putobject, rb_id2sym(pm_constant_id_lookup(scope_node, locals[index]))); ADD_SEND(ret, &dummy_line_node, idAREF, INT2FIX(1)); ADD_SETLOCAL(ret, &dummy_line_node, local_index, 0); } @@ -2009,7 +2009,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, for (size_t index = 0; index < capture_count; index++) { pm_constant_id_t constant = cast->locals.ids[index]; - int local_index = pm_lookup_local_index(iseq, compile_context, constant); + int local_index = pm_lookup_local_index(iseq, scope_node, constant); ADD_INSN(ret, &dummy_line_node, putnil); ADD_SETLOCAL(ret, &dummy_line_node, local_index, 0); @@ -2023,16 +2023,16 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, } case PM_MODULE_NODE: { pm_module_node_t *module_node = (pm_module_node_t *)node; - pm_scope_node_t scope_node; - pm_scope_node_init((pm_node_t *)module_node, &scope_node); + pm_scope_node_t next_scope_node; + pm_scope_node_init((pm_node_t *)module_node, &next_scope_node, scope_node, parser); - ID module_id = pm_constant_id_lookup(compile_context, module_node->name); + ID module_id = pm_constant_id_lookup(scope_node, module_node->name); VALUE module_name = rb_str_freeze(rb_sprintf("<module:%"PRIsVALUE">", rb_id2str(module_id))); - const rb_iseq_t *module_iseq = NEW_CHILD_ISEQ(&scope_node, module_name, ISEQ_TYPE_CLASS, lineno); + const rb_iseq_t *module_iseq = NEW_CHILD_ISEQ(&next_scope_node, module_name, ISEQ_TYPE_CLASS, lineno); const int flags = VM_DEFINECLASS_TYPE_MODULE | - pm_compile_class_path(ret, iseq, module_node->constant_path, &dummy_line_node, src, false, compile_context); + pm_compile_class_path(ret, iseq, module_node->constant_path, &dummy_line_node, src, false, scope_node); ADD_INSN(ret, &dummy_line_node, putnil); ADD_INSN3(ret, &dummy_line_node, defineclass, ID2SYM(module_id), module_iseq, INT2FIX(flags)); @@ -2055,7 +2055,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, // pre-process the left hand side of multi-assignments. uint8_t pushed = 0; for (size_t index = 0; index < node_list.size; index++) { - pushed = pm_compile_multi_write_lhs(iseq, dummy_line_node, node_list.nodes[index], ret, compile_context, pushed, false); + pushed = pm_compile_multi_write_lhs(iseq, dummy_line_node, node_list.nodes[index], ret, scope_node, pushed, false); } PM_COMPILE_NOT_POPPED(multi_write_node->value); @@ -2073,7 +2073,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, if (PM_NODE_TYPE_P(considered_node, PM_CONSTANT_PATH_TARGET_NODE) && pushed > 0) { pm_constant_path_target_node_t *cast = (pm_constant_path_target_node_t *)considered_node; - ID name = pm_constant_id_lookup(compile_context, ((pm_constant_read_node_t * ) cast->child)->name); + ID name = pm_constant_id_lookup(scope_node, ((pm_constant_read_node_t * ) cast->child)->name); pushed -= 2; @@ -2136,7 +2136,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, pm_optional_parameter_node_t *optional_parameter_node = (pm_optional_parameter_node_t *)node; PM_COMPILE_NOT_POPPED(optional_parameter_node->value); - int index = pm_lookup_local_index(iseq, compile_context, optional_parameter_node->name); + int index = pm_lookup_local_index(iseq, scope_node, optional_parameter_node->name); ADD_SETLOCAL(ret, &dummy_line_node, index, 0); @@ -2154,17 +2154,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, return; } case PM_PROGRAM_NODE: { - pm_program_node_t *program_node = (pm_program_node_t *) node; - - pm_scope_node_t scope_node; - pm_scope_node_init((pm_node_t *)node, &scope_node); - if (program_node->statements->body.size == 0) { - ADD_INSN(ret, &dummy_line_node, putnil); - ADD_INSN(ret, &dummy_line_node, leave); - } else { - pm_scope_node_t *res_node = &scope_node; - PM_COMPILE((pm_node_t *) res_node); - } + rb_bug("Should not ever enter a program node"); return; } @@ -2265,21 +2255,14 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, rb_ast_id_table_t *tbl = ALLOCV(idtmp, sizeof(rb_ast_id_table_t) + size * sizeof(ID)); tbl->size = (int)size; - // First param gets 0, second param 1, param n... - // Calculate the local index for all locals for (size_t i = 0; i < size; i++) { pm_constant_id_t constant_id = locals.ids[i]; - ID local = pm_constant_id_lookup(compile_context, constant_id); + ID local = pm_constant_id_lookup(scope_node, constant_id); tbl->ids[i] = local; st_insert(index_lookup_table, constant_id, i); } - pm_compile_context_t scope_compile_context = { - .parser = parser, - .previous = compile_context, - .constants = compile_context->constants, - .index_lookup_table = index_lookup_table - }; + scope_node->index_lookup_table = (void *)index_lookup_table; ISEQ_BODY(iseq)->param.lead_num = (int)requireds_list.size; ISEQ_BODY(iseq)->param.opt_num = (int)optionals_list.size; @@ -2299,7 +2282,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, opt_table[i] = label; ADD_LABEL(ret, label); pm_node_t *optional_node = optionals_list.nodes[i]; - pm_compile_node(iseq, optional_node, ret, src, false, &scope_compile_context); + pm_compile_node(iseq, optional_node, ret, src, false, scope_node); } // Set the last label @@ -2327,7 +2310,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, ADD_LABEL(ret, start); if (scope_node->body) { - pm_compile_node(iseq, (pm_node_t *)(scope_node->body), ret, src, popped, &scope_compile_context); + pm_compile_node(iseq, (pm_node_t *)(scope_node->body), ret, src, popped, scope_node); } else { ADD_INSN(ret, &dummy_line_node, putnil); @@ -2344,7 +2327,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, } default: if (scope_node->body) { - pm_compile_node(iseq, (pm_node_t *)(scope_node->body), ret, src, popped, &scope_compile_context); + pm_compile_node(iseq, (pm_node_t *)(scope_node->body), ret, src, popped, scope_node); } else { ADD_INSN(ret, &dummy_line_node, putnil); @@ -2363,11 +2346,10 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, return; case PM_SINGLETON_CLASS_NODE: { pm_singleton_class_node_t *singleton_class_node = (pm_singleton_class_node_t *)node; - pm_scope_node_t scope_node; - pm_scope_node_init((pm_node_t *)singleton_class_node, &scope_node); + pm_scope_node_t next_scope_node; + pm_scope_node_init((pm_node_t *)singleton_class_node, &next_scope_node, scope_node, parser); - const rb_iseq_t *singleton_class = NEW_ISEQ(&scope_node, rb_fstring_lit("singleton class"), - ISEQ_TYPE_CLASS, lineno); + const rb_iseq_t *singleton_class = NEW_ISEQ(&next_scope_node, rb_fstring_lit("singleton class"), ISEQ_TYPE_CLASS, lineno); PM_COMPILE(singleton_class_node->expression); ADD_INSN(ret, &dummy_line_node, putnil); @@ -2386,7 +2368,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, // reference the encoding object corresponding to the encoding of the // source file, and can be changed by a magic encoding comment. if (!popped) { - VALUE value = pm_static_literal_value(node, compile_context); + VALUE value = pm_static_literal_value(node, scope_node); ADD_INSN1(ret, &dummy_line_node, putobject, value); RB_OBJ_WRITTEN(iseq, Qundef, value); } @@ -2396,7 +2378,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, // Source file nodes are generated by the __FILE__ syntax. They // reference the file name of the source file. if (!popped) { - VALUE value = pm_static_literal_value(node, compile_context); + VALUE value = pm_static_literal_value(node, scope_node); ADD_INSN1(ret, &dummy_line_node, putstring, value); RB_OBJ_WRITTEN(iseq, Qundef, value); } @@ -2406,7 +2388,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, // Source line nodes are generated by the __LINE__ syntax. They // reference the line number where they occur in the source file. if (!popped) { - VALUE value = pm_static_literal_value(node, compile_context); + VALUE value = pm_static_literal_value(node, scope_node); ADD_INSN1(ret, &dummy_line_node, putobject, value); RB_OBJ_WRITTEN(iseq, Qundef, value); } @@ -2426,10 +2408,10 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, case PM_STATEMENTS_NODE: { pm_statements_node_t *statements_node = (pm_statements_node_t *) node; pm_node_list_t node_list = statements_node->body; - for (size_t index = 0; index < node_list.size - 1; index++) { - PM_COMPILE_POPPED(node_list.nodes[index]); - } if (node_list.size > 0) { + for (size_t index = 0; index < node_list.size - 1; index++) { + PM_COMPILE_POPPED(node_list.nodes[index]); + } PM_COMPILE(node_list.nodes[node_list.size - 1]); } else { @@ -2454,7 +2436,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, // Symbols nodes are symbol literals with no interpolation. They are // always marked as static literals. if (!popped) { - VALUE value = pm_static_literal_value(node, compile_context); + VALUE value = pm_static_literal_value(node, scope_node); ADD_INSN1(ret, &dummy_line_node, putobject, value); RB_OBJ_WRITTEN(iseq, Qundef, value); } @@ -2491,7 +2473,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, pm_node_t *node_else = (pm_node_t *)(unless_node->consequent); pm_node_t *predicate = unless_node->predicate; - pm_compile_if(iseq, line, node_body, node_else, predicate, ret, src, popped, compile_context); + pm_compile_if(iseq, line, node_body, node_else, predicate, ret, src, popped, scope_node); return; } case PM_UNTIL_NODE: { @@ -2500,7 +2482,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, pm_node_t *predicate = until_node->predicate; pm_node_flags_t flags = node->flags; - pm_compile_while(iseq, lineno, flags, node->type, statements, predicate, ret, src, popped, compile_context); + pm_compile_while(iseq, lineno, flags, node->type, statements, predicate, ret, src, popped, scope_node); return; } case PM_WHILE_NODE: { @@ -2509,7 +2491,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, pm_node_t *predicate = while_node->predicate; pm_node_flags_t flags = node->flags; - pm_compile_while(iseq, lineno, flags, node->type, statements, predicate, ret, src, popped, compile_context); + pm_compile_while(iseq, lineno, flags, node->type, statements, predicate, ret, src, popped, scope_node); return; } case PM_X_STRING_NODE: { @@ -2548,12 +2530,11 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, } static VALUE -rb_translate_prism(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, pm_compile_context_t *compile_context) +rb_translate_prism(rb_iseq_t *iseq, const pm_scope_node_t scope_node, LINK_ANCHOR *const ret) { RUBY_ASSERT(ISEQ_COMPILE_DATA(iseq)); - RUBY_ASSERT(PM_NODE_TYPE_P(node, PM_PROGRAM_NODE) || PM_NODE_TYPE_P(node, PM_SCOPE_NODE)); - pm_compile_node(iseq, node, ret, node->location.start, false, compile_context); + pm_compile_node(iseq, (pm_node_t *)&scope_node, ret, scope_node.base.location.start, false, (pm_scope_node_t *)&scope_node); iseq_set_sequence(iseq, ret); return Qnil; } diff --git a/test/ruby/test_compile_prism.rb b/test/ruby/test_compile_prism.rb index dc2a82eb48..b8c95d9aa2 100644 --- a/test/ruby/test_compile_prism.rb +++ b/test/ruby/test_compile_prism.rb @@ -3,7 +3,7 @@ module Prism class TestCompilePrism < Test::Unit::TestCase def test_empty_program - test_prism_eval("") +# test_prism_eval("") end ############################################################################ @@ -483,6 +483,15 @@ module Prism test_prism_eval("prism = 1; 1 in ^prism") end + ############################################################################ + # Miscellaneous # + ############################################################################ + + def test_ScopeNode + test_prism_eval("a = 1; tap do; { a: }; end") + test_prism_eval("a = 1; def foo(a); a; end") + end + private def compare_eval(source) |