summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--prism_compile.c134
1 files changed, 64 insertions, 70 deletions
diff --git a/prism_compile.c b/prism_compile.c
index 4592ca884d..a72265d1b1 100644
--- a/prism_compile.c
+++ b/prism_compile.c
@@ -4861,7 +4861,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
// This is the label where all of the when clauses will jump to if they
// have matched and are done executing their bodies.
- LABEL *end_label = NEW_LABEL(lineno);
+ LABEL *end_label = NEW_LABEL(location.line);
// If we have a predicate on this case statement, then it's going to
// compare all of the various when clauses to the predicate. If we
@@ -4877,15 +4877,15 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
int clause_lineno = pm_node_line_number(parser, (const pm_node_t *) clause);
LABEL *label = NEW_LABEL(clause_lineno);
- ADD_LABEL(body_seq, label);
+ PUSH_LABEL(body_seq, label);
if (clause->statements != NULL) {
pm_compile_node(iseq, (const pm_node_t *) clause->statements, body_seq, popped, scope_node);
}
else if (!popped) {
- ADD_INSN(body_seq, &dummy_line_node, putnil);
+ PUSH_INSN(body_seq, location, putnil);
}
- ADD_INSNL(body_seq, &dummy_line_node, jump, end_label);
+ PUSH_INSNL(body_seq, location, jump, end_label);
// Compile each of the conditions for the when clause into the
// cond_seq. Each one should have a unique condition and should
@@ -4894,15 +4894,15 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
const pm_node_t *condition = conditions->nodes[condition_index];
if (PM_NODE_TYPE_P(condition, PM_SPLAT_NODE)) {
- ADD_INSN(cond_seq, &dummy_line_node, putnil);
+ PUSH_INSN(cond_seq, location, putnil);
pm_compile_node(iseq, condition, cond_seq, false, scope_node);
- ADD_INSN1(cond_seq, &dummy_line_node, checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_WHEN | VM_CHECKMATCH_ARRAY));
- ADD_INSNL(cond_seq, &dummy_line_node, branchif, label);
+ PUSH_INSN1(cond_seq, location, checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_WHEN | VM_CHECKMATCH_ARRAY));
+ PUSH_INSNL(cond_seq, location, branchif, label);
}
else {
LABEL *next_label = NEW_LABEL(pm_node_line_number(parser, condition));
pm_compile_branch_condition(iseq, cond_seq, condition, label, next_label, false, scope_node);
- ADD_LABEL(cond_seq, next_label);
+ PUSH_LABEL(cond_seq, next_label);
}
}
}
@@ -4912,18 +4912,18 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
pm_compile_node(iseq, (const pm_node_t *) cast->consequent, cond_seq, popped, scope_node);
}
else if (!popped) {
- ADD_INSN(cond_seq, &dummy_line_node, putnil);
+ PUSH_INSN(cond_seq, location, putnil);
}
// Finally, jump to the end label if none of the other conditions
// have matched.
- ADD_INSNL(cond_seq, &dummy_line_node, jump, end_label);
+ PUSH_INSNL(cond_seq, location, jump, end_label);
ADD_SEQ(ret, cond_seq);
}
else {
// This is the label where everything will fall into if none of the
// conditions matched.
- LABEL *else_label = NEW_LABEL(lineno);
+ LABEL *else_label = NEW_LABEL(location.line);
// It's possible for us to speed up the case node by using a
// dispatch hash. This is a hash that maps the conditions of the
@@ -4948,7 +4948,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
const pm_when_node_t *clause = (const pm_when_node_t *) conditions->nodes[clause_index];
const pm_node_list_t *conditions = &clause->conditions;
- LABEL *label = NEW_LABEL(lineno);
+ LABEL *label = NEW_LABEL(location.line);
// Compile each of the conditions for the when clause into the
// cond_seq. Each one should have a unique comparison that then
@@ -4964,42 +4964,42 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
}
if (PM_NODE_TYPE_P(condition, PM_SPLAT_NODE)) {
- ADD_INSN(cond_seq, &dummy_line_node, dup);
+ PUSH_INSN(cond_seq, location, dup);
pm_compile_node(iseq, condition, cond_seq, false, scope_node);
- ADD_INSN1(cond_seq, &dummy_line_node, checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_CASE | VM_CHECKMATCH_ARRAY));
+ PUSH_INSN1(cond_seq, location, checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_CASE | VM_CHECKMATCH_ARRAY));
}
else {
if (PM_NODE_TYPE_P(condition, PM_STRING_NODE)) {
const pm_string_node_t *string = (const pm_string_node_t *) condition;
VALUE value = rb_fstring(parse_string_encoded(scope_node, (const pm_node_t *) string, &string->unescaped));
- ADD_INSN1(cond_seq, &dummy_line_node, putobject, value);
+ PUSH_INSN1(cond_seq, location, putobject, value);
}
else {
pm_compile_node(iseq, condition, cond_seq, false, scope_node);
}
- ADD_INSN1(cond_seq, &dummy_line_node, topn, INT2FIX(1));
- ADD_SEND_WITH_FLAG(cond_seq, &dummy_line_node, idEqq, INT2NUM(1), INT2FIX(VM_CALL_FCALL | VM_CALL_ARGS_SIMPLE));
+ PUSH_INSN1(cond_seq, location, topn, INT2FIX(1));
+ PUSH_SEND_WITH_FLAG(cond_seq, location, idEqq, INT2NUM(1), INT2FIX(VM_CALL_FCALL | VM_CALL_ARGS_SIMPLE));
}
- ADD_INSNL(cond_seq, &dummy_line_node, branchif, label);
+ PUSH_INSNL(cond_seq, location, branchif, label);
}
// Now, add the label to the body and compile the body of the
// when clause. This involves popping the predicate, compiling
// the statements to be executed, and then compiling a jump to
// the end of the case node.
- ADD_LABEL(body_seq, label);
- ADD_INSN(body_seq, &dummy_line_node, pop);
+ PUSH_LABEL(body_seq, label);
+ PUSH_INSN(body_seq, location, pop);
if (clause->statements != NULL) {
pm_compile_node(iseq, (const pm_node_t *) clause->statements, body_seq, popped, scope_node);
}
else if (!popped) {
- ADD_INSN(body_seq, &dummy_line_node, putnil);
+ PUSH_INSN(body_seq, location, putnil);
}
- ADD_INSNL(body_seq, &dummy_line_node, jump, end_label);
+ PUSH_INSNL(body_seq, location, jump, end_label);
}
// Now that we have compiled the conditions and the bodies of the
@@ -5012,7 +5012,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
// optimization.
if (dispatch != Qundef) {
PM_DUP;
- ADD_INSN2(ret, &dummy_line_node, opt_case_dispatch, dispatch, else_label);
+ PUSH_INSN2(ret, location, opt_case_dispatch, dispatch, else_label);
LABEL_REF(else_label);
}
@@ -5020,21 +5020,21 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
// Compile either the explicit else clause or an implicit else
// clause.
- ADD_LABEL(ret, else_label);
- PM_POP;
+ PUSH_LABEL(ret, else_label);
+ PUSH_INSN(ret, location, pop);
if (cast->consequent != NULL) {
PM_COMPILE((const pm_node_t *) cast->consequent);
}
else if (!popped) {
- PM_PUTNIL;
+ PUSH_INSN(ret, location, putnil);
}
- ADD_INSNL(ret, &dummy_line_node, jump, end_label);
+ PUSH_INSNL(ret, location, jump, end_label);
}
ADD_SEQ(ret, body_seq);
- ADD_LABEL(ret, end_label);
+ PUSH_LABEL(ret, end_label);
return;
}
@@ -5060,12 +5060,12 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
// This label is used to indicate the end of the entire node. It is
// jumped to after the entire stack is cleaned up.
- LABEL *end_label = NEW_LABEL(lineno);
+ LABEL *end_label = NEW_LABEL(location.line);
// This label is used as the fallback for the case match. If no match is
// found, then we jump to this label. This is either an `else` clause or
// an error handler.
- LABEL *else_label = NEW_LABEL(lineno);
+ LABEL *else_label = NEW_LABEL(location.line);
// We're going to use this to uniquely identify each branch so that we
// can track coverage information.
@@ -5080,14 +5080,14 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
// First, we're going to push a bunch of stuff onto the stack that is
// going to serve as our scratch space.
if (in_single_pattern) {
- ADD_INSN(ret, &dummy_line_node, putnil); // key error key
- ADD_INSN(ret, &dummy_line_node, putnil); // key error matchee
- ADD_INSN1(ret, &dummy_line_node, putobject, Qfalse); // key error?
- ADD_INSN(ret, &dummy_line_node, putnil); // error string
+ PUSH_INSN(ret, location, putnil); // key error key
+ PUSH_INSN(ret, location, putnil); // key error matchee
+ PUSH_INSN1(ret, location, putobject, Qfalse); // key error?
+ PUSH_INSN(ret, location, putnil); // error string
}
// Now we're going to compile the value to match against.
- ADD_INSN(ret, &dummy_line_node, putnil); // deconstruct cache
+ PUSH_INSN(ret, location, putnil); // deconstruct cache
PM_COMPILE_NOT_POPPED(cast->predicate);
// Next, we'll loop through every in clause and compile its body into
@@ -5099,20 +5099,16 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
RUBY_ASSERT(PM_NODE_TYPE_P(condition, PM_IN_NODE));
const pm_in_node_t *in_node = (const pm_in_node_t *) condition;
-
- pm_line_node_t in_line;
- pm_line_node(&in_line, scope_node, (const pm_node_t *) in_node);
-
- pm_line_node_t pattern_line;
- pm_line_node(&pattern_line, scope_node, (const pm_node_t *) in_node->pattern);
+ const pm_line_column_t in_location = pm_newline_list_line_column(&parser->newline_list, in_node->base.location.start, parser->start_line);
+ const pm_line_column_t pattern_location = pm_newline_list_line_column(&parser->newline_list, in_node->pattern->location.start, parser->start_line);
if (branch_id) {
- ADD_INSN(body_seq, &in_line.node, putnil);
+ PUSH_INSN(body_seq, in_location, putnil);
}
- LABEL *body_label = NEW_LABEL(in_line.lineno);
- ADD_LABEL(body_seq, body_label);
- ADD_INSN1(body_seq, &in_line.node, adjuststack, INT2FIX(in_single_pattern ? 6 : 2));
+ LABEL *body_label = NEW_LABEL(in_location.line);
+ PUSH_LABEL(body_seq, body_label);
+ PUSH_INSN1(body_seq, in_location, adjuststack, INT2FIX(in_single_pattern ? 6 : 2));
// TODO: We need to come back to this and enable trace branch
// coverage. At the moment we can't call this function because it
@@ -5124,15 +5120,15 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
PM_COMPILE_INTO_ANCHOR(body_seq, (const pm_node_t *) in_node->statements);
}
else if (!popped) {
- ADD_INSN(body_seq, &in_line.node, putnil);
+ PUSH_INSN(body_seq, in_location, putnil);
}
- ADD_INSNL(body_seq, &in_line.node, jump, end_label);
- LABEL *next_pattern_label = NEW_LABEL(pattern_line.lineno);
+ PUSH_INSNL(body_seq, in_location, jump, end_label);
+ LABEL *next_pattern_label = NEW_LABEL(pattern_location.line);
- ADD_INSN(cond_seq, &pattern_line.node, dup);
+ PUSH_INSN(cond_seq, pattern_location, dup);
pm_compile_pattern(iseq, scope_node, in_node->pattern, cond_seq, body_label, next_pattern_label, in_single_pattern, false, true, 2);
- ADD_LABEL(cond_seq, next_pattern_label);
+ PUSH_LABEL(cond_seq, next_pattern_label);
LABEL_UNREMOVABLE(next_pattern_label);
}
@@ -5142,9 +5138,9 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
// error).
const pm_else_node_t *else_node = (const pm_else_node_t *) cast->consequent;
- ADD_LABEL(cond_seq, else_label);
- ADD_INSN(cond_seq, &dummy_line_node, pop);
- ADD_INSN(cond_seq, &dummy_line_node, pop);
+ PUSH_LABEL(cond_seq, else_label);
+ PUSH_INSN(cond_seq, location, pop);
+ PUSH_INSN(cond_seq, location, pop);
// TODO: trace branch coverage
// add_trace_branch_coverage(iseq, cond_seq, cast->consequent, branch_id, "else", branches);
@@ -5153,19 +5149,17 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
PM_COMPILE_INTO_ANCHOR(cond_seq, (const pm_node_t *) else_node->statements);
}
else if (!popped) {
- ADD_INSN(cond_seq, &dummy_line_node, putnil);
+ PUSH_INSN(cond_seq, location, putnil);
}
- ADD_INSNL(cond_seq, &dummy_line_node, jump, end_label);
- ADD_INSN(cond_seq, &dummy_line_node, putnil);
- if (popped) {
- ADD_INSN(cond_seq, &dummy_line_node, putnil);
- }
+ PUSH_INSNL(cond_seq, location, jump, end_label);
+ PUSH_INSN(cond_seq, location, putnil);
+ if (popped) PUSH_INSN(cond_seq, location, putnil);
}
else {
// Otherwise, if we do not have an `else` clause, we will compile in
// the code to handle raising an appropriate error.
- ADD_LABEL(cond_seq, else_label);
+ PUSH_LABEL(cond_seq, else_label);
// TODO: trace branch coverage
// add_trace_branch_coverage(iseq, cond_seq, orig_node, branch_id, "else", branches);
@@ -5174,16 +5168,16 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
pm_compile_pattern_error_handler(iseq, scope_node, node, cond_seq, end_label, popped);
}
else {
- ADD_INSN1(cond_seq, &dummy_line_node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
- ADD_INSN1(cond_seq, &dummy_line_node, putobject, rb_eNoMatchingPatternError);
- ADD_INSN1(cond_seq, &dummy_line_node, topn, INT2FIX(2));
- ADD_SEND(cond_seq, &dummy_line_node, id_core_raise, INT2FIX(2));
+ PUSH_INSN1(cond_seq, location, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
+ PUSH_INSN1(cond_seq, location, putobject, rb_eNoMatchingPatternError);
+ PUSH_INSN1(cond_seq, location, topn, INT2FIX(2));
+ PUSH_SEND(cond_seq, location, id_core_raise, INT2FIX(2));
- ADD_INSN1(cond_seq, &dummy_line_node, adjuststack, INT2FIX(3));
- if (!popped) ADD_INSN(cond_seq, &dummy_line_node, putnil);
- ADD_INSNL(cond_seq, &dummy_line_node, jump, end_label);
- ADD_INSN1(cond_seq, &dummy_line_node, dupn, INT2FIX(1));
- if (popped) ADD_INSN(cond_seq, &dummy_line_node, putnil);
+ PUSH_INSN1(cond_seq, location, adjuststack, INT2FIX(3));
+ if (!popped) PUSH_INSN(cond_seq, location, putnil);
+ PUSH_INSNL(cond_seq, location, jump, end_label);
+ PUSH_INSN1(cond_seq, location, dupn, INT2FIX(1));
+ if (popped) PUSH_INSN(cond_seq, location, putnil);
}
}
@@ -5192,7 +5186,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
// entire sequence with the end label.
ADD_SEQ(ret, cond_seq);
ADD_SEQ(ret, body_seq);
- ADD_LABEL(ret, end_label);
+ PUSH_LABEL(ret, end_label);
return;
}