예제 #1
0
파일: bytecode.c 프로젝트: tomboy-64/MoarVM
/* 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;
    }
예제 #2
0
/* 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");
}