[YARP] Until Node, minor cleanup (#8325)

* Remove conditional from yp_compile_if

* Extracted yp_compile_while, compile UntilNode

* Small checks for body / value that could be empty
This commit is contained in:
Jemma Issroff 2023-08-29 17:17:08 -04:00 коммит произвёл GitHub
Родитель 80dc570a45
Коммит 3151d7876f
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
1 изменённых файлов: 114 добавлений и 90 удалений

Просмотреть файл

@ -197,26 +197,7 @@ again:
}
static void
yp_compile_if(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, const char * src, bool popped, yp_compile_context_t *compile_context) {
yp_parser_t *parser = compile_context->parser;
yp_statements_node_t *node_body;
yp_node_t *node_else;
yp_node_t *predicate;
if (node->type == YP_NODE_IF_NODE) {
yp_if_node_t *if_node = (yp_if_node_t *)node;
node_body = if_node->statements;
node_else = if_node->consequent;
predicate = if_node->predicate;
}
else {
yp_unless_node_t *unless_node = (yp_unless_node_t *)node;
node_body = unless_node->statements;
node_else = (yp_node_t *)(unless_node->consequent);
predicate = unless_node->predicate;
}
const int line = (int)yp_newline_list_line_column(&(parser->newline_list), node->location.start).line;
yp_compile_if(rb_iseq_t *iseq, const int line, yp_statements_node_t *node_body, yp_node_t *node_else, yp_node_t *predicate, LINK_ANCHOR *const ret, const char * src, bool popped, yp_compile_context_t *compile_context) {
NODE line_node = generate_dummy_line_node(line, line);
DECL_ANCHOR(cond_seq);
@ -279,6 +260,84 @@ yp_compile_if(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, co
return;
}
static void
yp_compile_while(rb_iseq_t *iseq, int lineno, yp_node_flags_t flags, enum yp_node_type type, yp_statements_node_t *statements, yp_node_t *predicate, LINK_ANCHOR *const ret, const char * src, bool popped, yp_compile_context_t *compile_context)
{
NODE dummy_line_node = generate_dummy_line_node(lineno, lineno);
LABEL *prev_start_label = ISEQ_COMPILE_DATA(iseq)->start_label;
LABEL *prev_end_label = ISEQ_COMPILE_DATA(iseq)->end_label;
LABEL *prev_redo_label = ISEQ_COMPILE_DATA(iseq)->redo_label;
int prev_loopval_popped = ISEQ_COMPILE_DATA(iseq)->loopval_popped;
// TODO: Deal with ensures in here
LABEL *next_label = ISEQ_COMPILE_DATA(iseq)->start_label = NEW_LABEL(lineno); /* next */
LABEL *redo_label = ISEQ_COMPILE_DATA(iseq)->redo_label = NEW_LABEL(lineno); /* redo */
LABEL *break_label = ISEQ_COMPILE_DATA(iseq)->end_label = NEW_LABEL(lineno); /* break */
LABEL *end_label = NEW_LABEL(lineno);
LABEL *adjust_label = NEW_LABEL(lineno);
LABEL *next_catch_label = NEW_LABEL(lineno);
LABEL *tmp_label = NULL;
ISEQ_COMPILE_DATA(iseq)->loopval_popped = 0;
// begin; end while true
if (flags & YP_LOOP_FLAGS_BEGIN_MODIFIER) {
ADD_INSNL(ret, &dummy_line_node, jump, next_label);
}
else {
// while true; end
tmp_label = NEW_LABEL(lineno);
ADD_INSNL(ret, &dummy_line_node, jump, tmp_label);
}
ADD_LABEL(ret, adjust_label);
ADD_INSN(ret, &dummy_line_node, putnil);
ADD_LABEL(ret, next_catch_label);
ADD_INSN(ret, &dummy_line_node, pop);
ADD_INSNL(ret, &dummy_line_node, jump, next_label);
if (tmp_label) ADD_LABEL(ret, tmp_label);
ADD_LABEL(ret, redo_label);
if (statements) {
yp_compile_node(iseq, (yp_node_t *)statements, ret, src, Qtrue, compile_context);
}
ADD_LABEL(ret, next_label);
if (type == YP_NODE_WHILE_NODE) {
yp_compile_branch_condition(iseq, ret, predicate, redo_label, end_label, src, popped, compile_context);
}
else if (type == YP_NODE_UNTIL_NODE) {
yp_compile_branch_condition(iseq, ret, predicate, end_label, redo_label, src, popped, compile_context);
}
ADD_LABEL(ret, end_label);
ADD_ADJUST_RESTORE(ret, adjust_label);
ADD_INSN(ret, &dummy_line_node, putnil);
ADD_LABEL(ret, break_label);
if (popped) {
ADD_INSN(ret, &dummy_line_node, pop);
}
ADD_CATCH_ENTRY(CATCH_TYPE_BREAK, redo_label, break_label, NULL,
break_label);
ADD_CATCH_ENTRY(CATCH_TYPE_NEXT, redo_label, break_label, NULL,
next_catch_label);
ADD_CATCH_ENTRY(CATCH_TYPE_REDO, redo_label, break_label, NULL,
ISEQ_COMPILE_DATA(iseq)->redo_label);
ISEQ_COMPILE_DATA(iseq)->start_label = prev_start_label;
ISEQ_COMPILE_DATA(iseq)->end_label = prev_end_label;
ISEQ_COMPILE_DATA(iseq)->redo_label = prev_redo_label;
ISEQ_COMPILE_DATA(iseq)->loopval_popped = prev_loopval_popped;
return;
}
static rb_iseq_t *
yp_new_child_iseq(rb_iseq_t *iseq, yp_scope_node_t * node, yp_parser_t *parser,
VALUE name, const rb_iseq_t *parent, enum rb_iseq_type type, int line_no)
@ -329,7 +388,8 @@ yp_compile_class_path(LINK_ANCHOR *const ret, rb_iseq_t *iseq, const yp_node_t *
* compile_context - Stores parser and local information
*/
static void
yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, const char * src, bool popped, yp_compile_context_t *compile_context) {
yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret, const char * src, bool popped, yp_compile_context_t *compile_context)
{
yp_parser_t *parser = compile_context->parser;
yp_newline_list_t newline_list = parser->newline_list;
int lineno = (int)yp_newline_list_line_column(&newline_list, node->location.start).line;
@ -398,7 +458,9 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
case YP_NODE_ASSOC_NODE: {
yp_assoc_node_t *assoc_node = (yp_assoc_node_t *) node;
yp_compile_node(iseq, assoc_node->key, ret, src, popped, compile_context);
yp_compile_node(iseq, assoc_node->value, ret, src, popped, compile_context);
if (assoc_node->value) {
yp_compile_node(iseq, assoc_node->value, ret, src, popped, compile_context);
}
return;
}
case YP_NODE_ASSOC_SPLAT_NODE: {
@ -703,7 +765,13 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
return;
}
case YP_NODE_IF_NODE: {
yp_compile_if(iseq, node, ret, src, popped, compile_context);
const int line = (int)yp_newline_list_line_column(&(parser->newline_list), node->location.start).line;
yp_if_node_t *if_node = (yp_if_node_t *)node;
yp_statements_node_t *node_body = if_node->statements;
yp_node_t *node_else = if_node->consequent;
yp_node_t *predicate = if_node->predicate;
yp_compile_if(iseq, line, node_body, node_else, predicate, ret, src, popped, compile_context);
return;
}
case YP_NODE_IMAGINARY_NODE: {
@ -1118,7 +1186,9 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
ADD_INSN (ret, &dummy_line_node, nop);
ADD_LABEL(ret, start);
yp_compile_node(iseq, (yp_node_t *)(scope_node->body), ret, src, popped, &scope_compile_context);
if (scope_node->body) {
yp_compile_node(iseq, (yp_node_t *)(scope_node->body), ret, src, popped, &scope_compile_context);
}
ADD_LABEL(ret, end);
ADD_TRACE(ret, RUBY_EVENT_B_RETURN);
@ -1234,77 +1304,31 @@ yp_compile_node(rb_iseq_t *iseq, const yp_node_t *node, LINK_ANCHOR *const ret,
return;
}
case YP_NODE_UNLESS_NODE: {
yp_compile_if(iseq, node, ret, src, popped, compile_context);
const int line = (int)yp_newline_list_line_column(&(parser->newline_list), node->location.start).line;
yp_unless_node_t *unless_node = (yp_unless_node_t *)node;
yp_statements_node_t *node_body = unless_node->statements;
yp_node_t *node_else = (yp_node_t *)(unless_node->consequent);
yp_node_t *predicate = unless_node->predicate;
yp_compile_if(iseq, line, node_body, node_else, predicate, ret, src, popped, compile_context);
return;
}
case YP_NODE_UNTIL_NODE: {
yp_until_node_t *until_node = (yp_until_node_t *)node;
yp_statements_node_t *statements = until_node->statements;
yp_node_t *predicate = until_node->predicate;
yp_node_flags_t flags = node->flags;
yp_compile_while(iseq, lineno, flags, node->type, statements, predicate, ret, src, popped, compile_context);
return;
}
case YP_NODE_WHILE_NODE: {
yp_while_node_t *while_node = (yp_while_node_t *)node;
yp_statements_node_t *statements = while_node->statements;
yp_node_t *predicate = while_node->predicate;
yp_node_flags_t flags = node->flags;
LABEL *prev_start_label = ISEQ_COMPILE_DATA(iseq)->start_label;
LABEL *prev_end_label = ISEQ_COMPILE_DATA(iseq)->end_label;
LABEL *prev_redo_label = ISEQ_COMPILE_DATA(iseq)->redo_label;
int prev_loopval_popped = ISEQ_COMPILE_DATA(iseq)->loopval_popped;
// TODO: Deal with ensures in here
LABEL *next_label = ISEQ_COMPILE_DATA(iseq)->start_label = NEW_LABEL(lineno); /* next */
LABEL *redo_label = ISEQ_COMPILE_DATA(iseq)->redo_label = NEW_LABEL(lineno); /* redo */
LABEL *break_label = ISEQ_COMPILE_DATA(iseq)->end_label = NEW_LABEL(lineno); /* break */
LABEL *end_label = NEW_LABEL(lineno);
LABEL *adjust_label = NEW_LABEL(lineno);
LABEL *next_catch_label = NEW_LABEL(lineno);
LABEL *tmp_label = NULL;
ISEQ_COMPILE_DATA(iseq)->loopval_popped = 0;
// begin; end while true
if (while_node->base.flags & YP_LOOP_FLAGS_BEGIN_MODIFIER) {
ADD_INSNL(ret, &dummy_line_node, jump, next_label);
}
else {
// while true; end
tmp_label = NEW_LABEL(lineno);
ADD_INSNL(ret, &dummy_line_node, jump, tmp_label);
}
ADD_LABEL(ret, adjust_label);
ADD_INSN(ret, &dummy_line_node, putnil);
ADD_LABEL(ret, next_catch_label);
ADD_INSN(ret, &dummy_line_node, pop);
ADD_INSNL(ret, &dummy_line_node, jump, next_label);
if (tmp_label) ADD_LABEL(ret, tmp_label);
ADD_LABEL(ret, redo_label);
if (while_node->statements) {
yp_compile_node(iseq, (yp_node_t *)while_node->statements, ret, src, Qfalse, compile_context);
}
ADD_LABEL(ret, next_label);
yp_compile_branch_condition(iseq, ret, while_node->predicate, redo_label, end_label, src, popped, compile_context);
ADD_LABEL(ret, end_label);
ADD_ADJUST_RESTORE(ret, adjust_label);
ADD_INSN(ret, &dummy_line_node, putnil);
ADD_LABEL(ret, break_label);
if (popped) {
ADD_INSN(ret, &dummy_line_node, pop);
}
ADD_CATCH_ENTRY(CATCH_TYPE_BREAK, redo_label, break_label, NULL,
break_label);
ADD_CATCH_ENTRY(CATCH_TYPE_NEXT, redo_label, break_label, NULL,
next_catch_label);
ADD_CATCH_ENTRY(CATCH_TYPE_REDO, redo_label, break_label, NULL,
ISEQ_COMPILE_DATA(iseq)->redo_label);
ISEQ_COMPILE_DATA(iseq)->start_label = prev_start_label;
ISEQ_COMPILE_DATA(iseq)->end_label = prev_end_label;
ISEQ_COMPILE_DATA(iseq)->redo_label = prev_redo_label;
ISEQ_COMPILE_DATA(iseq)->loopval_popped = prev_loopval_popped;
yp_compile_while(iseq, lineno, flags, node->type, statements, predicate, ret, src, popped, compile_context);
return;
}
case YP_NODE_X_STRING_NODE: {