Skip to content

Commit

Permalink
Merge pull request #4164 from WalterBright/copyliteral
Browse files Browse the repository at this point in the history
CTFE: copyLiteral() returns UnionExp
  • Loading branch information
9rnsr committed Nov 25, 2014
2 parents 2756d80 + a19ff89 commit c0e8143
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 52 deletions.
2 changes: 1 addition & 1 deletion src/ctfe.h
Expand Up @@ -132,7 +132,7 @@ bool needToCopyLiteral(Expression *expr);

/// Make a copy of the ArrayLiteral, AALiteral, String, or StructLiteral.
/// This value will be used for in-place modification.
Expression *copyLiteral(Expression *e);
UnionExp copyLiteral(Expression *e);

/// Set this literal to the given type, copying it if necessary
Expression *paintTypeOntoLiteral(Type *type, Expression *lit);
Expand Down
75 changes: 43 additions & 32 deletions src/ctfeexpr.c
Expand Up @@ -222,44 +222,46 @@ Expressions *copyLiteralArray(Expressions *oldelems)
Expressions *newelems = new Expressions();
newelems->setDim(oldelems->dim);
for (size_t i = 0; i < oldelems->dim; i++)
(*newelems)[i] = copyLiteral((*oldelems)[i]);
(*newelems)[i] = copyLiteral((*oldelems)[i]).copy();
return newelems;
}

// Make a copy of the ArrayLiteral, AALiteral, String, or StructLiteral.
// This value will be used for in-place modification.
Expression *copyLiteral(Expression *e)
UnionExp copyLiteral(Expression *e)
{
UnionExp ue;
if (e->op == TOKstring) // syntaxCopy doesn't make a copy for StringExp!
{
StringExp *se = (StringExp *)e;
utf8_t *s = (utf8_t *)mem.calloc(se->len + 1, se->sz);
memcpy(s, se->string, se->len * se->sz);
StringExp *se2 = new StringExp(se->loc, s, se->len);
new(&ue) StringExp(se->loc, s, se->len);
StringExp *se2 = (StringExp *)ue.exp();
se2->committed = se->committed;
se2->postfix = se->postfix;
se2->type = se->type;
se2->sz = se->sz;
se2->ownedByCtfe = true;
return se2;
return ue;
}
if (e->op == TOKarrayliteral)
{
ArrayLiteralExp *ae = (ArrayLiteralExp *)e;
ArrayLiteralExp *r = new ArrayLiteralExp(e->loc,
copyLiteralArray(ae->elements));
new(&ue) ArrayLiteralExp(e->loc, copyLiteralArray(ae->elements));
ArrayLiteralExp *r = (ArrayLiteralExp *)ue.exp();
r->type = e->type;
r->ownedByCtfe = true;
return r;
return ue;
}
if (e->op == TOKassocarrayliteral)
{
AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)e;
AssocArrayLiteralExp *r = new AssocArrayLiteralExp(e->loc,
copyLiteralArray(aae->keys), copyLiteralArray(aae->values));
new(&ue) AssocArrayLiteralExp(e->loc, copyLiteralArray(aae->keys), copyLiteralArray(aae->values));
AssocArrayLiteralExp *r = (AssocArrayLiteralExp *)ue.exp();
r->type = e->type;
r->ownedByCtfe = true;
return r;
return ue;
}
if (e->op == TOKstructliteral)
{
Expand Down Expand Up @@ -288,14 +290,15 @@ Expression *copyLiteral(Expression *e)
m = createBlockDuplicatedArrayLiteral(e->loc, v->type, m, (size_t)length);
}
else if (v->type->ty != Tarray && v->type->ty!=Taarray) // NOTE: do not copy array references
m = copyLiteral(m);
m = copyLiteral(m).copy();
(*newelems)[i] = m;
}
StructLiteralExp *r = new StructLiteralExp(e->loc, se->sd, newelems, se->stype);
new(&ue) StructLiteralExp(e->loc, se->sd, newelems, se->stype);
StructLiteralExp *r = (StructLiteralExp *)ue.exp();
r->type = e->type;
r->ownedByCtfe = true;
r->origin = ((StructLiteralExp *)e)->origin;
return r;
return ue;
}
if (e->op == TOKfunction || e->op == TOKdelegate ||
e->op == TOKsymoff || e->op == TOKnull ||
Expand All @@ -305,44 +308,52 @@ Expression *copyLiteral(Expression *e)
e->op == TOKvoid || e->op == TOKvector)
{
// Simple value types
Expression *r = e->copy(); // keep e1 for DelegateExp and DotVarExp
// Keep e1 for DelegateExp and DotVarExp
memcpy(&ue, e, e->size);
Expression *r = ue.exp();
r->type = e->type;
return r;
return ue;
}
if (isPointer(e->type))
{
// For pointers, we only do a shallow copy.
Expression *r;
if (e->op == TOKaddress)
r = new AddrExp(e->loc, ((AddrExp *)e)->e1);
new(&ue) AddrExp(e->loc, ((AddrExp *)e)->e1);
else if (e->op == TOKindex)
r = new IndexExp(e->loc, ((IndexExp *)e)->e1, ((IndexExp *)e)->e2);
new(&ue) IndexExp(e->loc, ((IndexExp *)e)->e1, ((IndexExp *)e)->e2);
else if (e->op == TOKdotvar)
{
r = new DotVarExp(e->loc, ((DotVarExp *)e)->e1,
new(&ue) DotVarExp(e->loc, ((DotVarExp *)e)->e1,
((DotVarExp *)e)->var, ((DotVarExp *)e)->hasOverloads);
}
else
assert(0);
Expression *r = ue.exp();
r->type = e->type;
return r;
return ue;
}
if (e->op == TOKslice)
{
// Array slices only do a shallow copy
Expression *r = new SliceExp(e->loc, ((SliceExp *)e)->e1,
new(&ue) SliceExp(e->loc, ((SliceExp *)e)->e1,
((SliceExp *)e)->lwr, ((SliceExp *)e)->upr);
Expression *r = ue.exp();
r->type = e->type;
return r;
return ue;
}
if (e->op == TOKclassreference)
return new ClassReferenceExp(e->loc, ((ClassReferenceExp *)e)->value, e->type);
{
new(&ue) ClassReferenceExp(e->loc, ((ClassReferenceExp *)e)->value, e->type);
return ue;
}
if (e->op == TOKerror)
return e;

{
memcpy(&ue, e, e->size);
return ue;
}
e->error("Internal Compiler Error: CTFE literal %s", e->toChars());
assert(0);
return e;
return ue;
}

/* Deal with type painting.
Expand Down Expand Up @@ -402,7 +413,7 @@ Expression *paintTypeOntoLiteral(Type *type, Expression *lit)
// level of indirection
if (lit->op == TOKstructliteral && isPointer(type))
lit->error("CTFE internal error painting %s", type->toChars());
e = copyLiteral(lit);
e = copyLiteral(lit).copy();
}
e->type = type;
return e;
Expand Down Expand Up @@ -470,7 +481,7 @@ ArrayLiteralExp *createBlockDuplicatedArrayLiteral(Loc loc, Type *type,
for (size_t i = 0; i < dim; i++)
{
if (mustCopy)
elem = copyLiteral(elem);
elem = copyLiteral(elem).copy();
(*elements)[i] = elem;
}
ArrayLiteralExp *ae = new ArrayLiteralExp(loc, elements);
Expand Down Expand Up @@ -1664,13 +1675,13 @@ UnionExp ctfeCat(Type *type, Expression *e1, Expression *e2)
t1->nextOf()->equals(t2->nextOf()))
{
// [ e1 ] ~ null ----> [ e1 ].dup
e = paintTypeOntoLiteral(type, copyLiteral(e1));
e = paintTypeOntoLiteral(type, copyLiteral(e1).copy());
}
else if (e1->op == TOKnull && e2->op == TOKarrayliteral &&
t1->nextOf()->equals(t2->nextOf()))
{
// null ~ [ e2 ] ----> [ e2 ].dup
e = paintTypeOntoLiteral(type, copyLiteral(e2));
e = paintTypeOntoLiteral(type, copyLiteral(e2).copy());
}
else
{
Expand Down Expand Up @@ -1975,7 +1986,7 @@ UnionExp changeArrayLiteralLength(Loc loc, TypeArray *arrayType,
* we need to create a unique copy for each element
*/
for (size_t i = copylen; i < newlen; i++)
(*elements)[i] = copyLiteral(defaultElem);
(*elements)[i] = copyLiteral(defaultElem).copy();
}
else
{
Expand Down Expand Up @@ -2251,7 +2262,7 @@ UnionExp voidInitLiteral(Type *t, VarDeclaration *var)
for (size_t i = 0; i < d; i++)
{
if (mustCopy && i > 0)
elem = copyLiteral(elem);
elem = copyLiteral(elem).copy();
(*elements)[i] = elem;
}
new(&ue) ArrayLiteralExp(var->loc, elements);
Expand Down
38 changes: 19 additions & 19 deletions src/interpret.c
Expand Up @@ -912,7 +912,7 @@ Expression *interpret(FuncDeclaration *fd, InterState *istate, Expressions *argu
* copy them if they are passed as const
*/
if (earg->op == TOKstructliteral && !(arg->storageClass & (STCconst | STCimmutable)))
earg = copyLiteral(earg);
earg = copyLiteral(earg).copy();
}
if (earg->op == TOKthrownexception)
{
Expand Down Expand Up @@ -1403,7 +1403,7 @@ class Interpreter : public Visitor
}

if (needToCopyLiteral(e))
e = copyLiteral(e);
e = copyLiteral(e).copy();
#if LOGASSIGN
printf("RETURN %s\n", s->loc.toChars());
showCtfeExpr(e);
Expand Down Expand Up @@ -2389,7 +2389,7 @@ class Interpreter : public Visitor
}
if (e && !CTFEExp::isCantExp(e) && e->op != TOKthrownexception)
{
e = copyLiteral(e);
e = copyLiteral(e).copy();
if (v->isDataseg() || (v->storage_class & STCmanifest))
ctfeStack.saveGlobalConstant(v, e);
}
Expand Down Expand Up @@ -2762,7 +2762,7 @@ class Interpreter : public Visitor
}
ArrayLiteralExp *ae = new ArrayLiteralExp(e->loc, expsx);
ae->type = e->type;
result = copyLiteral(ae);
result = copyLiteral(ae).copy();
return;
}
if (((TypeNext *)e->type)->next->mod & (MODconst | MODimmutable))
Expand All @@ -2771,7 +2771,7 @@ class Interpreter : public Visitor
result = e;
return;
}
result = copyLiteral(e);
result = copyLiteral(e).copy();
}

void visit(AssocArrayLiteralExp *e)
Expand Down Expand Up @@ -2949,7 +2949,7 @@ class Interpreter : public Visitor
result = se;
return;
}
result = copyLiteral(e);
result = copyLiteral(e).copy();
}

// Create an array literal of type 'newtype' with dimensions given by
Expand All @@ -2972,7 +2972,7 @@ class Interpreter : public Visitor
Expressions *elements = new Expressions();
elements->setDim(len);
for (size_t i = 0; i < len; i++)
(*elements)[i] = copyLiteral(elem);
(*elements)[i] = copyLiteral(elem).copy();
ArrayLiteralExp *ae = new ArrayLiteralExp(loc, elements);
ae->type = newtype;
ae->ownedByCtfe = true;
Expand Down Expand Up @@ -3050,7 +3050,7 @@ class Interpreter : public Visitor
result = CTFEExp::cantexp;
return;
}
result = new AddrExp(e->loc, copyLiteral(result));
result = new AddrExp(e->loc, copyLiteral(result).copy());
result->type = e->type;
return;
}
Expand Down Expand Up @@ -3087,7 +3087,7 @@ class Interpreter : public Visitor
m = v->type->defaultInitLiteral(e->loc);
if (exceptionOrCant(m))
return;
(*elems)[fieldsSoFar+i] = copyLiteral(m);
(*elems)[fieldsSoFar+i] = copyLiteral(m).copy();
}
}
// Hack: we store a ClassDeclaration instead of a StructDeclaration.
Expand Down Expand Up @@ -3133,7 +3133,7 @@ class Interpreter : public Visitor
*/
Expressions *elements = new Expressions();
elements->setDim(1);
(*elements)[0] = copyLiteral(newval);
(*elements)[0] = copyLiteral(newval).copy();
ArrayLiteralExp *ae = new ArrayLiteralExp(e->loc, elements);
ae->type = e->newtype->arrayOf();
ae->ownedByCtfe = true;
Expand Down Expand Up @@ -3560,7 +3560,7 @@ class Interpreter : public Visitor
// We need to dup it. We can skip this if it's a dynamic array,
// because it gets copied later anyway
if (newval->type->ty != Tarray)
newval = copyLiteral(newval);
newval = copyLiteral(newval).copy();
if (newval->op == TOKslice)
newval = resolveSlice(newval);
// It becomes a reference assignment
Expand Down Expand Up @@ -3690,7 +3690,7 @@ class Interpreter : public Visitor
// only modifying part of the variable. So we need to make sure
// that the parent variable exists.
if (e1->op != TOKvar && ultimateVar && !getValue(ultimateVar))
setValue(ultimateVar, copyLiteral(ultimateVar->type->defaultInitLiteral(e->loc)));
setValue(ultimateVar, copyLiteral(ultimateVar->type->defaultInitLiteral(e->loc)).copy());

// ---------------------------------------
// Deal with reference assignment
Expand Down Expand Up @@ -3722,7 +3722,7 @@ class Interpreter : public Visitor
newval->op == TOKarrayliteral)
{
if (needToCopyLiteral(newval))
newval = copyLiteral(newval);
newval = copyLiteral(newval).copy();
}

// Get the value to return. Note that 'newval' is an Lvalue,
Expand Down Expand Up @@ -3890,7 +3890,7 @@ class Interpreter : public Visitor
result = CTFEExp::cantexp;
return;
}
newval = copyLiteral(newval);
newval = copyLiteral(newval).copy();
if (getValue(v))
assignInPlace(getValue(v), newval);
else
Expand Down Expand Up @@ -5248,7 +5248,7 @@ class Interpreter : public Visitor
ctfeStack.push(v);
if (!v->init && !getValue(v))
{
setValue(v, copyLiteral(v->type->defaultInitLiteral(e->loc)));
setValue(v, copyLiteral(v->type->defaultInitLiteral(e->loc)).copy());
}
if (!getValue(v))
{
Expand All @@ -5266,7 +5266,7 @@ class Interpreter : public Visitor
if (newval->op != TOKvoidexp)
{
// v isn't necessarily null.
setValueWithoutChecking(v, copyLiteral(newval));
setValueWithoutChecking(v, copyLiteral(newval).copy());
}
}
if (goal == ctfeNeedLvalue || goal == ctfeNeedLvalueRef)
Expand Down Expand Up @@ -6557,7 +6557,7 @@ Expression *interpret_keys(InterState *istate, Expression *earg, Type *returnTyp
ArrayLiteralExp *ae = new ArrayLiteralExp(aae->loc, aae->keys);
ae->ownedByCtfe = aae->ownedByCtfe;
ae->type = returnType;
return copyLiteral(ae);
return copyLiteral(ae).copy();
}

Expression *interpret_values(InterState *istate, Expression *earg, Type *returnType)
Expand All @@ -6578,7 +6578,7 @@ Expression *interpret_values(InterState *istate, Expression *earg, Type *returnT
ae->ownedByCtfe = aae->ownedByCtfe;
ae->type = returnType;
//printf("result is %s\n", e->toChars());
return copyLiteral(ae);
return copyLiteral(ae).copy();
}

Expression *interpret_dup(InterState *istate, Expression *earg)
Expand All @@ -6594,7 +6594,7 @@ Expression *interpret_dup(InterState *istate, Expression *earg)
if (earg->op != TOKassocarrayliteral && earg->type->toBasetype()->ty != Taarray)
return NULL;
assert(earg->op == TOKassocarrayliteral);
AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)copyLiteral(earg);
AssocArrayLiteralExp *aae = (AssocArrayLiteralExp *)copyLiteral(earg).copy();
for (size_t i = 0; i < aae->keys->dim; i++)
{
if (Expression *e = evaluatePostblit(istate, (*aae->keys)[i]))
Expand Down

0 comments on commit c0e8143

Please sign in to comment.