summary refs log tree commit diff stats
path: root/compiler/ccgstmts.nim
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/ccgstmts.nim')
-rw-r--r--compiler/ccgstmts.nim43
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) =