Exemplo n.º 1
0
void TypeInfoTupleDeclaration::toDt(dt_t **pdt)
{
    //printf("TypeInfoTupleDeclaration::toDt() %s\n", tinfo->toChars());
    dtxoff(pdt, Type::typeinfotypelist->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoInterface
    dtdword(pdt, 0);                        // monitor

    assert(tinfo->ty == Ttuple);

    TypeTuple *tu = (TypeTuple *)tinfo;

    size_t dim = tu->arguments->dim;
    dtdword(pdt, dim);                      // elements.length

    dt_t *d = NULL;
    for (size_t i = 0; i < dim; i++)
    {   Parameter *arg = (Parameter *)tu->arguments->data[i];
        Expression *e = arg->type->getTypeInfo(NULL);
        e = e->optimize(WANTvalue);
        e->toDt(&d);
    }

    Symbol *s;
    s = static_sym();
    s->Sdt = d;
    outdata(s);

    dtxoff(pdt, s, 0, TYnptr);              // elements.ptr
}
Exemplo n.º 2
0
Arquivo: nteh.c Projeto: spott/dmd
void nteh_gentables()
{
    symbol *s = s_table;
    symbol_debug(s);
#if MARS
    //except_fillInEHTable(s);
#else
    /* NTEH table for C.
     * The table consists of triples:
     *  parent index
     *  filter address
     *  handler address
     */
    unsigned fsize = 4;             // target size of function pointer
    dt_t **pdt = &s->Sdt;
    int sz = 0;                     // size so far

    for (block *b = startblock; b; b = b->Bnext)
    {
        if (b->BC == BC_try)
        {   dt_t *dt;
            block *bhandler;

            pdt = dtdword(pdt,b->Blast_index);  // parent index

            // If try-finally
            if (list_nitems(b->Bsucc) == 2)
            {
                pdt = dtdword(pdt,0);           // filter address
                bhandler = list_block(list_next(b->Bsucc));
                assert(bhandler->BC == BC_finally);
                // To successor of BC_finally block
                bhandler = list_block(bhandler->Bsucc);
            }
            else // try-except
            {
                bhandler = list_block(list_next(b->Bsucc));
                assert(bhandler->BC == BC_filter);
                pdt = dtcoff(pdt,bhandler->Boffset);    // filter address
                bhandler = list_block(list_next(list_next(b->Bsucc)));
                assert(bhandler->BC == BC_except);
            }
            pdt = dtcoff(pdt,bhandler->Boffset);        // handler address
            sz += 4 + fsize * 2;
        }
    }
    assert(sz != 0);
#endif

    outdata(s);                 // output the scope table
#if MARS
    nteh_framehandler(s);
#endif
    s_table = NULL;
}
Exemplo n.º 3
0
void TypeInfoStaticArrayDeclaration::toDt(dt_t **pdt)
{
    //printf("TypeInfoStaticArrayDeclaration::toDt()\n");
    dtxoff(pdt, Type::typeinfostaticarray->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_StaticArray
    dtdword(pdt, 0);                        // monitor

    assert(tinfo->ty == Tsarray);

    TypeSArray *tc = (TypeSArray *)tinfo;

    tc->next->getTypeInfo(NULL);
    dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type

    dtdword(pdt, tc->dim->toInteger());         // length
}
Exemplo n.º 4
0
Symbol *objc_getImageInfo()
{
    assert(!objc_simageInfo); // only allow once per object file
    objc_hasSymbols = true;

    dt_t *dt = NULL;
    dtdword(&dt, 0); // version
    dtdword(&dt, 0); // flags

    objc_simageInfo = symbol_name("L_OBJC_IMAGE_INFO", SCstatic, type_allocn(TYarray, tschar));
    objc_simageInfo->Sdt = dt;
    objc_simageInfo->Sseg = objc_getSegment(SEGimage_info);
    outdata(objc_simageInfo);

    return objc_simageInfo;
}
Exemplo n.º 5
0
Arquivo: glue.c Projeto: Geod24/dnet
elem *Module::toEfilename()
{   elem *efilename;

    if (!sfilename)
    {
	dt_t *dt = NULL;
	char *id;
	int len;

	id = srcfile->toChars();
	len = strlen(id);
	dtdword(&dt, len);
	dtabytes(&dt,TYnptr, 0, len + 1, id);

	sfilename = symbol_generate(SCstatic,type_fake(TYdarray));
	sfilename->Sdt = dt;
	sfilename->Sfl = FLdata;
#if ELFOBJ
	sfilename->Sseg = CDATA;
#endif
#if MACHOBJ
	// Because of PIC and CDATA being in the _TEXT segment, cannot
	// have pointers in CDATA
	sfilename->Sseg = DATA;
#endif
	outdata(sfilename);
    }

    efilename = el_var(sfilename);
    return efilename;
}
Exemplo n.º 6
0
void TypeInfoInvariantDeclaration::toDt(dt_t **pdt)
{
    //printf("TypeInfoInvariantDeclaration::toDt() %s\n", toChars());
    dtxoff(pdt, Type::typeinfoinvariant->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Invariant
    dtdword(pdt, 0);                        // monitor
    Type *tm = tinfo->mutableOf();
    tm = tm->merge();
    tm->getTypeInfo(NULL);
    dtxoff(pdt, tm->vtinfo->toSymbol(), 0, TYnptr);
}
Exemplo n.º 7
0
void TypeInfoTypedefDeclaration::toDt(dt_t **pdt)
{
    //printf("TypeInfoTypedefDeclaration::toDt() %s\n", toChars());

    dtxoff(pdt, Type::typeinfotypedef->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Typedef
    dtdword(pdt, 0);                        // monitor

    assert(tinfo->ty == Ttypedef);

    TypeTypedef *tc = (TypeTypedef *)tinfo;
    TypedefDeclaration *sd = tc->sym;
    //printf("basetype = %s\n", sd->basetype->toChars());

    /* Put out:
     *  TypeInfo base;
     *  char[] name;
     *  void[] m_init;
     */

    sd->basetype = sd->basetype->merge();
    sd->basetype->getTypeInfo(NULL);            // generate vtinfo
    assert(sd->basetype->vtinfo);
    dtxoff(pdt, sd->basetype->vtinfo->toSymbol(), 0, TYnptr);   // TypeInfo for basetype

    const char *name = sd->toPrettyChars();
    size_t namelen = strlen(name);
    dtdword(pdt, namelen);
    dtabytes(pdt, TYnptr, 0, namelen + 1, name);

    // void[] init;
    if (tinfo->isZeroInit() || !sd->init)
    {   // 0 initializer, or the same as the base type
        dtdword(pdt, 0);        // init.length
        dtdword(pdt, 0);        // init.ptr
    }
    else
    {
        dtdword(pdt, sd->type->size()); // init.length
        dtxoff(pdt, sd->toInitializer(), 0, TYnptr);    // init.ptr
    }
}
Exemplo n.º 8
0
Arquivo: todt.c Projeto: Geod24/dnet
void ClassDeclaration::toDt(dt_t **pdt)
{
    //printf("ClassDeclaration::toDt(this = '%s')\n", toChars());

    // Put in first two members, the vtbl[] and the monitor
    dtxoff(pdt, toVtblSymbol(), 0, TYnptr);
    dtdword(pdt, 0);			// monitor

    // Put in the rest
    toDt2(pdt, this);

    //printf("-ClassDeclaration::toDt(this = '%s')\n", toChars());
}
Exemplo n.º 9
0
void TypeInfoPointerDeclaration::toDt(dt_t **pdt)
{
    //printf("TypeInfoPointerDeclaration::toDt()\n");
    dtxoff(pdt, Type::typeinfopointer->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Pointer
    dtdword(pdt, 0);                        // monitor

    assert(tinfo->ty == Tpointer);

    TypePointer *tc = (TypePointer *)tinfo;

    tc->next->getTypeInfo(NULL);
    dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for type being pointed to
}
Exemplo n.º 10
0
void TypeInfoFunctionDeclaration::toDt(dt_t **pdt)
{
    //printf("TypeInfoFunctionDeclaration::toDt()\n");
    dtxoff(pdt, Type::typeinfofunction->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Function
    dtdword(pdt, 0);                        // monitor

    assert(tinfo->ty == Tfunction);

    TypeFunction *tc = (TypeFunction *)tinfo;

    tc->next->getTypeInfo(NULL);
    dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for function return value
}
Exemplo n.º 11
0
void TypeInfoDelegateDeclaration::toDt(dt_t **pdt)
{
    //printf("TypeInfoDelegateDeclaration::toDt()\n");
    dtxoff(pdt, Type::typeinfodelegate->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Delegate
    dtdword(pdt, 0);                        // monitor

    assert(tinfo->ty == Tdelegate);

    TypeDelegate *tc = (TypeDelegate *)tinfo;

    tc->next->nextOf()->getTypeInfo(NULL);
    dtxoff(pdt, tc->next->nextOf()->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for delegate return value
}
Exemplo n.º 12
0
void TypeInfoArrayDeclaration::toDt(dt_t **pdt)
{
    //printf("TypeInfoArrayDeclaration::toDt()\n");
    dtxoff(pdt, Type::typeinfoarray->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Array
    dtdword(pdt, 0);                        // monitor

    assert(tinfo->ty == Tarray);

    TypeDArray *tc = (TypeDArray *)tinfo;

    tc->next->getTypeInfo(NULL);
    dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type
}
Exemplo n.º 13
0
void TypeInfoSharedDeclaration::toDt(dt_t **pdt)
{
    //printf("TypeInfoSharedDeclaration::toDt() %s\n", toChars());
    dtxoff(pdt, Type::typeinfoshared->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Shared
    dtdword(pdt, 0);                        // monitor
    Type *tm;
    if (tinfo->isConst())               // it was 'shared const'
        tm = tinfo->constOf();
    else                                // it was just 'shared'
        tm = tinfo->mutableOf();
    tm = tm->merge();
    tm->getTypeInfo(NULL);
    dtxoff(pdt, tm->vtinfo->toSymbol(), 0, TYnptr);
}
Exemplo n.º 14
0
void TypeInfoEnumDeclaration::toDt(dt_t **pdt)
{
    //printf("TypeInfoEnumDeclaration::toDt()\n");
    dtxoff(pdt, Type::typeinfoenum->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Enum
    dtdword(pdt, 0);                        // monitor

    assert(tinfo->ty == Tenum);

    TypeEnum *tc = (TypeEnum *)tinfo;
    EnumDeclaration *sd = tc->sym;

    /* Put out:
     *  TypeInfo base;
     *  char[] name;
     *  void[] m_init;
     */

    sd->memtype->getTypeInfo(NULL);
    dtxoff(pdt, sd->memtype->vtinfo->toSymbol(), 0, TYnptr);    // TypeInfo for enum members

    const char *name = sd->toPrettyChars();
    size_t namelen = strlen(name);
    dtdword(pdt, namelen);
    dtabytes(pdt, TYnptr, 0, namelen + 1, name);

    // void[] init;
    if (!sd->defaultval || tinfo->isZeroInit())
    {   // 0 initializer, or the same as the base type
        dtdword(pdt, 0);        // init.length
        dtdword(pdt, 0);        // init.ptr
    }
    else
    {
        dtdword(pdt, sd->type->size()); // init.length
        dtxoff(pdt, sd->toInitializer(), 0, TYnptr);    // init.ptr
    }
}
Exemplo n.º 15
0
void TypeInfoInterfaceDeclaration::toDt(dt_t **pdt)
{
    //printf("TypeInfoInterfaceDeclaration::toDt() %s\n", tinfo->toChars());
    dtxoff(pdt, Type::typeinfointerface->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoInterface
    dtdword(pdt, 0);                        // monitor

    assert(tinfo->ty == Tclass);

    TypeClass *tc = (TypeClass *)tinfo;
    Symbol *s;

    if (!tc->sym->vclassinfo)
        tc->sym->vclassinfo = new ClassInfoDeclaration(tc->sym);
    s = tc->sym->vclassinfo->toSymbol();
    dtxoff(pdt, s, 0, TYnptr);          // ClassInfo for tinfo
}
Exemplo n.º 16
0
Arquivo: todt.c Projeto: Geod24/dnet
dt_t *ArrayInitializer::toDt()
{
    //printf("ArrayInitializer::toDt('%s')\n", toChars());
    Type *tb = type->toBasetype();
    Type *tn = tb->nextOf()->toBasetype();

    Array dts;
    unsigned size;
    unsigned length;
    unsigned i;
    dt_t *dt;
    dt_t *d;
    dt_t **pdtend;

    //printf("\tdim = %d\n", dim);
    dts.setDim(dim);
    dts.zero();

    size = tn->size();

    length = 0;
    for (i = 0; i < index.dim; i++)
    {	Expression *idx;
	Initializer *val;

	idx = (Expression *)index.data[i];
	if (idx)
	    length = idx->toInteger();
	//printf("\tindex[%d] = %p, length = %u, dim = %u\n", i, idx, length, dim);

	assert(length < dim);
	val = (Initializer *)value.data[i];
	dt = val->toDt();
	if (dts.data[length])
	    error(loc, "duplicate initializations for index %d", length);
	dts.data[length] = (void *)dt;
	length++;
    }

    Expression *edefault = tb->nextOf()->defaultInit();

    unsigned n = 1;
    for (Type *tbn = tn; tbn->ty == Tsarray; tbn = tbn->nextOf()->toBasetype())
    {	TypeSArray *tsa = (TypeSArray *)tbn;

	n *= tsa->dim->toInteger();
    }

    d = NULL;
    pdtend = &d;
    for (i = 0; i < dim; i++)
    {
	dt = (dt_t *)dts.data[i];
	if (dt)
	    pdtend = dtcat(pdtend, dt);
	else
	{
	    for (int j = 0; j < n; j++)
		pdtend = edefault->toDt(pdtend);
	}
    }
    switch (tb->ty)
    {
	case Tsarray:
	{   unsigned tadim;
	    TypeSArray *ta = (TypeSArray *)tb;

	    tadim = ta->dim->toInteger();
	    if (dim < tadim)
	    {
		if (edefault->isBool(FALSE))
		    // pad out end of array
		    pdtend = dtnzeros(pdtend, size * (tadim - dim));
		else
		{
		    for (i = dim; i < tadim; i++)
		    {	for (int j = 0; j < n; j++)
			    pdtend = edefault->toDt(pdtend);
		    }
		}
	    }
	    else if (dim > tadim)
	    {
#ifdef DEBUG
		printf("1: ");
#endif
		error(loc, "too many initializers, %d, for array[%d]", dim, tadim);
	    }
	    break;
	}

	case Tpointer:
	case Tarray:
	    // Create symbol, and then refer to it
	    Symbol *s;
	    s = static_sym();
	    s->Sdt = d;
	    outdata(s);

	    d = NULL;
	    if (tb->ty == Tarray)
		dtdword(&d, dim);
	    dtxoff(&d, s, 0, TYnptr);
	    break;

	default:
	    assert(0);
    }
    return d;
}
Exemplo n.º 17
0
Arquivo: eh.c Projeto: nischu7/dmd
void except_fillInEHTable(symbol *s)
{
    unsigned fsize = NPTRSIZE;             // target size of function pointer
    dt_t **pdt = &s->Sdt;

    /*
        void*           pointer to start of function
        unsigned        offset of ESP from EBP
        unsigned        offset from start of function to return code
        unsigned nguards;       // dimension of guard[] (Linux)
        Guard guard[];
      catchoffset:
        unsigned ncatches;      // number of catch blocks
        {   void *type;         // symbol representing type
            unsigned bpoffset;  // EBP offset of catch variable
            void *handler;      // catch handler code
        } catch[];
     */

/* Be careful of this, as we need the sizeof Guard on the target, not
 * in the compiler.
 */
#if OUREH
#define GUARD_SIZE      (I64 ? 3*8 : 5*4)     // sizeof(Guard)
#else
#define GUARD_SIZE      (sizeof(Guard))
#endif

    int sz = 0;

    // Address of start of function
    symbol_debug(funcsym_p);
    pdt = dtxoff(pdt,funcsym_p,0,TYnptr);
    sz += fsize;

    //printf("ehtables: func = %s, offset = x%x, startblock->Boffset = x%x\n", funcsym_p->Sident, funcsym_p->Soffset, startblock->Boffset);

    // Get offset of ESP from EBP
    long spoff = cod3_spoff();
    pdt = dtdword(pdt,spoff);
    sz += 4;

    // Offset from start of function to return code
    pdt = dtdword(pdt,retoffset);
    sz += 4;

    // First, calculate starting catch offset
    int guarddim = 0;                               // max dimension of guard[]
    for (block *b = startblock; b; b = b->Bnext)
    {
        if (b->BC == BC_try && b->Bscope_index >= guarddim)
            guarddim = b->Bscope_index + 1;
//      printf("b->BC = %2d, Bscope_index = %2d, last_index = %2d, offset = x%x\n",
//              b->BC, b->Bscope_index, b->Blast_index, b->Boffset);
    }

#if OUREH
    pdt = dtsize_t(pdt,guarddim);
    sz += NPTRSIZE;
#endif

    unsigned catchoffset = sz + guarddim * GUARD_SIZE;

    // Generate guard[]
    int i = 0;
    for (block *b = startblock; b; b = b->Bnext)
    {
        //printf("b = %p, b->Btry = %p, b->offset = %x\n", b, b->Btry, b->Boffset);
        if (b->BC == BC_try)
        {
            assert(b->Bscope_index >= i);
            if (i < b->Bscope_index)
            {   int fillsize = (b->Bscope_index - i) * GUARD_SIZE;
                pdt = dtnzeros(pdt, fillsize);
                sz += fillsize;
            }
            i = b->Bscope_index + 1;

            int nsucc = list_nitems(b->Bsucc);

#if OUREH
            //printf("DHandlerInfo: offset = %x", (int)(b->Boffset - startblock->Boffset));
            pdt = dtdword(pdt,b->Boffset - startblock->Boffset);        // offset to start of block

            // Compute ending offset
            unsigned endoffset;
            for (block *bn = b->Bnext; 1; bn = bn->Bnext)
            {
                //printf("\tbn = %p, bn->Btry = %p, bn->offset = %x\n", bn, bn->Btry, bn->Boffset);
                assert(bn);
                if (bn->Btry == b->Btry)
                {    endoffset = bn->Boffset - startblock->Boffset;
                     break;
                }
            }
            //printf(" endoffset = %x, prev_index = %d\n", endoffset, b->Blast_index);
            pdt = dtdword(pdt,endoffset);               // offset past end of guarded block
#endif

            pdt = dtdword(pdt,b->Blast_index);          // parent index

            if (b->jcatchvar)                           // if try-catch
            {
                pdt = dtdword(pdt,catchoffset);
                pdt = dtsize_t(pdt,0);                  // no finally handler

                catchoffset += NPTRSIZE + (nsucc - 1) * (3 * NPTRSIZE);
            }
            else                                        // else try-finally
            {
                assert(nsucc == 2);
                pdt = dtdword(pdt,0);           // no catch offset
                block *bhandler = list_block(list_next(b->Bsucc));
                assert(bhandler->BC == BC_finally);
                // To successor of BC_finally block
                bhandler = list_block(bhandler->Bsucc);
#if OUREH
                pdt = dtxoff(pdt,funcsym_p,bhandler->Boffset - startblock->Boffset, TYnptr);    // finally handler address
#else
                pdt = dtcoff(pdt,bhandler->Boffset);  // finally handler address
#endif
            }
            sz += GUARD_SIZE;
        }
    }

    // Generate catch[]
    for (block *b = startblock; b; b = b->Bnext)
    {
        if (b->BC == BC_try)
        {   block *bhandler;
            int nsucc;

            if (b->jcatchvar)                           // if try-catch
            {   list_t bl;

                nsucc = list_nitems(b->Bsucc);
                pdt = dtsize_t(pdt,nsucc - 1);           // # of catch blocks
                sz += NPTRSIZE;

                for (bl = list_next(b->Bsucc); bl; bl = list_next(bl))
                {
                    block *bcatch = list_block(bl);

                    pdt = dtxoff(pdt,bcatch->Bcatchtype,0,TYjhandle);

                    pdt = dtsize_t(pdt,cod3_bpoffset(b->jcatchvar));     // EBP offset

#if OUREH
                    pdt = dtxoff(pdt,funcsym_p,bcatch->Boffset - startblock->Boffset, TYnptr);  // catch handler address
#else
                    pdt = dtcoff(pdt,bcatch->Boffset);        // catch handler address
#endif
                    sz += 3 * NPTRSIZE;
                }
            }
        }
    }
    assert(sz != 0);
}
Exemplo n.º 18
0
void genModuleInfo(Module *m)
{
    //printf("Module::genmoduleinfo() %s\n", m->toChars());

    if (!Module::moduleinfo)
    {
        ObjectNotFound(Id::ModuleInfo);
    }

    Symbol *msym = toSymbol(m);

    //////////////////////////////////////////////

    m->csym->Sclass = SCglobal;
    m->csym->Sfl = FLdata;

    dt_t *dt = NULL;
    ClassDeclarations aclasses;

    //printf("members->dim = %d\n", members->dim);
    for (size_t i = 0; i < m->members->dim; i++)
    {
        Dsymbol *member = (*m->members)[i];

        //printf("\tmember '%s'\n", member->toChars());
        member->addLocalClass(&aclasses);
    }

    // importedModules[]
    size_t aimports_dim = m->aimports.dim;
    for (size_t i = 0; i < m->aimports.dim; i++)
    {
        Module *mod = m->aimports[i];
        if (!mod->needmoduleinfo)
            aimports_dim--;
    }

    FuncDeclaration *sgetmembers = m->findGetMembers();

    // These must match the values in druntime/src/object_.d
    #define MIstandalone      0x4
    #define MItlsctor         0x8
    #define MItlsdtor         0x10
    #define MIctor            0x20
    #define MIdtor            0x40
    #define MIxgetMembers     0x80
    #define MIictor           0x100
    #define MIunitTest        0x200
    #define MIimportedModules 0x400
    #define MIlocalClasses    0x800
    #define MIname            0x1000

    unsigned flags = 0;
    if (!m->needmoduleinfo)
        flags |= MIstandalone;
    if (m->sctor)
        flags |= MItlsctor;
    if (m->sdtor)
        flags |= MItlsdtor;
    if (m->ssharedctor)
        flags |= MIctor;
    if (m->sshareddtor)
        flags |= MIdtor;
    if (sgetmembers)
        flags |= MIxgetMembers;
    if (m->sictor)
        flags |= MIictor;
    if (m->stest)
        flags |= MIunitTest;
    if (aimports_dim)
        flags |= MIimportedModules;
    if (aclasses.dim)
        flags |= MIlocalClasses;
    flags |= MIname;

    dtdword(&dt, flags);        // _flags
    dtdword(&dt, 0);            // _index

    if (flags & MItlsctor)
        dtxoff(&dt, m->sctor, 0, TYnptr);
    if (flags & MItlsdtor)
        dtxoff(&dt, m->sdtor, 0, TYnptr);
    if (flags & MIctor)
        dtxoff(&dt, m->ssharedctor, 0, TYnptr);
    if (flags & MIdtor)
        dtxoff(&dt, m->sshareddtor, 0, TYnptr);
    if (flags & MIxgetMembers)
        dtxoff(&dt, toSymbol(sgetmembers), 0, TYnptr);
    if (flags & MIictor)
        dtxoff(&dt, m->sictor, 0, TYnptr);
    if (flags & MIunitTest)
        dtxoff(&dt, m->stest, 0, TYnptr);
    if (flags & MIimportedModules)
    {
        dtsize_t(&dt, aimports_dim);
        for (size_t i = 0; i < m->aimports.dim; i++)
        {
            Module *mod = m->aimports[i];

            if (!mod->needmoduleinfo)
                continue;

            Symbol *s = toSymbol(mod);

            /* Weak references don't pull objects in from the library,
             * they resolve to 0 if not pulled in by something else.
             * Don't pull in a module just because it was imported.
             */
            s->Sflags |= SFLweak;
            dtxoff(&dt, s, 0, TYnptr);
        }
    }
    if (flags & MIlocalClasses)
    {
        dtsize_t(&dt, aclasses.dim);
        for (size_t i = 0; i < aclasses.dim; i++)
        {
            ClassDeclaration *cd = aclasses[i];
            dtxoff(&dt, toSymbol(cd), 0, TYnptr);
        }
    }
    if (flags & MIname)
    {
        // Put out module name as a 0-terminated string, to save bytes
        m->nameoffset = dt_size(dt);
        const char *name = m->toPrettyChars();
        m->namelen = strlen(name);
        dtnbytes(&dt, m->namelen + 1, name);
        //printf("nameoffset = x%x\n", nameoffset);
    }

    objc_Module_genmoduleinfo_classes();
    m->csym->Sdt = dt;
    out_readonly(m->csym);
    outdata(m->csym);

    //////////////////////////////////////////////

    objmod->moduleinfo(msym);
}
Exemplo n.º 19
0
void except_fillInEHTable(symbol *s)
{
    unsigned fsize = NPTRSIZE;             // target size of function pointer
    dt_t **pdt = &s->Sdt;

    /*
        void*           pointer to start of function (Windows)
        unsigned        offset of ESP from EBP
        unsigned        offset from start of function to return code
        unsigned nguards;       // dimension of guard[] (Linux)
        Guard guard[];          // sorted such that the enclosing guarded sections come first
      catchoffset:
        unsigned ncatches;      // number of catch blocks
        {   void *type;         // symbol representing type
            unsigned bpoffset;  // EBP offset of catch variable
            void *handler;      // catch handler code
        } catch[];
     */

/* Be careful of this, as we need the sizeof Guard on the target, not
 * in the compiler.
 */
    unsigned GUARD_SIZE;
    if (config.ehmethod == EH_DM)
        GUARD_SIZE = (I64 ? 3*8 : 5*4);
    else if (config.ehmethod == EH_WIN32)
        GUARD_SIZE = 3*4;
    else
        assert(0);

    int sz = 0;

    // Address of start of function
    if (config.ehmethod == EH_WIN32)
    {
        symbol_debug(funcsym_p);
        pdt = dtxoff(pdt,funcsym_p,0,TYnptr);
        sz += fsize;
    }

    //printf("ehtables: func = %s, offset = x%x, startblock->Boffset = x%x\n", funcsym_p->Sident, funcsym_p->Soffset, startblock->Boffset);

    // Get offset of ESP from EBP
    long spoff = cod3_spoff();
    pdt = dtdword(pdt,spoff);
    sz += 4;

    // Offset from start of function to return code
    pdt = dtdword(pdt,retoffset);
    sz += 4;

    // First, calculate starting catch offset
    int guarddim = 0;                               // max dimension of guard[]
    int ndctors = 0;                                // number of ESCdctor's
    for (block *b = startblock; b; b = b->Bnext)
    {
        if (b->BC == BC_try && b->Bscope_index >= guarddim)
            guarddim = b->Bscope_index + 1;
//      printf("b->BC = %2d, Bscope_index = %2d, last_index = %2d, offset = x%x\n",
//              b->BC, b->Bscope_index, b->Blast_index, b->Boffset);
        if (usednteh & EHcleanup)
            for (code *c = b->Bcode; c; c = code_next(c))
            {
                if (c->Iop == (ESCAPE | ESCddtor))
                    ndctors++;
            }
    }
    //printf("guarddim = %d, ndctors = %d\n", guarddim, ndctors);

    if (config.ehmethod == EH_DM)
    {
        pdt = dtsize_t(pdt,guarddim + ndctors);
        sz += NPTRSIZE;
    }

    unsigned catchoffset = sz + (guarddim + ndctors) * GUARD_SIZE;

    // Generate guard[]
    int i = 0;
    for (block *b = startblock; b; b = b->Bnext)
    {
        //printf("b = %p, b->Btry = %p, b->offset = %x\n", b, b->Btry, b->Boffset);
        if (b->BC == BC_try)
        {
            assert(b->Bscope_index >= i);
            if (i < b->Bscope_index)
            {   int fillsize = (b->Bscope_index - i) * GUARD_SIZE;
                pdt = dtnzeros(pdt, fillsize);
                sz += fillsize;
            }
            i = b->Bscope_index + 1;

            int nsucc = b->numSucc();

            if (config.ehmethod == EH_DM)
            {
            //printf("DHandlerInfo: offset = %x", (int)(b->Boffset - startblock->Boffset));
            pdt = dtdword(pdt,b->Boffset - startblock->Boffset);        // offset to start of block

            // Compute ending offset
            unsigned endoffset;
            for (block *bn = b->Bnext; 1; bn = bn->Bnext)
            {
                //printf("\tbn = %p, bn->Btry = %p, bn->offset = %x\n", bn, bn->Btry, bn->Boffset);
                assert(bn);
                if (bn->Btry == b->Btry)
                {    endoffset = bn->Boffset - startblock->Boffset;
                     break;
                }
            }
            //printf(" endoffset = %x, prev_index = %d\n", endoffset, b->Blast_index);
            pdt = dtdword(pdt,endoffset);               // offset past end of guarded block
            }

            pdt = dtdword(pdt,b->Blast_index);          // parent index

            if (b->jcatchvar)                           // if try-catch
            {
                assert(catchoffset);
                pdt = dtdword(pdt,catchoffset);
                pdt = dtsize_t(pdt,0);                  // no finally handler

                catchoffset += NPTRSIZE + (nsucc - 1) * (3 * NPTRSIZE);
            }
            else                                        // else try-finally
            {
                assert(nsucc == 2);
                pdt = dtdword(pdt,0);           // no catch offset
                block *bhandler = b->nthSucc(1);
                assert(bhandler->BC == BC_finally);
                // To successor of BC_finally block
                bhandler = bhandler->nthSucc(0);
                // finally handler address
                if (config.ehmethod == EH_DM)
                {
                    assert(bhandler->Boffset > startblock->Boffset);
                    pdt = dtsize_t(pdt,bhandler->Boffset - startblock->Boffset);    // finally handler offset
                }
                else
                    pdt = dtcoff(pdt,bhandler->Boffset);
            }
            sz += GUARD_SIZE;
        }
    }

    /* Append to guard[] the guard blocks for temporaries that are created and destroyed
     * within a single expression. These are marked by the special instruction pairs
     * (ESCAPE | ESCdctor) and (ESCAPE | ESCddtor).
     */
    if (usednteh & EHcleanup)
    {
        #define STACKINC 16
        int stackbuf[STACKINC];
        int *stack = stackbuf;
        int stackmax = STACKINC;

    int scopeindex = guarddim;
    for (block *b = startblock; b; b = b->Bnext)
    {
        /* Set up stack of scope indices
         */
        stack[0] = b->Btry ? b->Btry->Bscope_index : -1;
        int stacki = 1;

        unsigned boffset = b->Boffset;
        for (code *c = b->Bcode; c; c = code_next(c))
        {
            if (c->Iop == (ESCAPE | ESCdctor))
            {
                code *c2 = code_next(c);
                if (config.flags2 & CFG2seh)
                    nteh_patchindex(c2, scopeindex);
                if (config.ehmethod == EH_DM)
                    pdt = dtdword(pdt,boffset - startblock->Boffset); // guard offset
                // Find corresponding ddtor instruction
                int n = 0;
                unsigned eoffset = boffset;
                unsigned foffset;
                for (; 1; c2 = code_next(c2))
                {
                    // Bugzilla 13720: optimizer might elide the corresponding ddtor
                    if (!c2)
                        goto Lnodtor;

                    if (c2->Iop == (ESCAPE | ESCddtor))
                    {
                        if (n)
                            n--;
                        else
                        {
                            foffset = eoffset;
                            code *cf = code_next(c2);
                            if (config.flags2 & CFG2seh)
                            {
                                nteh_patchindex(cf, stack[stacki - 1]);
                                foffset += calccodsize(cf);
                                cf = code_next(cf);
                            }
                            foffset += calccodsize(cf);
                            while (!cf->isJumpOP())
                            {
                                cf = code_next(cf);
                                foffset += calccodsize(cf);
                            }
                            // issue 9438
                            //cf = code_next(cf);
                            //foffset += calccodsize(cf);
                            if (config.ehmethod == EH_DM)
                                pdt = dtdword(pdt,eoffset - startblock->Boffset); // guard offset
                            break;
                        }
                    }
                    else if (c2->Iop == (ESCAPE | ESCdctor))
                    {
                        n++;
                    }
                    else
                        eoffset += calccodsize(c2);
                }
                //printf("boffset = %x, eoffset = %x, foffset = %x\n", boffset, eoffset, foffset);
                pdt = dtdword(pdt,stack[stacki - 1]);   // parent index
                pdt = dtdword(pdt,0);           // no catch offset
                if (config.ehmethod == EH_DM)
                {
                    assert(foffset > startblock->Boffset);
                    pdt = dtsize_t(pdt,foffset - startblock->Boffset);    // finally handler offset
                }
                else
                    pdt = dtcoff(pdt,foffset);  // finally handler address
                if (stacki == stackmax)
                {   // stack[] is out of space; enlarge it
                    int *pi = (int *)malloc((stackmax + STACKINC) * sizeof(int));
                    assert(pi);
                    memcpy(pi, stack, stackmax * sizeof(int));
                    if (stack != stackbuf)
                        free(stack);
                    stack = pi;
                    stackmax += STACKINC;
                }
                stack[stacki++] = scopeindex;
                ++scopeindex;
                sz += GUARD_SIZE;
            }
            else if (c->Iop == (ESCAPE | ESCddtor))
            {
                stacki--;
                assert(stacki != 0);
            }
        Lnodtor:
            boffset += calccodsize(c);
        }
    }
        if (stack != stackbuf)
            free(stack);
    }

    // Generate catch[]
    for (block *b = startblock; b; b = b->Bnext)
    {
        if (b->BC == BC_try && b->jcatchvar)         // if try-catch
        {
            int nsucc = b->numSucc();
            pdt = dtsize_t(pdt,nsucc - 1);           // # of catch blocks
            sz += NPTRSIZE;

            for (int i = 1; i < nsucc; ++i)
            {
                block *bcatch = b->nthSucc(i);

                pdt = dtxoff(pdt,bcatch->Bcatchtype,0,TYnptr);

                pdt = dtsize_t(pdt,cod3_bpoffset(b->jcatchvar));     // EBP offset

                // catch handler address
                if (config.ehmethod == EH_DM)
                {
                    assert(bcatch->Boffset > startblock->Boffset);
                    pdt = dtsize_t(pdt,bcatch->Boffset - startblock->Boffset);  // catch handler offset
                }
                else
                    pdt = dtcoff(pdt,bcatch->Boffset);

                sz += 3 * NPTRSIZE;
            }
        }
    }
    assert(sz != 0);
}
Exemplo n.º 20
0
Arquivo: eh.c Projeto: Geod24/dnet
symbol *except_gentables()
{
    //printf("except_gentables()\n");
#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS
    symbol *s;
    int sz;			// size so far
    dt_t **pdt;
    unsigned fsize;		// target size of function pointer
    long spoff;
    block *b;
    int guarddim;
    int i;

    // BUG: alloca() changes the stack size, which is not reflected
    // in the fixed eh tables.
    assert(!usedalloca);

    s = symbol_generate(SCstatic,tsint);
    s->Sseg = UNKNOWN;
    symbol_keep(s);
    symbol_debug(s);

    fsize = 4;
    pdt = &s->Sdt;
    sz = 0;

    /*
	void*		pointer to start of function
	unsigned	offset of ESP from EBP
	unsigned	offset from start of function to return code
	unsigned nguards;	// dimension of guard[]
	{   unsigned offset;	// offset of start of guarded section
	    unsigned endoffset;	// ending offset of guarded section
	    int last_index;	// previous index (enclosing guarded section)
	    unsigned catchoffset;	// offset to catch block from symbol
	    void *finally;	// finally code to execute
	} guard[];
      catchoffset:
	unsigned ncatches;	// number of catch blocks
	{   void *type;		// symbol representing type
	    unsigned bpoffset;	// EBP offset of catch variable
	    void *handler;	// catch handler code
	} catch[];
     */
#define GUARD_SIZE	5	// number of 4 byte values in one guard

    sz = 0;

    // Address of start of function
    symbol_debug(funcsym_p);
    pdt = dtxoff(pdt,funcsym_p,0,TYnptr);
    sz += fsize;

    //printf("ehtables: func = %s, offset = x%x, startblock->Boffset = x%x\n", funcsym_p->Sident, funcsym_p->Soffset, startblock->Boffset);

    // Get offset of ESP from EBP
    spoff = cod3_spoff();
    pdt = dtdword(pdt,spoff);
    sz += 4;

    // Offset from start of function to return code
    pdt = dtdword(pdt,retoffset);
    sz += 4;

    // First, calculate starting catch offset
    guarddim = 0;				// max dimension of guard[]
    for (b = startblock; b; b = b->Bnext)
    {
	if (b->BC == BC_try && b->Bscope_index >= guarddim)
	    guarddim = b->Bscope_index + 1;
//	printf("b->BC = %2d, Bscope_index = %2d, last_index = %2d, offset = x%x\n",
//		b->BC, b->Bscope_index, b->Blast_index, b->Boffset);
    }

    pdt = dtdword(pdt,guarddim);
    sz += 4;

    unsigned catchoffset = sz + guarddim * (GUARD_SIZE * 4);

    // Generate guard[]
    i = 0;
    for (b = startblock; b; b = b->Bnext)
    {
	//printf("b = %p, b->Btry = %p, b->offset = %x\n", b, b->Btry, b->Boffset);
	if (b->BC == BC_try)
	{   dt_t *dt;
	    block *bhandler;
	    int nsucc;
	    unsigned endoffset;
	    block *bn;

	    assert(b->Bscope_index >= i);
	    if (i < b->Bscope_index)
	    {	int fillsize = (b->Bscope_index - i) * (GUARD_SIZE * 4);
		pdt = dtnzeros(pdt, fillsize);
		sz += fillsize;
	    }
	    i = b->Bscope_index + 1;

	    nsucc = list_nitems(b->Bsucc);
	    pdt = dtdword(pdt,b->Boffset - startblock->Boffset);	// offset to start of block

	    // Compute ending offset
	    for (bn = b->Bnext; 1; bn = bn->Bnext)
	    {
		//printf("\tbn = %p, bn->Btry = %p, bn->offset = %x\n", bn, bn->Btry, bn->Boffset);
		assert(bn);
		if (bn->Btry == b->Btry)
		{    endoffset = bn->Boffset - startblock->Boffset;
		     break;
		}
	    }
	    pdt = dtdword(pdt,endoffset);		// offset past end of guarded block

	    pdt = dtdword(pdt,b->Blast_index);		// parent index

	    if (b->jcatchvar)				// if try-catch
	    {
		pdt = dtdword(pdt,catchoffset);
		pdt = dtdword(pdt,0);			// no finally handler

		catchoffset += 4 + (nsucc - 1) * (3 * 4);
	    }
	    else					// else try-finally
	    {
		assert(nsucc == 2);
		pdt = dtdword(pdt,0);		// no catch offset
		bhandler = list_block(list_next(b->Bsucc));
		assert(bhandler->BC == BC_finally);
		// To successor of BC_finally block
		bhandler = list_block(bhandler->Bsucc);
		pdt = dtxoff(pdt,funcsym_p,bhandler->Boffset - startblock->Boffset, TYnptr);	// finally handler address
		//pdt = dtcoff(pdt,bhandler->Boffset);	// finally handler address
	    }
	    sz += GUARD_SIZE + 4;
	}
    }

    // Generate catch[]
    for (b = startblock; b; b = b->Bnext)
    {
	if (b->BC == BC_try)
	{   block *bhandler;
	    int nsucc;

	    if (b->jcatchvar)				// if try-catch
	    {	list_t bl;

		nsucc = list_nitems(b->Bsucc);
		pdt = dtdword(pdt,nsucc - 1);		// # of catch blocks
		sz += 4;

		for (bl = list_next(b->Bsucc); bl; bl = list_next(bl))
		{
		    block *bcatch = list_block(bl);

		    pdt = dtxoff(pdt,bcatch->Bcatchtype,0,TYjhandle);

		    pdt = dtdword(pdt,cod3_bpoffset(b->jcatchvar));	// EBP offset

		    pdt = dtxoff(pdt,funcsym_p,bcatch->Boffset - startblock->Boffset, TYnptr);	// catch handler address
		    //pdt = dtcoff(pdt,bcatch->Boffset);	// catch handler address

		    sz += 3 * 4;
		}
	    }
	}
    }
    assert(sz != 0);

    outdata(s);			// output the scope table

    obj_ehtables(funcsym_p,funcsym_p->Ssize,s);
#endif
    return NULL;
}
Exemplo n.º 21
0
void TypeInfoStructDeclaration::toDt(dt_t **pdt)
{
    //printf("TypeInfoStructDeclaration::toDt() '%s'\n", toChars());

    unsigned offset = Type::typeinfostruct->structsize;

    dtxoff(pdt, Type::typeinfostruct->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Struct
    dtdword(pdt, 0);                        // monitor

    assert(tinfo->ty == Tstruct);

    TypeStruct *tc = (TypeStruct *)tinfo;
    StructDeclaration *sd = tc->sym;

    /* Put out:
     *  char[] name;
     *  void[] init;
     *  hash_t function(void*) xtoHash;
     *  int function(void*,void*) xopEquals;
     *  int function(void*,void*) xopCmp;
     *  char[] function(void*) xtoString;
     *  uint m_flags;
     *
     *  name[]
     */

    const char *name = sd->toPrettyChars();
    size_t namelen = strlen(name);
    dtdword(pdt, namelen);
    //dtabytes(pdt, TYnptr, 0, namelen + 1, name);
    dtxoff(pdt, toSymbol(), offset, TYnptr);
    offset += namelen + 1;

    // void[] init;
    dtdword(pdt, sd->structsize);       // init.length
    if (sd->zeroInit)
        dtdword(pdt, 0);                // NULL for 0 initialization
    else
        dtxoff(pdt, sd->toInitializer(), 0, TYnptr);    // init.ptr

    FuncDeclaration *fd;
    FuncDeclaration *fdx;
    TypeFunction *tf;
    Type *ta;
    Dsymbol *s;

    static TypeFunction *tftohash;
    static TypeFunction *tftostring;

    if (!tftohash)
    {
        Scope sc;

        tftohash = new TypeFunction(NULL, Type::thash_t, 0, LINKd);
        tftohash = (TypeFunction *)tftohash->semantic(0, &sc);

        tftostring = new TypeFunction(NULL, Type::tchar->arrayOf(), 0, LINKd);
        tftostring = (TypeFunction *)tftostring->semantic(0, &sc);
    }

    TypeFunction *tfeqptr;
    {
        Scope sc;
        Parameters *arguments = new Parameters;
#if STRUCTTHISREF
        // arg type is ref const T
        Parameter *arg = new Parameter(STCref, tc->constOf(), NULL, NULL);
#else
        // arg type is const T*
        Parameter *arg = new Parameter(STCin, tc->pointerTo(), NULL, NULL);
#endif

        arguments->push(arg);
        tfeqptr = new TypeFunction(arguments, Type::tint32, 0, LINKd);
        tfeqptr = (TypeFunction *)tfeqptr->semantic(0, &sc);
    }

#if 0
    TypeFunction *tfeq;
    {
        Scope sc;
        Array *arguments = new Array;
        Parameter *arg = new Parameter(In, tc, NULL, NULL);

        arguments->push(arg);
        tfeq = new TypeFunction(arguments, Type::tint32, 0, LINKd);
        tfeq = (TypeFunction *)tfeq->semantic(0, &sc);
    }
#endif

    s = search_function(sd, Id::tohash);
    fdx = s ? s->isFuncDeclaration() : NULL;
    if (fdx)
    {   fd = fdx->overloadExactMatch(tftohash);
        if (fd)
            dtxoff(pdt, fd->toSymbol(), 0, TYnptr);
        else
            //fdx->error("must be declared as extern (D) uint toHash()");
            dtdword(pdt, 0);
    }
    else
        dtdword(pdt, 0);

    s = search_function(sd, Id::eq);
    fdx = s ? s->isFuncDeclaration() : NULL;
    for (int i = 0; i < 2; i++)
    {
        if (fdx)
        {   fd = fdx->overloadExactMatch(tfeqptr);
            if (fd)
                dtxoff(pdt, fd->toSymbol(), 0, TYnptr);
            else
                //fdx->error("must be declared as extern (D) int %s(%s*)", fdx->toChars(), sd->toChars());
                dtdword(pdt, 0);
        }
        else
            //fdx->error("must be declared as extern (D) int %s(%s*)", fdx->toChars(), sd->toChars());
            dtdword(pdt, 0);

        s = search_function(sd, Id::cmp);
        fdx = s ? s->isFuncDeclaration() : NULL;
    }

    s = search_function(sd, Id::tostring);
    fdx = s ? s->isFuncDeclaration() : NULL;
    if (fdx)
    {   fd = fdx->overloadExactMatch(tftostring);
        if (fd)
            dtxoff(pdt, fd->toSymbol(), 0, TYnptr);
        else
            //fdx->error("must be declared as extern (D) char[] toString()");
            dtdword(pdt, 0);
    }
    else
        dtdword(pdt, 0);

    // uint m_flags;
    dtdword(pdt, tc->hasPointers());

#if DMDV2
    // xgetMembers
    FuncDeclaration *sgetmembers = sd->findGetMembers();
    if (sgetmembers)
        dtxoff(pdt, sgetmembers->toSymbol(), 0, TYnptr);
    else
        dtdword(pdt, 0);                        // xgetMembers

    // xdtor
    FuncDeclaration *sdtor = sd->dtor;
    if (sdtor)
        dtxoff(pdt, sdtor->toSymbol(), 0, TYnptr);
    else
        dtdword(pdt, 0);                        // xdtor

    // xpostblit
    FuncDeclaration *spostblit = sd->postblit;
    if (spostblit)
        dtxoff(pdt, spostblit->toSymbol(), 0, TYnptr);
    else
        dtdword(pdt, 0);                        // xpostblit
#endif
    // name[]
    dtnbytes(pdt, namelen + 1, name);
}
Exemplo n.º 22
0
void TypeInfoDeclaration::toDt(dt_t **pdt)
{
    //printf("TypeInfoDeclaration::toDt() %s\n", toChars());
    dtxoff(pdt, Type::typeinfo->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo
    dtdword(pdt, 0);                        // monitor
}
Exemplo n.º 23
0
Arquivo: todt.c Projeto: Geod24/dnet
dt_t *ArrayInitializer::toDtBit()
{
#if DMDV1
    unsigned size;
    unsigned length;
    unsigned i;
    unsigned tadim;
    dt_t *d;
    dt_t **pdtend;
    Type *tb = type->toBasetype();

    //printf("ArrayInitializer::toDtBit('%s')\n", toChars());

    Bits databits;
    Bits initbits;

    if (tb->ty == Tsarray)
    {
	/* The 'dim' for ArrayInitializer is only the maximum dimension
	 * seen in the initializer, not the type. So, for static arrays,
	 * use instead the dimension of the type in order
	 * to get the whole thing.
	 */
	dinteger_t value = ((TypeSArray*)tb)->dim->toInteger();
	tadim = value;
	assert(tadim == value);	 // truncation overflow should already be checked
	databits.resize(tadim);
	initbits.resize(tadim);
    }
    else
    {
	databits.resize(dim);
	initbits.resize(dim);
    }

    /* The default initializer may be something other than zero.
     */
    if (tb->nextOf()->defaultInit()->toInteger())
       databits.set();

    size = sizeof(databits.data[0]);

    length = 0;
    for (i = 0; i < index.dim; i++)
    {	Expression *idx;
	Initializer *val;
	Expression *eval;

	idx = (Expression *)index.data[i];
	if (idx)
	{   dinteger_t value;
	    value = idx->toInteger();
	    length = value;
	    if (length != value)
	    {	error(loc, "index overflow %llu", value);
		length = 0;
	    }
	}
	assert(length < dim);

	val = (Initializer *)value.data[i];
	eval = val->toExpression();
	if (initbits.test(length))
	    error(loc, "duplicate initializations for index %d", length);
	initbits.set(length);
	if (eval->toInteger())		// any non-zero value is boolean 'true'
	    databits.set(length);
	else
	    databits.clear(length);	// boolean 'false'
	length++;
    }

    d = NULL;
    pdtend = dtnbytes(&d, databits.allocdim * size, (char *)databits.data);
    switch (tb->ty)
    {
	case Tsarray:
	{
	    if (dim > tadim)
	    {
#ifdef DEBUG
		printf("2: ");
#endif
		error(loc, "too many initializers, %d, for array[%d]", dim, tadim);
	    }
	    else
	    {
		tadim = (tadim + 31) / 32;
		if (databits.allocdim < tadim)
		    pdtend = dtnzeros(pdtend, size * (tadim - databits.allocdim));	// pad out end of array
	    }
	    break;
	}

	case Tpointer:
	case Tarray:
	    // Create symbol, and then refer to it
	    Symbol *s;
	    s = static_sym();
	    s->Sdt = d;
	    outdata(s);

	    d = NULL;
	    if (tb->ty == Tarray)
		dtdword(&d, dim);
	    dtxoff(&d, s, 0, TYnptr);
	    break;

	default:
	    assert(0);
    }
    return d;
#else
    return NULL;
#endif
}