diff options
-rw-r--r-- | prism_compile.c | 90 | ||||
-rw-r--r-- | spec/prism.mspec | 2 | ||||
-rw-r--r-- | test/.excludes-prism/TestSetTraceFunc.rb | 1 |
3 files changed, 50 insertions, 43 deletions
diff --git a/prism_compile.c b/prism_compile.c index 122a0f13c0..d207c6bf07 100644 --- a/prism_compile.c +++ b/prism_compile.c @@ -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; } + else { + enum rb_iseq_type type = ISEQ_BODY(iseq)->type; + LABEL *splabel = 0; - if (type == ISEQ_TYPE_METHOD) { - splabel = NEW_LABEL(0); - PUSH_LABEL(ret, splabel); - PUSH_ADJUST(ret, location, 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; + } - if (arguments) { - PM_COMPILE_NOT_POPPED((const pm_node_t *) arguments); - } - else { - PUSH_INSN(ret, location, putnil); - } + 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 && 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); + 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; diff --git a/spec/prism.mspec b/spec/prism.mspec index a4a5a343ee..c13b58b1cd 100644 --- a/spec/prism.mspec +++ b/spec/prism.mspec @@ -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 diff --git a/test/.excludes-prism/TestSetTraceFunc.rb b/test/.excludes-prism/TestSetTraceFunc.rb index dd0ea3b219..036faef650 100644 --- a/test/.excludes-prism/TestSetTraceFunc.rb +++ b/test/.excludes-prism/TestSetTraceFunc.rb @@ -1,2 +1 @@ exclude(:test_return, "unknown") -exclude(:test_return2, "unknown") |