removed nimdat in favor of per-module dat init procs
This commit is contained in:
parent
035b715dfd
commit
4841b6390c
6 changed files with 73 additions and 75 deletions
|
|
@ -567,6 +567,8 @@ type
|
||||||
# for a conditional:
|
# for a conditional:
|
||||||
# 1 iff the symbol is defined, else 0
|
# 1 iff the symbol is defined, else 0
|
||||||
# (or not in symbol table)
|
# (or not in symbol table)
|
||||||
|
# for modules, a unique index correspinding
|
||||||
|
# to the order of compilation
|
||||||
offset*: int # offset of record field
|
offset*: int # offset of record field
|
||||||
loc*: TLoc
|
loc*: TLoc
|
||||||
annex*: PLib # additional fields (seldom used, so we use a
|
annex*: PLib # additional fields (seldom used, so we use a
|
||||||
|
|
|
||||||
|
|
@ -1004,15 +1004,10 @@ proc genNewFinalize(p: BProc, e: PNode) =
|
||||||
oldModule: BModule
|
oldModule: BModule
|
||||||
refType = skipTypes(e.sons[1].typ, abstractVarRange)
|
refType = skipTypes(e.sons[1].typ, abstractVarRange)
|
||||||
InitLocExpr(p, e.sons[1], a)
|
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)
|
InitLocExpr(p, e.sons[2], f)
|
||||||
p.module = oldModule
|
|
||||||
initLoc(b, locExpr, a.t, OnHeap)
|
initLoc(b, locExpr, a.t, OnHeap)
|
||||||
ti = genTypeInfo(p.module, refType)
|
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))", [
|
b.r = ropecg(p.module, "($1) #newObj($2, sizeof($3))", [
|
||||||
getTypeDesc(p.module, refType),
|
getTypeDesc(p.module, refType),
|
||||||
ti, getTypeDesc(p.module, skipTypes(reftype.sons[0], abstractRange))])
|
ti, getTypeDesc(p.module, skipTypes(reftype.sons[0], abstractRange))])
|
||||||
|
|
|
||||||
|
|
@ -886,41 +886,43 @@ include ccgtrav
|
||||||
|
|
||||||
proc genTypeInfo(m: BModule, typ: PType): PRope =
|
proc genTypeInfo(m: BModule, typ: PType): PRope =
|
||||||
var t = getUniqueType(typ)
|
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)])
|
result = ropef("NTI$1", [toRope(t.id)])
|
||||||
if not ContainsOrIncl(m.typeInfoMarker, t.id):
|
let owner = typ.skipTypes(abstractPtrs).owner.getModule
|
||||||
# declare type information structures:
|
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, "TNimType")
|
||||||
discard cgsym(m, "TNimNode")
|
discard cgsym(m, "TNimNode")
|
||||||
appf(m.s[cfsVars], "extern TNimType* $1; /* $2 */$n",
|
appf(m.s[cfsVars], "extern TNimType* $1; /* $2 */$n",
|
||||||
[result, toRope(typeToString(t))])
|
[result, toRope(typeToString(t))])
|
||||||
if dataGenerated: return
|
return
|
||||||
|
if ContainsOrIncl(m.typeInfoMarker, t.id): return
|
||||||
case t.kind
|
case t.kind
|
||||||
of tyEmpty: result = toRope"0"
|
of tyEmpty: result = toRope"0"
|
||||||
of tyPointer, tyBool, tyChar, tyCString, tyString, tyInt..tyUInt64, tyVar:
|
of tyPointer, tyBool, tyChar, tyCString, tyString, tyInt..tyUInt64, tyVar:
|
||||||
genTypeInfoAuxBase(gNimDat, t, result, toRope"0")
|
genTypeInfoAuxBase(m, t, result, toRope"0")
|
||||||
of tyProc:
|
of tyProc:
|
||||||
if t.callConv != ccClosure:
|
if t.callConv != ccClosure:
|
||||||
genTypeInfoAuxBase(gNimDat, t, result, toRope"0")
|
genTypeInfoAuxBase(m, t, result, toRope"0")
|
||||||
else:
|
else:
|
||||||
genTupleInfo(gNimDat, fakeClosureType(t.owner), result)
|
genTupleInfo(m, fakeClosureType(t.owner), result)
|
||||||
of tySequence, tyRef:
|
of tySequence, tyRef:
|
||||||
genTypeInfoAux(gNimDat, t, result)
|
genTypeInfoAux(m, t, result)
|
||||||
if optRefcGC in gGlobalOptions:
|
if optRefcGC in gGlobalOptions:
|
||||||
let markerProc = genTraverseProc(gNimDat, t, tiNew)
|
let markerProc = genTraverseProc(m, t, tiNew)
|
||||||
appf(gNimDat.s[cfsTypeInit3], "$1->marker = $2;$n", [result, markerProc])
|
appf(m.s[cfsTypeInit3], "$1->marker = $2;$n", [result, markerProc])
|
||||||
of tyPtr, tyRange: genTypeInfoAux(gNimDat, t, result)
|
of tyPtr, tyRange: genTypeInfoAux(m, t, result)
|
||||||
of tyArrayConstr, tyArray: genArrayInfo(gNimDat, t, result)
|
of tyArrayConstr, tyArray: genArrayInfo(m, t, result)
|
||||||
of tySet: genSetInfo(gNimDat, t, result)
|
of tySet: genSetInfo(m, t, result)
|
||||||
of tyEnum: genEnumInfo(gNimDat, t, result)
|
of tyEnum: genEnumInfo(m, t, result)
|
||||||
of tyObject: genObjectInfo(gNimDat, t, result)
|
of tyObject: genObjectInfo(m, t, result)
|
||||||
of tyTuple:
|
of tyTuple:
|
||||||
# if t.n != nil: genObjectInfo(gNimDat, t, result)
|
# if t.n != nil: genObjectInfo(m, t, result)
|
||||||
# else:
|
# else:
|
||||||
# BUGFIX: use consistently RTTI without proper field names; otherwise
|
# BUGFIX: use consistently RTTI without proper field names; otherwise
|
||||||
# results are not deterministic!
|
# results are not deterministic!
|
||||||
genTupleInfo(gNimDat, t, result)
|
genTupleInfo(m, t, result)
|
||||||
else: InternalError("genTypeInfo(" & $t.kind & ')')
|
else: InternalError("genTypeInfo(" & $t.kind & ')')
|
||||||
|
|
||||||
proc genTypeSection(m: BModule, n: PNode) =
|
proc genTypeSection(m: BModule, n: PNode) =
|
||||||
|
|
|
||||||
|
|
@ -819,11 +819,12 @@ proc getFileHeader(cfilenoext: string): PRope =
|
||||||
proc genMainProc(m: BModule) =
|
proc genMainProc(m: BModule) =
|
||||||
const
|
const
|
||||||
CommonMainBody =
|
CommonMainBody =
|
||||||
"\tnim__datInit();$n" &
|
"\tsystemDatInit();$n" &
|
||||||
"\tsystemInit();$n" &
|
|
||||||
"$1" &
|
"$1" &
|
||||||
"$2" &
|
"$2" &
|
||||||
"$3"
|
"\tsystemInit();$n" &
|
||||||
|
"$3" &
|
||||||
|
"$4"
|
||||||
PosixNimMain =
|
PosixNimMain =
|
||||||
"int cmdCount;$n" &
|
"int cmdCount;$n" &
|
||||||
"char** cmdLine;$n" &
|
"char** cmdLine;$n" &
|
||||||
|
|
@ -877,7 +878,7 @@ proc genMainProc(m: BModule) =
|
||||||
platform.targetOS == osStandalone: "".toRope
|
platform.targetOS == osStandalone: "".toRope
|
||||||
else: ropecg(m, "\t#initStackBottom();$n")
|
else: ropecg(m, "\t#initStackBottom();$n")
|
||||||
inc(m.labels)
|
inc(m.labels)
|
||||||
appcg(m, m.s[cfsProcs], nimMain, [initStackBottomCall,
|
appcg(m, m.s[cfsProcs], nimMain, [mainDatInit, initStackBottomCall,
|
||||||
gBreakpoints, mainModInit, toRope(m.labels)])
|
gBreakpoints, mainModInit, toRope(m.labels)])
|
||||||
if optNoMain notin gGlobalOptions:
|
if optNoMain notin gGlobalOptions:
|
||||||
appcg(m, m.s[cfsProcs], otherMain, [])
|
appcg(m, m.s[cfsProcs], otherMain, [])
|
||||||
|
|
@ -885,12 +886,20 @@ proc genMainProc(m: BModule) =
|
||||||
proc getInitName(m: PSym): PRope =
|
proc getInitName(m: PSym): PRope =
|
||||||
result = ropeff("$1Init", "@$1Init", [toRope(m.name.s)])
|
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) =
|
proc registerModuleToMain(m: PSym) =
|
||||||
var initname = getInitName(m)
|
var
|
||||||
appff(mainModProcs, "N_NOINLINE(void, $1)(void);$n",
|
init = m.getInitName
|
||||||
"declare void $1() noinline$n", [initname])
|
datInit = m.getDatInitName
|
||||||
if not (sfSystemModule in m.flags):
|
appff(mainModProcs, "N_NOINLINE(void, $1)(void);$N",
|
||||||
appff(mainModInit, "$1();$n", "call void ()* $1$n", [initname])
|
"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) =
|
proc genInitCode(m: BModule) =
|
||||||
if optProfiler in m.initProc.options:
|
if optProfiler in m.initProc.options:
|
||||||
|
|
@ -914,25 +923,17 @@ proc genInitCode(m: BModule) =
|
||||||
getFrameDecl(m.initProc)
|
getFrameDecl(m.initProc)
|
||||||
|
|
||||||
app(prc, initGCFrame(m.initProc))
|
app(prc, initGCFrame(m.initProc))
|
||||||
|
|
||||||
app(prc, genSectionStart(cpsLocals))
|
app(prc, genSectionStart(cpsLocals))
|
||||||
app(prc, m.initProc.s(cpsLocals))
|
app(prc, m.initProc.s(cpsLocals))
|
||||||
app(prc, m.preInitProc.s(cpsLocals))
|
app(prc, m.preInitProc.s(cpsLocals))
|
||||||
app(prc, genSectionEnd(cpsLocals))
|
app(prc, genSectionEnd(cpsLocals))
|
||||||
|
|
||||||
app(prc, genSectionStart(cfsTypeInit1))
|
|
||||||
app(prc, m.s[cfsTypeInit1])
|
|
||||||
if optStackTrace in m.initProc.options and not m.PreventStackTrace:
|
if optStackTrace in m.initProc.options and not m.PreventStackTrace:
|
||||||
var procname = CStringLit(m.initProc, prc, m.module.name.s)
|
var procname = CStringLit(m.initProc, prc, m.module.name.s)
|
||||||
var filename = CStringLit(m.initProc, prc, toFilename(m.module.info))
|
var filename = CStringLit(m.initProc, prc, toFilename(m.module.info))
|
||||||
app(prc, initFrame(m.initProc, procname, filename))
|
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, genSectionStart(cpsInit))
|
||||||
app(prc, m.preInitProc.s(cpsInit))
|
app(prc, m.preInitProc.s(cpsInit))
|
||||||
app(prc, m.initProc.s(cpsInit))
|
app(prc, m.initProc.s(cpsInit))
|
||||||
|
|
@ -945,7 +946,17 @@ proc genInitCode(m: BModule) =
|
||||||
app(prc, deinitFrame(m.initProc))
|
app(prc, deinitFrame(m.initProc))
|
||||||
app(prc, genSectionEnd(cpsStmts))
|
app(prc, genSectionEnd(cpsStmts))
|
||||||
app(prc, deinitGCFrame(m.initProc))
|
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
|
# 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
|
# that would lead to a *nesting* of merge sections which the merger does
|
||||||
# not support. So we add it to another special section: ``cfsInitProc``
|
# 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 =
|
proc newModule(module: PSym, filename: string): BModule =
|
||||||
result = rawNewModule(module, filename)
|
result = rawNewModule(module, filename)
|
||||||
|
if gModules.len <= module.position: gModules.setLen(module.position + 1)
|
||||||
|
gModules[module.position] = result
|
||||||
|
|
||||||
if (optDeadCodeElim in gGlobalOptions):
|
if (optDeadCodeElim in gGlobalOptions):
|
||||||
if (sfDeadCodeElim in module.flags):
|
if (sfDeadCodeElim in module.flags):
|
||||||
InternalError("added pending module twice: " & filename)
|
InternalError("added pending module twice: " & filename)
|
||||||
addPendingModule(result)
|
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 =
|
proc myOpen(module: PSym, filename: string): PPassContext =
|
||||||
if gNimDat == nil: registerTypeInfoModule()
|
|
||||||
result = newModule(module, filename)
|
result = newModule(module, filename)
|
||||||
|
|
||||||
proc getCFile(m: BModule): string =
|
proc getCFile(m: BModule): string =
|
||||||
|
|
@ -1010,11 +1014,6 @@ proc getCFile(m: BModule): string =
|
||||||
|
|
||||||
proc myOpenCached(module: PSym, filename: string,
|
proc myOpenCached(module: PSym, filename: string,
|
||||||
rd: PRodReader): PPassContext =
|
rd: PRodReader): PPassContext =
|
||||||
if gNimDat == nil:
|
|
||||||
registerTypeInfoModule()
|
|
||||||
gNimDat.fromCache = true
|
|
||||||
readMergeInfo(getCFile(gNimDat), gNimDat)
|
|
||||||
|
|
||||||
var m = newModule(module, filename)
|
var m = newModule(module, filename)
|
||||||
readMergeInfo(getCFile(m), m)
|
readMergeInfo(getCFile(m), m)
|
||||||
result = m
|
result = m
|
||||||
|
|
@ -1100,9 +1099,6 @@ proc myClose(b: PPassContext, n: PNode): PNode =
|
||||||
# cached modules need to registered too:
|
# cached modules need to registered too:
|
||||||
registerModuleToMain(m.module)
|
registerModuleToMain(m.module)
|
||||||
|
|
||||||
if optDeadCodeElim notin gGlobalOptions and
|
|
||||||
sfDeadCodeElim notin m.module.flags:
|
|
||||||
finishModule(m)
|
|
||||||
if sfMainModule in m.module.flags:
|
if sfMainModule in m.module.flags:
|
||||||
var disp = generateMethodDispatchers()
|
var disp = generateMethodDispatchers()
|
||||||
for i in 0..sonsLen(disp)-1: genProcAux(m, disp.sons[i].sym)
|
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
|
# deps are allowed (and the system module is processed in the wrong
|
||||||
# order anyway)
|
# order anyway)
|
||||||
while gForwardedProcsCounter > 0:
|
while gForwardedProcsCounter > 0:
|
||||||
for i in countup(0, high(gPendingModules)):
|
for i in countup(0, high(gModules)):
|
||||||
finishModule(gPendingModules[i])
|
finishModule(gModules[i])
|
||||||
for i in countup(0, high(gPendingModules)):
|
for i in countup(0, high(gModules)):
|
||||||
writeModule(gPendingModules[i], pending=true)
|
writeModule(gModules[i], pending=true)
|
||||||
setlen(gPendingModules, 0)
|
writeMapping(gMapping)
|
||||||
if optDeadCodeElim notin gGlobalOptions and
|
|
||||||
sfDeadCodeElim notin m.module.flags:
|
|
||||||
writeModule(m, pending=false)
|
|
||||||
if sfMainModule in m.module.flags: writeMapping(gMapping)
|
|
||||||
|
|
||||||
proc cgenPass(): TPass =
|
proc cgenPass(): TPass =
|
||||||
initPass(result)
|
initPass(result)
|
||||||
result.open = myOpen
|
result.open = myOpen
|
||||||
|
|
|
||||||
|
|
@ -112,14 +112,14 @@ type
|
||||||
labels*: natural # for generating unique module-scope names
|
labels*: natural # for generating unique module-scope names
|
||||||
|
|
||||||
var
|
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)
|
gMapping*: PRope # the generated mapping file (if requested)
|
||||||
gProcProfile*: Natural # proc profile counter
|
gProcProfile*: Natural # proc profile counter
|
||||||
gPendingModules*: seq[BModule] = @[] # list of modules that are not
|
gPendingModules*: seq[BModule] = @[] # list of modules that are not
|
||||||
# finished with code generation
|
# finished with code generation
|
||||||
|
gModules*: seq[BModule] = @[] # list of all compiled modules
|
||||||
gForwardedProcsCounter*: int = 0
|
gForwardedProcsCounter*: int = 0
|
||||||
gNimDat*: BModule # generated global data
|
|
||||||
|
|
||||||
proc s*(p: BProc, s: TCProcSection): var PRope {.inline.} =
|
proc s*(p: BProc, s: TCProcSection): var PRope {.inline.} =
|
||||||
# section in the current block
|
# section in the current block
|
||||||
result = p.blocks[p.blocks.len - 1].sections[s]
|
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
|
# top level proc sections
|
||||||
result = p.blocks[0].sections[s]
|
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 =
|
proc newProc*(prc: PSym, module: BModule): BProc =
|
||||||
new(result)
|
new(result)
|
||||||
result.prc = prc
|
result.prc = prc
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@ proc registerModule(filename: string, module: PSym) =
|
||||||
proc getModule(filename: string): PSym =
|
proc getModule(filename: string): PSym =
|
||||||
result = compMods[filename]
|
result = compMods[filename]
|
||||||
|
|
||||||
|
var gModulesCount = 0
|
||||||
proc newModule(filename: string): PSym =
|
proc newModule(filename: string): PSym =
|
||||||
# We cannot call ``newSym`` here, because we have to circumvent the ID
|
# 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.
|
# 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.owner = result # a module belongs to itself
|
||||||
result.info = newLineInfo(filename, 1, 1)
|
result.info = newLineInfo(filename, 1, 1)
|
||||||
|
result.position = gModulesCount
|
||||||
|
inc gModulesCount
|
||||||
incl(result.flags, sfUsed)
|
incl(result.flags, sfUsed)
|
||||||
initStrTable(result.tab)
|
initStrTable(result.tab)
|
||||||
RegisterModule(filename, result)
|
RegisterModule(filename, result)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue