/* Finishes up reading and exploding of a frame. */ void MVM_bytecode_finish_frame(MVMThreadContext *tc, MVMCompUnit *cu, MVMStaticFrame *sf, MVMint32 dump_only) { MVMuint32 j; MVMuint8 *pos; MVMuint16 slvs; /* Ensure we've not already done this. */ if (sf->body.fully_deserialized) return; /* Acquire the update mutex on the CompUnit. */ MVM_reentrantmutex_lock(tc, (MVMReentrantMutex *)cu->body.update_mutex); /* Ensure no other thread has done this for us in the mean time. */ if (sf->body.fully_deserialized) { MVM_reentrantmutex_unlock(tc, (MVMReentrantMutex *)cu->body.update_mutex); return; } /* Locate start of frame body. */ pos = sf->body.frame_data_pos; /* Get the number of static lex values we'll need to apply. */ slvs = read_int16(pos, 40); /* Skip past header. */ pos += FRAME_HEADER_SIZE; /* Read the local types. */ if (sf->body.num_locals) { sf->body.local_types = MVM_malloc(sizeof(MVMuint16) * sf->body.num_locals); for (j = 0; j < sf->body.num_locals; j++) sf->body.local_types[j] = read_int16(pos, 2 * j); pos += 2 * sf->body.num_locals; } /* Read the lexical types. */ if (sf->body.num_lexicals) { /* Allocate names hash and types list. */ sf->body.lexical_types = MVM_malloc(sizeof(MVMuint16) * sf->body.num_lexicals); /* Read in data. */ if (sf->body.num_lexicals) { sf->body.lexical_names_list = MVM_malloc(sizeof(MVMLexicalRegistry *) * sf->body.num_lexicals); } for (j = 0; j < sf->body.num_lexicals; j++) { MVMString *name = get_heap_string(tc, cu, NULL, pos, 6 * j + 2); MVMLexicalRegistry *entry = MVM_calloc(1, sizeof(MVMLexicalRegistry)); MVM_ASSIGN_REF(tc, &(sf->common.header), entry->key, name); sf->body.lexical_names_list[j] = entry; entry->value = j; sf->body.lexical_types[j] = read_int16(pos, 6 * j); MVM_string_flatten(tc, name); MVM_HASH_BIND(tc, sf->body.lexical_names, name, entry) } pos += 6 * sf->body.num_lexicals; }
/* Ensures that a given compilation unit has access to the specified extop. */ static void demand_extop(MVMThreadContext *tc, MVMCompUnit *target_cu, MVMCompUnit *source_cu, const MVMOpInfo *info) { MVMExtOpRecord *extops; MVMuint16 i, num_extops; MVM_reentrantmutex_lock(tc, (MVMReentrantMutex *)target_cu->body.update_mutex); /* See if the target compunit already has the extop. */ extops = target_cu->body.extops; num_extops = target_cu->body.num_extops; for (i = 0; i < num_extops; i++) if (extops[i].info == info) { MVM_reentrantmutex_unlock(tc, (MVMReentrantMutex *)target_cu->body.update_mutex); return; } /* If not, need to add it. Locate it in the source CU. */ extops = source_cu->body.extops; num_extops = source_cu->body.num_extops; for (i = 0; i < num_extops; i++) { if (extops[i].info == info) { MVMuint32 size = (target_cu->body.num_extops + 1) * sizeof(MVMExtOpRecord); target_cu->body.extops = target_cu->body.extops ? MVM_realloc(target_cu->body.extops, size) : MVM_malloc(size); memcpy(&target_cu->body.extops[target_cu->body.num_extops], &extops[i], sizeof(MVMExtOpRecord)); target_cu->body.num_extops++; MVM_reentrantmutex_unlock(tc, (MVMReentrantMutex *)target_cu->body.update_mutex); return; } } /* Didn't find it; should be impossible. */ MVM_reentrantmutex_unlock(tc, (MVMReentrantMutex *)target_cu->body.update_mutex); MVM_oops(tc, "Spesh: inline failed to find source CU extop entry"); }