summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Newton <kddnewton@gmail.com>2024-04-04 11:48:23 -0400
committerKevin Newton <kddnewton@gmail.com>2024-04-04 14:14:55 -0400
commit2d523c27cff12bc9ed85ecc3197b4777da855b4a (patch)
tree2308afc909cd32a8cf53bbfa6eb398a6d51c898b
parent3410387096e763b742674f8f0c53a5d095a31974 (diff)
[PRISM] Remove dummy_line_node usage from defined expressions
-rw-r--r--prism_compile.c488
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: {