From a4ca12afa30be4ce5dfc3602f54a5563d069ffa5 Mon Sep 17 00:00:00 2001 From: Jonathan Worthington Date: Tue, 1 Dec 2015 22:45:08 +0100 Subject: [PATCH] Fix some failures to catch return outside routine. We actually ended up returning from the first thing we found down the call stack that could be returned from, which led to some rather odd behaviors. RT #123732 was a great example; this: for ^5 { .say; NEXT { return } } Ended up with the return binding to the run_phasers method that runs the NEXT phasers. This also makes return a tad cheaper, and will let us make return a multi sub too, for further performance win. But this patch just corrects the semantics. --- src/vm/jvm/runtime/org/perl6/rakudo/RakOps.java | 7 +------ src/vm/moar/ops/perl6_ops.c | 4 ++-- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/vm/jvm/runtime/org/perl6/rakudo/RakOps.java b/src/vm/jvm/runtime/org/perl6/rakudo/RakOps.java index 018eddc6047..5fe919f8ba9 100644 --- a/src/vm/jvm/runtime/org/perl6/rakudo/RakOps.java +++ b/src/vm/jvm/runtime/org/perl6/rakudo/RakOps.java @@ -569,12 +569,7 @@ private static SixModelObject getremotelex(CallFrame pad, String name) { /* use public static SixModelObject p6routinereturn(SixModelObject in, ThreadContext tc) { CallFrame ctx = tc.curFrame; - SixModelObject cont = null; - - for (ctx = ctx.caller; ctx != null; ctx = ctx.caller) { - cont = getremotelex(ctx, "RETURN"); - if (cont != null) break; - } + SixModelObject cont = getremotelex(ctx.caller, "RETURN"); if (!(cont instanceof LexoticInstance)) { SixModelObject thrower = getThrower(tc, "X::ControlFlow::Return"); diff --git a/src/vm/moar/ops/perl6_ops.c b/src/vm/moar/ops/perl6_ops.c index f8ed99992c6..393a8b79c16 100644 --- a/src/vm/moar/ops/perl6_ops.c +++ b/src/vm/moar/ops/perl6_ops.c @@ -358,8 +358,8 @@ static MVMuint8 s_p6routinereturn[] = { MVM_operand_obj | MVM_operand_read_reg, }; static void p6routinereturn(MVMThreadContext *tc, MVMuint8 *cur_op) { - MVMRegister *reg = MVM_frame_find_lexical_by_name_rel_caller(tc, str_return, - tc->cur_frame); + MVMRegister *reg = MVM_frame_find_lexical_by_name_rel(tc, str_return, + tc->cur_frame->caller); MVMObject *ret = (reg ? reg->o : NULL); if (!MVM_is_null(tc, ret) && IS_CONCRETE(ret) && REPR(ret)->ID == MVM_REPR_ID_Lexotic) { MVM_args_setup_thunk(tc, NULL, MVM_RETURN_VOID, &one_arg_callsite);