summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/ccgcalls.nim2
-rw-r--r--compiler/ccgstmts.nim7
-rw-r--r--compiler/cgen.nim21
-rw-r--r--compiler/cgendata.nim1
-rw-r--r--compiler/extccomp.nim3
-rw-r--r--compiler/nimrod.nim10
-rw-r--r--compiler/pragmas.nim8
-rw-r--r--compiler/semthreads.nim3
-rw-r--r--compiler/wordrecg.nim5
9 files changed, 47 insertions, 13 deletions
diff --git a/compiler/ccgcalls.nim b/compiler/ccgcalls.nim
index 1d6df3c15..07fba95a3 100644
--- a/compiler/ccgcalls.nim
+++ b/compiler/ccgcalls.nim
@@ -290,6 +290,7 @@ proc genCall(p: BProc, e: PNode, d: var TLoc) =
     genNamedParamCall(p, e, d)
   else:
     genPrefixCall(p, nil, e, d)
+  postStmtActions(p)
   when false:
     if d.s == onStack and containsGarbageCollectedRef(d.t): keepAlive(p, d)
 
@@ -303,6 +304,7 @@ proc genAsgnCall(p: BProc, le, ri: PNode, d: var TLoc) =
     genNamedParamCall(p, ri, d)
   else:
     genPrefixCall(p, le, ri, d)
+  postStmtActions(p)
   when false:
     if d.s == onStack and containsGarbageCollectedRef(d.t): keepAlive(p, d)
 
diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim
index 75cabf414..ac4bbb79f 100644
--- a/compiler/ccgstmts.nim
+++ b/compiler/ccgstmts.nim
@@ -906,7 +906,12 @@ proc genPragma(p: BProc, n: PNode) =
     of wEmit: genEmit(p, it)
     of wBreakpoint: genBreakPoint(p, it)
     of wWatchpoint: genWatchpoint(p, it)
-    else: nil
+    of wInjectStmt: 
+      var p = newProc(nil, p.module)
+      p.options = p.options - {optLineTrace, optStackTrace}
+      genStmts(p, it.sons[1])
+      p.module.injectStmt = p.s(cpsStmts)
+    else: discard
 
 proc FieldDiscriminantCheckNeeded(p: BProc, asgn: PNode): bool = 
   if optFieldCheck in p.options:
diff --git a/compiler/cgen.nim b/compiler/cgen.nim
index b0c90de76..6ccef5fde 100644
--- a/compiler/cgen.nim
+++ b/compiler/cgen.nim
@@ -289,6 +289,9 @@ proc genLineDir(p: BProc, t: PNode) =
     linefmt(p, cpsStmts, "nimln($1, $2);$n",
             line.toRope, t.info.quotedFilename)
 
+proc postStmtActions(p: BProc) {.inline.} =
+  app(p.s(cpsStmts), p.module.injectStmt)
+
 proc accessThreadLocalVar(p: BProc, s: PSym)
 proc emulatedThreadVars(): bool {.inline.}
 
@@ -1119,6 +1122,9 @@ proc newPostInitProc(m: BModule): BProc =
   # little hack so that unique temporaries are generated:
   result.labels = 200_000
 
+proc initProcOptions(m: BModule): TOptions = 
+  if sfSystemModule in m.module.flags: gOptions-{optStackTrace} else: gOptions
+
 proc rawNewModule(module: PSym, filename: string): BModule =
   new(result)
   InitLinkedList(result.headerFiles)
@@ -1131,7 +1137,7 @@ proc rawNewModule(module: PSym, filename: string): BModule =
   result.module = module
   result.typeInfoMarker = initIntSet()
   result.initProc = newProc(nil, result)
-  result.initProc.options = gOptions
+  result.initProc.options = initProcOptions(result)
   result.preInitProc = newPreInitProc(result)
   result.postInitProc = newPostInitProc(result)
   initNodeTable(result.dataCache)
@@ -1139,7 +1145,12 @@ proc rawNewModule(module: PSym, filename: string): BModule =
   result.forwardedProcs = @[]
   result.typeNodesName = getTempName()
   result.nimTypesName = getTempName()
-  result.PreventStackTrace = sfSystemModule in module.flags
+  # no line tracing for the init sections of the system module so that we
+  # don't generate a TFrame which can confuse the stack botton initialization:
+  if sfSystemModule in module.flags:
+    result.PreventStackTrace = true
+    excl(result.preInitProc.options, optStackTrace)
+    excl(result.postInitProc.options, optStackTrace)
 
 proc nullify[T](arr: var T) =
   for i in low(arr)..high(arr):
@@ -1152,7 +1163,7 @@ proc resetModule*(m: var BModule) =
   m.declaredProtos = initIntSet()
   initIdTable(m.forwTypeCache)
   m.initProc = newProc(nil, m)
-  m.initProc.options = gOptions
+  m.initProc.options = initProcOptions(m)
   m.preInitProc = newPreInitProc(m)
   m.postInitProc = newPostInitProc(m)
   initNodeTable(m.dataCache)
@@ -1242,7 +1253,7 @@ proc myProcess(b: PPassContext, n: PNode): PNode =
   result = n
   if b == nil or passes.skipCodegen(n): return
   var m = BModule(b)
-  m.initProc.options = gOptions
+  m.initProc.options = initProcOptions(m)
   genStmts(m.initProc, n)
 
 proc finishModule(m: BModule) = 
@@ -1329,7 +1340,7 @@ proc myClose(b: PPassContext, n: PNode): PNode =
   if b == nil or passes.skipCodegen(n): return 
   var m = BModule(b)
   if n != nil: 
-    m.initProc.options = gOptions
+    m.initProc.options = initProcOptions(m)
     genStmts(m.initProc, n)
   # cached modules need to registered too: 
   registerModuleToMain(m.module)
diff --git a/compiler/cgendata.nim b/compiler/cgendata.nim
index c156c40fe..a803c0ba1 100644
--- a/compiler/cgendata.nim
+++ b/compiler/cgendata.nim
@@ -111,6 +111,7 @@ type
     labels*: natural          # for generating unique module-scope names
     extensionLoaders*: array['0'..'9', PRope] # special procs for the
                                               # OpenGL wrapper
+    injectStmt*: PRope
 
 var
   mainModProcs*, mainModInit*, mainDatInit*: PRope # parts of the main module
diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim
index fe1bea3ff..d3b3cee75 100644
--- a/compiler/extccomp.nim
+++ b/compiler/extccomp.nim
@@ -616,7 +616,8 @@ proc CallCCompiler*(projectfile: string) =
       if options.outFile.len > 0: 
         exefile = options.outFile
       if not noAbsolutePaths():
-        exefile = joinPath(splitFile(projectFile).dir, exefile)
+        if not exeFile.isAbsolute():
+          exefile = joinPath(splitFile(projectFile).dir, exefile)
       exefile = quoteShell(exefile)
       let linkOptions = getLinkOptions()
       linkCmd = quoteShell(linkCmd % ["builddll", builddll,
diff --git a/compiler/nimrod.nim b/compiler/nimrod.nim
index 8e3c0e61e..2bc94e3f8 100644
--- a/compiler/nimrod.nim
+++ b/compiler/nimrod.nim
@@ -65,8 +65,14 @@ proc HandleCmdLine() =
             completeCFilePath(changeFileExt(gProjectFull, "js").prependCurDir))
           execExternalProgram("node " & ex & ' ' & service.arguments)
         else:
-          var ex = quoteShell(
-            changeFileExt(gProjectFull, exeExt).prependCurDir)
+          var binPath: string
+          if options.outFile.len > 0:
+            # If the user specified an outFile path, use that directly.
+            binPath = options.outFile.prependCurDir
+          else:
+            # Figure out ourselves a valid binary name.
+            binPath = changeFileExt(gProjectFull, exeExt).prependCurDir
+          var ex = quoteShell(binPath)
           execExternalProgram(ex & ' ' & service.arguments)
 
 when defined(GC_setMaxPause):
diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim
index 8c2425de3..6f1e7af25 100644
--- a/compiler/pragmas.nim
+++ b/compiler/pragmas.nim
@@ -43,7 +43,8 @@ const
     wFatal, wDefine, wUndef, wCompile, wLink, wLinkSys, wPure, wPush, wPop,
     wBreakpoint, wWatchpoint, wPassL, wPassC, wDeadCodeElim, wDeprecated,
     wFloatChecks, wInfChecks, wNanChecks, wPragma, wEmit, wUnroll,
-    wLinearScanEnd, wPatterns, wEffects, wNoForward, wComputedGoto}
+    wLinearScanEnd, wPatterns, wEffects, wNoForward, wComputedGoto,
+    wInjectStmt}
   lambdaPragmas* = {FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl, 
     wNosideEffect, wSideEffect, wNoreturn, wDynLib, wHeader, 
     wDeprecated, wExtern, wThread, wImportcpp, wImportobjc, wNoStackFrame,
@@ -722,6 +723,11 @@ proc singlePragma(c: PContext, sym: PSym, n: PNode, i: int,
         of wOperator:
           if sym == nil: invalidPragma(it)
           else: sym.position = expectIntLit(c, it)
+        of wInjectStmt:
+          if it.kind != nkExprColonExpr:
+            localError(it.info, errExprExpected)
+          else: 
+            it.sons[1] = c.semExpr(c, it.sons[1])
         else: invalidPragma(it)
       else: invalidPragma(it)
   else: processNote(c, it)
diff --git a/compiler/semthreads.nim b/compiler/semthreads.nim
index 595ab0454..eded99325 100644
--- a/compiler/semthreads.nim
+++ b/compiler/semthreads.nim
@@ -380,7 +380,8 @@ proc analyseThreadProc*(prc: PSym) =
   var formals = skipTypes(prc.typ, abstractInst).n
   for i in 1 .. formals.len-1:
     var formal = formals.sons[i].sym 
-    c.mapping[formal.id] = toTheirs # thread receives foreign data!
+    # the input is copied and belongs to the thread:
+    c.mapping[formal.id] = toMine
   discard analyse(c, prc.getBody)
 
 proc needsGlobalAnalysis*: bool =
diff --git a/compiler/wordrecg.nim b/compiler/wordrecg.nim
index b37a7bb4f..39b19646e 100644
--- a/compiler/wordrecg.nim
+++ b/compiler/wordrecg.nim
@@ -60,7 +60,7 @@ type
     wPassc, wPassl, wBorrow, wDiscardable,
     wFieldChecks, 
     wWatchPoint, wSubsChar, 
-    wAcyclic, wShallow, wUnroll, wLinearScanEnd, wComputedGoto,
+    wAcyclic, wShallow, wUnroll, wLinearScanEnd, wComputedGoto, wInjectStmt,
     wWrite, wGensym, wInject, wDirty, wInheritable, wThreadVar, wEmit, 
     wNoStackFrame,
     wImplicitStatic, wGlobal, wCodegenDecl,
@@ -142,7 +142,8 @@ const
     "compiletime", "noinit",
     "passc", "passl", "borrow", "discardable", "fieldchecks",
     "watchpoint",
-    "subschar", "acyclic", "shallow", "unroll", "linearscanend", "computedgoto",
+    "subschar", "acyclic", "shallow", "unroll", "linearscanend",
+    "computedgoto", "injectstmt",
     "write", "gensym", "inject", "dirty", "inheritable", "threadvar", "emit",
     "nostackframe", "implicitstatic", "global", "codegendecl",