diff options
Diffstat (limited to 'compiler')
-rwxr-xr-x | compiler/ccgstmts.nim | 13 | ||||
-rw-r--r-- | compiler/ccgtrav.nim | 21 | ||||
-rwxr-xr-x | compiler/ccgtypes.nim | 4 | ||||
-rwxr-xr-x | compiler/commands.nim | 12 | ||||
-rwxr-xr-x | compiler/ecmasgen.nim | 30 | ||||
-rwxr-xr-x | compiler/nimrod.nim | 4 | ||||
-rwxr-xr-x | compiler/options.nim | 5 |
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 |