/* Sets the passed thread context's thread up so that we'll run a finalize * handler on it in the near future. */ static void finalize_handler_caller(MVMThreadContext *tc, void *sr_data) { MVMObject *handler = MVM_hll_current(tc)->finalize_handler; if (handler) { /* Drain the finalizing queue to an array. */ MVMObject *drain = MVM_repr_alloc_init(tc, tc->instance->boot_types.BOOTArray); while (tc->num_finalizing > 0) MVM_repr_push_o(tc, drain, tc->finalizing[--tc->num_finalizing]); /* Invoke the handler. */ handler = MVM_frame_find_invokee(tc, handler, NULL); MVM_args_setup_thunk(tc, NULL, MVM_RETURN_VOID, MVM_callsite_get_common(tc, MVM_CALLSITE_ID_INV_ARG)); tc->cur_frame->args[0].o = drain; STABLE(handler)->invoke(tc, handler, MVM_callsite_get_common(tc, MVM_CALLSITE_ID_INV_ARG), tc->cur_frame->args); } }
void MVM_6model_can_method(MVMThreadContext *tc, MVMObject *obj, MVMString *name, MVMRegister *res) { MVMObject *HOW, *find_method, *code; MVMCallsite *findmeth_callsite; MVMint64 can_cached = MVM_6model_can_method_cache_only(tc, obj, name); if (can_cached == 0 || can_cached == 1) { res->i64 = can_cached; return; } /* If no method in cache and the cache is not authoritative, need to make * a late-bound call to find_method. */ HOW = MVM_6model_get_how(tc, STABLE(obj)); find_method = MVM_6model_find_method_cache_only(tc, HOW, tc->instance->str_consts.find_method); if (MVM_is_null(tc, find_method)) { /* This'll count as a "no"... */ res->i64 = 0; return; } /* Set up the call, using the result register as the target. A little bad * as we're really talking about */ code = MVM_frame_find_invokee(tc, find_method, NULL); findmeth_callsite = MVM_callsite_get_common(tc, MVM_CALLSITE_ID_FIND_METHOD); MVM_args_setup_thunk(tc, res, MVM_RETURN_OBJ, findmeth_callsite); tc->cur_frame->special_return = late_bound_can_return; tc->cur_frame->special_return_data = res; tc->cur_frame->args[0].o = HOW; tc->cur_frame->args[1].o = obj; tc->cur_frame->args[2].s = name; STABLE(code)->invoke(tc, code, findmeth_callsite, tc->cur_frame->args); }
static void code_pair_fetch_internal(MVMThreadContext *tc, MVMObject *cont, MVMRegister *res, MVMReturnType res_type) { CodePairContData *data = (CodePairContData *)STABLE(cont)->container_data; MVMObject *code = MVM_frame_find_invokee(tc, data->fetch_code, NULL); MVMCallsite *inv_arg_callsite = MVM_callsite_get_common(tc, MVM_CALLSITE_ID_INV_ARG); MVM_args_setup_thunk(tc, res, res_type, inv_arg_callsite); tc->cur_frame->args[0].o = cont; STABLE(code)->invoke(tc, code, inv_arg_callsite, tc->cur_frame->args); }
static void rakudo_scalar_store(MVMThreadContext *tc, MVMObject *cont, MVMObject *value) { RakudoContData *data = (RakudoContData *)STABLE(cont)->container_data; MVMObject *code = MVM_frame_find_invokee(tc, data->store, NULL); MVMCallsite *cs = MVM_callsite_get_common(tc, MVM_CALLSITE_ID_TWO_OBJ); MVM_args_setup_thunk(tc, NULL, MVM_RETURN_VOID, cs); tc->cur_frame->args[0].o = cont; tc->cur_frame->args[1].o = value; STABLE(code)->invoke(tc, code, cs, tc->cur_frame->args); }
static void code_pair_store(MVMThreadContext *tc, MVMObject *cont, MVMObject *obj) { CodePairContData *data = (CodePairContData *)STABLE(cont)->container_data; MVMObject *code = MVM_frame_find_invokee(tc, data->store_code, NULL); MVMCallsite *two_args_callsite = MVM_callsite_get_common(tc, MVM_CALLSITE_ID_TWO_OBJ); MVM_args_setup_thunk(tc, NULL, MVM_RETURN_VOID, two_args_callsite); tc->cur_frame->args[0].o = cont; tc->cur_frame->args[1].o = obj; STABLE(code)->invoke(tc, code, two_args_callsite, tc->cur_frame->args); }
static void run_handler(MVMThreadContext *tc, LocatedHandler lh, MVMObject *ex_obj, MVMuint32 category) { switch (lh.handler->action) { case MVM_EX_ACTION_GOTO: if (lh.jit_handler) { void **labels = lh.frame->spesh_cand->jitcode->labels; MVMuint8 *pc = lh.frame->spesh_cand->jitcode->bytecode; lh.frame->jit_entry_label = labels[lh.jit_handler->goto_label]; MVM_frame_unwind_to(tc, lh.frame, pc, 0, NULL); } else { MVM_frame_unwind_to(tc, lh.frame, NULL, lh.handler->goto_offset, NULL); } break; case MVM_EX_ACTION_INVOKE: { /* Create active handler record. */ MVMActiveHandler *ah = MVM_malloc(sizeof(MVMActiveHandler)); MVMFrame *cur_frame = tc->cur_frame; MVMObject *handler_code; /* Ensure we have an exception object. */ if (ex_obj == NULL) { ex_obj = MVM_repr_alloc_init(tc, tc->instance->boot_types.BOOTException); ((MVMException *)ex_obj)->body.category = category; } /* Find frame to invoke. */ handler_code = MVM_frame_find_invokee(tc, lh.frame->work[lh.handler->block_reg].o, NULL); /* Install active handler record. */ ah->frame = MVM_frame_inc_ref(tc, lh.frame); ah->handler = lh.handler; ah->jit_handler = lh.jit_handler; ah->ex_obj = ex_obj; ah->next_handler = tc->active_handlers; tc->active_handlers = ah; /* Set up special return to unwinding after running the * handler. */ cur_frame->return_value = (MVMRegister *)&tc->last_handler_result; cur_frame->return_type = MVM_RETURN_OBJ; cur_frame->special_return = unwind_after_handler; cur_frame->special_unwind = cleanup_active_handler; cur_frame->special_return_data = ah; /* Invoke the handler frame and return to runloop. */ STABLE(handler_code)->invoke(tc, handler_code, MVM_callsite_get_common(tc, MVM_CALLSITE_ID_NULL_ARGS), cur_frame->args); break; } default: MVM_panic(1, "Unimplemented handler action"); } }
void MVM_6model_find_method(MVMThreadContext *tc, MVMObject *obj, MVMString *name, MVMRegister *res) { MVMObject *cache, *HOW, *find_method, *code; MVMCallsite *findmeth_callsite; if (MVM_is_null(tc, obj)) MVM_exception_throw_adhoc(tc, "Cannot call method '%s' on a null object", MVM_string_utf8_encode_C_string(tc, name)); /* First try to find it in the cache. If we find it, we have a result. * If we don't find it, but the cache is authoritative, then error. */ cache = get_method_cache(tc, STABLE(obj)); if (cache && IS_CONCRETE(cache)) { MVMObject *meth = MVM_repr_at_key_o(tc, cache, name); if (!MVM_is_null(tc, meth)) { res->o = meth; return; } if (STABLE(obj)->mode_flags & MVM_METHOD_CACHE_AUTHORITATIVE) { die_over_missing_method(tc, obj, name); return; } } /* Otherwise, need to call the find_method method. We make the assumption * that the invocant's meta-object's type is composed. */ HOW = MVM_6model_get_how(tc, STABLE(obj)); find_method = MVM_6model_find_method_cache_only(tc, HOW, tc->instance->str_consts.find_method); if (MVM_is_null(tc, find_method)) MVM_exception_throw_adhoc(tc, "Cannot find method '%s': no method cache and no .^find_method", MVM_string_utf8_encode_C_string(tc, name)); /* Set up the call, using the result register as the target. */ code = MVM_frame_find_invokee(tc, find_method, NULL); findmeth_callsite = MVM_callsite_get_common(tc, MVM_CALLSITE_ID_FIND_METHOD); MVM_args_setup_thunk(tc, res, MVM_RETURN_OBJ, findmeth_callsite); { FindMethodSRData *fm = MVM_malloc(sizeof(FindMethodSRData)); fm->obj = obj; fm->name = name; fm->res = res; tc->cur_frame->special_return = late_bound_find_method_return; tc->cur_frame->special_return_data = fm; tc->cur_frame->mark_special_return_data = mark_find_method_sr_data; } tc->cur_frame->args[0].o = HOW; tc->cur_frame->args[1].o = obj; tc->cur_frame->args[2].s = name; STABLE(code)->invoke(tc, code, findmeth_callsite, tc->cur_frame->args); }
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); });
static void die_over_missing_method(MVMThreadContext *tc, MVMObject *obj, MVMString *name) { MVMObject *handler = MVM_hll_current(tc)->method_not_found_error; if (!MVM_is_null(tc, handler)) { MVMCallsite *methnotfound_callsite = MVM_callsite_get_common(tc, MVM_CALLSITE_ID_METH_NOT_FOUND); handler = MVM_frame_find_invokee(tc, handler, NULL); MVM_args_setup_thunk(tc, NULL, MVM_RETURN_VOID, methnotfound_callsite); tc->cur_frame->args[0].o = obj; tc->cur_frame->args[1].s = name; STABLE(handler)->invoke(tc, handler, methnotfound_callsite, tc->cur_frame->args); return; } else { MVM_exception_throw_adhoc(tc, "Cannot find method '%s'", MVM_string_utf8_encode_C_string(tc, name)); } }
void MVM_coerce_smart_stringify(MVMThreadContext *tc, MVMObject *obj, MVMRegister *res_reg) { MVMObject *strmeth; const MVMStorageSpec *ss; /* Handle null case. */ if (MVM_is_null(tc, obj)) { res_reg->s = tc->instance->str_consts.empty; return; } /* If it can unbox as a string, that wins right off. */ ss = REPR(obj)->get_storage_spec(tc, STABLE(obj)); if (ss->can_box & MVM_STORAGE_SPEC_CAN_BOX_STR && IS_CONCRETE(obj)) { res_reg->s = REPR(obj)->box_funcs.get_str(tc, STABLE(obj), obj, OBJECT_BODY(obj)); return; } /* Check if there is a Str method. */ strmeth = MVM_6model_find_method_cache_only(tc, obj, tc->instance->str_consts.Str); if (!MVM_is_null(tc, strmeth)) { /* We need to do the invocation; just set it up with our result reg as * the one for the call. */ MVMObject *code = MVM_frame_find_invokee(tc, strmeth, NULL); MVMCallsite *inv_arg_callsite = MVM_callsite_get_common(tc, MVM_CALLSITE_ID_INV_ARG); MVM_args_setup_thunk(tc, res_reg, MVM_RETURN_STR, inv_arg_callsite); tc->cur_frame->args[0].o = obj; STABLE(code)->invoke(tc, code, inv_arg_callsite, tc->cur_frame->args); return; } /* Otherwise, guess something appropriate. */ if (!IS_CONCRETE(obj)) res_reg->s = tc->instance->str_consts.empty; else { if (REPR(obj)->ID == MVM_REPR_ID_MVMException) res_reg->s = ((MVMException *)obj)->body.message; else if (ss->can_box & MVM_STORAGE_SPEC_CAN_BOX_INT) res_reg->s = MVM_coerce_i_s(tc, REPR(obj)->box_funcs.get_int(tc, STABLE(obj), obj, OBJECT_BODY(obj))); else if (ss->can_box & MVM_STORAGE_SPEC_CAN_BOX_NUM) res_reg->s = MVM_coerce_n_s(tc, REPR(obj)->box_funcs.get_num(tc, STABLE(obj), obj, OBJECT_BODY(obj))); else MVM_exception_throw_adhoc(tc, "cannot stringify this"); } }
void MVM_coerce_smart_numify(MVMThreadContext *tc, MVMObject *obj, MVMRegister *res_reg) { MVMObject *nummeth; /* Handle null case. */ if (MVM_is_null(tc, obj)) { res_reg->n64 = 0.0; return; } /* Check if there is a Num method. */ nummeth = MVM_6model_find_method_cache_only(tc, obj, tc->instance->str_consts.Num); if (!MVM_is_null(tc, nummeth)) { /* We need to do the invocation; just set it up with our result reg as * the one for the call. */ MVMObject *code = MVM_frame_find_invokee(tc, nummeth, NULL); MVMCallsite *inv_arg_callsite = MVM_callsite_get_common(tc, MVM_CALLSITE_ID_INV_ARG); MVM_args_setup_thunk(tc, res_reg, MVM_RETURN_NUM, inv_arg_callsite); tc->cur_frame->args[0].o = obj; STABLE(code)->invoke(tc, code, inv_arg_callsite, tc->cur_frame->args); return; } /* Otherwise, guess something appropriate. */ if (!IS_CONCRETE(obj)) { res_reg->n64 = 0.0; } else { const MVMStorageSpec *ss = REPR(obj)->get_storage_spec(tc, STABLE(obj)); if (ss->can_box & MVM_STORAGE_SPEC_CAN_BOX_INT) res_reg->n64 = (MVMnum64)REPR(obj)->box_funcs.get_int(tc, STABLE(obj), obj, OBJECT_BODY(obj)); else if (ss->can_box & MVM_STORAGE_SPEC_CAN_BOX_NUM) res_reg->n64 = REPR(obj)->box_funcs.get_num(tc, STABLE(obj), obj, OBJECT_BODY(obj)); else if (ss->can_box & MVM_STORAGE_SPEC_CAN_BOX_STR) res_reg->n64 = MVM_coerce_s_n(tc, REPR(obj)->box_funcs.get_str(tc, STABLE(obj), obj, OBJECT_BODY(obj))); else if (REPR(obj)->ID == MVM_REPR_ID_MVMArray) res_reg->n64 = (MVMnum64)REPR(obj)->elems(tc, STABLE(obj), obj, OBJECT_BODY(obj)); else if (REPR(obj)->ID == MVM_REPR_ID_MVMHash) res_reg->n64 = (MVMnum64)REPR(obj)->elems(tc, STABLE(obj), obj, OBJECT_BODY(obj)); else MVM_exception_throw_adhoc(tc, "cannot numify this"); } }
/* Checks if an object has a given type, delegating to the type_check or * accepts_type methods as needed. */ static void do_accepts_type_check(MVMThreadContext *tc, MVMObject *obj, MVMObject *type, MVMRegister *res) { MVMObject *HOW = MVM_6model_get_how(tc, STABLE(type)); MVMObject *meth = MVM_6model_find_method_cache_only(tc, HOW, tc->instance->str_consts.accepts_type); if (!MVM_is_null(tc, meth)) { /* Set up the call, using the result register as the target. */ MVMObject *code = MVM_frame_find_invokee(tc, meth, NULL); MVMCallsite *typecheck_callsite = MVM_callsite_get_common(tc, MVM_CALLSITE_ID_TYPECHECK); MVM_args_setup_thunk(tc, res, MVM_RETURN_INT, typecheck_callsite); tc->cur_frame->args[0].o = HOW; tc->cur_frame->args[1].o = type; tc->cur_frame->args[2].o = obj; STABLE(code)->invoke(tc, code, typecheck_callsite, tc->cur_frame->args); return; } else { MVM_exception_throw_adhoc(tc, "Expected 'accepts_type' method, but none found in meta-object"); } }
void MVM_continuation_reset(MVMThreadContext *tc, MVMObject *tag, MVMObject *code, MVMRegister *res_reg) { /* Save the tag. */ MVMContinuationTag *tag_record = MVM_malloc(sizeof(MVMContinuationTag)); tag_record->tag = tag; tag_record->active_handlers = tc->active_handlers; tag_record->next = tc->cur_frame->continuation_tags; tc->cur_frame->continuation_tags = tag_record; /* Were we passed code or a continuation? */ if (REPR(code)->ID == MVM_REPR_ID_MVMContinuation) { /* Continuation; invoke it. */ MVM_continuation_invoke(tc, (MVMContinuation *)code, NULL, res_reg); } else { /* Run the passed code. */ MVMCallsite *null_args_callsite = MVM_callsite_get_common(tc, MVM_CALLSITE_ID_NULL_ARGS); code = MVM_frame_find_invokee(tc, code, NULL); MVM_args_setup_thunk(tc, res_reg, MVM_RETURN_OBJ, null_args_callsite); tc->cur_frame->special_return = clear_tag; tc->cur_frame->special_return_data = tag_record; STABLE(code)->invoke(tc, code, null_args_callsite, tc->cur_frame->args); } }
static void code_pair_store(MVMThreadContext *tc, MVMObject *cont, MVMObject *obj) { MVMRegister r; r.o = obj; code_pair_store_internal(tc, cont, r, MVM_callsite_get_common(tc, MVM_CALLSITE_ID_TWO_OBJ)); }
void MVM_6model_istype(MVMThreadContext *tc, MVMObject *obj, MVMObject *type, MVMRegister *res) { MVMObject **cache; MVMSTable *st; MVMint64 mode; /* Null never type-checks. */ if (MVM_is_null(tc, obj)) { res->i64 = 0; return; } st = STABLE(obj); mode = STABLE(type)->mode_flags & MVM_TYPE_CHECK_CACHE_FLAG_MASK; cache = st->type_check_cache; if (cache) { /* We have the cache, so just look for the type object we * want to be in there. */ MVMint64 elems = STABLE(obj)->type_check_cache_length; MVMint64 i; for (i = 0; i < elems; i++) { if (cache[i] == type) { res->i64 = 1; return; } } /* If the type check cache is definitive, we're done. */ if ((mode & MVM_TYPE_CHECK_CACHE_THEN_METHOD) == 0 && (mode & MVM_TYPE_CHECK_NEEDS_ACCEPTS) == 0) { res->i64 = 0; return; } } /* If we get here, need to call .^type_check on the value we're * checking, unless it's an accepts check. */ if (!cache || (mode & MVM_TYPE_CHECK_CACHE_THEN_METHOD)) { MVMObject *HOW = MVM_6model_get_how(tc, st); MVMObject *meth = MVM_6model_find_method_cache_only(tc, HOW, tc->instance->str_consts.type_check); if (!MVM_is_null(tc, meth)) { /* Set up the call, using the result register as the target. */ MVMObject *code = MVM_frame_find_invokee(tc, meth, NULL); MVMCallsite *typecheck_callsite = MVM_callsite_get_common(tc, MVM_CALLSITE_ID_TYPECHECK); MVM_args_setup_thunk(tc, res, MVM_RETURN_INT, typecheck_callsite); tc->cur_frame->args[0].o = HOW; tc->cur_frame->args[1].o = obj; tc->cur_frame->args[2].o = type; if (mode & MVM_TYPE_CHECK_NEEDS_ACCEPTS) { AcceptsTypeSRData *atd = MVM_malloc(sizeof(AcceptsTypeSRData)); atd->obj = obj; atd->type = type; atd->res = res; tc->cur_frame->special_return = accepts_type_sr; tc->cur_frame->special_return_data = atd; tc->cur_frame->mark_special_return_data = mark_sr_data; } STABLE(code)->invoke(tc, code, typecheck_callsite, tc->cur_frame->args); return; } } /* If the flag to call .accepts_type on the target value is set, do so. */ if (mode & MVM_TYPE_CHECK_NEEDS_ACCEPTS) { do_accepts_type_check(tc, obj, type, res); } else { /* If all else fails... */ res->i64 = 0; } }
/* 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); }
static void code_pair_store_s(MVMThreadContext *tc, MVMObject *cont, MVMString *value) { MVMRegister r; r.s = value; code_pair_store_internal(tc, cont, r, MVM_callsite_get_common(tc, MVM_CALLSITE_ID_OBJ_STR)); }
void MVM_coerce_istrue(MVMThreadContext *tc, MVMObject *obj, MVMRegister *res_reg, MVMuint8 *true_addr, MVMuint8 *false_addr, MVMuint8 flip) { MVMint64 result = 0; if (!MVM_is_null(tc, obj)) { MVMBoolificationSpec *bs = obj->st->boolification_spec; switch (bs == NULL ? MVM_BOOL_MODE_NOT_TYPE_OBJECT : bs->mode) { case MVM_BOOL_MODE_CALL_METHOD: { MVMObject *code = MVM_frame_find_invokee(tc, bs->method, NULL); MVMCallsite *inv_arg_callsite = MVM_callsite_get_common(tc, MVM_CALLSITE_ID_INV_ARG); if (res_reg) { /* We need to do the invocation, and set this register * the result. Then we just do the call. For the flip * case, just set up special return handler to flip * the register. */ MVM_args_setup_thunk(tc, res_reg, MVM_RETURN_INT, inv_arg_callsite); tc->cur_frame->args[0].o = obj; if (flip) { tc->cur_frame->special_return = flip_return; tc->cur_frame->special_return_data = res_reg; } STABLE(code)->invoke(tc, code, inv_arg_callsite, tc->cur_frame->args); } else { /* Need to set up special return hook. */ BoolMethReturnData *data = MVM_malloc(sizeof(BoolMethReturnData)); data->true_addr = true_addr; data->false_addr = false_addr; data->flip = flip; tc->cur_frame->special_return = boolify_return; tc->cur_frame->special_return_data = data; MVM_args_setup_thunk(tc, &data->res_reg, MVM_RETURN_INT, inv_arg_callsite); tc->cur_frame->args[0].o = obj; STABLE(code)->invoke(tc, code, inv_arg_callsite, tc->cur_frame->args); } return; } case MVM_BOOL_MODE_UNBOX_INT: result = !IS_CONCRETE(obj) || REPR(obj)->box_funcs.get_int(tc, STABLE(obj), obj, OBJECT_BODY(obj)) == 0 ? 0 : 1; break; case MVM_BOOL_MODE_UNBOX_NUM: result = !IS_CONCRETE(obj) || REPR(obj)->box_funcs.get_num(tc, STABLE(obj), obj, OBJECT_BODY(obj)) == 0.0 ? 0 : 1; break; case MVM_BOOL_MODE_UNBOX_STR_NOT_EMPTY: { MVMString *str; if (!IS_CONCRETE(obj)) { result = 0; break; } str = REPR(obj)->box_funcs.get_str(tc, STABLE(obj), obj, OBJECT_BODY(obj)); result = MVM_coerce_istrue_s(tc, str); break; } case MVM_BOOL_MODE_UNBOX_STR_NOT_EMPTY_OR_ZERO: { MVMString *str; MVMint64 chars; if (!IS_CONCRETE(obj)) { result = 0; break; } str = REPR(obj)->box_funcs.get_str(tc, STABLE(obj), obj, OBJECT_BODY(obj)); if (str == NULL || !IS_CONCRETE(str)) { result = 0; break; } chars = MVM_string_graphs(tc, str); result = chars == 0 || (chars == 1 && MVM_string_get_grapheme_at_nocheck(tc, str, 0) == 48) ? 0 : 1; break; } case MVM_BOOL_MODE_NOT_TYPE_OBJECT: result = !IS_CONCRETE(obj) ? 0 : 1; break; case MVM_BOOL_MODE_BIGINT: result = IS_CONCRETE(obj) ? MVM_bigint_bool(tc, obj) : 0; break; case MVM_BOOL_MODE_ITER: result = IS_CONCRETE(obj) ? MVM_iter_istrue(tc, (MVMIter *)obj) : 0; break; case MVM_BOOL_MODE_HAS_ELEMS: result = IS_CONCRETE(obj) ? MVM_repr_elems(tc, obj) != 0 : 0; break; default: MVM_exception_throw_adhoc(tc, "Invalid boolification spec mode used"); } } if (flip) result = result ? 0 : 1; if (res_reg) { res_reg->i64 = result; } else { if (result) *(tc->interp_cur_op) = true_addr; else *(tc->interp_cur_op) = false_addr; } }
static void code_pair_store_n(MVMThreadContext *tc, MVMObject *cont, MVMnum64 value) { MVMRegister r; r.n64 = value; code_pair_store_internal(tc, cont, r, MVM_callsite_get_common(tc, MVM_CALLSITE_ID_OBJ_NUM)); }