diff options
Diffstat (limited to 'compiler/ccgexprs.nim')
-rw-r--r-- | compiler/ccgexprs.nim | 46 |
1 files changed, 26 insertions, 20 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 34836d843..cab2c78f5 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -31,10 +31,18 @@ proc intLiteral(i: BiggestInt): Rope = result = ~"(IL64(-9223372036854775807) - IL64(1))" proc genLiteral(p: BProc, n: PNode, ty: PType): Rope = - if ty == nil: internalError(p.config, n.info, "genLiteral: ty is nil") case n.kind of nkCharLit..nkUInt64Lit: - case skipTypes(ty, abstractVarRange).kind + var k: TTypeKind + if ty != nil: + k = skipTypes(ty, abstractVarRange).kind + else: + case n.kind + of nkCharLit: k = tyChar + of nkUInt64Lit: k = tyUInt64 + of nkInt64Lit: k = tyInt64 + else: k = tyNil # don't go into the case variant that uses 'ty' + case k of tyChar, tyNil: result = intLiteral(n.intVal) of tyBool: @@ -46,8 +54,8 @@ proc genLiteral(p: BProc, n: PNode, ty: PType): Rope = result = "(($1) $2)" % [getTypeDesc(p.module, ty), intLiteral(n.intVal)] of nkNilLit: - let t = skipTypes(ty, abstractVarRange) - if t.kind == tyProc and t.callConv == ccClosure: + let k = if ty == nil: tyPointer else: skipTypes(ty, abstractVarRange).kind + if k == tyProc and skipTypes(ty, abstractVarRange).callConv == ccClosure: let id = nodeTableTestOrSet(p.module.dataCache, n, p.module.labels) result = p.module.tmpBase & rope(id) if id == p.module.labels: @@ -59,7 +67,9 @@ proc genLiteral(p: BProc, n: PNode, ty: PType): Rope = else: result = rope("NIM_NIL") of nkStrLit..nkTripleStrLit: - case skipTypes(ty, abstractVarRange + {tyStatic, tyUserTypeClass, tyUserTypeClassInst}).kind + let k = if ty == nil: tyString + else: skipTypes(ty, abstractVarRange + {tyStatic, tyUserTypeClass, tyUserTypeClassInst}).kind + case k of tyNil: result = genNilStringLiteral(p.module, n.info) of tyString: @@ -168,7 +178,7 @@ proc canMove(p: BProc, n: PNode): bool = # echo n.info, " optimized ", n # result = false -proc genRefAssign(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = +proc genRefAssign(p: BProc, dest, src: TLoc) = if (dest.storage == OnStack and p.config.selectedGC != gcGo) or not usesWriteBarrier(p.config): linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src)) elif dest.storage == OnHeap: @@ -266,12 +276,12 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = let ty = skipTypes(dest.t, abstractRange + tyUserTypeClasses + {tyStatic}) case ty.kind of tyRef: - genRefAssign(p, dest, src, flags) + genRefAssign(p, dest, src) of tySequence: if p.config.selectedGC == gcDestructors: genGenericAsgn(p, dest, src, flags) elif (needToCopy notin flags and src.storage != OnStatic) or canMove(p, src.lode): - genRefAssign(p, dest, src, flags) + genRefAssign(p, dest, src) else: linefmt(p, cpsStmts, "#genericSeqAssign($1, $2, $3);$n", addrLoc(p.config, dest), rdLoc(src), @@ -280,7 +290,7 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = if p.config.selectedGC == gcDestructors: genGenericAsgn(p, dest, src, flags) elif (needToCopy notin flags and src.storage != OnStatic) or canMove(p, src.lode): - genRefAssign(p, dest, src, flags) + genRefAssign(p, dest, src) else: if (dest.storage == OnStack and p.config.selectedGC != gcGo) or not usesWriteBarrier(p.config): linefmt(p, cpsStmts, "$1 = #copyString($2);$n", dest.rdLoc, src.rdLoc) @@ -295,16 +305,16 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = linefmt(p, cpsStmts, "#unsureAsgnRef((void**) $1, #copyString($2));$n", addrLoc(p.config, dest), rdLoc(src)) of tyProc: - if needsComplexAssignment(dest.t): + if containsGarbageCollectedRef(dest.t): # optimize closure assignment: let a = optAsgnLoc(dest, dest.t, "ClE_0".rope) let b = optAsgnLoc(src, dest.t, "ClE_0".rope) - genRefAssign(p, a, b, flags) + genRefAssign(p, a, b) linefmt(p, cpsStmts, "$1.ClP_0 = $2.ClP_0;$n", rdLoc(dest), rdLoc(src)) else: linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src)) of tyTuple: - if needsComplexAssignment(dest.t): + if containsGarbageCollectedRef(dest.t): if dest.t.len <= 4: genOptAsgnTuple(p, dest, src, flags) else: genGenericAsgn(p, dest, src, flags) else: @@ -315,7 +325,7 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src)) elif not isObjLackingTypeField(ty): genGenericAsgn(p, dest, src, flags) - elif needsComplexAssignment(ty): + elif containsGarbageCollectedRef(ty): if ty.sons[0].isNil and asgnComplexity(ty.n) <= 4: discard getTypeDesc(p.module, ty) internalAssert p.config, ty.n != nil @@ -325,7 +335,7 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = else: linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src)) of tyArray: - if needsComplexAssignment(dest.t): + if containsGarbageCollectedRef(dest.t): genGenericAsgn(p, dest, src, flags) else: linefmt(p, cpsStmts, @@ -334,7 +344,7 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = of tyOpenArray, tyVarargs: # open arrays are always on the stack - really? What if a sequence is # passed to an open array? - if needsComplexAssignment(dest.t): + if containsGarbageCollectedRef(dest.t): linefmt(p, cpsStmts, # XXX: is this correct for arrays? "#genericAssignOpenArray((void*)$1, (void*)$2, $1Len_0, $3);$n", addrLoc(p.config, dest), addrLoc(p.config, src), @@ -840,7 +850,6 @@ proc genUncheckedArrayElem(p: BProc, n, x, y: PNode, d: var TLoc) = var a, b: TLoc initLocExpr(p, x, a) initLocExpr(p, y, b) - var ty = skipTypes(a.t, abstractVarRange + abstractPtrs + tyUserTypeClasses) d.inheritLocation(a) putIntoDest(p, d, n, ropecg(p.module, "$1[$2]", rdLoc(a), rdCharLoc(b)), a.storage) @@ -874,7 +883,6 @@ proc genCStringElem(p: BProc, n, x, y: PNode, d: var TLoc) = var a, b: TLoc initLocExpr(p, x, a) initLocExpr(p, y, b) - var ty = skipTypes(a.t, abstractVarRange) inheritLocation(d, a) putIntoDest(p, d, n, ropecg(p.module, "$1[$2]", rdLoc(a), rdCharLoc(b)), a.storage) @@ -1128,7 +1136,7 @@ proc genSeqElemAppend(p: BProc, e: PNode, d: var TLoc) = genTypeInfo(p.module, seqType, e.info)]) # emit the write barrier if required, but we can always move here, so # use 'genRefAssign' for the seq. - genRefAssign(p, a, call, {}) + genRefAssign(p, a, call) #if bt != b.t: # echo "YES ", e.info, " new: ", typeToString(bt), " old: ", typeToString(b.t) initLoc(dest, locExpr, e.sons[2], OnHeap) @@ -1392,7 +1400,6 @@ proc genArrToSeq(p: BProc, n: PNode, d: var TLoc) = else: var i: TLoc getTemp(p, getSysType(p.module.g.graph, unknownLineInfo(), tyInt), i) - let oldCode = p.s(cpsStmts) linefmt(p, cpsStmts, "for ($1 = 0; $1 < $2; $1++) {$n", i.r, L.rope) initLoc(elem, locExpr, lodeTyp elemType(skipTypes(n.typ, abstractInst)), OnHeap) elem.r = ropecg(p.module, "$1$3[$2]", rdLoc(d), rdLoc(i), dataField(p)) @@ -2566,7 +2573,6 @@ proc genConstObjConstr(p: BProc; n: PNode): Rope = proc genConstSimpleList(p: BProc, n: PNode): Rope = var length = sonsLen(n) result = rope("{") - let t = n.typ.skipTypes(abstractInst) for i in countup(0, length - 2): addf(result, "$1,$n", [genNamedConstExpr(p, n.sons[i])]) if length > 0: |