diff options
| author | Kevin Newton <kddnewton@gmail.com> | 2024-04-04 11:48:23 -0400 |
|---|---|---|
| committer | Kevin Newton <kddnewton@gmail.com> | 2024-04-04 14:14:55 -0400 |
| commit | 2d523c27cff12bc9ed85ecc3197b4777da855b4a (patch) | |
| tree | 2308afc909cd32a8cf53bbfa6eb398a6d51c898b | |
| parent | 3410387096e763b742674f8f0c53a5d095a31974 (diff) | |
[PRISM] Remove dummy_line_node usage from defined expressions
| -rw-r--r-- | prism_compile.c | 488 |
1 files changed, 242 insertions, 246 deletions
diff --git a/prism_compile.c b/prism_compile.c index ccf599d2a2..4592ca884d 100644 --- a/prism_compile.c +++ b/prism_compile.c @@ -808,32 +808,32 @@ pm_compile_flip_flop(const pm_flip_flop_node_t *flip_flop_node, LABEL *else_labe ADD_INSNL(ret, &dummy_line_node, jump, then_label); } -void pm_compile_defined_expr(rb_iseq_t *iseq, const pm_node_t *defined_node, LINK_ANCHOR *const ret, bool popped, pm_scope_node_t *scope_node, NODE dummy_line_node, int lineno, bool in_condition); +static void pm_compile_defined_expr(rb_iseq_t *iseq, const pm_node_t *node, const pm_line_column_t *node_location, LINK_ANCHOR *const ret, bool popped, pm_scope_node_t *scope_node, bool in_condition); 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, bool popped, pm_scope_node_t *scope_node) +pm_compile_branch_condition(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const pm_node_t *cond, LABEL *then_label, LABEL *else_label, bool popped, pm_scope_node_t *scope_node) { - int lineno = pm_node_line_number(scope_node->parser, cond); - NODE dummy_line_node = generate_dummy_line_node(lineno, lineno); + const pm_line_column_t location = pm_newline_list_line_column(&scope_node->parser->newline_list, cond->location.start, scope_node->parser->start_line); 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, popped, scope_node); - cond = and_node->right; + const pm_and_node_t *cast = (const pm_and_node_t *) cond; + pm_compile_logical(iseq, ret, cast->left, NULL, else_label, popped, scope_node); + + cond = cast->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, popped, scope_node); - cond = or_node->right; + const pm_or_node_t *cast = (const pm_or_node_t *) cond; + pm_compile_logical(iseq, ret, cast->left, then_label, NULL, popped, scope_node); + + cond = cast->right; goto again; } case PM_FALSE_NODE: case PM_NIL_NODE: - ADD_INSNL(ret, &dummy_line_node, jump, else_label); + PUSH_INSNL(ret, location, jump, else_label); return; case PM_FLOAT_NODE: case PM_IMAGINARY_NODE: @@ -844,14 +844,14 @@ again: case PM_STRING_NODE: case PM_SYMBOL_NODE: case PM_TRUE_NODE: - ADD_INSNL(ret, &dummy_line_node, jump, then_label); + PUSH_INSNL(ret, location, jump, then_label); return; case PM_FLIP_FLOP_NODE: - pm_compile_flip_flop((const pm_flip_flop_node_t *) cond, else_label, then_label, iseq, lineno, ret, popped, scope_node); + pm_compile_flip_flop((const pm_flip_flop_node_t *) cond, else_label, then_label, iseq, location.line, ret, popped, scope_node); return; case PM_DEFINED_NODE: { - pm_defined_node_t *defined_node = (pm_defined_node_t *)cond; - pm_compile_defined_expr(iseq, defined_node->value, ret, popped, scope_node, dummy_line_node, lineno, true); + const pm_defined_node_t *cast = (const pm_defined_node_t *) cond; + pm_compile_defined_expr(iseq, cast->value, &location, ret, popped, scope_node, true); break; } default: { @@ -859,9 +859,9 @@ again: break; } } - ADD_INSNL(ret, &dummy_line_node, branchunless, else_label); - ADD_INSNL(ret, &dummy_line_node, jump, then_label); - return; + + PUSH_INSNL(ret, location, branchunless, else_label); + PUSH_INSNL(ret, location, jump, then_label); } /** @@ -2799,13 +2799,104 @@ pm_scope_node_destroy(pm_scope_node_t *scope_node) } } -static void pm_compile_call(rb_iseq_t *iseq, const pm_call_node_t *call_node, LINK_ANCHOR *const ret, bool popped, pm_scope_node_t *scope_node, ID method_id, LABEL *start); +static void +pm_compile_call(rb_iseq_t *iseq, const pm_call_node_t *call_node, LINK_ANCHOR *const ret, bool popped, pm_scope_node_t *scope_node, ID method_id, LABEL *start) +{ + const pm_location_t *message_loc = &call_node->message_loc; + if (message_loc->start == NULL) message_loc = &call_node->base.location; -void -pm_compile_defined_expr0(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, bool popped, pm_scope_node_t *scope_node, NODE dummy_line_node, int lineno, bool in_condition, LABEL **lfinish, bool explicit_receiver) + const pm_line_column_t location = pm_newline_list_line_column(&scope_node->parser->newline_list, message_loc->start, scope_node->parser->start_line); + LABEL *else_label = NEW_LABEL(location.line); + LABEL *end_label = NEW_LABEL(location.line); + + if (PM_NODE_FLAG_P(call_node, PM_CALL_NODE_FLAGS_SAFE_NAVIGATION)) { + PUSH_INSN(ret, location, dup); + PUSH_INSNL(ret, location, branchnil, else_label); + } + + int flags = 0; + struct rb_callinfo_kwarg *kw_arg = NULL; + + int orig_argc = pm_setup_args(call_node->arguments, call_node->block, &flags, &kw_arg, iseq, ret, scope_node, &location); + const rb_iseq_t *block_iseq = NULL; + + if (call_node->block != NULL && PM_NODE_TYPE_P(call_node->block, PM_BLOCK_NODE)) { + // Scope associated with the block + pm_scope_node_t next_scope_node; + pm_scope_node_init(call_node->block, &next_scope_node, scope_node); + + block_iseq = NEW_CHILD_ISEQ(&next_scope_node, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, pm_node_line_number(scope_node->parser, call_node->block)); + pm_scope_node_destroy(&next_scope_node); + + if (ISEQ_BODY(block_iseq)->catch_table) { + ADD_CATCH_ENTRY(CATCH_TYPE_BREAK, start, end_label, block_iseq, end_label); + } + ISEQ_COMPILE_DATA(iseq)->current_block = block_iseq; + } + else { + if (PM_NODE_FLAG_P(call_node, PM_CALL_NODE_FLAGS_VARIABLE_CALL)) { + flags |= VM_CALL_VCALL; + } + + if (!flags) { + flags |= VM_CALL_ARGS_SIMPLE; + } + } + + if (PM_NODE_FLAG_P(call_node, PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY)) { + flags |= VM_CALL_FCALL; + } + + if (!popped && PM_NODE_FLAG_P(call_node, PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE)) { + if (flags & VM_CALL_ARGS_BLOCKARG) { + PUSH_INSN1(ret, location, topn, INT2FIX(1)); + if (flags & VM_CALL_ARGS_SPLAT) { + PUSH_INSN1(ret, location, putobject, INT2FIX(-1)); + PUSH_SEND_WITH_FLAG(ret, location, idAREF, INT2FIX(1), INT2FIX(0)); + } + PUSH_INSN1(ret, location, setn, INT2FIX(orig_argc + 3)); + PUSH_INSN(ret, location, pop); + } + else if (flags & VM_CALL_ARGS_SPLAT) { + PUSH_INSN(ret, location, dup); + PUSH_INSN1(ret, location, putobject, INT2FIX(-1)); + PUSH_SEND_WITH_FLAG(ret, location, idAREF, INT2FIX(1), INT2FIX(0)); + PUSH_INSN1(ret, location, setn, INT2FIX(orig_argc + 2)); + PUSH_INSN(ret, location, pop); + } + else { + PUSH_INSN1(ret, location, setn, INT2FIX(orig_argc + 1)); + } + } + + if ((flags & VM_CALL_KW_SPLAT) && (flags & VM_CALL_ARGS_BLOCKARG) && !(flags & VM_CALL_KW_SPLAT_MUT)) { + PUSH_INSN(ret, location, splatkw); + } + + PUSH_SEND_R(ret, location, method_id, INT2FIX(orig_argc), block_iseq, INT2FIX(flags), kw_arg); + + if (PM_NODE_FLAG_P(call_node, PM_CALL_NODE_FLAGS_SAFE_NAVIGATION)) { + PUSH_INSNL(ret, location, jump, end_label); + PUSH_LABEL(ret, else_label); + } + + if (PM_NODE_FLAG_P(call_node, PM_CALL_NODE_FLAGS_SAFE_NAVIGATION) || (block_iseq && ISEQ_BODY(block_iseq)->catch_table)) { + PUSH_LABEL(ret, end_label); + } + + if (PM_NODE_FLAG_P(call_node, PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE) && !popped) { + PUSH_INSN(ret, location, pop); + } + + if (popped) PUSH_INSN(ret, location, pop); +} + +static void +pm_compile_defined_expr0(rb_iseq_t *iseq, const pm_node_t *node, const pm_line_column_t *node_location, LINK_ANCHOR *const ret, bool popped, pm_scope_node_t *scope_node, bool in_condition, LABEL **lfinish, bool explicit_receiver) { // in_condition is the same as compile.c's needstr enum defined_type dtype = DEFINED_NOT_DEFINED; + const pm_line_column_t location = *node_location; switch (PM_NODE_TYPE(node)) { case PM_ARGUMENTS_NODE: { @@ -2813,12 +2904,12 @@ pm_compile_defined_expr0(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *co const pm_node_list_t *arguments = &cast->arguments; for (size_t idx = 0; idx < arguments->size; idx++) { const pm_node_t *argument = arguments->nodes[idx]; - pm_compile_defined_expr0(iseq, argument, ret, popped, scope_node, dummy_line_node, lineno, in_condition, lfinish, explicit_receiver); + pm_compile_defined_expr0(iseq, argument, node_location, ret, popped, scope_node, in_condition, lfinish, explicit_receiver); if (!lfinish[1]) { - lfinish[1] = NEW_LABEL(lineno); + lfinish[1] = NEW_LABEL(location.line); } - ADD_INSNL(ret, &dummy_line_node, branchunless, lfinish[1]); + PUSH_INSNL(ret, location, branchunless, lfinish[1]); } dtype = DEFINED_TRUE; break; @@ -2836,7 +2927,7 @@ pm_compile_defined_expr0(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *co else if (PM_NODE_TYPE_P(cast->body, PM_STATEMENTS_NODE) && ((const pm_statements_node_t *) cast->body)->body.size == 1) { // If we have a parentheses node that is wrapping a single statement // then we want to recurse down to that statement and compile it. - pm_compile_defined_expr0(iseq, ((const pm_statements_node_t *) cast->body)->body.nodes[0], ret, popped, scope_node, dummy_line_node, lineno, in_condition, lfinish, explicit_receiver); + pm_compile_defined_expr0(iseq, ((const pm_statements_node_t *) cast->body)->body.nodes[0], node_location, ret, popped, scope_node, in_condition, lfinish, explicit_receiver); return; } else { @@ -2857,17 +2948,17 @@ pm_compile_defined_expr0(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *co dtype = DEFINED_FALSE; break; case PM_ARRAY_NODE: { - pm_array_node_t *cast = (pm_array_node_t *) node; + const pm_array_node_t *cast = (const pm_array_node_t *) node; if (!PM_NODE_FLAG_P(cast, PM_ARRAY_NODE_FLAGS_CONTAINS_SPLAT)) { for (size_t index = 0; index < cast->elements.size; index++) { - pm_compile_defined_expr0(iseq, cast->elements.nodes[index], ret, popped, scope_node, dummy_line_node, lineno, true, lfinish, false); + pm_compile_defined_expr0(iseq, cast->elements.nodes[index], node_location, ret, popped, scope_node, true, lfinish, false); if (!lfinish[1]) { - lfinish[1] = NEW_LABEL(lineno); + lfinish[1] = NEW_LABEL(location.line); } - ADD_INSNL(ret, &dummy_line_node, branchunless, lfinish[1]); + PUSH_INSNL(ret, location, branchunless, lfinish[1]); } } } @@ -2918,133 +3009,127 @@ pm_compile_defined_expr0(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *co case PM_LOCAL_VARIABLE_READ_NODE: dtype = DEFINED_LVAR; break; + #define PUSH_VAL(type) (in_condition ? Qtrue : rb_iseq_defined_string(type)) + case PM_INSTANCE_VARIABLE_READ_NODE: { - pm_instance_variable_read_node_t *instance_variable_read_node = (pm_instance_variable_read_node_t *)node; - ID id = pm_constant_id_lookup(scope_node, instance_variable_read_node->name); - ADD_INSN3(ret, &dummy_line_node, definedivar, - ID2SYM(id), get_ivar_ic_value(iseq, id), PUSH_VAL(DEFINED_IVAR)); + const pm_instance_variable_read_node_t *cast = (const pm_instance_variable_read_node_t *) node; + + ID name = pm_constant_id_lookup(scope_node, cast->name); + PUSH_INSN3(ret, location, definedivar, ID2SYM(name), get_ivar_ic_value(iseq, name), PUSH_VAL(DEFINED_IVAR)); + return; } case PM_BACK_REFERENCE_READ_NODE: { - char *char_ptr = (char *)(node->location.start) + 1; + const char *char_ptr = (const char *) (node->location.start + 1); ID backref_val = INT2FIX(rb_intern2(char_ptr, 1)) << 1 | 1; - PM_PUTNIL; - ADD_INSN3(ret, &dummy_line_node, defined, INT2FIX(DEFINED_REF), - backref_val, - PUSH_VAL(DEFINED_GVAR)); + PUSH_INSN(ret, location, putnil); + PUSH_INSN3(ret, location, defined, INT2FIX(DEFINED_REF), backref_val, PUSH_VAL(DEFINED_GVAR)); return; } case PM_NUMBERED_REFERENCE_READ_NODE: { - uint32_t reference_number = ((pm_numbered_reference_read_node_t *)node)->number; + uint32_t reference_number = ((const pm_numbered_reference_read_node_t *) node)->number; - PM_PUTNIL; - ADD_INSN3(ret, &dummy_line_node, defined, INT2FIX(DEFINED_REF), - INT2FIX(reference_number << 1), - PUSH_VAL(DEFINED_GVAR)); + PUSH_INSN(ret, location, putnil); + PUSH_INSN3(ret, location, defined, INT2FIX(DEFINED_REF), INT2FIX(reference_number << 1), PUSH_VAL(DEFINED_GVAR)); return; } case PM_GLOBAL_VARIABLE_READ_NODE: { - pm_global_variable_read_node_t *glabal_variable_read_node = (pm_global_variable_read_node_t *)node; - PM_PUTNIL; - ADD_INSN3(ret, &dummy_line_node, defined, INT2FIX(DEFINED_GVAR), - ID2SYM(pm_constant_id_lookup(scope_node, glabal_variable_read_node->name)), PUSH_VAL(DEFINED_GVAR)); + const pm_global_variable_read_node_t *cast = (const pm_global_variable_read_node_t *) node; + VALUE name = ID2SYM(pm_constant_id_lookup(scope_node, cast->name)); + + PUSH_INSN(ret, location, putnil); + PUSH_INSN3(ret, location, defined, INT2FIX(DEFINED_GVAR), name, PUSH_VAL(DEFINED_GVAR)); + return; } case PM_CLASS_VARIABLE_READ_NODE: { - pm_class_variable_read_node_t *class_variable_read_node = (pm_class_variable_read_node_t *)node; - PM_PUTNIL; - ADD_INSN3(ret, &dummy_line_node, defined, INT2FIX(DEFINED_CVAR), - ID2SYM(pm_constant_id_lookup(scope_node, class_variable_read_node->name)), PUSH_VAL(DEFINED_CVAR)); + const pm_class_variable_read_node_t *cast = (const pm_class_variable_read_node_t *) node; + VALUE name = ID2SYM(pm_constant_id_lookup(scope_node, cast->name)); + + PUSH_INSN(ret, location, putnil); + PUSH_INSN3(ret, location, defined, INT2FIX(DEFINED_CVAR), name, PUSH_VAL(DEFINED_CVAR)); return; } case PM_CONSTANT_READ_NODE: { - pm_constant_read_node_t *constant_node = (pm_constant_read_node_t *)node; - PM_PUTNIL; - ADD_INSN3(ret, &dummy_line_node, defined, INT2FIX(DEFINED_CONST), - ID2SYM(pm_constant_id_lookup(scope_node, constant_node->name)), PUSH_VAL(DEFINED_CONST)); + const pm_constant_read_node_t *cast = (const pm_constant_read_node_t *) node; + VALUE name = ID2SYM(pm_constant_id_lookup(scope_node, cast->name)); + + PUSH_INSN(ret, location, putnil); + PUSH_INSN3(ret, location, defined, INT2FIX(DEFINED_CONST), name, PUSH_VAL(DEFINED_CONST)); + return; } case PM_CONSTANT_PATH_NODE: { - pm_constant_path_node_t *constant_path_node = ((pm_constant_path_node_t *)node); - if (constant_path_node->parent) { - if (!lfinish[1]) { - lfinish[1] = NEW_LABEL(lineno); - } - pm_compile_defined_expr0(iseq, constant_path_node->parent, ret, popped, scope_node, dummy_line_node, lineno, true, lfinish, false); - ADD_INSNL(ret, &dummy_line_node, branchunless, lfinish[1]); - PM_COMPILE(constant_path_node->parent); + const pm_constant_path_node_t *cast = (const pm_constant_path_node_t *) node; + VALUE name = ID2SYM(pm_constant_id_lookup(scope_node, ((const pm_constant_read_node_t *) cast->child)->name)); + + if (cast->parent != NULL) { + if (!lfinish[1]) lfinish[1] = NEW_LABEL(location.line); + pm_compile_defined_expr0(iseq, cast->parent, node_location, ret, popped, scope_node, true, lfinish, false); + + PUSH_INSNL(ret, location, branchunless, lfinish[1]); + PM_COMPILE(cast->parent); } else { - ADD_INSN1(ret, &dummy_line_node, putobject, rb_cObject); + PUSH_INSN1(ret, location, putobject, rb_cObject); } - ADD_INSN3(ret, &dummy_line_node, defined, INT2FIX(DEFINED_CONST_FROM), - ID2SYM(pm_constant_id_lookup(scope_node, ((pm_constant_read_node_t *)constant_path_node->child)->name)), PUSH_VAL(DEFINED_CONST)); + + PUSH_INSN3(ret, location, defined, INT2FIX(DEFINED_CONST_FROM), name, PUSH_VAL(DEFINED_CONST)); return; } - case PM_CALL_NODE: { - pm_call_node_t *call_node = ((pm_call_node_t *)node); - ID method_id = pm_constant_id_lookup(scope_node, call_node->name); + const pm_call_node_t *cast = ((const pm_call_node_t *) node); + ID method_id = pm_constant_id_lookup(scope_node, cast->name); - if (call_node->receiver || call_node->arguments) { - if (!lfinish[1]) { - lfinish[1] = NEW_LABEL(lineno); - } - if (!lfinish[2]) { - lfinish[2] = NEW_LABEL(lineno); - } + if (cast->receiver || cast->arguments) { + if (!lfinish[1]) lfinish[1] = NEW_LABEL(location.line); + if (!lfinish[2]) lfinish[2] = NEW_LABEL(location.line); } - if (call_node->arguments) { - pm_compile_defined_expr0(iseq, (const pm_node_t *)call_node->arguments, ret, popped, scope_node, dummy_line_node, lineno, true, lfinish, false); - ADD_INSNL(ret, &dummy_line_node, branchunless, lfinish[1]); + if (cast->arguments) { + pm_compile_defined_expr0(iseq, (const pm_node_t *) cast->arguments, node_location, ret, popped, scope_node, true, lfinish, false); + PUSH_INSNL(ret, location, branchunless, lfinish[1]); } - if (call_node->receiver) { - pm_compile_defined_expr0(iseq, call_node->receiver, ret, popped, scope_node, dummy_line_node, lineno, true, lfinish, true); - if (PM_NODE_TYPE_P(call_node->receiver, PM_CALL_NODE)) { - ADD_INSNL(ret, &dummy_line_node, branchunless, lfinish[2]); + if (cast->receiver) { + pm_compile_defined_expr0(iseq, cast->receiver, node_location, ret, popped, scope_node, true, lfinish, true); + + if (PM_NODE_TYPE_P(cast->receiver, PM_CALL_NODE)) { + PUSH_INSNL(ret, location, branchunless, lfinish[2]); - const pm_call_node_t *receiver = (const pm_call_node_t *)call_node->receiver; + const pm_call_node_t *receiver = (const pm_call_node_t *) cast->receiver; ID method_id = pm_constant_id_lookup(scope_node, receiver->name); pm_compile_call(iseq, receiver, ret, popped, scope_node, method_id, NULL); } else { - ADD_INSNL(ret, &dummy_line_node, branchunless, lfinish[1]); - PM_COMPILE(call_node->receiver); + PUSH_INSNL(ret, location, branchunless, lfinish[1]); + PM_COMPILE(cast->receiver); } - if (explicit_receiver) { - PM_DUP; - } - - ADD_INSN3(ret, &dummy_line_node, defined, INT2FIX(DEFINED_METHOD), rb_id2sym(method_id), PUSH_VAL(DEFINED_METHOD)); + if (explicit_receiver) PUSH_INSN(ret, location, dup); + PUSH_INSN3(ret, location, defined, INT2FIX(DEFINED_METHOD), rb_id2sym(method_id), PUSH_VAL(DEFINED_METHOD)); } else { - PM_PUTSELF; - if (explicit_receiver) { - PM_DUP; - } - ADD_INSN3(ret, &dummy_line_node, defined, INT2FIX(DEFINED_FUNC), rb_id2sym(method_id), PUSH_VAL(DEFINED_METHOD)); + PUSH_INSN(ret, location, putself); + if (explicit_receiver) PUSH_INSN(ret, location, dup); + PUSH_INSN3(ret, location, defined, INT2FIX(DEFINED_FUNC), rb_id2sym(method_id), PUSH_VAL(DEFINED_METHOD)); } + return; } - case PM_YIELD_NODE: - PM_PUTNIL; - ADD_INSN3(ret, &dummy_line_node, defined, INT2FIX(DEFINED_YIELD), 0, - PUSH_VAL(DEFINED_YIELD)); + PUSH_INSN(ret, location, putnil); + PUSH_INSN3(ret, location, defined, INT2FIX(DEFINED_YIELD), 0, PUSH_VAL(DEFINED_YIELD)); return; case PM_SUPER_NODE: case PM_FORWARDING_SUPER_NODE: - PM_PUTNIL; - ADD_INSN3(ret, &dummy_line_node, defined, INT2FIX(DEFINED_ZSUPER), 0, - PUSH_VAL(DEFINED_ZSUPER)); + PUSH_INSN(ret, location, putnil); + PUSH_INSN3(ret, location, defined, INT2FIX(DEFINED_ZSUPER), 0, PUSH_VAL(DEFINED_ZSUPER)); return; case PM_CALL_AND_WRITE_NODE: case PM_CALL_OPERATOR_WRITE_NODE: @@ -3092,156 +3177,66 @@ pm_compile_defined_expr0(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *co } RUBY_ASSERT(dtype != DEFINED_NOT_DEFINED); - - ADD_INSN1(ret, &dummy_line_node, putobject, PUSH_VAL(dtype)); + PUSH_INSN1(ret, location, putobject, PUSH_VAL(dtype)); #undef PUSH_VAL } static void -pm_defined_expr(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, bool popped, pm_scope_node_t *scope_node, NODE dummy_line_node, int lineno, bool in_condition, LABEL **lfinish, bool explicit_receiver) +pm_defined_expr(rb_iseq_t *iseq, const pm_node_t *node, const pm_line_column_t *node_location, LINK_ANCHOR *const ret, bool popped, pm_scope_node_t *scope_node, bool in_condition, LABEL **lfinish, bool explicit_receiver) { LINK_ELEMENT *lcur = ret->last; - - pm_compile_defined_expr0(iseq, node, ret, popped, scope_node, dummy_line_node, lineno, in_condition, lfinish, false); + pm_compile_defined_expr0(iseq, node, node_location, ret, popped, scope_node, in_condition, lfinish, false); if (lfinish[1]) { - LABEL *lstart = NEW_LABEL(lineno); - LABEL *lend = NEW_LABEL(lineno); + LABEL *lstart = NEW_LABEL(node_location->line); + LABEL *lend = NEW_LABEL(node_location->line); struct rb_iseq_new_with_callback_callback_func *ifunc = rb_iseq_new_with_callback_new_callback(build_defined_rescue_iseq, NULL); - const rb_iseq_t *rescue = new_child_iseq_with_callback(iseq, ifunc, - rb_str_concat(rb_str_new2("defined guard in "), - ISEQ_BODY(iseq)->location.label), - iseq, ISEQ_TYPE_RESCUE, 0); + const rb_iseq_t *rescue = new_child_iseq_with_callback( + iseq, + ifunc, + rb_str_concat(rb_str_new2("defined guard in "), ISEQ_BODY(iseq)->location.label), + iseq, + ISEQ_TYPE_RESCUE, + 0 + ); lstart->rescued = LABEL_RESCUE_BEG; lend->rescued = LABEL_RESCUE_END; APPEND_LABEL(ret, lcur, lstart); - ADD_LABEL(ret, lend); + PUSH_LABEL(ret, lend); ADD_CATCH_ENTRY(CATCH_TYPE_RESCUE, lstart, lend, rescue, lfinish[1]); } } -void -pm_compile_defined_expr(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, bool popped, pm_scope_node_t *scope_node, NODE dummy_line_node, int lineno, bool in_condition) +static void +pm_compile_defined_expr(rb_iseq_t *iseq, const pm_node_t *node, const pm_line_column_t *node_location, LINK_ANCHOR *const ret, bool popped, pm_scope_node_t *scope_node, bool in_condition) { LABEL *lfinish[3]; LINK_ELEMENT *last = ret->last; - lfinish[0] = NEW_LABEL(lineno); + lfinish[0] = NEW_LABEL(node_location->line); lfinish[1] = 0; lfinish[2] = 0; if (!popped) { - pm_defined_expr(iseq, node, ret, popped, scope_node, dummy_line_node, lineno, in_condition, lfinish, false); + pm_defined_expr(iseq, node, node_location, ret, popped, scope_node, in_condition, lfinish, false); } if (lfinish[1]) { - ELEM_INSERT_NEXT(last, &new_insn_body(iseq, nd_line(&dummy_line_node), nd_node_id(&dummy_line_node), BIN(putnil), 0)->link); - PM_SWAP; - if (lfinish[2]) { - ADD_LABEL(ret, lfinish[2]); - } - PM_POP; - ADD_LABEL(ret, lfinish[1]); - - } - ADD_LABEL(ret, lfinish[0]); -} - -static void -pm_compile_call(rb_iseq_t *iseq, const pm_call_node_t *call_node, LINK_ANCHOR *const ret, bool popped, pm_scope_node_t *scope_node, ID method_id, LABEL *start) -{ - const pm_location_t *message_loc = &call_node->message_loc; - if (message_loc->start == NULL) message_loc = &call_node->base.location; - - const pm_line_column_t location = pm_newline_list_line_column(&scope_node->parser->newline_list, message_loc->start, scope_node->parser->start_line); - LABEL *else_label = NEW_LABEL(location.line); - LABEL *end_label = NEW_LABEL(location.line); - - if (PM_NODE_FLAG_P(call_node, PM_CALL_NODE_FLAGS_SAFE_NAVIGATION)) { - PUSH_INSN(ret, location, dup); - PUSH_INSNL(ret, location, branchnil, else_label); - } - - int flags = 0; - struct rb_callinfo_kwarg *kw_arg = NULL; - - int orig_argc = pm_setup_args(call_node->arguments, call_node->block, &flags, &kw_arg, iseq, ret, scope_node, &location); - const rb_iseq_t *block_iseq = NULL; - - if (call_node->block != NULL && PM_NODE_TYPE_P(call_node->block, PM_BLOCK_NODE)) { - // Scope associated with the block - pm_scope_node_t next_scope_node; - pm_scope_node_init(call_node->block, &next_scope_node, scope_node); - - block_iseq = NEW_CHILD_ISEQ(&next_scope_node, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, pm_node_line_number(scope_node->parser, call_node->block)); - pm_scope_node_destroy(&next_scope_node); - - if (ISEQ_BODY(block_iseq)->catch_table) { - ADD_CATCH_ENTRY(CATCH_TYPE_BREAK, start, end_label, block_iseq, end_label); - } - ISEQ_COMPILE_DATA(iseq)->current_block = block_iseq; - } - else { - if (PM_NODE_FLAG_P(call_node, PM_CALL_NODE_FLAGS_VARIABLE_CALL)) { - flags |= VM_CALL_VCALL; - } + ELEM_INSERT_NEXT(last, &new_insn_body(iseq, node_location->line, node_location->column, BIN(putnil), 0)->link); + PUSH_INSN(ret, *node_location, swap); - if (!flags) { - flags |= VM_CALL_ARGS_SIMPLE; - } - } - - if (PM_NODE_FLAG_P(call_node, PM_CALL_NODE_FLAGS_IGNORE_VISIBILITY)) { - flags |= VM_CALL_FCALL; - } + if (lfinish[2]) PUSH_LABEL(ret, lfinish[2]); + PUSH_INSN(ret, *node_location, pop); + PUSH_LABEL(ret, lfinish[1]); - if (!popped && PM_NODE_FLAG_P(call_node, PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE)) { - if (flags & VM_CALL_ARGS_BLOCKARG) { - PUSH_INSN1(ret, location, topn, INT2FIX(1)); - if (flags & VM_CALL_ARGS_SPLAT) { - PUSH_INSN1(ret, location, putobject, INT2FIX(-1)); - PUSH_SEND_WITH_FLAG(ret, location, idAREF, INT2FIX(1), INT2FIX(0)); - } - PUSH_INSN1(ret, location, setn, INT2FIX(orig_argc + 3)); - PUSH_INSN(ret, location, pop); - } - else if (flags & VM_CALL_ARGS_SPLAT) { - PUSH_INSN(ret, location, dup); - PUSH_INSN1(ret, location, putobject, INT2FIX(-1)); - PUSH_SEND_WITH_FLAG(ret, location, idAREF, INT2FIX(1), INT2FIX(0)); - PUSH_INSN1(ret, location, setn, INT2FIX(orig_argc + 2)); - PUSH_INSN(ret, location, pop); - } - else { - PUSH_INSN1(ret, location, setn, INT2FIX(orig_argc + 1)); - } } - if ((flags & VM_CALL_KW_SPLAT) && (flags & VM_CALL_ARGS_BLOCKARG) && !(flags & VM_CALL_KW_SPLAT_MUT)) { - PUSH_INSN(ret, location, splatkw); - } - - PUSH_SEND_R(ret, location, method_id, INT2FIX(orig_argc), block_iseq, INT2FIX(flags), kw_arg); - - if (PM_NODE_FLAG_P(call_node, PM_CALL_NODE_FLAGS_SAFE_NAVIGATION)) { - PUSH_INSNL(ret, location, jump, end_label); - PUSH_LABEL(ret, else_label); - } - - if (PM_NODE_FLAG_P(call_node, PM_CALL_NODE_FLAGS_SAFE_NAVIGATION) || (block_iseq && ISEQ_BODY(block_iseq)->catch_table)) { - PUSH_LABEL(ret, end_label); - } - - if (PM_NODE_FLAG_P(call_node, PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE) && !popped) { - PUSH_INSN(ret, location, pop); - } - - if (popped) PUSH_INSN(ret, location, pop); + PUSH_LABEL(ret, lfinish[0]); } // This is exactly the same as add_ensure_iseq, except it compiled @@ -4186,18 +4181,17 @@ pm_opt_aset_with_p(const rb_iseq_t *iseq, const pm_call_node_t *node) static void pm_compile_constant_read(rb_iseq_t *iseq, VALUE name, const pm_location_t *name_loc, LINK_ANCHOR *const ret, const pm_scope_node_t *scope_node) { - int lineno = pm_location_line_number(scope_node->parser, name_loc); - NODE dummy_line_node = generate_dummy_line_node(lineno, lineno); + const pm_line_column_t location = pm_newline_list_line_column(&scope_node->parser->newline_list, name_loc->start, scope_node->parser->start_line); if (ISEQ_COMPILE_DATA(iseq)->option->inline_const_cache) { ISEQ_BODY(iseq)->ic_size++; VALUE segments = rb_ary_new_from_args(1, name); - ADD_INSN1(ret, &dummy_line_node, opt_getconstant_path, segments); + PUSH_INSN1(ret, location, opt_getconstant_path, segments); } else { - PM_PUTNIL; - ADD_INSN1(ret, &dummy_line_node, putobject, Qtrue); - ADD_INSN1(ret, &dummy_line_node, getconstant, name); + PUSH_INSN(ret, location, putnil); + PUSH_INSN1(ret, location, putobject, Qtrue); + PUSH_INSN1(ret, location, getconstant, name); } } @@ -4246,16 +4240,15 @@ pm_constant_path_parts(const pm_node_t *node, const pm_scope_node_t *scope_node) static void pm_compile_constant_path(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const prefix, LINK_ANCHOR *const body, bool popped, pm_scope_node_t *scope_node) { - int lineno = pm_node_line_number(scope_node->parser, node); - NODE dummy_line_node = generate_dummy_line_node(lineno, lineno); + const pm_line_column_t location = pm_newline_list_line_column(&scope_node->parser->newline_list, node->location.start, scope_node->parser->start_line); switch (PM_NODE_TYPE(node)) { case PM_CONSTANT_READ_NODE: { const pm_constant_read_node_t *cast = (const pm_constant_read_node_t *) node; VALUE name = ID2SYM(pm_constant_id_lookup(scope_node, cast->name)); - ADD_INSN1(body, &dummy_line_node, putobject, Qtrue); - ADD_INSN1(body, &dummy_line_node, getconstant, name); + PUSH_INSN1(body, location, putobject, Qtrue); + PUSH_INSN1(body, location, getconstant, name); break; } case PM_CONSTANT_PATH_NODE: { @@ -4263,15 +4256,15 @@ pm_compile_constant_path(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *co VALUE name = ID2SYM(pm_constant_id_lookup(scope_node, ((const pm_constant_read_node_t *) cast->child)->name)); if (cast->parent == NULL) { - ADD_INSN(body, &dummy_line_node, pop); - ADD_INSN1(body, &dummy_line_node, putobject, rb_cObject); - ADD_INSN1(body, &dummy_line_node, putobject, Qtrue); - ADD_INSN1(body, &dummy_line_node, getconstant, name); + PUSH_INSN(body, location, pop); + PUSH_INSN1(body, location, putobject, rb_cObject); + PUSH_INSN1(body, location, putobject, Qtrue); + PUSH_INSN1(body, location, getconstant, name); } else { pm_compile_constant_path(iseq, cast->parent, prefix, body, false, scope_node); - ADD_INSN1(body, &dummy_line_node, putobject, Qfalse); - ADD_INSN1(body, &dummy_line_node, getconstant, name); + PUSH_INSN1(body, location, putobject, Qfalse); + PUSH_INSN1(body, location, getconstant, name); } break; } @@ -5605,31 +5598,34 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret, return; } case PM_DEF_NODE: { - pm_def_node_t *def_node = (pm_def_node_t *) node; - ID method_name = pm_constant_id_lookup(scope_node, def_node->name); + const pm_def_node_t *cast = (const pm_def_node_t *) node; + ID method_name = pm_constant_id_lookup(scope_node, cast->name); pm_scope_node_t next_scope_node; - pm_scope_node_init((pm_node_t *)def_node, &next_scope_node, scope_node); - rb_iseq_t *method_iseq = NEW_ISEQ(&next_scope_node, rb_id2str(method_name), ISEQ_TYPE_METHOD, lineno); + pm_scope_node_init((const pm_node_t *) cast, &next_scope_node, scope_node); + rb_iseq_t *method_iseq = NEW_ISEQ(&next_scope_node, rb_id2str(method_name), ISEQ_TYPE_METHOD, location.line); pm_scope_node_destroy(&next_scope_node); - if (def_node->receiver) { - PM_COMPILE_NOT_POPPED(def_node->receiver); - ADD_INSN2(ret, &dummy_line_node, definesmethod, ID2SYM(method_name), method_iseq); + if (cast->receiver) { + PM_COMPILE_NOT_POPPED(cast->receiver); + PUSH_INSN2(ret, location, definesmethod, ID2SYM(method_name), method_iseq); } else { - ADD_INSN2(ret, &dummy_line_node, definemethod, ID2SYM(method_name), method_iseq); + PUSH_INSN2(ret, location, definemethod, ID2SYM(method_name), method_iseq); } - RB_OBJ_WRITTEN(iseq, Qundef, (VALUE)method_iseq); + RB_OBJ_WRITTEN(iseq, Qundef, (VALUE) method_iseq); if (!popped) { - ADD_INSN1(ret, &dummy_line_node, putobject, ID2SYM(method_name)); + PUSH_INSN1(ret, location, putobject, ID2SYM(method_name)); } + return; } case PM_DEFINED_NODE: { - pm_defined_node_t *defined_node = (pm_defined_node_t *)node; - pm_compile_defined_expr(iseq, defined_node->value, ret, popped, scope_node, dummy_line_node, lineno, false); + // defined?(a) + // ^^^^^^^^^^^ + const pm_defined_node_t *cast = (const pm_defined_node_t *) node; + pm_compile_defined_expr(iseq, cast->value, &location, ret, popped, scope_node, false); return; } case PM_EMBEDDED_STATEMENTS_NODE: { |
