From a19ff89c81782621405ff54dd9b6424dd64b65ed Mon Sep 17 00:00:00 2001 From: Walter Bright Date: Mon, 24 Nov 2014 12:44:34 -0800 Subject: [PATCH] CTFE: copyLiteral() returns UnionExp --- src/ctfe.h | 2 +- src/ctfeexpr.c | 75 ++++++++++++++++++++++++++++--------------------- src/interpret.c | 38 ++++++++++++------------- 3 files changed, 63 insertions(+), 52 deletions(-) diff --git a/src/ctfe.h b/src/ctfe.h index 99bac6abf258..73311ec52221 100644 --- a/src/ctfe.h +++ b/src/ctfe.h @@ -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); diff --git a/src/ctfeexpr.c b/src/ctfeexpr.c index a8b225e2615d..2a7837d724b8 100644 --- a/src/ctfeexpr.c +++ b/src/ctfeexpr.c @@ -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) { @@ -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 || @@ -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. @@ -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; @@ -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); @@ -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 { @@ -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 { @@ -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); diff --git a/src/interpret.c b/src/interpret.c index e70cb6a03b78..5d9813efb7db 100644 --- a/src/interpret.c +++ b/src/interpret.c @@ -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) { @@ -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); @@ -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); } @@ -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)) @@ -2771,7 +2771,7 @@ class Interpreter : public Visitor result = e; return; } - result = copyLiteral(e); + result = copyLiteral(e).copy(); } void visit(AssocArrayLiteralExp *e) @@ -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 @@ -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; @@ -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; } @@ -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. @@ -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; @@ -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 @@ -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 @@ -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, @@ -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 @@ -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)) { @@ -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) @@ -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) @@ -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) @@ -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]))