summary refs log tree commit diff stats
path: root/compiler/cgen.nim
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/cgen.nim')
-rwxr-xr-xcompiler/cgen.nim116
1 files changed, 55 insertions, 61 deletions
diff --git a/compiler/cgen.nim b/compiler/cgen.nim
index de91205e2..e8073b555 100755
--- a/compiler/cgen.nim
+++ b/compiler/cgen.nim
@@ -151,7 +151,7 @@ proc appcg(m: BModule, s: TCFileSection, frmt: TFormatStr,
 
 proc appcg(p: BProc, s: TCProcSection, frmt: TFormatStr, 
            args: openarray[PRope]) = 
-  app(p.s[s], ropecg(p.module, frmt, args))
+  app(p.s(s), ropecg(p.module, frmt, args))
 
 proc safeLineNm(info: TLineInfo): int =
   result = toLinenumber(info)
@@ -168,14 +168,14 @@ proc genCLineDir(r: var PRope, info: TLineInfo) =
 
 proc genLineDir(p: BProc, t: PNode) = 
   var line = t.info.safeLineNm
-  genCLineDir(p.s[cpsStmts], t.info.toFullPath, line)
+  genCLineDir(p.s(cpsStmts), t.info.toFullPath, line)
   if ({optStackTrace, optEndb} * p.Options == {optStackTrace, optEndb}) and
       (p.prc == nil or sfPure notin p.prc.flags): 
     appcg(p, cpsStmts, "#endb($1);$n", [toRope(line)])
   elif ({optLineTrace, optStackTrace} * p.Options ==
       {optLineTrace, optStackTrace}) and
       (p.prc == nil or sfPure notin p.prc.flags): 
-    appf(p.s[cpsStmts], "F.line = $1;F.filename = $2;$n", 
+    appf(p.s(cpsStmts), "F.line = $1;F.filename = $2;$n", 
         [toRope(line), makeCString(toFilename(t.info).extractFilename)])
 
 include "ccgtypes.nim"
@@ -229,45 +229,37 @@ proc isComplexValueType(t: PType): bool {.inline.} =
   result = t.kind in {tyArray, tyArrayConstr, tySet, tyTuple, tyObject} or
     (t.kind == tyProc and t.callConv == ccClosure)
 
-proc zeroVar(p: BProc, loc: TLoc, containsGCref: bool) = 
+proc resetLoc(p: BProc, loc: var TLoc) =
+  let containsGcRef = containsGarbageCollectedRef(loc.t)
   if not isComplexValueType(skipTypes(loc.t, abstractVarRange)):
-    if containsGcref and p.WithInLoop > 0:
-      appf(p.s[cpsInit], "$1 = 0;$n", [rdLoc(loc)])
+    if containsGcRef:
       var nilLoc: TLoc
       initLoc(nilLoc, locTemp, loc.t, onStack)
       nilLoc.r = toRope("NIM_NIL")
-      # puts ``unsureAsgnRef`` etc to ``p.s[cpsStmts]``:
       genRefAssign(p, loc, nilLoc, {afSrcIsNil})
     else:
-      appf(p.s[cpsStmts], "$1 = 0;$n", [rdLoc(loc)])
+      appf(p.s(cpsStmts), "$1 = 0;$n", [rdLoc(loc)])
   else:
-    if containsGcref and p.WithInLoop > 0:
-      appf(p.s[cpsInit], "memset((void*)$1, 0, sizeof($2));$n", 
-           [addrLoc(loc), rdLoc(loc)])
-      genObjectInit(p, cpsInit, loc.t, loc, true)
-      appcg(p, cpsStmts, "#genericReset((void*)$1, $2);$n", 
-           [addrLoc(loc), genTypeInfo(p.module, loc.t)])
+    if loc.s != OnStack:
+      appcg(p, cpsStmts, "#genericReset((void*)$1, $2);$n",
+        [addrLoc(loc), genTypeInfo(p.module, loc.t)])
+      # XXX: generated reset procs should not touch the m_type
+      # field, so disabling this should be safe:
+      genObjectInit(p, cpsStmts, loc.t, loc, true)
     else:
-      appf(p.s[cpsStmts], "memset((void*)$1, 0, sizeof($2));$n", 
-           [addrLoc(loc), rdLoc(loc)])
+      appf(p.s(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 zeroTemp(p: BProc, loc: TLoc) =
+proc constructLoc(p: BProc, loc: TLoc, section = cpsStmts) =
   if not isComplexValueType(skipTypes(loc.t, abstractVarRange)):
-    appf(p.s[cpsStmts], "$1 = 0;$n", [rdLoc(loc)])
-    when false:
-      var nilLoc: TLoc
-      initLoc(nilLoc, locTemp, loc.t, onStack)
-      nilLoc.r = toRope("NIM_NIL")
-      # puts ``unsureAsgnRef`` etc to ``p.s[cpsStmts]``:
-      genRefAssign(p, loc, nilLoc, {afSrcIsNil})
+    appf(p.s(section), "$1 = 0;$n", [rdLoc(loc)])
   else:
-    appf(p.s[cpsStmts], "memset((void*)$1, 0, sizeof($2));$n", 
-         [addrLoc(loc), rdLoc(loc)])
-    # XXX no object init necessary for temporaries?
-    when false:
-      appcg(p, cpsStmts, "#genericReset((void*)$1, $2);$n", 
-           [addrLoc(loc), genTypeInfo(p.module, loc.t)])
+    appf(p.s(section), "memset((void*)$1, 0, sizeof($2));$n",
+       [addrLoc(loc), rdLoc(loc)])
+    genObjectInit(p, section, loc.t, loc, true)
 
 proc initLocalVar(p: BProc, v: PSym, immediateAsgn: bool) =
   if sfNoInit notin v.flags:
@@ -279,11 +271,13 @@ proc initLocalVar(p: BProc, v: PSym, immediateAsgn: bool) =
     # ``var v = X()`` gets transformed into ``X(&v)``. 
     # Nowadays the logic in ccgcalls deals with this case however.
     if not immediateAsgn:
-      zeroVar(p, v.loc, containsGarbageCollectedRef(v.typ))
-    
-proc initTemp(p: BProc, tmp: var TLoc) = 
+      constructLoc(p, v.loc)
+
+proc initTemp(p: BProc, tmp: var TLoc) =
+  # XXX: This is still suspicious.
+  # Objects should always be constructed?
   if containsGarbageCollectedRef(tmp.t) or isInvalidReturnType(tmp.t):
-    zeroTemp(p, tmp)
+    constructLoc(p, tmp)
 
 proc getTemp(p: BProc, t: PType, result: var TLoc) = 
   inc(p.labels)
@@ -291,7 +285,7 @@ proc getTemp(p: BProc, t: PType, result: var TLoc) =
     result.r = con("%LOC", toRope(p.labels))
   else: 
     result.r = con("LOC", toRope(p.labels))
-    appf(p.s[cpsLocals], "$1 $2;$n", [getTypeDesc(p.module, t), result.r])
+    appf(p.s(cpsLocals), "$1 $2;$n", [getTypeDesc(p.module, t), result.r])
   result.k = locTemp
   result.a = - 1
   result.t = getUniqueType(t)
@@ -361,7 +355,7 @@ proc allocParam(p: BProc, s: PSym) =
     var tmp = con("%LOC", toRope(p.labels))
     incl(s.loc.flags, lfParamCopy)
     incl(s.loc.flags, lfIndirect)
-    appf(p.s[cpsInit], "$1 = alloca $3$n" & "store $3 $2, $3* $1$n", 
+    appf(p.s(cpsInit), "$1 = alloca $3$n" & "store $3 $2, $3* $1$n", 
          [tmp, s.loc.r, getTypeDesc(p.module, s.loc.t)])
     s.loc.r = tmp
 
@@ -371,7 +365,7 @@ proc localDebugInfo(p: BProc, s: PSym) =
   if skipTypes(s.typ, abstractVar).kind == tyOpenArray: return
   var a = con("&", s.loc.r)
   if (s.kind == skParam) and ccgIntroducedPtr(s): a = s.loc.r
-  appf(p.s[cpsInit], 
+  appf(p.s(cpsInit), 
        "F.s[$1].address = (void*)$3; F.s[$1].typ = $4; F.s[$1].name = $2;$n",
        [toRope(p.frameLen), makeCString(normalize(s.name.s)), a, 
         genTypeInfo(p.module, s.loc.t)])
@@ -384,13 +378,13 @@ proc assignLocalVar(p: BProc, s: PSym) =
   if s.loc.k == locNone: 
     fillLoc(s.loc, locLocalVar, s.typ, mangleName(s), OnStack)
     if s.kind == skLet: incl(s.loc.flags, lfNoDeepCopy)
-  app(p.s[cpsLocals], getTypeDesc(p.module, s.loc.t))
-  if sfRegister in s.flags: app(p.s[cpsLocals], " register")
+  app(p.s(cpsLocals), getTypeDesc(p.module, s.loc.t))
+  if sfRegister in s.flags: app(p.s(cpsLocals), " register")
   #elif skipTypes(s.typ, abstractInst).kind in GcTypeKinds:
   #  app(p.s[cpsLocals], " GC_GUARD")
   if (sfVolatile in s.flags) or (p.nestedTryStmts.len > 0): 
-    app(p.s[cpsLocals], " volatile")
-  appf(p.s[cpsLocals], " $1;$n", [s.loc.r])
+    app(p.s(cpsLocals), " volatile")
+  appf(p.s(cpsLocals), " $1;$n", [s.loc.r])
   localDebugInfo(p, s)
 
 include ccgthreadvars
@@ -410,7 +404,7 @@ proc assignGlobalVar(p: BProc, s: PSym) =
     appf(p.module.s[cfsVars], " $1;$n", [s.loc.r])
   if p.withinLoop > 0:
     # fixes tests/run/tzeroarray:
-    initLocalVar(p, s, false)
+    resetLoc(p, s.loc)
   if p.module.module.options * {optStackTrace, optEndb} ==
                                {optStackTrace, optEndb}: 
     appcg(p.module, p.module.s[cfsDebugInit], 
@@ -433,7 +427,7 @@ proc getLabel(p: BProc): TLabel =
   result = con("LA", toRope(p.labels))
 
 proc fixLabel(p: BProc, labl: TLabel) = 
-  appf(p.s[cpsStmts], "$1: ;$n", [labl])
+  appf(p.s(cpsStmts), "$1: ;$n", [labl])
 
 proc genVarPrototype(m: BModule, sym: PSym)
 proc requestConstImpl(p: BProc, sym: PSym)
@@ -481,9 +475,9 @@ proc loadDynamicLib(m: BModule, lib: PLib) =
       var p = newProc(nil, m)
       var dest: TLoc
       initLocExpr(p, lib.path, dest)
-      app(m.s[cfsVars], p.s[cpsLocals])
-      app(m.s[cfsDynLibInit], p.s[cpsInit])
-      app(m.s[cfsDynLibInit], p.s[cpsStmts])
+      app(m.s[cfsVars], p.s(cpsLocals))
+      app(m.s[cfsDynLibInit], p.s(cpsInit))
+      app(m.s[cfsDynLibInit], p.s(cpsStmts))
       appcg(m, m.s[cfsDynLibInit], 
            "if (!($1 = #nimLoadLibrary($2))) #nimLoadLibraryError($2);$n", 
            [tmp, rdLoc(dest)])
@@ -551,13 +545,13 @@ proc getFrameDecl(p: BProc) =
                    [toRope(p.frameLen)])
   else: 
     slots = nil
-  appff(p.s[cpsLocals], "volatile struct {TFrame* prev;" &
+  appff(p.s(cpsLocals), "volatile struct {TFrame* prev;" &
       "NCSTRING procname;NI line;NCSTRING filename;" & 
       "NI len;$n$1} F;$n", 
       "%TF = type {%TFrame*, i8*, %NI, %NI$1}$n" & 
       "%F = alloca %TF$n", [slots])
   inc(p.labels)
-  prepend(p.s[cpsInit], ropeff("F.len = $1;$n", 
+  prepend(p.s(cpsInit), ropeff("F.len = $1;$n", 
       "%LOC$2 = getelementptr %TF %F, %NI 4$n" &
       "store %NI $1, %NI* %LOC$2$n", [toRope(p.frameLen), toRope(p.labels)]))
 
@@ -613,32 +607,32 @@ proc genProcAux(m: BModule, prc: PSym) =
   var generatedProc: PRope
   if sfPure in prc.flags: 
     generatedProc = ropeff("$1 {$n$2$3$4}$n", "define $1 {$n$2$3$4}$n",
-        [header, p.s[cpsLocals], p.s[cpsInit], p.s[cpsStmts]])
+        [header, p.s(cpsLocals), p.s(cpsInit), p.s(cpsStmts)])
   else:
     generatedProc = ropeff("$1 {$n", "define $1 {$n", [header])
     app(generatedProc, initGCFrame(p))
     if optStackTrace in prc.options: 
       getFrameDecl(p)
-      app(generatedProc, p.s[cpsLocals])
+      app(generatedProc, p.s(cpsLocals))
       var procname = CStringLit(p, generatedProc, prc.name.s)
       var filename = CStringLit(p, generatedProc, toFilename(prc.info))
       app(generatedProc, initFrame(p, procname, filename))
     else: 
-      app(generatedProc, p.s[cpsLocals])
+      app(generatedProc, p.s(cpsLocals))
     if (optProfiler in prc.options) and (gCmd != cmdCompileToLLVM): 
       if gProcProfile >= 64 * 1024: 
         InternalError(prc.info, "too many procedures for profiling")
       discard cgsym(m, "profileData")
-      appf(p.s[cpsLocals], "ticks NIM_profilingStart;$n")
+      appf(p.s(cpsLocals), "ticks NIM_profilingStart;$n")
       if prc.loc.a < 0: 
         appf(m.s[cfsDebugInit], "profileData[$1].procname = $2;$n", [
             toRope(gProcProfile), 
             makeCString(prc.name.s)])
         prc.loc.a = gProcProfile
         inc(gProcProfile)
-      prepend(p.s[cpsInit], ropef("NIM_profilingStart = getticks();$n"))
-    app(generatedProc, p.s[cpsInit])
-    app(generatedProc, p.s[cpsStmts])
+      prepend(p.s(cpsInit), ropef("NIM_profilingStart = getticks();$n"))
+    app(generatedProc, p.s(cpsInit))
+    app(generatedProc, p.s(cpsStmts))
     if p.beforeRetNeeded: appf(generatedProc, "BeforeRet: $n;")
     app(generatedProc, deinitGCFrame(p))
     if optStackTrace in prc.options: app(generatedProc, deinitFrame(p))
@@ -858,8 +852,8 @@ proc genInitCode(m: BModule) =
   app(prc, initGCFrame(m.initProc))
   
   app(prc, genSectionStart(cpsLocals))
-  app(prc, m.initProc.s[cpsLocals])
-  app(prc, m.preInitProc.s[cpsLocals])
+  app(prc, m.initProc.s(cpsLocals))
+  app(prc, m.preInitProc.s(cpsLocals))
   app(prc, genSectionEnd(cpsLocals))
 
   app(prc, genSectionStart(cfsTypeInit1))
@@ -876,13 +870,13 @@ proc genInitCode(m: BModule) =
     app(prc, genSectionEnd(i))
   
   app(prc, genSectionStart(cpsInit))
-  app(prc, m.preInitProc.s[cpsInit])
-  app(prc, m.initProc.s[cpsInit])
+  app(prc, m.preInitProc.s(cpsInit))
+  app(prc, m.initProc.s(cpsInit))
   app(prc, genSectionEnd(cpsInit))
 
   app(prc, genSectionStart(cpsStmts))
-  app(prc, m.preInitProc.s[cpsStmts])
-  app(prc, m.initProc.s[cpsStmts])
+  app(prc, m.preInitProc.s(cpsStmts))
+  app(prc, m.initProc.s(cpsStmts))
   if optStackTrace in m.initProc.options and not m.PreventStackTrace:
     app(prc, deinitFrame(m.initProc))
   app(prc, genSectionEnd(cpsStmts))