Skip to content

Commit

Permalink
Update MVMContext at_key/exists_key to traverse
Browse files Browse the repository at this point in the history
  • Loading branch information
jnthn committed Jul 17, 2018
1 parent 02cedc1 commit df6271a
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 60 deletions.
118 changes: 62 additions & 56 deletions src/6model/reprs/MVMContext.c
Expand Up @@ -28,56 +28,81 @@ static void gc_mark(MVMThreadContext *tc, MVMSTable *st, void *data, MVMGCWorkli
MVM_gc_worklist_add(tc, worklist, &body->context);
}

static MVMint32 apply_traversals(MVMThreadContext *tc, MVMSpeshFrameWalker *fw, MVMuint8 *traversals,
MVMuint32 num_traversals) {
MVMuint32 i;
MVMuint32 could_move = 1;
for (i = 0; i < num_traversals; i++) {
switch (traversals[i]) {
case MVM_CTX_TRAV_OUTER:
could_move = MVM_spesh_frame_walker_move_outer(tc, fw);
break;
case MVM_CTX_TRAV_CALLER:
could_move = MVM_spesh_frame_walker_move_caller(tc, fw);
break;
case MVM_CTX_TRAV_OUTER_SKIP_THUNKS:
could_move = MVM_spesh_frame_walker_move_outer_skip_thunks(tc, fw);
break;
case MVM_CTX_TRAV_CALLER_SKIP_THUNKS:
could_move = MVM_spesh_frame_walker_move_caller_skip_thunks(tc, fw);
break;
default:
MVM_exception_throw_adhoc(tc, "Unrecognized context traversal operation");
}
if (!could_move)
break;
}
return could_move;
}

static MVMuint32 setup_frame_walker(MVMThreadContext *tc, MVMSpeshFrameWalker *fw, MVMContextBody *data) {
MVM_spesh_frame_walker_init(tc, fw, data->context, 0);
return apply_traversals(tc, fw, data->traversals, data->num_traversals);
}

static void at_key(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMObject *key, MVMRegister *result, MVMuint16 kind) {
MVMString *name = (MVMString *)key;
MVMContextBody *body = (MVMContextBody *)data;
MVMFrame *frame = body->context;
MVMLexicalRegistry *lexical_names = frame->static_info->body.lexical_names, *entry;
if (!lexical_names) {
char *c_name = MVM_string_utf8_encode_C_string(tc, name);
char *waste[] = { c_name, NULL };
MVM_exception_throw_adhoc_free(tc, waste,
"Lexical with name '%s' does not exist in this frame",
c_name);
}
MVM_HASH_GET(tc, lexical_names, name, entry);
if (!entry) {

MVMSpeshFrameWalker fw;
MVMRegister *found;
MVMuint16 found_kind;
if (!setup_frame_walker(tc, &fw, body) || !MVM_spesh_frame_walker_get_lex(tc, &fw,
name, &found, &found_kind, 1)) {
char *c_name = MVM_string_utf8_encode_C_string(tc, name);
char *waste[] = { c_name, NULL };
MVM_exception_throw_adhoc_free(tc, waste,
"Lexical with name '%s' does not exist in this frame",
c_name);
c_name);
}
if (frame->static_info->body.lexical_types[entry->value] != kind) {
MVM_spesh_frame_walker_cleanup(tc, &fw);

if (found_kind != kind) {
if (kind == MVM_reg_int64) {
switch (frame->static_info->body.lexical_types[entry->value]) {
switch (found_kind) {
case MVM_reg_int8:
result->i64 = frame->env[entry->value].i8;
result->i64 = found->i8;
return;
case MVM_reg_int16:
result->i64 = frame->env[entry->value].i16;
result->i64 = found->i16;
return;
case MVM_reg_int32:
result->i64 = frame->env[entry->value].i32;
result->i64 = found->i32;
return;
}
}
else if (kind == MVM_reg_uint64) {
switch (frame->static_info->body.lexical_types[entry->value]) {
switch (found_kind) {
case MVM_reg_uint8:
result->u64 = frame->env[entry->value].u8;
result->u64 = found->u8;
return;
case MVM_reg_uint16:
result->u64 = frame->env[entry->value].u16;
result->u64 = found->u16;
return;
case MVM_reg_uint32:
result->u64 = frame->env[entry->value].u32;
return;
case MVM_reg_uint64:
result->u64 = frame->env[entry->value].u64;
result->u64 = found->u32;
return;
}

}
{
char *c_name = MVM_string_utf8_encode_C_string(tc, name);
Expand All @@ -87,9 +112,7 @@ static void at_key(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *d
c_name);
}
}
*result = frame->env[entry->value];
if (kind == MVM_reg_obj && !result->o)
result->o = MVM_frame_vivify_lexical(tc, frame, entry->value);
*result = *found;
}

static void bind_key(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMObject *key, MVMRegister value, MVMuint16 kind) {
Expand Down Expand Up @@ -143,12 +166,15 @@ static MVMuint64 elems(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, voi
static MVMint64 exists_key(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMObject *key) {
MVMContextBody *body = (MVMContextBody *)data;
MVMFrame *frame = body->context;
MVMLexicalRegistry *lexical_names = frame->static_info->body.lexical_names, *entry;
MVMString *name = (MVMString *)key;
if (!lexical_names)
return 0;
MVM_HASH_GET(tc, lexical_names, name, entry);
return entry ? 1 : 0;

MVMSpeshFrameWalker fw;
MVMRegister *found;
MVMuint16 found_kind;
MVMuint64 result = setup_frame_walker(tc, &fw, body) && MVM_spesh_frame_walker_get_lex(tc, &fw,
(MVMString *)key, &found, &found_kind, 0);
MVM_spesh_frame_walker_cleanup(tc, &fw);

return result;
}

static void delete_key(MVMThreadContext *tc, MVMSTable *st, MVMObject *root, void *data, MVMObject *key) {
Expand Down Expand Up @@ -244,29 +270,9 @@ MVMObject * MVM_context_from_frame(MVMThreadContext *tc, MVMFrame *f) {
static MVMint32 traversal_exists(MVMThreadContext *tc, MVMFrame *base, MVMuint8 *traversals,
MVMuint32 num_traversals) {
MVMSpeshFrameWalker fw;
MVMuint32 i;
MVMuint32 could_move = 1;
MVMuint32 could_move;
MVM_spesh_frame_walker_init(tc, &fw, base, 0);
for (i = 0; i < num_traversals; i++) {
switch (traversals[i]) {
case MVM_CTX_TRAV_OUTER:
could_move = MVM_spesh_frame_walker_move_outer(tc, &fw);
break;
case MVM_CTX_TRAV_CALLER:
could_move = MVM_spesh_frame_walker_move_caller(tc, &fw);
break;
case MVM_CTX_TRAV_OUTER_SKIP_THUNKS:
could_move = MVM_spesh_frame_walker_move_outer_skip_thunks(tc, &fw);
break;
case MVM_CTX_TRAV_CALLER_SKIP_THUNKS:
could_move = MVM_spesh_frame_walker_move_caller_skip_thunks(tc, &fw);
break;
default:
MVM_exception_throw_adhoc(tc, "Unrecognized context traversal operation");
}
if (!could_move)
break;
}
could_move = apply_traversals(tc, &fw, traversals, num_traversals);
MVM_spesh_frame_walker_cleanup(tc, &fw);
return could_move;
}
Expand Down
2 changes: 1 addition & 1 deletion src/core/frame.c
Expand Up @@ -1387,7 +1387,7 @@ MVMRegister * MVM_frame_find_lexical_by_name_rel_caller(MVMThreadContext *tc, MV
while (MVM_spesh_frame_walker_next(tc, &fw)) {
MVMRegister *found;
MVMuint16 found_kind;
if (MVM_spesh_frame_walker_get_lex(tc, &fw, name, &found, &found_kind)) {
if (MVM_spesh_frame_walker_get_lex(tc, &fw, name, &found, &found_kind, 1)) {
MVM_spesh_frame_walker_cleanup(tc, &fw);
if (found_kind == MVM_reg_obj) {
return found;
Expand Down
4 changes: 2 additions & 2 deletions src/spesh/frame_walker.c
Expand Up @@ -141,7 +141,7 @@ MVMuint32 MVM_spesh_frame_walker_next(MVMThreadContext *tc, MVMSpeshFrameWalker
* trigger vivification of the lexical if needed. */
MVMuint32 MVM_spesh_frame_walker_get_lex(MVMThreadContext *tc, MVMSpeshFrameWalker *fw,
MVMString *name, MVMRegister **found_out,
MVMuint16 *found_kind_out) {
MVMuint16 *found_kind_out, MVMuint32 vivify) {
MVMFrame *cur_frame;
MVMStaticFrame *sf;
MVMuint32 base_index;
Expand Down Expand Up @@ -173,7 +173,7 @@ MVMuint32 MVM_spesh_frame_walker_get_lex(MVMThreadContext *tc, MVMSpeshFrameWalk
MVMuint16 kind = sf->body.lexical_types[entry->value];
*found_out = result;
*found_kind_out = kind;
if (kind == MVM_reg_obj && !result->o)
if (vivify && kind == MVM_reg_obj && !result->o)
MVM_frame_vivify_lexical(tc, cur_frame, index);
return 1;
}
Expand Down
2 changes: 1 addition & 1 deletion src/spesh/frame_walker.h
Expand Up @@ -27,7 +27,7 @@ void MVM_spesh_frame_walker_init(MVMThreadContext *tc, MVMSpeshFrameWalker *fw,
MVMuint8 visit_outers);
MVMuint32 MVM_spesh_frame_walker_next(MVMThreadContext *tc, MVMSpeshFrameWalker *fw);
MVMuint32 MVM_spesh_frame_walker_get_lex(MVMThreadContext *tc, MVMSpeshFrameWalker *fw,
MVMString *name, MVMRegister **found_out, MVMuint16 *found_kind_out);
MVMString *name, MVMRegister **found_out, MVMuint16 *found_kind_out, MVMuint32 vivify);
void MVM_spesh_frame_walker_cleanup(MVMThreadContext *tc, MVMSpeshFrameWalker *fw);
MVMuint32 MVM_spesh_frame_walker_move_outer(MVMThreadContext *tc, MVMSpeshFrameWalker *fw);
MVMuint32 MVM_spesh_frame_walker_move_caller(MVMThreadContext *tc, MVMSpeshFrameWalker *fw);
Expand Down

0 comments on commit df6271a

Please sign in to comment.