summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rwxr-xr-xcompiler/ccgstmts.nim13
-rw-r--r--compiler/ccgtrav.nim21
-rwxr-xr-xcompiler/ccgtypes.nim4
-rwxr-xr-xcompiler/commands.nim12
-rwxr-xr-xcompiler/ecmasgen.nim30
-rwxr-xr-xcompiler/nimrod.nim4
-rwxr-xr-xcompiler/options.nim5
7 files changed, 60 insertions, 29 deletions
diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim
index 2f07d24cb..473d10e7b 100755
--- a/compiler/ccgstmts.nim
+++ b/compiler/ccgstmts.nim
@@ -1,7 +1,7 @@
 #
 #
 #           The Nimrod Compiler
-#        (c) Copyright 2012 Andreas Rumpf
+#        (c) Copyright 2013 Andreas Rumpf
 #
 #    See the file "copying.txt", included in this
 #    distribution, for details about the copyright.
@@ -15,6 +15,14 @@ const
   stringCaseThreshold = 8
     # above X strings a hash-switch for strings is generated
 
+proc registerGcRoot(p: BProc, v: PSym) =
+  if gSelectedGc == gcMarkAndSweep and containsGarbageCollectedRef(v.loc.t):
+    # we register a specialized marked proc here; this has the advantage
+    # that it works out of the box for thread local storage then :-)
+    let prc = genTraverseProcForGlobal(p.module, v)
+    linefmt(p.module.initProc, cpsStmts,
+      "#nimRegisterGlobalMarker($1);$n", prc)
+
 proc genVarTuple(p: BProc, n: PNode) = 
   var tup, field: TLoc
   if n.kind != nkVarTuple: InternalError(n.info, "genVarTuple")
@@ -28,6 +36,7 @@ proc genVarTuple(p: BProc, n: PNode) =
     if sfGlobal in v.flags:
       assignGlobalVar(p, v)
       genObjectInit(p, cpsInit, v.typ, v.loc, true)
+      registerGcRoot(p, v)
     else:
       assignLocalVar(p, v)
       initLocalVar(p, v, immediateAsgn=true)
@@ -143,7 +152,7 @@ proc genSingleVar(p: BProc, a: PNode) =
     # if sfImportc notin v.flags: constructLoc(p.module.preInitProc, v.loc)
     if sfExportc in v.flags and generatedHeader != nil:
       genVarPrototypeAux(generatedHeader, v)
-
+    registerGcRoot(p, v)
   else:
     assignLocalVar(p, v)
     initLocalVar(p, v, immediateAsgn)
diff --git a/compiler/ccgtrav.nim b/compiler/ccgtrav.nim
index 938330f1c..7a0b564a2 100644
--- a/compiler/ccgtrav.nim
+++ b/compiler/ccgtrav.nim
@@ -1,7 +1,7 @@
 #
 #
 #           The Nimrod Compiler
-#        (c) Copyright 2012 Andreas Rumpf
+#        (c) Copyright 2013 Andreas Rumpf
 #
 #    See the file "copying.txt", included in this
 #    distribution, for details about the copyright.
@@ -13,7 +13,7 @@
 # included from cgen.nim
 
 type
-  TTraversalClosure {.pure, final.} = object
+  TTraversalClosure = object
     p: BProc
     visitorFrmt: string
 
@@ -127,3 +127,20 @@ proc genTraverseProc(m: BModule, typ: PType, reason: TTypeInfoReason): PRope =
   m.s[cfsProcs].app(generatedProc)
 
 
+proc genTraverseProcForGlobal(m: BModule, s: PSym): PRope =
+  discard genTypeInfo(m, s.loc.t)
+  
+  var c: TTraversalClosure
+  var p = newProc(nil, m)
+  result = getGlobalTempName()
+  
+  c.visitorFrmt = "#nimGCvisit((void*)$1, 0);$n"
+  c.p = p
+  let header = ropef("N_NIMCALL(void, $1)()", result)
+  genTraverseProc(c, s.loc.r, s.loc.t)
+  
+  let generatedProc = ropef("$1 {$n$2$3$4}$n",
+        [header, p.s(cpsLocals), p.s(cpsInit), p.s(cpsStmts)])
+  
+  m.s[cfsProcHeaders].appf("$1;$n", header)
+  m.s[cfsProcs].app(generatedProc)
diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim
index 281b4ee14..c65d9072d 100755
--- a/compiler/ccgtypes.nim
+++ b/compiler/ccgtypes.nim
@@ -1,7 +1,7 @@
 #
 #
 #           The Nimrod Compiler
-#        (c) Copyright 2012 Andreas Rumpf
+#        (c) Copyright 2013 Andreas Rumpf
 #
 #    See the file "copying.txt", included in this
 #    distribution, for details about the copyright.
@@ -938,7 +938,7 @@ proc genTypeInfo(m: BModule, typ: PType): PRope =
       genTupleInfo(m, fakeClosureType(t.owner), result)
   of tySequence, tyRef:
     genTypeInfoAux(m, t, result)
-    if usesNativeGC():
+    if gSelectedGC >= gcMarkAndSweep:
       let markerProc = genTraverseProc(m, t, tiNew)
       appf(m.s[cfsTypeInit3], "$1.marker = $2;$n", [result, markerProc])
   of tyPtr, tyRange: genTypeInfoAux(m, t, result)
diff --git a/compiler/commands.nim b/compiler/commands.nim
index 878d838b6..a2154c907 100755
--- a/compiler/commands.nim
+++ b/compiler/commands.nim
@@ -139,10 +139,11 @@ proc testCompileOptionArg*(switch, arg: string, info: TLineInfo): bool =
   case switch.normalize
   of "gc":
     case arg.normalize
-    of "boehm": result = gSelectedGC == gcBoehm
-    of "refc":  result = gSelectedGC == gcRefc
-    of "v2":    result = gSelectedGC == gcV2
-    of "none":  result = gSelectedGC == gcNone
+    of "boehm":        result = gSelectedGC == gcBoehm
+    of "refc":         result = gSelectedGC == gcRefc
+    of "v2":           result = gSelectedGC == gcV2
+    of "markandsweep": result = gSelectedGC == gcMarkAndSweep
+    of "none":         result = gSelectedGC == gcNone
     else: LocalError(info, errNoneBoehmRefcExpectedButXFound, arg)
   of "opt":
     case arg.normalize
@@ -276,6 +277,9 @@ proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) =
       gSelectedGC = gcRefc
     of "v2":
       gSelectedGC = gcV2
+    of "markandsweep":
+      gSelectedGC = gcMarkAndSweep
+      defineSymbol("gcmarkandsweep")
     of "none":
       gSelectedGC = gcNone
       defineSymbol("nogc")
diff --git a/compiler/ecmasgen.nim b/compiler/ecmasgen.nim
index 34b3b4ff5..a8c62ae09 100755
--- a/compiler/ecmasgen.nim
+++ b/compiler/ecmasgen.nim
@@ -140,6 +140,8 @@ proc mangleName(s: PSym): PRope =
     app(result, toRope(s.id))
     s.loc.r = result
 
+proc makeJSString(s: string): PRope = strutils.escape(s).toRope
+
 proc genTypeInfo(p: var TProc, typ: PType): PRope
 proc genObjectFields(p: var TProc, typ: PType, n: PNode): PRope = 
   var 
@@ -165,7 +167,7 @@ proc genObjectFields(p: var TProc, typ: PType, n: PNode): PRope =
     s = genTypeInfo(p, field.typ)
     result = ropef("{kind: 1, offset: \"$1\", len: 0, " &
         "typ: $2, name: $3, sons: null}", 
-                   [mangleName(field), s, makeCString(field.name.s)])
+                   [mangleName(field), s, makeJSString(field.name.s)])
   of nkRecCase: 
     length = sonsLen(n)
     if (n.sons[0].kind != nkSym): InternalError(n.info, "genObjectFields")
@@ -193,7 +195,7 @@ proc genObjectFields(p: var TProc, typ: PType, n: PNode): PRope =
            [u, genObjectFields(p, typ, lastSon(b))])
     result = ropef("{kind: 3, offset: \"$1\", len: $3, " &
         "typ: $2, name: $4, sons: [$5]}", [mangleName(field), s, 
-        toRope(lengthOrd(field.typ)), makeCString(field.name.s), result])
+        toRope(lengthOrd(field.typ)), makeJSString(field.name.s), result])
   else: internalError(n.info, "genObjectFields")
   
 proc genObjectInfo(p: var TProc, typ: PType, name: PRope) = 
@@ -234,7 +236,7 @@ proc genEnumInfo(p: var TProc, typ: PType, name: PRope) =
     if i > 0: app(s, ", " & tnl)
     let extName = if field.ast == nil: field.name.s else: field.ast.strVal
     appf(s, "{kind: 1, offset: $1, typ: $2, name: $3, len: 0, sons: null}", 
-         [toRope(field.position), name, makeCString(extName)])
+         [toRope(field.position), name, makeJSString(extName)])
   var n = ropef("var NNI$1 = {kind: 2, offset: 0, typ: null, " &
       "name: null, len: $2, sons: [$3]};$n", [toRope(typ.id), toRope(length), s])
   s = ropef("var $1 = {size: 0, kind: $2, base: null, node: null, " &
@@ -588,7 +590,7 @@ proc genRaiseStmt(p: var TProc, n: PNode, r: var TCompRes) =
     typ = skipTypes(n.sons[0].typ, abstractPtrs)
     useMagic(p, "raiseException")
     appf(r.com, "raiseException($1, $2);$n", 
-         [a.res, makeCString(typ.sym.name.s)])
+         [a.res, makeJSString(typ.sym.name.s)])
   else: 
     useMagic(p, "reraiseException")
     app(r.com, "reraiseException();" & tnl)
@@ -626,7 +628,7 @@ proc genCaseStmt(p: var TProc, n: PNode, r: var TCompRes) =
           if stringSwitch: 
             case e.kind
             of nkStrLit..nkTripleStrLit: appf(r.com, "case $1: ", 
-                [makeCString(e.strVal)])
+                [makeJSString(e.strVal)])
             else: InternalError(e.info, "ecmasgen.genCaseStmt: 2")
           else: 
             appf(r.com, "case $1: ", [cond.res])
@@ -827,12 +829,12 @@ proc genFieldAddr(p: var TProc, n: PNode, r: var TCompRes) =
   var b = if n.kind == nkHiddenAddr: n.sons[0] else: n
   gen(p, b.sons[0], a)
   if skipTypes(b.sons[0].typ, abstractVarRange).kind == tyTuple:
-    r.res = makeCString("Field" & $getFieldPosition(b.sons[1]))
+    r.res = makeJSString("Field" & $getFieldPosition(b.sons[1]))
   else:
     if b.sons[1].kind != nkSym: InternalError(b.sons[1].info, "genFieldAddr")
     var f = b.sons[1].sym
     if f.loc.r == nil: f.loc.r = mangleName(f)
-    r.res = makeCString(ropeToStr(f.loc.r))
+    r.res = makeJSString(ropeToStr(f.loc.r))
   r.com = mergeExpr(a)
 
 proc genFieldAccess(p: var TProc, n: PNode, r: var TCompRes) = 
@@ -903,7 +905,7 @@ proc genAddr(p: var TProc, n: PNode, r: var TCompRes) =
         # globals are always indirect accessible
         r.kind = etyBaseIndex
         r.com = toRope("Globals")
-        r.res = makeCString(ropeToStr(s.loc.r))
+        r.res = makeJSString(ropeToStr(s.loc.r))
       elif sfAddrTaken in s.flags: 
         r.kind = etyBaseIndex
         r.com = s.loc.r
@@ -1422,8 +1424,8 @@ proc genReturnStmt(p: var TProc, n: PNode, r: var TCompRes) =
 proc genProcBody(p: var TProc, prc: PSym, r: TCompRes): PRope = 
   if optStackTrace in prc.options: 
     result = ropef("var F={procname:$1,prev:framePtr,filename:$2,line:0};$n" &
-        "framePtr = F;$n", [makeCString(prc.owner.name.s & '.' & prc.name.s), 
-                            makeCString(toFilename(prc.info))])
+        "framePtr = F;$n", [makeJSString(prc.owner.name.s & '.' & prc.name.s), 
+                            makeJSString(toFilename(prc.info))])
   else: 
     result = nil
   if p.beforeRetNeeded: 
@@ -1540,9 +1542,9 @@ proc gen(p: var TProc, n: PNode, r: var TCompRes) =
   of nkStrLit..nkTripleStrLit: 
     if skipTypes(n.typ, abstractVarRange).kind == tyString: 
       useMagic(p, "cstrToNimstr")
-      r.res = ropef("cstrToNimstr($1)", [makeCString(n.strVal)])
+      r.res = ropef("cstrToNimstr($1)", [makeJSString(n.strVal)])
     else: 
-      r.res = makeCString(n.strVal)
+      r.res = makeJSString(n.strVal)
   of nkFloatLit..nkFloat64Lit: 
     f = n.floatVal
     if f != f: r.res = toRope"NaN"
@@ -1611,8 +1613,8 @@ proc genModule(p: var TProc, n: PNode, r: var TCompRes) =
   if optStackTrace in p.options: 
     r.com = ropef("var F = {procname:$1,prev:framePtr,filename:$2,line:0};$n" &
         "framePtr = F;$n" & "$3" & "framePtr = framePtr.prev;$n", [
-        makeCString("module " & p.module.module.name.s), 
-        makeCString(toFilename(p.module.module.info)), r.com])
+        makeJSString("module " & p.module.module.name.s), 
+        makeJSString(toFilename(p.module.module.info)), r.com])
 
 proc myProcess(b: PPassContext, n: PNode): PNode = 
   if passes.skipCodegen(n): return n
diff --git a/compiler/nimrod.nim b/compiler/nimrod.nim
index 5b67a10ac..3666046ea 100755
--- a/compiler/nimrod.nim
+++ b/compiler/nimrod.nim
@@ -72,9 +72,9 @@ proc HandleCmdLine() =
 when defined(GC_setMaxPause):
   GC_setMaxPause 2_000
 
-when compileOption("gc", "v2"):
+when compileOption("gc", "v2") or compileOption("gc", "refc"):
   # the new correct mark&sweet collector is too slow :-/
   GC_disableMarkAndSweep()
 condsyms.InitDefines()
 HandleCmdLine()
-quit(options.gExitcode)
+quit(int8(msgs.gErrorCounter > 0))
diff --git a/compiler/options.nim b/compiler/options.nim
index 6381ced41..d74bc7304 100755
--- a/compiler/options.nim
+++ b/compiler/options.nim
@@ -80,8 +80,8 @@ type                          # please make sure we have under 32 options
     cmdInteractive,           # start interactive session
     cmdRun                    # run the project via TCC backend
   TStringSeq* = seq[string]
-  TGCMode* = enum                   # the selected GC
-    gcNone, gcBoehm, gcRefc, gcV2   #
+  TGCMode* = enum             # the selected GC
+    gcNone, gcBoehm, gcMarkAndSweep, gcRefc, gcV2
 
 const
   ChecksOptions* = {optObjCheck, optFieldCheck, optRangeCheck, optNilCheck, 
@@ -269,7 +269,6 @@ proc binaryStrSearch*(x: openarray[string], y: string): int =
       return mid
   result = - 1
 
-# Can we keep this? I'm using it all the time
 template nimdbg*: expr = c.module.fileIdx == gProjectMainIdx
 template cnimdbg*: expr = p.module.module.fileIdx == gProjectMainIdx
 template pnimdbg*: expr = p.lex.fileIdx == gProjectMainIdx