static dt_t *createTsarrayDt(dt_t * dt, Type *t) { assert(dt != NULL); size_t eoa_size = dt_size(dt); if (eoa_size == t->size()) return dt; else { TypeSArray * tsa = (TypeSArray *) t->toBasetype(); assert(tsa->ty == Tsarray); size_t dim = tsa->dim->toInteger(); dt_t * adt = NULL; dt_t ** padt = & adt; if (eoa_size * dim == eoa_size) { for (size_t i = 0; i < dim; i++) padt = dtcontainer(padt, NULL, dt); } else { assert(tsa->size(0) % eoa_size == 0); for (size_t i = 0; i < dim; i++) padt = dtcontainer(padt, NULL, createTsarrayDt(dt, tsa->next)); } dt_t * cdt = NULL; dtcontainer(& cdt, t, adt); return cdt; } }
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); }
/*************************** * Return size of data. */ unsigned DtBuilder::length() { return dt_size(head); }
/************************************** * Repeat a list of dt_t's count times. */ void DtBuilder::repeat(dt_t *dt, size_t count) { if (!count) return; unsigned size = dt_size(dt); if (!size) return; if (dtallzeros(dt)) { if (head && dtallzeros(head)) head->DTazeros += size * count; else nzeros(size * count); return; } if (dtpointers(dt)) { dt_t *dtp = NULL; dt_t **pdt = &dtp; for (size_t i = 0; i < count; ++i) { for (dt_t *dtn = dt; dtn; dtn = dtn->DTnext) { dt_t *dtx = dt_calloc(dtn->dt); *dtx = *dtn; dtx->DTnext = NULL; switch (dtx->dt) { case DT_abytes: case DT_nbytes: dtx->DTpbytes = (char *) MEM_PH_MALLOC(dtx->DTnbytes); memcpy(dtx->DTpbytes, dtn->DTpbytes, dtx->DTnbytes); break; } *pdt = dtx; pdt = &dtx->DTnext; } } assert(!*pTail); *pTail = dtp; assert(*pdt == NULL); pTail = pdt; return; } char *p = (char *)MEM_PH_MALLOC(size * count); size_t offset = 0; for (dt_t *dtn = dt; dtn; dtn = dtn->DTnext) { switch (dtn->dt) { case DT_nbytes: memcpy(p + offset, dtn->DTpbytes, dtn->DTnbytes); offset += dtn->DTnbytes; break; case DT_ibytes: memcpy(p + offset, dtn->DTdata, dtn->DTn); offset += dtn->DTn; break; case DT_azeros: memset(p + offset, 0, dtn->DTazeros); offset += dtn->DTazeros; break; default: #ifdef DEBUG printf("dt = %p, dt = %d\n",dt,dt->dt); #endif assert(0); } } assert(offset == size); for (size_t i = 1; i < count; ++i) { memcpy(p + offset, p, size); offset += size; } dt_t *dtx = dt_calloc(DT_nbytes); dtx->DTnbytes = size * count; dtx->DTpbytes = p; assert(!*pTail); *pTail = dtx; pTail = &dtx->DTnext; assert(!*pTail); }
dt_t *StructInitializer::toDt() { Array dts; dt_t *dt; dt_t *d; dt_t **pdtend; unsigned offset; //printf("StructInitializer::toDt('%s')\n", toChars()); dts.setDim(ad->fields.dim); dts.zero(); for (size_t i = 0; i < vars.dim; i++) { VarDeclaration *v = (VarDeclaration *)vars.data[i]; Initializer *val = (Initializer *)value.data[i]; //printf("vars[%d] = %s\n", i, v->toChars()); for (size_t j = 0; 1; j++) { assert(j < dts.dim); //printf(" adfield[%d] = %s\n", j, ((VarDeclaration *)ad->fields.data[j])->toChars()); if ((VarDeclaration *)ad->fields.data[j] == v) { if (dts.data[j]) error(loc, "field %s of %s already initialized", v->toChars(), ad->toChars()); dts.data[j] = (void *)val->toDt(); break; } } } dt = NULL; pdtend = &dt; offset = 0; for (size_t j = 0; j < dts.dim; j++) { VarDeclaration *v = (VarDeclaration *)ad->fields.data[j]; d = (dt_t *)dts.data[j]; if (!d) { // An instance specific initializer was not provided. // Look to see if there's a default initializer from the // struct definition if (v->init) { d = v->init->toDt(); } else if (v->offset >= offset) { unsigned k; unsigned offset2 = v->offset + v->type->size(); // Make sure this field does not overlap any explicitly // initialized field. for (k = j + 1; 1; k++) { if (k == dts.dim) // didn't find any overlap { v->type->toDt(&d); break; } VarDeclaration *v2 = (VarDeclaration *)ad->fields.data[k]; if (v2->offset < offset2 && dts.data[k]) break; // overlap } } } if (d) { if (v->offset < offset) error(loc, "duplicate union initialization for %s", v->toChars()); else { size_t sz = dt_size(d); size_t vsz = v->type->size(); size_t voffset = v->offset; if (sz > vsz) { assert(v->type->ty == Tsarray && vsz == 0); error(loc, "zero length array %s has non-zero length initializer", v->toChars()); } unsigned dim = 1; for (Type *vt = v->type->toBasetype(); vt->ty == Tsarray; vt = vt->next->toBasetype()) { TypeSArray *tsa = (TypeSArray *)vt; dim *= tsa->dim->toInteger(); } //printf("sz = %d, dim = %d, vsz = %d\n", sz, dim, vsz); assert(sz == vsz || sz * dim <= vsz); for (size_t i = 0; i < dim; i++) { if (offset < voffset) pdtend = dtnzeros(pdtend, voffset - offset); if (!d) { if (v->init) d = v->init->toDt(); else v->type->toDt(&d); } pdtend = dtcat(pdtend, d); d = NULL; offset = voffset + sz; voffset += vsz / dim; if (sz == vsz) break; } } } } if (offset < ad->structsize) dtnzeros(pdtend, ad->structsize - offset); #ifdef IN_GCC dt_t * cdt = NULL; dtcontainer(&cdt, ad->type, dt); dt = cdt; #endif return dt; }