diff options
author | Araq <rumpf_a@web.de> | 2011-05-16 00:27:47 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2011-05-16 00:27:47 +0200 |
commit | 67a30d837132e8000d1a8b10ce3d32423d149318 (patch) | |
tree | b059b56027b57c45777d15d33e88b3dac9313f14 /compiler | |
parent | c7b3d828be1bbca81f3576875636ea571e595402 (diff) | |
download | Nim-67a30d837132e8000d1a8b10ce3d32423d149318.tar.gz |
further steps for thread support; bootstrapping should require unzip C sources and ./build.sh
Diffstat (limited to 'compiler')
-rwxr-xr-x | compiler/ccgexprs.nim | 50 | ||||
-rwxr-xr-x | compiler/ccgstmts.nim | 83 | ||||
-rwxr-xr-x | compiler/cgen.nim | 30 | ||||
-rwxr-xr-x | compiler/commands.nim | 2 |
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) |