wattype.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,874 行 · 第 1/4 页

C
1,874
字号
                return( DS_ERR|DS_BAD_LOCATION );
            }
            LocationAdd( ll, adj.e[0].u.addr.mach.offset * 8 );
            new = new->prev;
        }
        ok = LoadType( ii, is->im, is->u.typ.t.entry );
        if( ok != DS_OK ) {
            PopLoad();
            return( ok );
        }
        p = Type->start + is->u.typ.t.offset;
    }
    /* do field offset and bit field selection */
    bit_start = 0;
    bit_len = 0;
    switch( p[1] ) {
    case STRUCT_TYPE+ST_BIT_BYTE:
        bit_start = p[3];
        bit_len   = p[4];
        /* fall through */
    case STRUCT_TYPE+ST_FIELD_BYTE:
        offset = *(unsigned_8 *)(p+2);
        break;
    case STRUCT_TYPE+ST_BIT_WORD:
        bit_start = p[4];
        bit_len   = p[5];
        /* fall through */
    case STRUCT_TYPE+ST_FIELD_WORD:
        offset = *(unsigned_16 *)(p+2);
        break;
    case STRUCT_TYPE+ST_BIT_LONG:
        bit_start = p[6];
        bit_len   = p[7];
        /* fall through */
    case STRUCT_TYPE+ST_FIELD_LONG:
        offset = *(unsigned_32 *)(p+2);
        break;
    case STRUCT_TYPE+ST_FIELD_LOC:
    case STRUCT_TYPE+ST_BIT_LOC:
        if( info & (NEED_BASE|EMPTY_EXPR) ) PushBaseLocation( ll );
        ok = EvalLocation( ii, lc, p + 3, ll );
        if( ok != DS_OK ) {
            PopLoad();
            return( ok );
        }
        if( p[1] == STRUCT_TYPE+ST_BIT_LOC ) {
            p = SkipLocation( p + 3 );
            bit_start = p[0];
            bit_len = p[1];
        }
        offset = 0;
    }
    PopLoad();
    LocationAdd( ll, offset * 8 + bit_start );
    LocationTrunc( ll, bit_len );
    return( DS_OK );
}

dip_status SymHdl2MbrInfo( imp_image_handle *ii, imp_sym_handle *is,
                        sym_info *si, location_context *lc )
{
    byte                *p;
    unsigned            index;
    dip_status          ret;
    unsigned            attrib;
    imp_type_handle     tmp;
    imp_sym_handle      func_is;
    byte                kind;
    location_list       ll;
    typeinfo            typeld;

    PushLoad( &typeld );
    ret = LoadType( ii, is->im, is->u.typ.t.entry );
    if( ret != DS_OK ) {
        PopLoad();
        return( ret );
    }
    p = Type->start + is->u.typ.t.offset;
    switch( p[1] ) {
    case STRUCT_TYPE+ST_FIELD_LOC:
    case STRUCT_TYPE+ST_BIT_LOC:
        attrib = p[2];
        break;
    default:
        attrib = 0;
        break;
    }
    p = BaseTypePtr( p );
    GetIndex( p, &index );
    ret = FindRawTypeHandle( ii, is->im, index, &tmp );
    if( ret != DS_OK ) return( ret );
    kind = GetRealTypeHandle( ii, &tmp ) & CLASS_MASK;
    PopLoad();
    switch( kind ) {
    case PROC_TYPE:
        si->kind = SK_PROCEDURE;
        ret = SymHdl2MbrLoc( ii, is, lc, &ll );
        if( ret == DS_OK ) {
            func_is.im = is->im;
            if( LookupLclAddr( ii, ll.e[0].u.addr, &func_is ) == SR_EXACT ) {
                ret = SymHdl2LclInfo( ii, &func_is, si );
            }
        }
        break;
    default:
        si->kind = SK_DATA;
        break;
    }
    si->member = 1;
    if( attrib & 0x01 ) si->compiler = 1;
    if( attrib & 0x02 ) si->is_public = 1;
    if( attrib & 0x04 ) si->is_protected = 1;
    if( attrib & 0x08 ) si->is_private = 1;
    return( ret );
}

dip_status DIPENTRY DIPImpTypeThunkAdjust( imp_image_handle *ii,
                    imp_type_handle *oit, imp_type_handle *mit,
                    location_context *lc, address *addr )
{
    byte                *p;
    unsigned            count;
    struct anc_graph    *pending, *new, *tmp;
    imp_type_handle     new_it;
    unsigned            index;
    dip_status          ok;
    location_list       adj;
    typeinfo            typeld;

    if( oit->im != mit->im ) return( DS_FAIL );
    PushLoad( &typeld );
    ok = LoadType( ii, oit->im, oit->t.entry );
    if( ok != DS_OK ) {
        PopLoad();
        return( ok );
    }
    p = Type->start + oit->t.offset;
    pending = NULL;
    count = *(unsigned_16 *)(p+2);
    for( ;; ) {
        if( count == 0 ) {
            if( pending == NULL ) return( DS_FAIL );
            ok = LoadType( ii, oit->im, pending->entry );
            if( ok != DS_OK ) {
                PopLoad();
                return( ok );
            }
            count = pending->u.s.count;
            p = Type->start + pending->u.s.off;
            pending = pending->prev;
        }
        --count;
        p = NEXT_TYPE( p );
        if( p[1] == STRUCT_TYPE+ST_INHERIT ) {
            new = __alloca( sizeof( *new ) );
            new->entry = Type->entry;
            new->u.s.off = p - Type->start;
            new->u.s.count = count;
            new->prev = pending;
            pending = new;
            p = SkipLocation( p + 2 );
            GetIndex( p, &index );
            ok = DoFindTypeHandle( ii, oit->im, index, &new_it );
            if( ok != DS_OK ) {
                PopLoad();
                return( ok );
            }
            if( new_it.t.offset == mit->t.offset
              && new_it.t.entry == mit->t.entry ) break;
            p = Type->start + new_it.t.offset;
            count = *(unsigned_16 *)(p+2);
        }
    }
    /* reverse the inheritance list */
    new = NULL;
    while( pending != NULL ) {
        tmp = pending;
        pending = tmp->prev;
        tmp->prev = new;
        new = tmp;
    }
    /* do the adjustors at each level */
    while( new != NULL ) {
        ok = LoadType( ii, oit->im, new->entry );
        if( ok != DS_OK ) {
            PopLoad();
            return( ok );
        }
        p = new->u.s.off + Type->start;
        ok = EvalLocation( ii, lc, p + 2, &adj );
        if( !ok ) {
            PopLoad();
            return( ok );
        }
        if( adj.num != 1 || adj.e[0].type != LT_ADDR ) {
            PopLoad();
            DCStatus( DS_ERR|DS_BAD_LOCATION );
            return( DS_ERR|DS_BAD_LOCATION );
        }
        addr->mach.offset += adj.e[0].u.addr.mach.offset;
        new = new->prev;
    }
    PopLoad();
    return( DS_OK );
}

search_result SearchMbr( imp_image_handle *ii, imp_type_handle *it,
                 lookup_item *li, void *d )
{
    byte                *p;
    unsigned            count;
    search_result       sr;
    struct anc_graph    *pending, *new;
    imp_type_handle     new_it;
    unsigned            index;
    int                 (*comp)();
    imp_sym_handle      *is;
    byte                *name;
    unsigned            len;
    typeinfo            typeld;

    PushLoad( &typeld );
    if( LoadType( ii, it->im, it->t.entry ) != DS_OK ) {
        PopLoad();
        return( SR_NONE );
    }
    p = Type->start + it->t.offset;
    if( (p[1] & CLASS_MASK) != STRUCT_TYPE ) {
        PopLoad();
        return( SR_NONE );
    }
    if( li->case_sensitive ) {
        comp = memcmp;
    } else {
        comp = memicmp;
    }
    sr = SR_NONE;
    pending = NULL;
    count = *(unsigned_16 *)(p+2);
    for( ;; ) {
        if( count == 0 ) {
            if( pending == NULL ) break;
            if( LoadType( ii, it->im, pending->entry ) != DS_OK ) {
                PopLoad();
                return( WR_STOP );
            }
            count = pending->u.s.count;
            p = Type->start + pending->u.s.off;
            pending = pending->prev;
        }
        --count;
        p = NEXT_TYPE( p );
        if( p[1] == STRUCT_TYPE+ST_INHERIT ) {
            new = __alloca( sizeof( *new ) );
            new->entry = Type->entry;
            new->u.s.off = p - Type->start;
            new->u.s.count = count;
            new->prev = pending;
            pending = new;
            p = SkipLocation( p + 2 );
            GetIndex( p, &index );
            if( DoFindTypeHandle( ii, it->im, index, &new_it ) != DS_OK ) {
                PopLoad();
                return( WR_STOP );
            }
            p = Type->start + new_it.t.offset;
            count = *(unsigned_16 *)(p+2);
        } else {
            name = NamePtr( p );
            len = *p - (name - p);
            if( len==li->name.len && comp(name,li->name.start,len)==0 ) {
                is = DCSymCreate( ii, d );
                is->u.typ.t.offset = p - Type->start;
                is->u.typ.t.entry = Type->entry;
                is->name_off = name - p;
                is->im = it->im;
                is->u.typ.h = it->t;
                is->type = SH_MBR;
                sr = SR_EXACT;
            }
        }
    }
    PopLoad();
    return( sr );
}

walk_result WalkTypeSymList( imp_image_handle *ii, imp_type_handle *it,
                 IMP_SYM_WKR *wk, imp_sym_handle *is, void *d )
{
    byte                        *p;
    unsigned                    count;
    walk_result                 wr;
    struct anc_graph            *pending, *new;
    imp_type_handle             new_it;
    unsigned                    index;
    struct pending_entry        *list, *new_entry, *used;
    typeinfo                    typeld;

    PushLoad( &typeld );
    if( LoadType( ii, it->im, it->t.entry ) != DS_OK ) {
        PopLoad();
        return( WR_STOP );
    }
    is->im = it->im;
    is->u.typ.h = it->t;
    list = NULL;
    used = NULL;
    pending = NULL;
    p = Type->start + it->t.offset;
    switch( p[1] & CLASS_MASK ) {
    case STRUCT_TYPE:
        is->type = SH_MBR;
        goto do_walk;
    case ENUM_TYPE:
        is->type = SH_CST;
do_walk:
        count = *(unsigned_16 *)(p+2);
        wr = WR_CONTINUE;
        for( ;; ) {
            while( count != 0 ) {
                /* structure list is backwards -- reverse it */
                p = NEXT_TYPE( p );
                if( used == NULL ) {
                    new_entry = __alloca( sizeof( *new_entry ) );
                } else {
                    new_entry = used;
                    used = used->prev;
                }
                new_entry->off = p - Type->start;
                new_entry->prev = list;
                list = new_entry;
                --count;
            }
            if( list == NULL ) {
                if( pending == NULL ) break;
                wk( ii, SWI_INHERIT_END, NULL, d );
                if( LoadType( ii, it->im, pending->entry ) != DS_OK ) {
                    PopLoad();
                    return( WR_STOP );
                }
                list = pending->u.todo;
                pending = pending->prev;
            }
            p = list->off + Type->start;
            if( p[1] == STRUCT_TYPE+ST_INHERIT ) {
                if( wk( ii, SWI_INHERIT_START, NULL, d ) == WR_CONTINUE ) {
                    if( list->prev != NULL ) {
                        new = __alloca( sizeof( *new ) );
                        new->entry = Type->entry;
                        new->u.todo = list->prev;
                        new->prev = pending;
                        pending = new;
                    }
                    p = SkipLocation( p + 2 );
                    GetIndex( p, &index );
                    if( DoFindTypeHandle( ii, it->im, index, &new_it ) != DS_OK ) {
                        PopLoad();
                        return( WR_STOP );
                    }
                    list = NULL;
                    p = Type->start + new_it.t.offset;
                    count = *(unsigned_16 *)(p+2);
                    /* setting count will cause the list to be reversed */
                    continue;
                }
            } else {
                is->u.typ.t.offset = p - Type->start;
                is->u.typ.t.entry = Type->entry;
                is->name_off = NamePtr( p ) - p;
                wr = wk( ii, SWI_SYMBOL, is, d );
                if( wr != WR_CONTINUE ) break;
            }
            new_entry = list->prev;
            list->prev = used;
            used = list;
            list = new_entry;
        }
        break;
    default:
        wr = WR_STOP;
        break;
    }
    PopLoad();
    return( wr );
}

imp_mod_handle DIPENTRY DIPImpTypeMod( imp_image_handle *ii,
                                imp_type_handle *it )
{
    ii = ii;
    return( it->im );
}

void *FindSpecCueTable( imp_image_handle *ii, imp_mod_handle im, void **base )
{
    typeinfo            typeld;
    byte                *p;
    unsigned            entry;
    unsigned long       offset;
    unsigned            size;

    PushLoad( &typeld );
    if( LoadType( ii, im, 0 ) != DS_OK ) goto missing;
    for( p = Type->start; p < Type->end; p = NEXT_TYPE( p ) ) {
        if( p[1] == (NAME_TYPE+TYPE_CUE_TABLE) ) {
            offset = *(unsigned_32 *)(p+2);
            entry = 0;
            for( ;; ) {
                size = InfoSize( ii, im, DMND_TYPES, entry );
                if( size == 0 ) goto missing;
                if( size > offset ) break;
                offset -= size;
                ++entry;
            }
            if( LoadType( ii, im, entry ) != DS_OK ) goto missing;
            p = Type->start;
            *base = p;
            InfoSpecLock( p ); /* so that the PopLoad doesn't free it */
            PopLoad();
            return( p + (unsigned)offset );
        }
    }
missing:
    *base = NULL;
    PopLoad();
    return( NULL );
}

int DIPENTRY DIPImpTypeCmp( imp_image_handle *ii, imp_type_handle *it1,
                        imp_type_handle *it2 )
{
    ii = ii;
    if( it1->im != it2->im ) return( it1->im - it2->im );
    if( it1->t.entry != it2->t.entry ) return( it1->t.entry - it2->t.entry );
    return( it1->t.offset - it2->t.offset );
}


unsigned DIPENTRY DIPImpTypeName( imp_image_handle *ii, imp_type_handle *it,
                unsigned num, symbol_type *tag, char *buff, unsigned max )
{
    //NYI: stub implementation
    ii = ii; it = it; num = num; tag = tag; buff = buff; max = max;
    return( 0 );
}

dip_status DIPENTRY DIPImpTypeAddRef( imp_image_handle *ii, imp_type_handle *it )
{
    ii=ii;
    it=it;
    return(DS_OK);
}

dip_status DIPENTRY DIPImpTypeRelease( imp_image_handle *ii, imp_type_handle *it )
{
    ii=ii;
    it=it;
    return(DS_OK);
}

dip_status DIPENTRY DIPImpTypeFreeAll( imp_image_handle *ii )
{
    ii=ii;
    return(DS_OK);
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?