Skip to content

Commit

Permalink
Update lexprimspec to do context traversal
Browse files Browse the repository at this point in the history
  • Loading branch information
jnthn committed Jul 18, 2018
1 parent 93b1ee2 commit aae518b
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 38 deletions.
17 changes: 17 additions & 0 deletions src/6model/reprs/MVMContext.c
Expand Up @@ -329,3 +329,20 @@ MVMObject * MVM_context_lexicals_as_hash(MVMThreadContext *tc, MVMContext *ctx)
MVM_spesh_frame_walker_cleanup(tc, &fw);
return result;
}

/* Find the primitive lexical type of a lexical in the context. */
MVMint64 MVM_context_lexical_primspec(MVMThreadContext *tc, MVMContext *ctx, MVMString *name) {
MVMSpeshFrameWalker fw;
MVMint64 primspec = -1;
MVM_spesh_frame_walker_init(tc, &fw, ctx->body.context, 0);
if (apply_traversals(tc, &fw, ctx->body.traversals, ctx->body.num_traversals))
primspec = MVM_spesh_frame_walker_get_lexical_primspec(tc, &fw, name);
MVM_spesh_frame_walker_cleanup(tc, &fw);
if (primspec < 0) {
char *c_name = MVM_string_utf8_encode_C_string(tc, name);
char *waste[] = { c_name, NULL };
MVM_exception_throw_adhoc_free(tc, waste, "Frame has no lexical with name '%s'",
c_name);
}
return primspec;
}
1 change: 1 addition & 0 deletions src/6model/reprs/MVMContext.h
Expand Up @@ -34,6 +34,7 @@ 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);
MVMObject * MVM_context_lexicals_as_hash(MVMThreadContext *tc, MVMContext *ctx);
MVMint64 MVM_context_lexical_primspec(MVMThreadContext *tc, MVMContext *ctx, MVMString *name);

/* Compatibility shim for Rakudo ext ops. */
#define MVM_frame_context_wrapper MVM_context_from_frame
70 changes: 35 additions & 35 deletions src/core/frame.c
Expand Up @@ -1716,47 +1716,47 @@ MVMRegister * MVM_frame_try_get_lexical(MVMThreadContext *tc, MVMFrame *f, MVMSt
return NULL;
}

/* Translates a register kind into a primitive storage spec constant. */
MVMuint16 MVM_frame_translate_to_primspec(MVMThreadContext *tc, MVMuint16 kind) {
switch (MVM_EXPECT(kind, MVM_reg_obj)) {
case MVM_reg_int64:
return MVM_STORAGE_SPEC_BP_INT;
case MVM_reg_num64:
return MVM_STORAGE_SPEC_BP_NUM;
case MVM_reg_str:
return MVM_STORAGE_SPEC_BP_STR;
case MVM_reg_obj:
return MVM_STORAGE_SPEC_BP_NONE;
case MVM_reg_int8:
return MVM_STORAGE_SPEC_BP_INT8;
case MVM_reg_int16:
return MVM_STORAGE_SPEC_BP_INT16;
case MVM_reg_int32:
return MVM_STORAGE_SPEC_BP_INT32;
case MVM_reg_uint8:
return MVM_STORAGE_SPEC_BP_UINT8;
case MVM_reg_uint16:
return MVM_STORAGE_SPEC_BP_UINT16;
case MVM_reg_uint32:
return MVM_STORAGE_SPEC_BP_UINT32;
case MVM_reg_uint64:
return MVM_STORAGE_SPEC_BP_UINT64;
default:
MVM_exception_throw_adhoc(tc,
"Unhandled lexical type '%s' in lexprimspec",
MVM_reg_get_debug_name(tc, kind));
}
}

/* Returns the primitive type specification for a lexical. */
MVMuint16 MVM_frame_lexical_primspec(MVMThreadContext *tc, MVMFrame *f, MVMString *name) {
MVMLexicalRegistry *lexical_names = f->static_info->body.lexical_names;
if (lexical_names) {
MVMLexicalRegistry *entry;
MVM_HASH_GET(tc, lexical_names, name, entry)
if (entry) {
switch (MVM_EXPECT(f->static_info->body.lexical_types[entry->value], MVM_reg_obj)) {
case MVM_reg_int64:
return MVM_STORAGE_SPEC_BP_INT;
case MVM_reg_num64:
return MVM_STORAGE_SPEC_BP_NUM;
case MVM_reg_str:
return MVM_STORAGE_SPEC_BP_STR;
case MVM_reg_obj:
return MVM_STORAGE_SPEC_BP_NONE;
case MVM_reg_int8:
return MVM_STORAGE_SPEC_BP_INT8;
case MVM_reg_int16:
return MVM_STORAGE_SPEC_BP_INT16;
case MVM_reg_int32:
return MVM_STORAGE_SPEC_BP_INT32;
case MVM_reg_uint8:
return MVM_STORAGE_SPEC_BP_UINT8;
case MVM_reg_uint16:
return MVM_STORAGE_SPEC_BP_UINT16;
case MVM_reg_uint32:
return MVM_STORAGE_SPEC_BP_UINT32;
case MVM_reg_uint64:
return MVM_STORAGE_SPEC_BP_UINT64;
default:
{
char *c_name = MVM_string_utf8_encode_C_string(tc, name);
char *waste[] = { c_name, NULL };
MVM_exception_throw_adhoc_free(tc, waste,
"Unhandled lexical type '%s' in lexprimspec for '%s'",
MVM_reg_get_debug_name(tc, f->static_info->body.lexical_types[entry->value]),
c_name);
}
}
}
if (entry)
return MVM_frame_translate_to_primspec(tc,
f->static_info->body.lexical_types[entry->value]);
}
{
char *c_name = MVM_string_utf8_encode_C_string(tc, name);
Expand Down
1 change: 1 addition & 0 deletions src/core/frame.h
Expand Up @@ -226,6 +226,7 @@ MVMObject * MVM_frame_getdynlex(MVMThreadContext *tc, MVMString *name, MVMFrame
void MVM_frame_binddynlex(MVMThreadContext *tc, MVMString *name, MVMObject *value, MVMFrame *cur_frame);
MVMRegister * MVM_frame_lexical(MVMThreadContext *tc, MVMFrame *f, MVMString *name);
MVM_PUBLIC MVMRegister * MVM_frame_try_get_lexical(MVMThreadContext *tc, MVMFrame *f, MVMString *name, MVMuint16 type);
MVMuint16 MVM_frame_translate_to_primspec(MVMThreadContext *tc, MVMuint16 kind);
MVMuint16 MVM_frame_lexical_primspec(MVMThreadContext *tc, MVMFrame *f, MVMString *name);
MVM_PUBLIC MVMObject * MVM_frame_find_invokee(MVMThreadContext *tc, MVMObject *code, MVMCallsite **tweak_cs);
MVMObject * MVM_frame_find_invokee_multi_ok(MVMThreadContext *tc, MVMObject *code, MVMCallsite **tweak_cs, MVMRegister *args, MVMuint16 *was_multi);
Expand Down
4 changes: 2 additions & 2 deletions src/core/interp.c
Expand Up @@ -450,8 +450,8 @@ void MVM_interp_run(MVMThreadContext *tc, void (*initial_invoke)(MVMThreadContex
MVMString *name = GET_REG(cur_op, 4).s;
if (REPR(ctx)->ID != MVM_REPR_ID_MVMContext || !IS_CONCRETE(ctx))
MVM_exception_throw_adhoc(tc, "lexprimspec needs a context");
GET_REG(cur_op, 0).i64 = MVM_frame_lexical_primspec(tc,
((MVMContext *)ctx)->body.context, name);
GET_REG(cur_op, 0).i64 = MVM_context_lexical_primspec(tc,
(MVMContext *)ctx, name);
cur_op += 6;
goto NEXT;
}
Expand Down
20 changes: 19 additions & 1 deletion src/spesh/frame_walker.c
Expand Up @@ -248,7 +248,6 @@ MVMObject * MVM_spesh_frame_walker_get_lexicals_hash(MVMThreadContext *tc, MVMSp
MVMFrame *frame;
MVMStaticFrame *sf;
MVMuint32 base_index;
MVMLexicalRegistry *lexical_names;
MVMHLLConfig *hll = MVM_hll_current(tc);
MVMObject *ctx_hash = MVM_repr_alloc_init(tc, hll->slurpy_hash_type);
find_lex_info(tc, fw, &frame, &sf, &base_index);
Expand Down Expand Up @@ -344,6 +343,25 @@ MVMObject * MVM_spesh_frame_walker_get_lexicals_hash(MVMThreadContext *tc, MVMSp
return ctx_hash;
}

/* Get the kind of lexical with the given name at the frame walker's current
* location. Returns -1 if there is no such lexical. */
MVMint64 MVM_spesh_frame_walker_get_lexical_primspec(MVMThreadContext *tc,
MVMSpeshFrameWalker *fw, MVMString *name) {
MVMFrame *cur_frame;
MVMStaticFrame *sf;
MVMuint32 base_index;
MVMLexicalRegistry *lexical_names;
find_lex_info(tc, fw, &cur_frame, &sf, &base_index);
lexical_names = sf->body.lexical_names;
if (lexical_names) {
MVMLexicalRegistry *entry;
MVM_HASH_GET(tc, lexical_names, name, entry)
if (entry)
return MVM_frame_translate_to_primspec(tc, sf->body.lexical_types[entry->value]);
}
return -1;
}

/* Cleans up the spesh frame walker after use. */
void MVM_spesh_frame_walker_cleanup(MVMThreadContext *tc, MVMSpeshFrameWalker *fw) {
MVM_gc_root_temp_pop_n(tc, 2);
Expand Down
2 changes: 2 additions & 0 deletions src/spesh/frame_walker.h
Expand Up @@ -37,3 +37,5 @@ MVMuint32 MVM_spesh_frame_walker_move_caller_skip_thunks(MVMThreadContext *tc,
MVMSpeshFrameWalker *fw);
MVMFrame * MVM_spesh_frame_walker_get_frame(MVMThreadContext *tc, MVMSpeshFrameWalker *fw);
MVMObject * MVM_spesh_frame_walker_get_lexicals_hash(MVMThreadContext *tc, MVMSpeshFrameWalker *fw);
MVMint64 MVM_spesh_frame_walker_get_lexical_primspec(MVMThreadContext *tc,
MVMSpeshFrameWalker *fw, MVMString *name);

0 comments on commit aae518b

Please sign in to comment.