mirror of
https://github.com/nim-lang/Nim.git
synced 2026-02-12 22:33:49 +00:00
removed nimdat in favor of per-module dat init procs
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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))])
|
||||
|
||||
@@ -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) =
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user