Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions src/backend/rtlsym.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,7 @@ SYMBOL_MARS(NEWARRAYT, FLfunc,FREGSAVED,"_d_newarrayT", 0, t) \
SYMBOL_MARS(NEWARRAYIT, FLfunc,FREGSAVED,"_d_newarrayiT", 0, t) \
SYMBOL_MARS(NEWARRAYMT, FLfunc,FREGSAVED,"_d_newarraymT", 0, tv) \
SYMBOL_MARS(NEWARRAYMIT, FLfunc,FREGSAVED,"_d_newarraymiT", 0, tv) \
SYMBOL_MARS(ARRAYLITERALT, FLfunc,FREGSAVED,"_d_arrayliteralT", 0, tv) \
SYMBOL_MARS(ARRAYLITERALTX, FLfunc,FREGSAVED,"_d_arrayliteralTX", 0, t) \
SYMBOL_MARS(ASSOCARRAYLITERALT, FLfunc,FREGSAVED,"_d_assocarrayliteralT", 0, tv) \
SYMBOL_MARS(ASSOCARRAYLITERALTX, FLfunc,FREGSAVED,"_d_assocarrayliteralTX", 0, t) \
SYMBOL_MARS(CALLFINALIZER, FLfunc,FREGSAVED,"_d_callfinalizer", 0, t) \
SYMBOL_MARS(CALLINTERFACEFINALIZER, FLfunc,FREGSAVED,"_d_callinterfacefinalizer", 0, t) \
Expand Down
269 changes: 66 additions & 203 deletions src/e2ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -2465,33 +2465,10 @@ elem *InExp::toElem(IRState *irs)
elem *keyti;
TypeAArray *taa = (TypeAArray *)e2->type->toBasetype();


// set to:
Symbol *s;
if (I64)
{
// aaInX(aa, keyti, key);
key = addressElem(key, e1->type);
s = taa->aaGetSymbol("InX", 0);
}
else
{
// aaIn(aa, keyti, key);
if (tybasic(key->Ety) == TYstruct)
{
key = el_una(OPstrpar, TYstruct, key);
key->ET = key->E1->ET;
}
else if (tybasic(key->Ety) == TYarray && taa->index->ty == Tsarray)
{ // e2->elem() turns string literals into a TYarray, so the
// length is lost. Restore it.
key = el_una(OPstrpar, TYstruct, key);
assert(e1->type->size() == taa->index->size());
key->ET = taa->index->toCtype();
}

s = taa->aaGetSymbol("In", 0);
}
// aaInX(aa, keyti, key);
key = addressElem(key, e1->type);
Symbol *s = taa->aaGetSymbol("InX", 0);
keyti = taa->index->getInternalTypeInfo(NULL)->toElem(irs);
ep = el_params(key, keyti, aa, NULL);
e = el_bin(OPcall, type->totym(), el_var(s), ep);
Expand All @@ -2513,22 +2490,8 @@ elem *RemoveExp::toElem(IRState *irs)
elem *ep;
elem *keyti;

Symbol *s;
if (I64)
{
ekey = addressElem(ekey, e1->type);
s = taa->aaGetSymbol("DelX", 0);
}
else
{
if (tybasic(ekey->Ety) == TYstruct || tybasic(ekey->Ety) == TYarray)
{
ekey = el_una(OPstrpar, TYstruct, ekey);
ekey->ET = ekey->E1->ET;
}

s = taa->aaGetSymbol("Del", 0);
}
ekey = addressElem(ekey, e1->type);
Symbol *s = taa->aaGetSymbol("DelX", 0);
keyti = taa->index->getInternalTypeInfo(NULL)->toElem(irs);
ep = el_params(ekey, keyti, ea, NULL);
e = el_bin(OPcall, TYnptr, el_var(s), ep);
Expand Down Expand Up @@ -4457,38 +4420,22 @@ elem *IndexExp::toElem(IRState *irs)
// n2 becomes the index, also known as the key
elem *n2 = e2->toElem(irs);

if (I64)
{
/* Turn n2 into a pointer to the index. If it's an lvalue,
* take the address of it. If not, copy it to a temp and
* take the address of that.
*/
n2 = addressElem(n2, taa->index);
}
else
{
if (tybasic(n2->Ety) == TYstruct || tybasic(n2->Ety) == TYarray)
{
n2 = el_una(OPstrpar, TYstruct, n2);
n2->ET = n2->E1->ET;
if (taa->index->ty == Tsarray)
{
assert(e2->type->size() == taa->index->size());
}
//printf("numbytes = %d\n", n2->Enumbytes);
}
}
/* Turn n2 into a pointer to the index. If it's an lvalue,
* take the address of it. If not, copy it to a temp and
* take the address of that.
*/
n2 = addressElem(n2, taa->index);

elem *valuesize = el_long(TYsize_t, vsize);
//printf("valuesize: "); elem_print(valuesize);
if (modifiable)
{
n1 = el_una(OPaddr, TYnptr, n1);
s = taa->aaGetSymbol(I64 ? "GetX" : "Get", 1);
s = taa->aaGetSymbol("GetX", 1);
}
else
{
s = taa->aaGetSymbol(I64 ? "GetRvalueX" : "GetRvalue", 1);
s = taa->aaGetSymbol("GetRvalueX", 1);
}
//printf("taa->index = %s\n", taa->index->toChars());
elem* keyti = taa->index->getInternalTypeInfo(NULL)->toElem(irs);
Expand Down Expand Up @@ -4607,81 +4554,48 @@ elem *ArrayLiteralExp::toElem(IRState *irs)
Type *tb = type->toBasetype();
if (elements)
{
if (I64)
{ /* Instead of passing the initializers on the stack, allocate the
* array and assign the members inline.
* Avoids the whole variadic arg mess.
*/
dim = elements->dim;
Expressions args;
args.setDim(dim); // +1 for number of args parameter
e = el_long(TYsize_t, dim);
e = el_param(e, type->getTypeInfo(NULL)->toElem(irs));
// call _d_arrayliteralTX(ti, dim)
e = el_bin(OPcall,TYnptr,el_var(rtlsym[RTLSYM_ARRAYLITERALTX]),e);
Symbol *stmp = symbol_genauto(Type::tvoid->pointerTo()->toCtype());
e = el_bin(OPeq,TYnptr,el_var(stmp),e);
/* Instead of passing the initializers on the stack, allocate the
* array and assign the members inline.
* Avoids the whole variadic arg mess.
*/
dim = elements->dim;
Expressions args;
args.setDim(dim); // +1 for number of args parameter
e = el_long(TYsize_t, dim);
e = el_param(e, type->getTypeInfo(NULL)->toElem(irs));
// call _d_arrayliteralTX(ti, dim)
e = el_bin(OPcall,TYnptr,el_var(rtlsym[RTLSYM_ARRAYLITERALTX]),e);
Symbol *stmp = symbol_genauto(Type::tvoid->pointerTo()->toCtype());
e = el_bin(OPeq,TYnptr,el_var(stmp),e);

targ_size_t sz = tb->nextOf()->size(); // element size
::type *te = tb->nextOf()->toCtype(); // element type
for (size_t i = 0; i < dim; i++)
{ Expression *el = (Expression *)elements->data[i];
targ_size_t sz = tb->nextOf()->size(); // element size
::type *te = tb->nextOf()->toCtype(); // element type
for (size_t i = 0; i < dim; i++)
{ Expression *el = (Expression *)elements->data[i];

/* Generate: *(stmp + i * sz) = element[i]
*/
elem *ep = el->toElem(irs);
elem *ev = el_var(stmp);
ev = el_bin(OPadd, TYnptr, ev, el_long(TYsize_t, i * sz));
ev = el_una(OPind, te->Tty, ev);
elem *eeq = el_bin(OPeq,te->Tty,ev,ep);
/* Generate: *(stmp + i * sz) = element[i]
*/
elem *ep = el->toElem(irs);
elem *ev = el_var(stmp);
ev = el_bin(OPadd, TYnptr, ev, el_long(TYsize_t, i * sz));
ev = el_una(OPind, te->Tty, ev);
elem *eeq = el_bin(OPeq,te->Tty,ev,ep);

if (tybasic(te->Tty) == TYstruct)
{
eeq->Eoper = OPstreq;
eeq->ET = te;
}
else if (tybasic(te->Tty) == TYarray)
{
eeq->Eoper = OPstreq;
eeq->Ejty = eeq->Ety = TYstruct;
eeq->ET = te;
}
args.data[i] = (void *)eeq;
if (tybasic(te->Tty) == TYstruct)
{
eeq->Eoper = OPstreq;
eeq->ET = te;
}
e = el_combine(e, el_combines(args.data, dim));
e = el_combine(e, el_var(stmp));
}
else
{
Expressions args;
dim = elements->dim;
args.setDim(dim + 1); // +1 for number of args parameter
e = el_long(TYsize_t, dim);
args.data[dim] = (void *)e;
for (size_t i = 0; i < dim; i++)
{ Expression *el = (Expression *)elements->data[i];
elem *ep = el->toElem(irs);

if (tybasic(ep->Ety) == TYstruct || tybasic(ep->Ety) == TYarray)
{
ep = el_una(OPstrpar, TYstruct, ep);
ep->ET = el->type->toCtype();
}
args.data[dim - (i + 1)] = (void *)ep;
else if (tybasic(te->Tty) == TYarray)
{
eeq->Eoper = OPstreq;
eeq->Ejty = eeq->Ety = TYstruct;
eeq->ET = te;
}

/* Because the number of parameters can get very large, produce
* a balanced binary tree so we don't blow up the stack in
* the subsequent tree walking code.
*/
e = el_params(args.data, dim + 1);

e = el_param(e, type->getTypeInfo(NULL)->toElem(irs));

// call _d_arrayliteralT(ti, dim, ...)
e = el_bin(OPcall,TYnptr,el_var(rtlsym[RTLSYM_ARRAYLITERALT]),e);
e->Eflags |= EFLAGS_variadic;
args.data[i] = (void *)eeq;
}
e = el_combine(e, el_combines(args.data, dim));
e = el_combine(e, el_var(stmp));
}
else
{ dim = 0;
Expand Down Expand Up @@ -4759,80 +4673,29 @@ elem *AssocArrayLiteralExp::toElem(IRState *irs)
size_t dim = keys->dim;
elem *e;

if (I64)
{ // call _d_assocarrayliteralTX(TypeInfo_AssociativeArray ti, void[] keys, void[] values)
// Prefer this to avoid the varargs fiasco in 64 bit code
Type *t = type->toBasetype()->mutableOf();
assert(t->ty == Taarray);
TypeAArray *ta = (TypeAArray *)t;
// call _d_assocarrayliteralTX(TypeInfo_AssociativeArray ti, void[] keys, void[] values)
// Prefer this to avoid the varargs fiasco in 64 bit code
Type *t = type->toBasetype()->mutableOf();
assert(t->ty == Taarray);
TypeAArray *ta = (TypeAArray *)t;

symbol *skeys;
elem *ekeys = ExpressionsToStaticArray(irs, loc, keys, ta->index, &skeys);
symbol *skeys;
elem *ekeys = ExpressionsToStaticArray(irs, loc, keys, ta->index, &skeys);

symbol *svalues;
elem *evalues = ExpressionsToStaticArray(irs, loc, values, ta->nextOf(), &svalues);
symbol *svalues;
elem *evalues = ExpressionsToStaticArray(irs, loc, values, ta->nextOf(), &svalues);

e = el_params(el_pair(TYdarray, el_long(TYsize_t, dim), el_ptr(svalues)),
el_pair(TYdarray, el_long(TYsize_t, dim), el_ptr(skeys )),
ta->getTypeInfo(NULL)->toElem(irs),
NULL);

// call _d_assocarrayliteralTX(ti, keys, values)
e = el_bin(OPcall,TYnptr,el_var(rtlsym[RTLSYM_ASSOCARRAYLITERALTX]),e);
el_setLoc(e,loc);
e = el_params(el_pair(TYdarray, el_long(TYsize_t, dim), el_ptr(svalues)),
el_pair(TYdarray, el_long(TYsize_t, dim), el_ptr(skeys )),
ta->getTypeInfo(NULL)->toElem(irs),
NULL);

e = el_combine(evalues, e);
e = el_combine(ekeys, e);
}
else // Keep for binary backwards compatibility
{ // call _d_assocarrayliteralT(TypeInfo_AssociativeArray ti, size_t length, ...)
e = el_long(TYsize_t, dim);
for (size_t i = 0; i < dim; i++)
{ Expression *el = (Expression *)keys->data[i];

for (int j = 0; j < 2; j++)
{
elem *ep = el->toElem(irs);

if (tybasic(ep->Ety) == TYstruct || tybasic(ep->Ety) == TYarray)
{
ep = el_una(OPstrpar, TYstruct, ep);
ep->ET = el->type->toCtype();
}
//printf("[%d] %s\n", i, el->toChars());
//elem_print(ep);
e = el_param(ep, e);
el = (Expression *)values->data[i];
}
}

Type *t = type->toBasetype()->mutableOf();
assert(t->ty == Taarray);
TypeAArray *ta = (TypeAArray *)t;

#if 0
/* Unfortunately, the hash function for Aa (array of chars) is custom and
* different from Axa and Aya, which get the generic hash function.
* So, rewrite the type of the AArray so that if it's key type
* is an array of const or invariant, make it an array of mutable.
*/
Type *tkey = ta->index->toBasetype();
if (tkey->ty == Tarray)
{
tkey = tkey->nextOf()->mutableOf()->arrayOf();
tkey = tkey->semantic(0, NULL);
ta = new TypeAArray(ta->nextOf(), tkey);
ta = (TypeAArray *)ta->merge();
}
#endif

e = el_param(e, ta->getTypeInfo(NULL)->toElem(irs));
// call _d_assocarrayliteralTX(ti, keys, values)
e = el_bin(OPcall,TYnptr,el_var(rtlsym[RTLSYM_ASSOCARRAYLITERALTX]),e);
el_setLoc(e,loc);

// call _d_assocarrayliteralT(ti, dim, ...)
e = el_bin(OPcall,TYnptr,el_var(rtlsym[RTLSYM_ASSOCARRAYLITERALT]),e);
e->Eflags |= EFLAGS_variadic;
el_setLoc(e,loc);
}
e = el_combine(evalues, e);
e = el_combine(ekeys, e);

return e;
}
Expand Down