[PRISM] Use redundant return flag

This commit is contained in:
Kevin Newton 2024-04-26 14:22:34 -04:00
parent 9688093124
commit 46480e3042
3 changed files with 51 additions and 44 deletions

View File

@ -7389,53 +7389,63 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
const pm_return_node_t *cast = (const pm_return_node_t *) node;
const pm_arguments_node_t *arguments = cast->arguments;
enum rb_iseq_type type = ISEQ_BODY(iseq)->type;
LABEL *splabel = 0;
const rb_iseq_t *parent_iseq = iseq;
enum rb_iseq_type parent_type = ISEQ_BODY(parent_iseq)->type;
while (parent_type == ISEQ_TYPE_RESCUE || parent_type == ISEQ_TYPE_ENSURE) {
if (!(parent_iseq = ISEQ_BODY(parent_iseq)->parent_iseq)) break;
parent_type = ISEQ_BODY(parent_iseq)->type;
}
switch (parent_type) {
case ISEQ_TYPE_TOP:
case ISEQ_TYPE_MAIN:
if (PM_NODE_FLAG_P(cast, PM_RETURN_NODE_FLAGS_REDUNDANT)) {
if (arguments) {
rb_warn("argument of top-level return is ignored");
PM_COMPILE_NOT_POPPED((const pm_node_t *) arguments);
}
if (parent_iseq == iseq) {
type = ISEQ_TYPE_METHOD;
else {
PUSH_INSN(ret, location, putnil);
}
break;
default:
break;
}
if (type == ISEQ_TYPE_METHOD) {
splabel = NEW_LABEL(0);
PUSH_LABEL(ret, splabel);
PUSH_ADJUST(ret, location, 0);
}
if (arguments) {
PM_COMPILE_NOT_POPPED((const pm_node_t *) arguments);
}
else {
PUSH_INSN(ret, location, putnil);
}
enum rb_iseq_type type = ISEQ_BODY(iseq)->type;
LABEL *splabel = 0;
if (type == ISEQ_TYPE_METHOD && can_add_ensure_iseq(iseq)) {
pm_add_ensure_iseq(ret, iseq, 1, scope_node);
PUSH_TRACE(ret, RUBY_EVENT_RETURN);
PUSH_INSN(ret, location, leave);
PUSH_ADJUST_RESTORE(ret, splabel);
if (!popped) PUSH_INSN(ret, location, putnil);
}
else {
PUSH_INSN1(ret, location, throw, INT2FIX(TAG_RETURN));
if (popped) PUSH_INSN(ret, location, pop);
const rb_iseq_t *parent_iseq = iseq;
enum rb_iseq_type parent_type = ISEQ_BODY(parent_iseq)->type;
while (parent_type == ISEQ_TYPE_RESCUE || parent_type == ISEQ_TYPE_ENSURE) {
if (!(parent_iseq = ISEQ_BODY(parent_iseq)->parent_iseq)) break;
parent_type = ISEQ_BODY(parent_iseq)->type;
}
switch (parent_type) {
case ISEQ_TYPE_TOP:
case ISEQ_TYPE_MAIN:
if (arguments) {
rb_warn("argument of top-level return is ignored");
}
if (parent_iseq == iseq) {
type = ISEQ_TYPE_METHOD;
}
break;
default:
break;
}
if (type == ISEQ_TYPE_METHOD) {
splabel = NEW_LABEL(0);
PUSH_LABEL(ret, splabel);
PUSH_ADJUST(ret, location, 0);
}
if (arguments) {
PM_COMPILE_NOT_POPPED((const pm_node_t *) arguments);
}
else {
PUSH_INSN(ret, location, putnil);
}
if (type == ISEQ_TYPE_METHOD && can_add_ensure_iseq(iseq)) {
pm_add_ensure_iseq(ret, iseq, 1, scope_node);
PUSH_TRACE(ret, RUBY_EVENT_RETURN);
PUSH_INSN(ret, location, leave);
PUSH_ADJUST_RESTORE(ret, splabel);
if (!popped) PUSH_INSN(ret, location, putnil);
}
else {
PUSH_INSN1(ret, location, throw, INT2FIX(TAG_RETURN));
if (popped) PUSH_INSN(ret, location, pop);
}
}
return;

View File

@ -19,8 +19,6 @@ MSpec.register(:exclude, "Regexps with encoding modifiers preserves UTF-8 as /u
MSpec.register(:exclude, "A Symbol literal raises an SyntaxError at parse time when Symbol with invalid bytes")
## Core
MSpec.register(:exclude, "TracePoint#inspect returns a String showing the event, method, path and line for a :return event")
MSpec.register(:exclude, "TracePoint.new includes multiple events when multiple event names are passed as params")
MSpec.register(:exclude, "TracePoint#path equals \"(eval at __FILE__:__LINE__)\" inside an eval for :end event")
## Library

View File

@ -1,2 +1 @@
exclude(:test_return, "unknown")
exclude(:test_return2, "unknown")