diff options
Diffstat (limited to 'compiler/ccgstmts.nim')
-rw-r--r-- | compiler/ccgstmts.nim | 43 |
1 files changed, 37 insertions, 6 deletions
diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index a8cfa57e4..037594e89 100644 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -1,7 +1,7 @@ # # # The Nimrod Compiler -# (c) Copyright 2013 Andreas Rumpf +# (c) Copyright 2014 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -24,10 +24,29 @@ proc registerGcRoot(p: BProc, v: PSym) = linefmt(p.module.initProc, cpsStmts, "#nimRegisterGlobalMarker($1);$n", prc) +proc isAssignedImmediately(n: PNode): bool {.inline.} = + if n.kind == nkEmpty: return false + if isInvalidReturnType(n.typ): + # var v = f() + # is transformed into: var v; f(addr v) + # where 'f' **does not** initialize the result! + return false + result = true + proc genVarTuple(p: BProc, n: PNode) = var tup, field: TLoc if n.kind != nkVarTuple: internalError(n.info, "genVarTuple") var L = sonsLen(n) + + # if we have a something that's been captured, use the lowering instead: + var useLowering = false + for i in countup(0, L-3): + if n[i].kind != nkSym: + useLowering = true; break + if useLowering: + genStmts(p, lowerTupleUnpacking(n, p.prc)) + return + genLineDir(p, n) initLocExpr(p, n.sons[L-1], tup) var t = tup.t @@ -40,7 +59,7 @@ proc genVarTuple(p: BProc, n: PNode) = registerGcRoot(p, v) else: assignLocalVar(p, v) - initLocalVar(p, v, immediateAsgn=true) + initLocalVar(p, v, immediateAsgn=isAssignedImmediately(n[L-1])) initLoc(field, locExpr, t.sons[i], tup.s) if t.kind == tyTuple: field.r = ropef("$1.Field$2", [rdLoc(tup), toRope(i)]) @@ -146,12 +165,16 @@ proc genBreakState(p: BProc, n: PNode) = # lineF(p, cpsStmts, "if (($1) < 0) break;$n", [rdLoc(a)]) proc genVarPrototypeAux(m: BModule, sym: PSym) + proc genSingleVar(p: BProc, a: PNode) = var v = a.sons[0].sym if sfCompileTime in v.flags: return var targetProc = p - var immediateAsgn = a.sons[2].kind != nkEmpty if sfGlobal in v.flags: + if v.flags * {sfImportc, sfExportc} == {sfImportc} and + a.sons[2].kind == nkEmpty and + v.loc.flags * {lfHeader, lfNoDecl} != {}: + return if sfPure in v.flags: # v.owner.kind != skModule: targetProc = p.module.preInitProc @@ -170,9 +193,9 @@ proc genSingleVar(p: BProc, a: PNode) = registerGcRoot(p, v) else: assignLocalVar(p, v) - initLocalVar(p, v, immediateAsgn) + initLocalVar(p, v, isAssignedImmediately(a.sons[2])) - if immediateAsgn: + if a.sons[2].kind != nkEmpty: genLineDir(targetProc, a) loadInto(targetProc, a.sons[0], a.sons[2], v.loc) @@ -809,7 +832,14 @@ proc genTry(p: BProc, t: PNode, d: var TLoc) = discard cgsym(p.module, "E_Base") linefmt(p, cpsLocals, "#TSafePoint $1;$n", safePoint) linefmt(p, cpsStmts, "#pushSafePoint(&$1);$n", safePoint) - linefmt(p, cpsStmts, "$1.status = setjmp($1.context);$n", safePoint) + if isDefined("nimStdSetjmp"): + linefmt(p, cpsStmts, "$1.status = setjmp($1.context);$n", safePoint) + elif isDefined("nimSigSetjmp"): + linefmt(p, cpsStmts, "$1.status = sigsetjmp($1.context, 0);$n", safePoint) + elif isDefined("nimRawSetjmp"): + linefmt(p, cpsStmts, "$1.status = _setjmp($1.context);$n", safePoint) + else: + linefmt(p, cpsStmts, "$1.status = setjmp($1.context);$n", safePoint) startBlock(p, "if ($1.status == 0) {$n", [safePoint]) var length = sonsLen(t) add(p.nestedTryStmts, t) @@ -891,6 +921,7 @@ proc genAsmOrEmitStmt(p: BProc, t: PNode, isAsmStmt=false): PRope = app(result, x) app(result, "\\n\"\n") else: + res.add(tnl) result = res.toRope proc genAsmStmt(p: BProc, t: PNode) = |