summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2011-05-16 00:27:47 +0200
committerAraq <rumpf_a@web.de>2011-05-16 00:27:47 +0200
commit67a30d837132e8000d1a8b10ce3d32423d149318 (patch)
treeb059b56027b57c45777d15d33e88b3dac9313f14 /compiler
parentc7b3d828be1bbca81f3576875636ea571e595402 (diff)
downloadNim-67a30d837132e8000d1a8b10ce3d32423d149318.tar.gz
further steps for thread support; bootstrapping should require unzip C sources and ./build.sh
Diffstat (limited to 'compiler')
-rwxr-xr-xcompiler/ccgexprs.nim50
-rwxr-xr-xcompiler/ccgstmts.nim83
-rwxr-xr-xcompiler/cgen.nim30
-rwxr-xr-xcompiler/commands.nim2
4 files changed, 106 insertions, 59 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim
index 69c06fbb5..dc17a39c7 100755
--- a/compiler/ccgexprs.nim
+++ b/compiler/ccgexprs.nim
@@ -154,29 +154,25 @@ proc getStorageLoc(n: PNode): TStorageLoc =
   else: result = OnUnknown
 
 proc genRefAssign(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
-  if (dest.s == OnStack) or not (optRefcGC in gGlobalOptions):
+  if dest.s == OnStack or optRefcGC notin gGlobalOptions:
     appf(p.s[cpsStmts], "$1 = $2;$n", [rdLoc(dest), rdLoc(src)])
   elif dest.s == OnHeap:
     # location is on heap
     # now the writer barrier is inlined for performance:
     #
-    #    if afSrcIsNotNil in flags then begin
-    #      UseMagic(p.module, 'nimGCref');
-    #      appf(p.s[cpsStmts], 'nimGCref($1);$n', [rdLoc(src)]);
-    #    end
-    #    else if not (afSrcIsNil in flags) then begin
-    #      UseMagic(p.module, 'nimGCref');
-    #      appf(p.s[cpsStmts], 'if ($1) nimGCref($1);$n', [rdLoc(src)]);
-    #    end;
-    #    if afDestIsNotNil in flags then begin
-    #      UseMagic(p.module, 'nimGCunref');
-    #      appf(p.s[cpsStmts], 'nimGCunref($1);$n', [rdLoc(dest)]);
-    #    end
-    #    else if not (afDestIsNil in flags) then begin
-    #      UseMagic(p.module, 'nimGCunref');
-    #      appf(p.s[cpsStmts], 'if ($1) nimGCunref($1);$n', [rdLoc(dest)]);
-    #    end;
-    #    appf(p.s[cpsStmts], '$1 = $2;$n', [rdLoc(dest), rdLoc(src)]);
+    #    if afSrcIsNotNil in flags:
+    #      UseMagic(p.module, 'nimGCref')
+    #      appf(p.s[cpsStmts], 'nimGCref($1);$n', [rdLoc(src)])
+    #    elif afSrcIsNil notin flags:
+    #      UseMagic(p.module, 'nimGCref')
+    #      appf(p.s[cpsStmts], 'if ($1) nimGCref($1);$n', [rdLoc(src)])
+    #    if afDestIsNotNil in flags:
+    #      UseMagic(p.module, 'nimGCunref')
+    #      appf(p.s[cpsStmts], 'nimGCunref($1);$n', [rdLoc(dest)])
+    #    elif afDestIsNil notin flags:
+    #      UseMagic(p.module, 'nimGCunref')
+    #      appf(p.s[cpsStmts], 'if ($1) nimGCunref($1);$n', [rdLoc(dest)])
+    #    appf(p.s[cpsStmts], '$1 = $2;$n', [rdLoc(dest), rdLoc(src)])
     if canFormAcycle(dest.t):
       appcg(p.module, p.s[cpsStmts], "#asgnRef((void**) $1, $2);$n",
            [addrLoc(dest), rdLoc(src)])
@@ -196,7 +192,7 @@ proc genGenericAsgn(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
   # (for objects, etc.):
   if needToCopy notin flags or 
       tfShallow in skipTypes(dest.t, abstractVarRange).flags:
-    if (dest.s == OnStack) or not (optRefcGC in gGlobalOptions):
+    if dest.s == OnStack or optRefcGC notin gGlobalOptions:
       appcg(p, cpsStmts,
            "memcpy((void*)$1, (NIM_CONST void*)$2, sizeof($3));$n",
            [addrLoc(dest), addrLoc(src), rdLoc(dest)])
@@ -224,7 +220,7 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
     if needToCopy notin flags:
       genRefAssign(p, dest, src, flags)
     else:
-      if (dest.s == OnStack) or not (optRefcGC in gGlobalOptions):
+      if dest.s == OnStack or optRefcGC notin gGlobalOptions:
         appcg(p, cpsStmts, "$1 = #copyString($2);$n", [rdLoc(dest), rdLoc(src)])
       elif dest.s == OnHeap:
         appcg(p, cpsStmts, "#asgnRefNoCycle((void**) $1, #copyString($2));$n",
@@ -826,19 +822,7 @@ proc genCall(p: BProc, t: PNode, d: var TLoc) =
     app(pl, ")")
     app(p.s[cpsStmts], pl)
     app(p.s[cpsStmts], ';' & tnl)
-    
-  when false:
-    app(pl, ")")
-    if (typ.sons[0] != nil) and not invalidRetType:
-      if d.k == locNone: getTemp(p, typ.sons[0], d)
-      assert(d.t != nil)        # generate an assignment to d:
-      initLoc(list, locCall, nil, OnUnknown)
-      list.r = pl
-      genAssignment(p, d, list, {}) # no need for deep copying
-    else:
-      app(p.s[cpsStmts], pl)
-      app(p.s[cpsStmts], ';' & tnl)
-
+  
 proc genStrConcat(p: BProc, e: PNode, d: var TLoc) =
   #   <Nimrod code>
   #   s = 'Hello ' & name & ', how do you feel?' & 'z'
diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim
index 1816c0f31..c9b5832fb 100755
--- a/compiler/ccgstmts.nim
+++ b/compiler/ccgstmts.nim
@@ -7,13 +7,11 @@
 #    distribution, for details about the copyright.
 #
 
-const 
+const
   RangeExpandLimit = 256      # do not generate ranges
                               # over 'RangeExpandLimit' elements
   stringCaseThreshold = 8
     # above X strings a hash-switch for strings is generated
-    # this version sets it too high to avoid hashing, because this has not
-    # been tested for a long time
 
 proc genLineDir(p: BProc, t: PNode) = 
   var line = toLinenumber(t.info) # BUGFIX
@@ -23,11 +21,11 @@ proc genLineDir(p: BProc, t: PNode) =
     appff(p.s[cpsStmts], "#line $2 \"$1\"$n", "; line $2 \"$1\"$n", 
           [toRope(toFilename(t.info)), toRope(line)])
   if ({optStackTrace, optEndb} * p.Options == {optStackTrace, optEndb}) and
-      ((p.prc == nil) or not (sfPure in p.prc.flags)): 
+      (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 not (sfPure in p.prc.flags)): 
+      (p.prc == nil or sfPure notin p.prc.flags): 
     appf(p.s[cpsStmts], "F.line = $1;F.filename = $2;$n", 
         [toRope(line), makeCString(toFilename(t.info).extractFilename)])
 
@@ -458,7 +456,7 @@ proc genTryStmtCpp(p: BProc, t: PNode) =
     rethrowFlag = getTempName()
     appf(p.s[cpsLocals], "volatile NIM_BOOL $1 = NIM_FALSE;$n", [rethrowFlag])
   if optStackTrace in p.Options: 
-    appcg(p, cpsStmts, "#framePtr = (TFrame*)&F;" & tnl)
+    appcg(p, cpsStmts, "#setFrame((TFrame*)&F);$n")
   app(p.s[cpsStmts], "try {" & tnl)
   add(p.nestedTryStmts, t)
   genStmts(p, t.sons[0])
@@ -493,6 +491,72 @@ proc genTryStmtCpp(p: BProc, t: PNode) =
   if rethrowFlag != nil: 
     appf(p.s[cpsStmts], "if ($1) { throw; }$n", [rethrowFlag])
   
+proc genTryStmtCpp2(p: BProc, t: PNode) = 
+  # code to generate:
+  #
+  #  TSafePoint sp;
+  #  pushSafePoint(&sp);
+  #  sp.status = setjmp(sp.context);
+  #  if (sp.status == 0) {
+  #    myDiv(4, 9);
+  #    popSafePoint();
+  #  } else {
+  #    popSafePoint();
+  #    /* except DivisionByZero: */
+  #    if (sp.status == DivisionByZero) {
+  #      printf('Division by Zero\n');
+  #      clearException();
+  #    } else {
+  #      clearException();
+  #    }
+  #  }
+  #  /* finally: */
+  #  printf('fin!\n');
+  #  if (exception not cleared)
+  #    propagateCurrentException();
+  genLineDir(p, t)
+  var safePoint = getTempName()
+  discard cgsym(p.module, "E_Base")
+  appcg(p, cpsLocals, "#TSafePoint $1;$n", [safePoint])
+  appcg(p, cpsStmts, "#pushSafePoint(&$1);$n" &
+        "$1.status = setjmp($1.context);$n", [safePoint])
+  if optStackTrace in p.Options: 
+    appcg(p, cpsStmts, "#setFrame((TFrame*)&F);$n")
+  appf(p.s[cpsStmts], "if ($1.status == 0) {$n", [safePoint])
+  var length = sonsLen(t)
+  add(p.nestedTryStmts, t)
+  genStmts(p, t.sons[0])
+  appcg(p, cpsStmts, "#popSafePoint();$n} else {$n#popSafePoint();$n")
+  var i = 1
+  while (i < length) and (t.sons[i].kind == nkExceptBranch): 
+    var blen = sonsLen(t.sons[i])
+    if blen == 1: 
+      # general except section:
+      if i > 1: app(p.s[cpsStmts], "else {" & tnl)
+      genStmts(p, t.sons[i].sons[0])
+      appcg(p, cpsStmts, "$1.status = 0;#popCurrentException();$n", [safePoint])
+      if i > 1: app(p.s[cpsStmts], '}' & tnl)
+    else: 
+      var orExpr: PRope = nil
+      for j in countup(0, blen - 2): 
+        assert(t.sons[i].sons[j].kind == nkType)
+        if orExpr != nil: app(orExpr, "||")
+        appcg(p.module, orExpr, 
+              "#isObj(#getCurrentException()->Sup.m_type, $1)", 
+              [genTypeInfo(p.module, t.sons[i].sons[j].typ)])
+      if i > 1: app(p.s[cpsStmts], "else ")
+      appf(p.s[cpsStmts], "if ($1) {$n", [orExpr])
+      genStmts(p, t.sons[i].sons[blen-1]) 
+      # code to clear the exception:
+      appcg(p, cpsStmts, "$1.status = 0;#popCurrentException();}$n",
+           [safePoint])
+    inc(i)
+  app(p.s[cpsStmts], '}' & tnl) # end of if statement
+  discard pop(p.nestedTryStmts)
+  if i < length and t.sons[i].kind == nkFinally: 
+    genStmts(p, t.sons[i].sons[0])
+  appcg(p, cpsStmts, "if ($1.status != 0) #reraiseException();$n", [safePoint])
+  
 proc genTryStmt(p: BProc, t: PNode) = 
   # code to generate:
   #
@@ -523,7 +587,7 @@ proc genTryStmt(p: BProc, t: PNode) =
   appcg(p, cpsStmts, "#pushSafePoint(&$1);$n" &
         "$1.status = setjmp($1.context);$n", [safePoint])
   if optStackTrace in p.Options: 
-    appcg(p, cpsStmts, "#framePtr = (TFrame*)&F;" & tnl)
+    appcg(p, cpsStmts, "#setFrame((TFrame*)&F);$n")
   appf(p.s[cpsStmts], "if ($1.status == 0) {$n", [safePoint])
   var length = sonsLen(t)
   add(p.nestedTryStmts, t)
@@ -543,8 +607,9 @@ proc genTryStmt(p: BProc, t: PNode) =
       for j in countup(0, blen - 2): 
         assert(t.sons[i].sons[j].kind == nkType)
         if orExpr != nil: app(orExpr, "||")
-        appcg(p.module, orExpr, "#getCurrentException()->Sup.m_type == $1", 
-             [genTypeInfo(p.module, t.sons[i].sons[j].typ)])
+        appcg(p.module, orExpr, 
+              "#isObj(#getCurrentException()->Sup.m_type, $1)", 
+              [genTypeInfo(p.module, t.sons[i].sons[j].typ)])
       if i > 1: app(p.s[cpsStmts], "else ")
       appf(p.s[cpsStmts], "if ($1) {$n", [orExpr])
       genStmts(p, t.sons[i].sons[blen-1]) 
diff --git a/compiler/cgen.nim b/compiler/cgen.nim
index 61cd36c42..7f162b6e6 100755
--- a/compiler/cgen.nim
+++ b/compiler/cgen.nim
@@ -84,6 +84,7 @@ type
     module*: PSym
     filename*: string
     s*: TCFileSections        # sections of the C file
+    PreventStackTrace: bool   # true if stack traces need to be prevented
     cfilename*: string        # filename of the module (including path,
                               # without extension)
     typeCache*: TIdTable      # cache the generated types
@@ -99,7 +100,6 @@ type
     typeNodes*, nimTypes*: int # used for type info generation
     typeNodesName*, nimTypesName*: PRope # used for type info generation
     labels*: natural          # for generating unique module-scope names
-  
 
 var 
   mainModProcs, mainModInit: PRope # parts of the main module
@@ -603,19 +603,12 @@ proc retIsNotVoid(s: PSym): bool =
 proc initFrame(p: BProc, procname, filename: PRope): PRope = 
   result = ropecg(p.module, 
     "F.procname = $1;$n" &
-    "F.prev = #framePtr;$n" &
     "F.filename = $2;$n" & 
     "F.line = 0;$n" & 
-    "framePtr = (TFrame*)&F;$n", [procname, filename])
+    "#pushFrame((TFrame*)&F);$n", [procname, filename])
 
-proc deinitFrame(p: BProc): PRope = 
-  inc(p.labels, 3)
-  result = ropeff("framePtr = framePtr->prev;$n", 
-      "%LOC$1 = load %TFrame* @framePtr$n" &
-      "%LOC$2 = getelementptr %TFrame* %LOC$1, %NI 0$n" &
-      "%LOC$3 = load %TFrame** %LOC$2$n" &
-      "store %TFrame* $LOC$3, %TFrame** @framePtr", [toRope(p.labels), 
-      toRope(p.labels - 1), toRope(p.labels - 2)])
+proc deinitFrame(p: BProc): PRope =
+  result = ropecg(p.module, "#popFrame();$n")
 
 proc genProcAux(m: BModule, prc: PSym) = 
   var 
@@ -628,7 +621,7 @@ proc genProcAux(m: BModule, prc: PSym) =
     header = con("N_LIB_EXPORT ", header)
   returnStmt = nil
   assert(prc.ast != nil)
-  if not (sfPure in prc.flags) and (prc.typ.sons[0] != nil): 
+  if sfPure notin prc.flags and prc.typ.sons[0] != nil:
     res = prc.ast.sons[resultPos].sym # get result symbol
     if not isInvalidReturnType(prc.typ.sons[0]): 
       # declare the result symbol:
@@ -868,14 +861,17 @@ proc genInitCode(m: BModule) =
   if m.nimTypes > 0: 
     appcg(m, m.s[cfsTypeInit1], "static #TNimType $1[$2];$n", 
           [m.nimTypesName, toRope(m.nimTypes)])
-  if optStackTrace in m.initProc.options: 
+  if optStackTrace in m.initProc.options:
+    # BUT: the generated init code might depend on a current frame, so
+    # declare it nevertheless:
     getFrameDecl(m.initProc)
+  if optStackTrace in m.initProc.options and not m.PreventStackTrace: 
     app(prc, m.initProc.s[cpsLocals])
     app(prc, m.s[cfsTypeInit1])
     procname = CStringLit(m.initProc, prc, m.module.name.s)
     filename = CStringLit(m.initProc, prc, toFilename(m.module.info))
     app(prc, initFrame(m.initProc, procname, filename))
-  else: 
+  else:
     app(prc, m.initProc.s[cpsLocals])
     app(prc, m.s[cfsTypeInit1])
   app(prc, m.s[cfsTypeInit2])
@@ -884,7 +880,8 @@ proc genInitCode(m: BModule) =
   app(prc, m.s[cfsDynLibInit])
   app(prc, m.initProc.s[cpsInit])
   app(prc, m.initProc.s[cpsStmts])
-  if optStackTrace in m.initProc.options: app(prc, deinitFrame(m.initProc))
+  if optStackTrace in m.initProc.options and not m.PreventStackTrace: 
+    app(prc, deinitFrame(m.initProc))
   app(prc, '}' & tnl & tnl)
   app(m.s[cfsProcs], prc)
 
@@ -911,6 +908,7 @@ proc rawNewModule(module: PSym, filename: string): BModule =
   result.forwardedProcs = @[]
   result.typeNodesName = getTempName()
   result.nimTypesName = getTempName()
+  result.PreventStackTrace = sfSystemModule in module.flags
 
 proc newModule(module: PSym, filename: string): BModule = 
   result = rawNewModule(module, filename)
@@ -923,6 +921,7 @@ proc registerTypeInfoModule() =
   const moduleName = "nim__dat"
   var s = NewSym(skModule, getIdent(moduleName), nil)
   gNimDat = rawNewModule(s, joinPath(options.projectPath, moduleName) & ".nim")
+  gNimDat.PreventStackTrace = true
   addPendingModule(gNimDat)
   appff(mainModProcs, "N_NOINLINE(void, $1)(void);$n", 
         "declare void $1() noinline$n", [getInitName(s)])
@@ -935,7 +934,6 @@ proc myOpenCached(module: PSym, filename: string,
                   rd: PRodReader): PPassContext = 
   if gNimDat == nil: 
     registerTypeInfoModule()
-    #MessageOut('cgen.myOpenCached has been called ' + filename)
   var cfile = changeFileExt(completeCFilePath(filename), cExt)
   var cfilenoext = changeFileExt(cfile, "")
   addFileToLink(cfilenoext)
diff --git a/compiler/commands.nim b/compiler/commands.nim
index a4763d6b2..1295a5490 100755
--- a/compiler/commands.nim
+++ b/compiler/commands.nim
@@ -513,7 +513,7 @@ proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) =
     else: InvalidCmdLineOption(pass, switch, info)
   
 proc ProcessCommand(switch: string, pass: TCmdLinePass) = 
-  var 
+  var
     cmd, arg: string
     info: TLineInfo
   info = newLineInfo("command line", 1, 1)