diff options
author | Zahary Karadjov <zahary@gmail.com> | 2012-07-19 19:04:18 +0300 |
---|---|---|
committer | Zahary Karadjov <zahary@gmail.com> | 2012-07-19 19:43:58 +0300 |
commit | 4841b6390c136a0e6a4f641d0d45f65a422809f6 (patch) | |
tree | 7a3d574d3f2f04d7dece4e7126e9ab5073809bd8 /compiler | |
parent | 035b715dfdcb65396b2e5cbc443b051d5f4ace53 (diff) | |
download | Nim-4841b6390c136a0e6a4f641d0d45f65a422809f6.tar.gz |
removed nimdat in favor of per-module dat init procs
Diffstat (limited to 'compiler')
-rwxr-xr-x | compiler/ast.nim | 2 | ||||
-rwxr-xr-x | compiler/ccgexprs.nim | 7 | ||||
-rwxr-xr-x | compiler/ccgtypes.nim | 38 | ||||
-rwxr-xr-x | compiler/cgen.nim | 88 | ||||
-rw-r--r-- | compiler/cgendata.nim | 10 | ||||
-rwxr-xr-x | compiler/main.nim | 3 |
6 files changed, 73 insertions, 75 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index 7bd893a07..c28cb6e0b 100755 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -567,6 +567,8 @@ type # for a conditional: # 1 iff the symbol is defined, else 0 # (or not in symbol table) + # for modules, a unique index correspinding + # to the order of compilation offset*: int # offset of record field loc*: TLoc annex*: PLib # additional fields (seldom used, so we use a diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 7b24e86db..78e9e5c31 100755 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -1004,15 +1004,10 @@ proc genNewFinalize(p: BProc, e: PNode) = oldModule: BModule refType = skipTypes(e.sons[1].typ, abstractVarRange) InitLocExpr(p, e.sons[1], a) - # This is a little hack: - # XXX this is also a bug, if the finalizer expression produces side-effects - oldModule = p.module - p.module = gNimDat InitLocExpr(p, e.sons[2], f) - p.module = oldModule initLoc(b, locExpr, a.t, OnHeap) ti = genTypeInfo(p.module, refType) - appf(gNimDat.s[cfsTypeInit3], "$1->finalizer = (void*)$2;$n", [ti, rdLoc(f)]) + appf(p.module.s[cfsTypeInit3], "$1->finalizer = (void*)$2;$n", [ti, rdLoc(f)]) b.r = ropecg(p.module, "($1) #newObj($2, sizeof($3))", [ getTypeDesc(p.module, refType), ti, getTypeDesc(p.module, skipTypes(reftype.sons[0], abstractRange))]) diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index eb75895f8..e3efe2d13 100755 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -886,41 +886,43 @@ include ccgtrav proc genTypeInfo(m: BModule, typ: PType): PRope = var t = getUniqueType(typ) - # gNimDat contains all the type information nowadays: - var dataGenerated = ContainsOrIncl(gNimDat.typeInfoMarker, t.id) result = ropef("NTI$1", [toRope(t.id)]) - if not ContainsOrIncl(m.typeInfoMarker, t.id): - # declare type information structures: + let owner = typ.skipTypes(abstractPtrs).owner.getModule + if owner != m.module: + # make sure the type info is created in the owner module + discard genTypeInfo(owner.bmod, typ) + # refenrece the type info as extern here discard cgsym(m, "TNimType") discard cgsym(m, "TNimNode") appf(m.s[cfsVars], "extern TNimType* $1; /* $2 */$n", [result, toRope(typeToString(t))]) - if dataGenerated: return + return + if ContainsOrIncl(m.typeInfoMarker, t.id): return case t.kind of tyEmpty: result = toRope"0" of tyPointer, tyBool, tyChar, tyCString, tyString, tyInt..tyUInt64, tyVar: - genTypeInfoAuxBase(gNimDat, t, result, toRope"0") + genTypeInfoAuxBase(m, t, result, toRope"0") of tyProc: if t.callConv != ccClosure: - genTypeInfoAuxBase(gNimDat, t, result, toRope"0") + genTypeInfoAuxBase(m, t, result, toRope"0") else: - genTupleInfo(gNimDat, fakeClosureType(t.owner), result) + genTupleInfo(m, fakeClosureType(t.owner), result) of tySequence, tyRef: - genTypeInfoAux(gNimDat, t, result) + genTypeInfoAux(m, t, result) if optRefcGC in gGlobalOptions: - let markerProc = genTraverseProc(gNimDat, t, tiNew) - appf(gNimDat.s[cfsTypeInit3], "$1->marker = $2;$n", [result, markerProc]) - of tyPtr, tyRange: genTypeInfoAux(gNimDat, t, result) - of tyArrayConstr, tyArray: genArrayInfo(gNimDat, t, result) - of tySet: genSetInfo(gNimDat, t, result) - of tyEnum: genEnumInfo(gNimDat, t, result) - of tyObject: genObjectInfo(gNimDat, t, result) + let markerProc = genTraverseProc(m, t, tiNew) + appf(m.s[cfsTypeInit3], "$1->marker = $2;$n", [result, markerProc]) + of tyPtr, tyRange: genTypeInfoAux(m, t, result) + of tyArrayConstr, tyArray: genArrayInfo(m, t, result) + of tySet: genSetInfo(m, t, result) + of tyEnum: genEnumInfo(m, t, result) + of tyObject: genObjectInfo(m, t, result) of tyTuple: - # if t.n != nil: genObjectInfo(gNimDat, t, result) + # if t.n != nil: genObjectInfo(m, t, result) # else: # BUGFIX: use consistently RTTI without proper field names; otherwise # results are not deterministic! - genTupleInfo(gNimDat, t, result) + genTupleInfo(m, t, result) else: InternalError("genTypeInfo(" & $t.kind & ')') proc genTypeSection(m: BModule, n: PNode) = diff --git a/compiler/cgen.nim b/compiler/cgen.nim index c7bfced73..c23084f5c 100755 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -819,11 +819,12 @@ proc getFileHeader(cfilenoext: string): PRope = proc genMainProc(m: BModule) = const CommonMainBody = - "\tnim__datInit();$n" & - "\tsystemInit();$n" & + "\tsystemDatInit();$n" & "$1" & "$2" & - "$3" + "\tsystemInit();$n" & + "$3" & + "$4" PosixNimMain = "int cmdCount;$n" & "char** cmdLine;$n" & @@ -877,7 +878,7 @@ proc genMainProc(m: BModule) = platform.targetOS == osStandalone: "".toRope else: ropecg(m, "\t#initStackBottom();$n") inc(m.labels) - appcg(m, m.s[cfsProcs], nimMain, [initStackBottomCall, + appcg(m, m.s[cfsProcs], nimMain, [mainDatInit, initStackBottomCall, gBreakpoints, mainModInit, toRope(m.labels)]) if optNoMain notin gGlobalOptions: appcg(m, m.s[cfsProcs], otherMain, []) @@ -885,12 +886,20 @@ proc genMainProc(m: BModule) = proc getInitName(m: PSym): PRope = result = ropeff("$1Init", "@$1Init", [toRope(m.name.s)]) +proc getDatInitName(m: PSym): PRope = + result = ropeff("$1DatInit", "@$1DatInit", [toRope(m.name.s)]) + proc registerModuleToMain(m: PSym) = - var initname = getInitName(m) - appff(mainModProcs, "N_NOINLINE(void, $1)(void);$n", - "declare void $1() noinline$n", [initname]) - if not (sfSystemModule in m.flags): - appff(mainModInit, "$1();$n", "call void ()* $1$n", [initname]) + var + init = m.getInitName + datInit = m.getDatInitName + appff(mainModProcs, "N_NOINLINE(void, $1)(void);$N", + "declare void $1() noinline$N", [init]) + appff(mainModProcs, "N_NOINLINE(void, $1)(void);$N", + "declare void $1() noinline$N", [datInit]) + if not (sfSystemModule in m.flags): + appff(mainModInit, "\t$1();$n", "call void ()* $1$n", [init]) + appff(mainDatInit, "\t$1();$n", "call void ()* $1$n", [datInit]) proc genInitCode(m: BModule) = if optProfiler in m.initProc.options: @@ -914,25 +923,17 @@ proc genInitCode(m: BModule) = getFrameDecl(m.initProc) app(prc, initGCFrame(m.initProc)) - + app(prc, genSectionStart(cpsLocals)) app(prc, m.initProc.s(cpsLocals)) app(prc, m.preInitProc.s(cpsLocals)) app(prc, genSectionEnd(cpsLocals)) - app(prc, genSectionStart(cfsTypeInit1)) - app(prc, m.s[cfsTypeInit1]) if optStackTrace in m.initProc.options and not m.PreventStackTrace: var procname = CStringLit(m.initProc, prc, m.module.name.s) var filename = CStringLit(m.initProc, prc, toFilename(m.module.info)) app(prc, initFrame(m.initProc, procname, filename)) - app(prc, genSectionEnd(cfsTypeInit1)) - - for i in cfsTypeInit2..cfsDynLibInit: - app(prc, genSectionStart(i)) - app(prc, m.s[i]) - app(prc, genSectionEnd(i)) - + app(prc, genSectionStart(cpsInit)) app(prc, m.preInitProc.s(cpsInit)) app(prc, m.initProc.s(cpsInit)) @@ -945,7 +946,17 @@ proc genInitCode(m: BModule) = app(prc, deinitFrame(m.initProc)) app(prc, genSectionEnd(cpsStmts)) app(prc, deinitGCFrame(m.initProc)) - appf(prc, "}$n$n") + appf(prc, "}$N$N") + + prc.appff("N_NOINLINE(void, $1)(void) {$n", + "define void $1() noinline {$n", [getDatInitName(m.module)]) + + for i in cfsTypeInit1..cfsDynLibInit: + app(prc, genSectionStart(i)) + app(prc, m.s[i]) + app(prc, genSectionEnd(i)) + + appf(prc, "}$N$N") # we cannot simply add the init proc to ``m.s[cfsProcs]`` anymore because # that would lead to a *nesting* of merge sections which the merger does # not support. So we add it to another special section: ``cfsInitProc`` @@ -987,22 +998,15 @@ proc rawNewModule(module: PSym, filename: string): BModule = proc newModule(module: PSym, filename: string): BModule = result = rawNewModule(module, filename) + if gModules.len <= module.position: gModules.setLen(module.position + 1) + gModules[module.position] = result + if (optDeadCodeElim in gGlobalOptions): if (sfDeadCodeElim in module.flags): InternalError("added pending module twice: " & filename) addPendingModule(result) -proc registerTypeInfoModule() = - const moduleName = "nim__dat" - var s = NewSym(skModule, getIdent(moduleName), nil) - gNimDat = rawNewModule(s, (options.gProjectPath / moduleName) & ".nim") - gNimDat.PreventStackTrace = true - addPendingModule(gNimDat) - appff(mainModProcs, "N_NOINLINE(void, $1)(void);$n", - "declare void $1() noinline$n", [getInitName(s)]) - proc myOpen(module: PSym, filename: string): PPassContext = - if gNimDat == nil: registerTypeInfoModule() result = newModule(module, filename) proc getCFile(m: BModule): string = @@ -1010,11 +1014,6 @@ proc getCFile(m: BModule): string = proc myOpenCached(module: PSym, filename: string, rd: PRodReader): PPassContext = - if gNimDat == nil: - registerTypeInfoModule() - gNimDat.fromCache = true - readMergeInfo(getCFile(gNimDat), gNimDat) - var m = newModule(module, filename) readMergeInfo(getCFile(m), m) result = m @@ -1100,9 +1099,6 @@ proc myClose(b: PPassContext, n: PNode): PNode = # cached modules need to registered too: registerModuleToMain(m.module) - if optDeadCodeElim notin gGlobalOptions and - sfDeadCodeElim notin m.module.flags: - finishModule(m) if sfMainModule in m.module.flags: var disp = generateMethodDispatchers() for i in 0..sonsLen(disp)-1: genProcAux(m, disp.sons[i].sym) @@ -1111,16 +1107,12 @@ proc myClose(b: PPassContext, n: PNode): PNode = # deps are allowed (and the system module is processed in the wrong # order anyway) while gForwardedProcsCounter > 0: - for i in countup(0, high(gPendingModules)): - finishModule(gPendingModules[i]) - for i in countup(0, high(gPendingModules)): - writeModule(gPendingModules[i], pending=true) - setlen(gPendingModules, 0) - if optDeadCodeElim notin gGlobalOptions and - sfDeadCodeElim notin m.module.flags: - writeModule(m, pending=false) - if sfMainModule in m.module.flags: writeMapping(gMapping) - + for i in countup(0, high(gModules)): + finishModule(gModules[i]) + for i in countup(0, high(gModules)): + writeModule(gModules[i], pending=true) + writeMapping(gMapping) + proc cgenPass(): TPass = initPass(result) result.open = myOpen diff --git a/compiler/cgendata.nim b/compiler/cgendata.nim index 72c7ceae5..fabad86ab 100644 --- a/compiler/cgendata.nim +++ b/compiler/cgendata.nim @@ -112,14 +112,14 @@ type labels*: natural # for generating unique module-scope names var - mainModProcs*, mainModInit*: PRope # parts of the main module + mainModProcs*, mainModInit*, mainDatInit*: PRope # parts of the main module gMapping*: PRope # the generated mapping file (if requested) gProcProfile*: Natural # proc profile counter gPendingModules*: seq[BModule] = @[] # list of modules that are not # finished with code generation + gModules*: seq[BModule] = @[] # list of all compiled modules gForwardedProcsCounter*: int = 0 - gNimDat*: BModule # generated global data - + proc s*(p: BProc, s: TCProcSection): var PRope {.inline.} = # section in the current block result = p.blocks[p.blocks.len - 1].sections[s] @@ -128,6 +128,10 @@ proc procSec*(p: BProc, s: TCProcSection): var PRope {.inline.} = # top level proc sections result = p.blocks[0].sections[s] +proc bmod*(module: PSym): BModule = + # obtains the BModule for a given module PSym + result = gModules[module.position] + proc newProc*(prc: PSym, module: BModule): BProc = new(result) result.prc = prc diff --git a/compiler/main.nim b/compiler/main.nim index d3a40a32d..a9b00c4d2 100755 --- a/compiler/main.nim +++ b/compiler/main.nim @@ -39,6 +39,7 @@ proc registerModule(filename: string, module: PSym) = proc getModule(filename: string): PSym = result = compMods[filename] +var gModulesCount = 0 proc newModule(filename: string): PSym = # We cannot call ``newSym`` here, because we have to circumvent the ID # mechanism, which we do in order to assign each module a persistent ID. @@ -51,6 +52,8 @@ proc newModule(filename: string): PSym = result.owner = result # a module belongs to itself result.info = newLineInfo(filename, 1, 1) + result.position = gModulesCount + inc gModulesCount incl(result.flags, sfUsed) initStrTable(result.tab) RegisterModule(filename, result) |