wattype.c

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

C
1,874
字号
}

dip_status DIPENTRY DIPImpTypeBase(imp_image_handle *ii, imp_type_handle *it,
                 imp_type_handle *base,
                 location_context *lc, location_list *ll )
{
    unsigned    index;
    byte        *p;
    dip_status  ret;
    typeinfo    typeld;

    PushLoad( &typeld );
    *base = *it;
    ret = LoadType( ii, it->im, it->t.entry );
    if( ret != DS_OK ) {
        PopLoad();
        return( ret );
    }
    p = it->t.offset + Type->start;
    if( base->f.s.col_major ) {
        if( base->f.s.array_ss > 1 ) {
            base->f.s.array_ss--;
        } else {
            base->f.s.col_major = 0;
            do {
                p = BaseTypePtr( p );
                GetIndex( p, &index );
                FindRawTypeHandle( ii, base->im, index, base );
                p = base->t.offset + Type->start;
            } while( (p[1] & CLASS_MASK) == ARRAY_TYPE );
        }
        PopLoad();
    } else if( p[1] == ENUM_TYPE+ENUM_LIST ) {
        base->t.offset = *(unsigned_8 *)(p+4);
        base->f.s.sclr = 1;
        PopLoad();
    } else {
        p = BaseTypePtr( p );
        if( p == NULL ) return( DS_FAIL );
        GetIndex( p, &index );
        PopLoad();
        FindTypeHandle( ii, it->im, index, base );
    }
    return( DS_OK );
}

dip_status DIPENTRY DIPImpTypeArrayInfo(imp_image_handle *ii, imp_type_handle *it,
             location_context *lc, array_info *ai, imp_type_handle *index )
{
    byte                *p;
    unsigned            index_idx;
    unsigned            scalar;
    imp_type_handle     tmp;
    address             addr;
    byte                is_32;
    long                hi;
    type_info           info;
    unsigned            count;
    dip_status          ret;
    typeinfo            typeld;

    if( it->f.s.col_major ) {
        tmp = *it;
        tmp.f.s.col_major = 0;
        for( count = tmp.f.s.array_ss-1; count != 0; --count ) {
            ImpInterface.type_base( ii, &tmp, &tmp, NULL, NULL );
        }
        ImpInterface.type_array_info( ii, &tmp, lc, ai, index );
        ai->num_dims = tmp.f.s.array_ss - ai->num_dims + 1;
        ai->column_major = 1;
        return( DS_OK );
    }
    PushLoad( &typeld );
    ret = LoadType( ii, it->im, it->t.entry );
    if( ret != DS_OK ) {
        PopLoad();
        return( ret );
    }
    is_32 = 1;
    index_idx = 0;
    scalar = SCLR_UNSIGNED | 3;
    p = it->t.offset + Type->start;
    switch( p[1] ) {
    case ARRAY_TYPE+ARRAY_BYTE_INDEX:
        ai->num_elts = *(unsigned_8 *)(p+2) + 1;
        ai->low_bound = 0;
        break;
    case ARRAY_TYPE+ARRAY_WORD_INDEX:
        ai->num_elts = *(unsigned_16 *)(p+2) + 1;
        ai->low_bound = 0;
        break;
    case ARRAY_TYPE+ARRAY_LONG_INDEX:
        ai->num_elts = *(unsigned_32 *)(p+2) + 1;
        ai->low_bound = 0;
        break;
    case ARRAY_TYPE+ARRAY_TYPE_INDEX:
        GetIndex( p + 2, &index_idx );
        ret = FindTypeHandle( ii, it->im, index_idx, &tmp );
        if( ret != DS_OK ) {
            PopLoad();
            return( ret );
        }
        ret = LoadType( ii, tmp.im, tmp.t.entry );
        if( ret != DS_OK ) {
            PopLoad();
            return( ret );
        }
        p = tmp.t.offset + Type->start;
        switch( p[1] ) {
        case SUBRANGE_TYPE+SUBRANGE_BYTE:
            ai->low_bound = *(signed_8 *)(p+2);
            hi = *(signed_8 *)(p+3);
            break;
        case SUBRANGE_TYPE+SUBRANGE_WORD:
            ai->low_bound = *(signed_16 *)(p+2);
            hi = *(signed_16 *)(p+4);
            break;
        case SUBRANGE_TYPE+SUBRANGE_LONG:
            ai->low_bound = *(signed_32 *)(p+2);
            hi = *(signed_32 *)(p+6);
            break;
        }
        ai->num_elts = (hi - ai->low_bound) + 1;
        break;
    case ARRAY_TYPE+ARRAY_DESC_INDEX:
        is_32 = 0;
        /* fall through */
    case ARRAY_TYPE+ARRAY_DESC386_INDEX:
        GetAddress( ii, p + 4, &addr, is_32 );
        scalar = *(unsigned_8 *)(p+2);
        ai->low_bound = GetScalar( addr, scalar );
        addr.mach.offset += (scalar & SCLR_LEN_MASK) + 1;
        ai->num_elts = GetScalar( addr, *(unsigned_8 *)(p+3) );
        break;
    }
    PopLoad();
    ImpInterface.type_base( ii, it, &tmp, NULL, NULL );
    ai->num_dims = 1;
    ret = GetTypeInfo( ii, &tmp, lc, &info, &ai->num_dims );
    if( ret != DS_OK ) return( ret );
    ai->stride = info.size;
    ai->column_major = 0;
    if( index != NULL ) {
        if( index_idx != 0 ) {
            FindTypeHandle( ii, it->im, index_idx, index );
        } else {
            index->im = it->im;
            index->f.all = 0;
            index->f.s.sclr = 1;
            index->t.offset = scalar;
        }
    }
    return( DS_OK );
}

dip_status DIPENTRY DIPImpTypeProcInfo(imp_image_handle *ii, imp_type_handle *it,
                 imp_type_handle *parm, unsigned num )
{
    byte        *p;
    byte        *end;
    unsigned    index;
    dip_status  ret;
    typeinfo    typeld;

    PushLoad( &typeld );
    ret = LoadType( ii, it->im, it->t.entry );
    if( ret != DS_OK ) {
        PopLoad();
        return( ret );
    }
    p = Type->start + it->t.offset;
    end = NEXT_TYPE( p );
    p = GetIndex( p + 2, &index );
    if( num == 0 ) {
        /* nothing to do */
    } else if( num <= *p ) {
        ++p;
        for( ;; ) {
            if( p == end ) {
                /* handle EXT_PARMS record */
                p += 2;
                end = NEXT_TYPE( p );
            }
            p = GetIndex( p, &index );
            --num;
            if( num == 0 ) break;
        }
    } else {
        PopLoad();
        return( DS_NO_PARM );
    }
    PopLoad();
    return( FindTypeHandle( ii, it->im, index, parm ) );
}

dip_status DIPENTRY DIPImpTypePtrAddrSpace( imp_image_handle *ii,
                    imp_type_handle *it, location_context *lc, address *addr )
{
    byte                *p;
    byte                *end;
    dip_status          ret;
    location_list       ll;
    unsigned            dummy;
    typeinfo            typeld;

    PushLoad( &typeld );
    ret = LoadType( ii, it->im, it->t.entry );
    if( ret != DS_OK ) {
        PopLoad();
        return( ret );
    }
    p = Type->start + it->t.offset;
    end = NEXT_TYPE( p );
    p = GetIndex( p + 2, &dummy );
    if( p >= end ) {
        PopLoad();
        return( DS_FAIL );
    }
    LocationCreate( &ll, LT_ADDR, addr );
    PushBaseLocation( &ll );
    ret = EvalLocation( ii, lc, p, &ll );
    PopLoad();
    if( ret != DS_OK ) return( ret );
    if( ll.num != 1 || ll.e[0].type != LT_ADDR ) {
        return( DS_ERR|DS_BAD_LOCATION );
    }
    *addr = ll.e[0].u.addr;
    return( DS_OK );
}

unsigned SymHdl2CstName( imp_image_handle *ii, imp_sym_handle *is,
                        char *name, unsigned max )
{
    byte        *p;
    unsigned    len;
    typeinfo    typeld;

    PushLoad( &typeld );
    if( LoadType( ii, is->im, is->u.typ.t.entry ) != DS_OK ) {
        PopLoad();
        return( 0 );
    }
    p = Type->start + is->u.typ.t.offset;
    len = *p - is->name_off;
    if( max > 0 ) {
        --max;
        if( max > len ) max = len;
        memcpy( name, p + is->name_off, max );
        name[max] = '\0';
    }
    PopLoad();
    return( len );
}

unsigned SymHdl2TypName( imp_image_handle *ii, imp_sym_handle *is,
                        char *name, unsigned max )
{
    return( SymHdl2CstName( ii, is, name, max ) );
}

unsigned SymHdl2MbrName( imp_image_handle *ii, imp_sym_handle *is,
                        char *name, unsigned max )
{
    return( SymHdl2CstName( ii, is, name, max ) );
}

dip_status SymHdl2CstValue( imp_image_handle *ii, imp_sym_handle *is, void *d )
{
    byte                *p;
    byte                *e;
    unsigned_64         val;
    dip_status          ret;
    typeinfo            typeld;

    PushLoad( &typeld );
    ret = LoadType( ii, is->im, is->u.typ.t.entry );
    if( ret != DS_OK ) {
        PopLoad();
        return( ret );
    }
    memset( &val, 0, sizeof( val ) );
    p = Type->start + is->u.typ.t.offset;
    switch( p[1] ) {
    case ENUM_TYPE+ENUM_CONST_BYTE:
        val.u._32[0] = *(signed_8 *)(p+2);
        break;
    case ENUM_TYPE+ENUM_CONST_WORD:
        val.u._32[0] = *(signed_16 *)(p+2);
        break;
    case ENUM_TYPE+ENUM_CONST_LONG:
        val.u._32[0] = *(signed_32 *)(p+2);
        break;
    case ENUM_TYPE+ENUM_CONST_I64:
        memcpy( &val, p + 2, sizeof( val ) );
        break;
    }
    e = Type->start + is->u.typ.h.offset;
    memcpy( d, &val, (*(e+4) & SCLR_LEN_MASK) + 1 );
    PopLoad();
    return( DS_OK );
}

dip_status SymHdl2CstType( imp_image_handle *ii, imp_sym_handle *is,
                        imp_type_handle *it )
{
    ii = ii;
    it->im = is->im;
    it->t = is->u.typ.h;
    it->f.all = 0;
    return( DS_OK );
}

dip_status SymHdl2TypType( imp_image_handle *ii, imp_sym_handle *is,
                        imp_type_handle *it )
{
    ii = ii;
    it->im = is->im;
    it->t = is->u.typ.t;
    it->f.all = 0;
    return( DS_OK );
}

dip_status SymHdl2MbrType( imp_image_handle *ii, imp_sym_handle *is,
                        imp_type_handle *it )
{
    byte        *p;
    unsigned    index;
    dip_status  ret;
    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;
    p = BaseTypePtr( p );
    GetIndex( p, &index );
    PopLoad();
    return( FindTypeHandle( ii, is->im, index, it ) );
}


struct pending_entry {
    struct pending_entry        *prev;
    unsigned short              off;
};

struct anc_graph {
    struct anc_graph            *prev;
    union {
        struct pending_entry    *todo;
        struct {
            unsigned short      off;
            unsigned short      count;
        }                       s;
    }                           u;
    unsigned short              entry;
};

dip_status SymHdl2MbrLoc( imp_image_handle *ii, imp_sym_handle *is,
                         location_context *lc, location_list *ll )
{
    byte                *p;
    unsigned            count;
    struct anc_graph    *pending, *new, *tmp;
    imp_type_handle     new_it;
    unsigned            index;
    dip_status          ok;
    location_list       adj;
    addr_off            offset;
    unsigned            bit_start;
    unsigned            bit_len;
    location_info       info;
    typeinfo            typeld;

    PushLoad( &typeld );
    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;
    switch( p[1] ) {
    case STRUCT_TYPE+ST_FIELD_LOC:
    case STRUCT_TYPE+ST_BIT_LOC:
        info = InfoLocation( p + 3 );
        break;
    default:
        info = NEED_BASE;
        break;
    }
    if( info & (NEED_BASE|EMPTY_EXPR) ) {
        ok = LoadType( ii, is->im, is->u.typ.h.entry );
        if( ok != DS_OK ) {
            PopLoad();
            return( ok );
        }
        p = Type->start + is->u.typ.h.offset;
        pending = NULL;
        count = *(unsigned_16 *)(p+2);
        for( ;; ) {
            if( count == 0 ) {
                if( pending == NULL ) return( DS_FAIL );
                ok = LoadType( ii, is->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, is->im, index, &new_it );
                if( ok != DS_OK ) {
                    PopLoad();
                    return( ok );
                }
                p = Type->start + new_it.t.offset;
                count = *(unsigned_16 *)(p+2);
            } else {
                if( is->u.typ.t.entry == Type->entry
                 && is->u.typ.t.offset == (p - Type->start) ) break;
            }
        }
        FreeLoad();
        /* 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 */
        ok = DCItemLocation( lc, CI_OBJECT, ll );
        if( ok != DS_OK ) {
            PopLoad();
            DCStatus( ok );
            return( ok );
        }
        while( new != NULL ) {
            ok = LoadType( ii, is->im, new->entry );
            if( ok != DS_OK ) {
                PopLoad();
                return( ok );
            }
            PushBaseLocation( ll );
            p = new->u.s.off + Type->start;
            ok = EvalLocation( ii, lc, p + 2, &adj );
            if( ok != DS_OK ) {
                PopLoad();
                return( ok );
            }
            if( adj.num != 1 || adj.e[0].type != LT_ADDR ) {
                PopLoad();
                DCStatus( DS_ERR|DS_BAD_LOCATION );

⌨️ 快捷键说明

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