Skip to content

Commit

Permalink
Make forceouterctx more forgiving
Browse files Browse the repository at this point in the history
* Try going for an outer frame if the immediately available one is
  inlined (this will work together with a change in Rakudo to mark
  frames that use `EVAL` as no-inline, and mean that `try EVAL $x`
  will work out fine)
* If that doesn't work, don't SEGV, but throw
  • Loading branch information
jnthn committed Aug 23, 2018
1 parent 8063990 commit 9a6adf2
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 1 deletion.
17 changes: 17 additions & 0 deletions src/6model/reprs/MVMContext.c
Expand Up @@ -346,6 +346,23 @@ MVMFrame * MVM_context_get_frame(MVMThreadContext *tc, MVMContext *ctx) {
return result;
}

/* Resolves the context to an exact frame; if the frame in question is an
* inline, takes the inline's outer. Returns NULL if neither resolves. */
MVMFrame * MVM_context_get_frame_or_outer(MVMThreadContext *tc, MVMContext *ctx) {
MVMSpeshFrameWalker fw;
MVMFrame *result = NULL;
MVM_spesh_frame_walker_init(tc, &fw, ctx->body.context, 0);
if (apply_traversals(tc, &fw, ctx->body.traversals, ctx->body.num_traversals)) {
result = MVM_spesh_frame_walker_get_frame(tc, &fw);
if (!result) {
MVM_spesh_frame_walker_move_outer(tc, &fw);
result = MVM_spesh_frame_walker_get_frame(tc, &fw);
}
}
MVM_spesh_frame_walker_cleanup(tc, &fw);
return result;
}

/* Resolves the context and gets a hash of its lexicals. */
MVMObject * MVM_context_lexicals_as_hash(MVMThreadContext *tc, MVMContext *ctx) {
MVMSpeshFrameWalker fw;
Expand Down
1 change: 1 addition & 0 deletions src/6model/reprs/MVMContext.h
Expand Up @@ -33,6 +33,7 @@ const MVMREPROps * MVMContext_initialize(MVMThreadContext *tc);
MVM_PUBLIC MVMObject * MVM_context_from_frame(MVMThreadContext *tc, MVMFrame *f);
MVMObject * MVM_context_apply_traversal(MVMThreadContext *tc, MVMContext *ctx, MVMuint8 traversal);
MVMFrame * MVM_context_get_frame(MVMThreadContext *tc, MVMContext *ctx);
MVMFrame * MVM_context_get_frame_or_outer(MVMThreadContext *tc, MVMContext *ctx);
MVMObject * MVM_context_lexicals_as_hash(MVMThreadContext *tc, MVMContext *ctx);
MVMint64 MVM_context_lexical_primspec(MVMThreadContext *tc, MVMContext *ctx, MVMString *name);
MVMObject * MVM_context_get_code(MVMThreadContext *tc, MVMContext *ctx);
Expand Down
4 changes: 3 additions & 1 deletion src/core/interp.c
Expand Up @@ -2824,7 +2824,9 @@ void MVM_interp_run(MVMThreadContext *tc, void (*initial_invoke)(MVMThreadContex
MVM_exception_throw_adhoc(tc, "forceouterctx needs a code ref");
if (REPR(ctx)->ID != MVM_REPR_ID_MVMContext || !IS_CONCRETE(ctx))
MVM_exception_throw_adhoc(tc, "forceouterctx needs a context");
context = MVM_context_get_frame(tc, (MVMContext *)ctx);
context = MVM_context_get_frame_or_outer(tc, (MVMContext *)ctx);
if (!context)
MVM_exception_throw_adhoc(tc, "Failed to resolve context for forceouterctx");

orig = ((MVMCode *)obj)->body.outer;
sf = ((MVMCode *)obj)->body.sf;
Expand Down

0 comments on commit 9a6adf2

Please sign in to comment.