void MVM_intcache_for(MVMThreadContext *tc, MVMObject *type) { int type_index; int right_slot = -1; uv_mutex_lock(&tc->instance->mutex_int_const_cache); for (type_index = 0; type_index < 4; type_index++) { if (tc->instance->int_const_cache->types[type_index] == NULL) { right_slot = type_index; break; } else if (tc->instance->int_const_cache->types[type_index] == type) { uv_mutex_unlock(&tc->instance->mutex_int_const_cache); return; } } if (right_slot != -1) { int val; for (val = 0; val < 16; val++) { MVMObject *obj; obj = MVM_repr_alloc_init(tc, type); MVM_repr_set_int(tc, obj, val); tc->instance->int_const_cache->cache[type_index][val] = obj; MVM_gc_root_add_permanent(tc, (MVMCollectable **)&tc->instance->int_const_cache->cache[type_index][val]); } tc->instance->int_const_cache->types[type_index] = type; MVM_gc_root_add_permanent(tc, (MVMCollectable **)&tc->instance->int_const_cache->types[type_index]); } uv_mutex_unlock(&tc->instance->mutex_int_const_cache); }
/* Set up some standard file handles. */ static void setup_std_handles(MVMThreadContext *tc) { tc->instance->stdin_handle = MVM_file_get_stdstream(tc, 0, 1); MVM_gc_root_add_permanent(tc, (MVMCollectable **)&tc->instance->stdin_handle); tc->instance->stdout_handle = MVM_file_get_stdstream(tc, 1, 0); MVM_gc_root_add_permanent(tc, (MVMCollectable **)&tc->instance->stdout_handle); tc->instance->stderr_handle = MVM_file_get_stdstream(tc, 2, 0); MVM_gc_root_add_permanent(tc, (MVMCollectable **)&tc->instance->stderr_handle); }
/* Sets up some string constants. */ static void string_consts(MVMThreadContext *tc) { MVMInstance * const instance = tc->instance; instance->str_consts.empty = MVM_string_ascii_decode_nt(tc, tc->instance->VMString, ""); MVM_gc_root_add_permanent(tc, (MVMCollectable **)&instance->str_consts.empty); instance->str_consts.Str = MVM_string_ascii_decode_nt(tc, tc->instance->VMString, "Str"); MVM_gc_root_add_permanent(tc, (MVMCollectable **)&instance->str_consts.Str); instance->str_consts.Num = MVM_string_ascii_decode_nt(tc, tc->instance->VMString, "Num"); MVM_gc_root_add_permanent(tc, (MVMCollectable **)&instance->str_consts.Num); }
/* Bootstraps the KnowHOW type. */ static void bootstrap_KnowHOW(MVMThreadContext *tc) { MVMObject *VMString = tc->instance->VMString; MVMObject *BOOTArray = tc->instance->boot_types->BOOTArray; MVMObject *BOOTHash = tc->instance->boot_types->BOOTHash; /* Create our KnowHOW type object. Note we don't have a HOW just yet, so * pass in NULL. */ MVMREPROps *REPR = MVM_repr_get_by_id(tc, MVM_REPR_ID_KnowHOWREPR); MVMObject *knowhow = REPR->type_object_for(tc, NULL); /* We create a KnowHOW instance that can describe itself. This means * (once we tie the knot) that .HOW.HOW.HOW.HOW etc will always return * that, which closes the model up. Note that the STable for it must * be allocated first, since that holds the allocation size. */ MVMKnowHOWREPR *knowhow_how; MVMSTable *st = MVM_gc_allocate_stable(tc, REPR, NULL); st->WHAT = (MVMObject *)knowhow; st->size = sizeof(MVMKnowHOWREPR); knowhow_how = (MVMKnowHOWREPR *)REPR->allocate(tc, st); st->HOW = (MVMObject *)knowhow_how; knowhow_how->common.st = st; /* Add various methods to the KnowHOW's HOW. */ REPR->initialize(tc, NULL, (MVMObject *)knowhow_how, &knowhow_how->body); add_knowhow_how_method(tc, knowhow_how, "new_type", new_type); add_knowhow_how_method(tc, knowhow_how, "add_method", add_method); add_knowhow_how_method(tc, knowhow_how, "add_attribute", add_attribute); add_knowhow_how_method(tc, knowhow_how, "compose", compose); add_knowhow_how_method(tc, knowhow_how, "attributes", attributes); add_knowhow_how_method(tc, knowhow_how, "methods", methods); add_knowhow_how_method(tc, knowhow_how, "name", name); /* Set name KnowHOW for the KnowHOW's HOW. */ knowhow_how->body.name = MVM_string_ascii_decode_nt(tc, VMString, "KnowHOW"); /* Set this built up HOW as the KnowHOW's HOW. */ STABLE(knowhow)->HOW = (MVMObject *)knowhow_how; /* Give it an authoritative method cache; this in turn will make the * method dispatch bottom out. */ STABLE(knowhow)->method_cache = knowhow_how->body.methods; STABLE(knowhow)->mode_flags = MVM_METHOD_CACHE_AUTHORITATIVE; STABLE(knowhow_how)->method_cache = knowhow_how->body.methods; STABLE(knowhow_how)->mode_flags = MVM_METHOD_CACHE_AUTHORITATIVE; /* Associate the created objects with the initial core serialization * context. */ /* XXX TODO */ /* Stash the created KnowHOW. */ tc->instance->KnowHOW = (MVMObject *)knowhow; MVM_gc_root_add_permanent(tc, (MVMCollectable **)&tc->instance->KnowHOW); }
/* Registers a representation. */ static void register_repr(MVMThreadContext *tc, const MVMREPROps *repr, MVMString *name) { MVMReprRegistry *entry; if (!name) name = MVM_string_ascii_decode_nt(tc, tc->instance->VMString, repr->name); /* Fill a registry entry. */ entry = malloc(sizeof(MVMReprRegistry)); entry->name = name; entry->repr = repr; /* Name should become a permanent GC root. */ MVM_gc_root_add_permanent(tc, (MVMCollectable **)&entry->name); /* Enter into registry. */ tc->instance->repr_list[repr->ID] = entry; MVM_string_flatten(tc, name); MVM_HASH_BIND(tc, tc->instance->repr_hash, name, entry); }
int MVM_dll_load(MVMThreadContext *tc, MVMString *name, MVMString *path) { MVMDLLRegistry *entry; char *cpath; DLLib *lib; uv_mutex_lock(&tc->instance->mutex_dll_registry); MVM_string_flatten(tc, name); MVM_HASH_GET(tc, tc->instance->dll_registry, name, entry); /* already loaded */ if (entry && entry->lib) { uv_mutex_unlock(&tc->instance->mutex_dll_registry); return 0; } cpath = MVM_string_utf8_encode_C_string(tc, path); lib = dlLoadLibrary(cpath); if (!lib) { uv_mutex_unlock(&tc->instance->mutex_dll_registry); MVM_exception_throw_adhoc(tc, "failed to load library '%s'", cpath); } free(cpath); if (!entry) { entry = malloc(sizeof *entry); entry->name = name; entry->refcount = 0; MVM_gc_root_add_permanent(tc, (MVMCollectable **)&entry->name); MVM_HASH_BIND(tc, tc->instance->dll_registry, name, entry); } entry->lib = lib; uv_mutex_unlock(&tc->instance->mutex_dll_registry); return 1; }
/* Registers a representation. It this is ever made public, it should first be * made thread-safe, and it should check if the name is already registered. */ static void register_repr(MVMThreadContext *tc, MVMString *name, MVMREPROps *repr) { /* Allocate an ID. */ MVMuint32 ID = tc->instance->num_reprs; /* Allocate a hash entry for the name-to-ID. Could one day be unified with MVMREPROps, I suppose. */ MVMREPRHashEntry *entry = calloc(sizeof(MVMREPRHashEntry), 1); entry->value = ID; /* Bump the repr count */ tc->instance->num_reprs++; /* Stash ID and name. */ repr->ID = ID; repr->name = name; /* Name should become a permanent GC root. */ MVM_gc_root_add_permanent(tc, (MVMCollectable **)&repr->name); /* Enter into registry. */ if (tc->instance->repr_registry) tc->instance->repr_registry = realloc(tc->instance->repr_registry, tc->instance->num_reprs * sizeof(MVMREPROps *)); else tc->instance->repr_registry = malloc(tc->instance->num_reprs * sizeof(MVMREPROps *)); tc->instance->repr_registry[ID] = repr; MVM_string_flatten(tc, name); MVM_HASH_BIND(tc, tc->instance->repr_name_to_id_hash, name, entry); /* Add default "not implemented" function table implementations. */ if (!repr->elems) repr->elems = default_elems; if (!repr->attr_funcs) add_default_attr_funcs(tc, repr); if (!repr->box_funcs) add_default_box_funcs(tc, repr); if (!repr->pos_funcs) add_default_pos_funcs(tc, repr); if (!repr->ass_funcs) add_default_ass_funcs(tc, repr); }
/* Sets up some string constants. */ static void string_consts(MVMThreadContext *tc) { MVMInstance * const instance = tc->instance; instance->str_consts.empty = MVM_string_ascii_decode_nt(tc, tc->instance->VMString, ""); MVM_gc_root_add_permanent(tc, (MVMCollectable **)&instance->str_consts.empty); instance->str_consts.Str = MVM_string_ascii_decode_nt(tc, tc->instance->VMString, "Str"); MVM_gc_root_add_permanent(tc, (MVMCollectable **)&instance->str_consts.Str); instance->str_consts.Num = MVM_string_ascii_decode_nt(tc, tc->instance->VMString, "Num"); MVM_gc_root_add_permanent(tc, (MVMCollectable **)&instance->str_consts.Num); instance->str_consts.find_method = MVM_string_ascii_decode_nt(tc, tc->instance->VMString, "find_method"); MVM_gc_root_add_permanent(tc, (MVMCollectable **)&instance->str_consts.find_method); instance->str_consts.type_check = MVM_string_ascii_decode_nt(tc, tc->instance->VMString, "type_check"); MVM_gc_root_add_permanent(tc, (MVMCollectable **)&instance->str_consts.type_check); instance->str_consts.accepts_type = MVM_string_ascii_decode_nt(tc, tc->instance->VMString, "accepts_type"); MVM_gc_root_add_permanent(tc, (MVMCollectable **)&instance->str_consts.accepts_type); }
MVMHLLConfig *MVM_hll_get_config_for(MVMThreadContext *tc, MVMString *name) { void *kdata; MVMHLLConfig *entry; size_t klen; MVM_HASH_EXTRACT_KEY(tc, &kdata, &klen, name, "get hll config needs concrete string"); uv_mutex_lock(&tc->instance->mutex_hllconfigs); if (tc->instance->hll_compilee_depth) HASH_FIND(hash_handle, tc->instance->compilee_hll_configs, kdata, klen, entry); else HASH_FIND(hash_handle, tc->instance->compiler_hll_configs, kdata, klen, entry); if (!entry) { entry = calloc(sizeof(MVMHLLConfig), 1); entry->name = name; entry->int_box_type = tc->instance->boot_types.BOOTInt; entry->num_box_type = tc->instance->boot_types.BOOTNum; entry->str_box_type = tc->instance->boot_types.BOOTStr; entry->slurpy_array_type = tc->instance->boot_types.BOOTArray; entry->slurpy_hash_type = tc->instance->boot_types.BOOTHash; entry->array_iterator_type = tc->instance->boot_types.BOOTIter; entry->hash_iterator_type = tc->instance->boot_types.BOOTIter; entry->foreign_type_int = tc->instance->boot_types.BOOTInt; entry->foreign_type_num = tc->instance->boot_types.BOOTNum; entry->foreign_type_str = tc->instance->boot_types.BOOTStr; entry->foreign_transform_array = NULL; entry->foreign_transform_hash = NULL; entry->foreign_transform_code = NULL; entry->null_value = NULL; entry->exit_handler = NULL; entry->bind_error = NULL; entry->method_not_found_error = NULL; if (tc->instance->hll_compilee_depth) HASH_ADD_KEYPTR(hash_handle, tc->instance->compilee_hll_configs, kdata, klen, entry); else HASH_ADD_KEYPTR(hash_handle, tc->instance->compiler_hll_configs, kdata, klen, entry); MVM_gc_root_add_permanent(tc, (MVMCollectable **)&entry->int_box_type); MVM_gc_root_add_permanent(tc, (MVMCollectable **)&entry->num_box_type); MVM_gc_root_add_permanent(tc, (MVMCollectable **)&entry->str_box_type); MVM_gc_root_add_permanent(tc, (MVMCollectable **)&entry->slurpy_array_type); MVM_gc_root_add_permanent(tc, (MVMCollectable **)&entry->slurpy_hash_type); MVM_gc_root_add_permanent(tc, (MVMCollectable **)&entry->array_iterator_type); MVM_gc_root_add_permanent(tc, (MVMCollectable **)&entry->hash_iterator_type); MVM_gc_root_add_permanent(tc, (MVMCollectable **)&entry->foreign_type_int); MVM_gc_root_add_permanent(tc, (MVMCollectable **)&entry->foreign_type_num); MVM_gc_root_add_permanent(tc, (MVMCollectable **)&entry->foreign_type_str); MVM_gc_root_add_permanent(tc, (MVMCollectable **)&entry->foreign_transform_array); MVM_gc_root_add_permanent(tc, (MVMCollectable **)&entry->foreign_transform_hash); MVM_gc_root_add_permanent(tc, (MVMCollectable **)&entry->foreign_transform_code); MVM_gc_root_add_permanent(tc, (MVMCollectable **)&entry->null_value); MVM_gc_root_add_permanent(tc, (MVMCollectable **)&entry->exit_handler); MVM_gc_root_add_permanent(tc, (MVMCollectable **)&entry->bind_error); MVM_gc_root_add_permanent(tc, (MVMCollectable **)&entry->method_not_found_error); MVM_gc_root_add_permanent(tc, (MVMCollectable **)&entry->name); } uv_mutex_unlock(&tc->instance->mutex_hllconfigs); return entry; }