/* This callback is passed to the interpreter code. It takes care of making * the initial invocation. */ static void toplevel_initial_invoke(MVMThreadContext *tc, void *data) { /* Dummy, 0-arg callsite. */ static MVMCallsite no_arg_callsite = { NULL, 0, 0, 0 }; /* Create initial frame, which sets up all of the interpreter state also. */ MVM_frame_invoke(tc, (MVMStaticFrame *)data, &no_arg_callsite, NULL, NULL, NULL); }
/* Invocation protocol handler. */ static void invoke_handler(MVMThreadContext *tc, MVMObject *invokee, MVMCallsite *callsite, MVMRegister *args) { if (IS_CONCRETE(invokee)) { MVMCode *code = (MVMCode *)invokee; MVM_frame_invoke(tc, code->body.sf, callsite, args, code->body.outer, invokee); } else { MVM_exception_throw_adhoc(tc, "Cannot invoke code type object"); } }
void MVM_load_bytecode(MVMThreadContext *tc, MVMString *filename) { MVMCompUnit *cu; MVMLoadedCompUnitName *loaded_name; /* Work out actual filename to use, taking --libpath into account. */ filename = MVM_file_in_libpath(tc, filename); /* See if we already loaded this. */ uv_mutex_lock(&tc->instance->mutex_loaded_compunits); MVM_string_flatten(tc, filename); MVM_HASH_GET(tc, tc->instance->loaded_compunits, filename, loaded_name); if (loaded_name) { /* already loaded */ uv_mutex_unlock(&tc->instance->mutex_loaded_compunits); return; } /* Otherwise, load from disk. */ MVMROOT(tc, filename, { char *c_filename = MVM_string_utf8_c8_encode_C_string(tc, filename); /* XXX any exception from MVM_cu_map_from_file needs to be handled * and c_filename needs to be freed */ cu = MVM_cu_map_from_file(tc, c_filename); MVM_free(c_filename); cu->body.filename = filename; /* If there's a deserialization frame, need to run that. */ if (cu->body.deserialize_frame) { /* Set up special return to delegate to running the load frame, * if any. */ tc->cur_frame->return_value = NULL; tc->cur_frame->return_type = MVM_RETURN_VOID; tc->cur_frame->special_return = run_load; tc->cur_frame->special_return_data = cu; tc->cur_frame->mark_special_return_data = mark_sr_data; /* Invoke the deserialization frame and return to the runloop. */ MVM_frame_invoke(tc, cu->body.deserialize_frame, MVM_callsite_get_common(tc, MVM_CALLSITE_ID_NULL_ARGS), NULL, NULL, NULL, -1); } else { /* No deserialize frame, so do load frame instead. */ run_load(tc, cu); } loaded_name = MVM_calloc(1, sizeof(MVMLoadedCompUnitName)); loaded_name->filename = filename; MVM_HASH_BIND(tc, tc->instance->loaded_compunits, filename, loaded_name); });
/* This callback is passed to the interpreter code. It takes care of making * the initial invocation. */ static void toplevel_initial_invoke(MVMThreadContext *tc, void *data) { /* Create initial frame, which sets up all of the interpreter state also. */ MVM_frame_invoke(tc, (MVMStaticFrame *)data, MVM_callsite_get_common(tc, MVM_CALLSITE_ID_NULL_ARGS), NULL, NULL, NULL, -1); }