summary refs log tree commit diff stats
path: root/compiler/cgen.nim
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/cgen.nim')
-rw-r--r--compiler/cgen.nim46
1 files changed, 34 insertions, 12 deletions
diff --git a/compiler/cgen.nim b/compiler/cgen.nim
index 910e675e1..6ccef5fde 100644
--- a/compiler/cgen.nim
+++ b/compiler/cgen.nim
@@ -72,6 +72,11 @@ proc isSimpleConst(typ: PType): bool =
       {tyTuple, tyObject, tyArray, tyArrayConstr, tySet, tySequence} and not
       (t.kind == tyProc and t.callConv == ccClosure)
 
+proc useStringh(m: BModule) =
+  if not m.includesStringh:
+    m.includesStringh = true
+    discard lists.IncludeStr(m.headerFiles, "<string.h>")
+
 proc useHeader(m: BModule, sym: PSym) = 
   if lfHeader in sym.loc.Flags: 
     assert(sym.annex != nil)
@@ -284,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.}
 
@@ -358,19 +366,24 @@ proc resetLoc(p: BProc, loc: var TLoc) =
       # field, so disabling this should be safe:
       genObjectInit(p, cpsStmts, loc.t, loc, true)
     else:
+      useStringh(p.module)
       linefmt(p, cpsStmts, "memset((void*)$1, 0, sizeof($2));$n",
               addrLoc(loc), rdLoc(loc))
       # XXX: We can be extra clever here and call memset only 
       # on the bytes following the m_type field?
       genObjectInit(p, cpsStmts, loc.t, loc, true)
 
-proc constructLoc(p: BProc, loc: TLoc, section = cpsStmts) =
+proc constructLoc(p: BProc, loc: TLoc, isTemp = false) =
   if not isComplexValueType(skipTypes(loc.t, abstractRange)):
-    linefmt(p, section, "$1 = 0;$n", rdLoc(loc))
+    linefmt(p, cpsStmts, "$1 = 0;$n", rdLoc(loc))
   else:
-    linefmt(p, section, "memset((void*)$1, 0, sizeof($2));$n",
-            addrLoc(loc), rdLoc(loc))
-    genObjectInit(p, section, loc.t, loc, true)
+    if not isTemp or containsGarbageCollectedRef(loc.t):
+      # don't use memset for temporary values for performance if we can
+      # avoid it:
+      useStringh(p.module)
+      linefmt(p, cpsStmts, "memset((void*)$1, 0, sizeof($2));$n",
+              addrLoc(loc), rdLoc(loc))
+    genObjectInit(p, cpsStmts, loc.t, loc, true)
 
 proc initLocalVar(p: BProc, v: PSym, immediateAsgn: bool) =
   if sfNoInit notin v.flags:
@@ -396,7 +409,7 @@ proc getTemp(p: BProc, t: PType, result: var TLoc) =
   result.t = getUniqueType(t)
   result.s = OnStack
   result.flags = {}
-  constructLoc(p, result)
+  constructLoc(p, result, isTemp=true)
 
 proc keepAlive(p: BProc, toKeepAlive: TLoc) =
   when false:
@@ -418,6 +431,7 @@ proc keepAlive(p: BProc, toKeepAlive: TLoc) =
     if not isComplexValueType(skipTypes(toKeepAlive.t, abstractVarRange)):
       linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(result), rdLoc(toKeepAlive))
     else:
+      useStringh(p.module)
       linefmt(p, cpsStmts,
            "memcpy((void*)$1, (NIM_CONST void*)$2, sizeof($3));$n",
            addrLoc(result), addrLoc(toKeepAlive), rdLoc(result))
@@ -933,9 +947,9 @@ proc genMainProc(m: BModule) =
   const 
     CommonMainBody =
         "\tsystemDatInit();$n" &
+        "\tsystemInit();$n" &
         "$1" &
         "$2" &
-        "\tsystemInit();$n" &
         "$3" &
         "$4"
     PosixNimMain = 
@@ -1108,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)
@@ -1120,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)
@@ -1128,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):
@@ -1141,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)
@@ -1231,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) = 
@@ -1318,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)