further steps for incremental C code generation
This commit is contained in:
parent
a6f90d4cdd
commit
43eace163a
3 changed files with 74 additions and 41 deletions
|
|
@ -220,8 +220,7 @@ proc processMergeInfo(L: var TBaseLexer, m: BModule) =
|
||||||
of "labels": m.labels = decodeVInt(L.buf, L.bufpos)
|
of "labels": m.labels = decodeVInt(L.buf, L.bufpos)
|
||||||
else: InternalError("ccgmerge: unkown key: " & k)
|
else: InternalError("ccgmerge: unkown key: " & k)
|
||||||
|
|
||||||
proc readMergeInfo*(cfilename: string, m: BModule) =
|
template withCFile(cfilename: string, body: stmt) =
|
||||||
## reads the merge information into `m`.
|
|
||||||
var s = LLStreamOpen(cfilename, fmRead)
|
var s = LLStreamOpen(cfilename, fmRead)
|
||||||
if s == nil: return
|
if s == nil: return
|
||||||
var L: TBaseLexer
|
var L: TBaseLexer
|
||||||
|
|
@ -229,9 +228,28 @@ proc readMergeInfo*(cfilename: string, m: BModule) =
|
||||||
while true:
|
while true:
|
||||||
skipUntilCmd(L)
|
skipUntilCmd(L)
|
||||||
if ^L.bufpos == '\0': break
|
if ^L.bufpos == '\0': break
|
||||||
|
body
|
||||||
|
closeBaseLexer(L)
|
||||||
|
|
||||||
|
proc readMergeInfo*(cfilename: string, m: BModule) =
|
||||||
|
## reads the merge meta information into `m`.
|
||||||
|
withCFile(cfilename):
|
||||||
|
var k = readKey(L)
|
||||||
|
if k == "NIM_merge_INFO":
|
||||||
|
processMergeInfo(L, m)
|
||||||
|
break
|
||||||
|
|
||||||
|
type
|
||||||
|
TMergeSections = object {.pure.}
|
||||||
|
f: TCFileSections
|
||||||
|
p: TCProcSections
|
||||||
|
|
||||||
|
proc readMergeSections(cfilename: string, m: var TMergeSections) =
|
||||||
|
## reads the merge sections into `m`.
|
||||||
|
withCFile(cfilename):
|
||||||
var k = readKey(L)
|
var k = readKey(L)
|
||||||
if k == "NIM_merge_INFO":
|
if k == "NIM_merge_INFO":
|
||||||
processMergeInfo(L, m)
|
nil
|
||||||
elif ^L.bufpos == '*' and ^(L.bufpos+1) == '/':
|
elif ^L.bufpos == '*' and ^(L.bufpos+1) == '/':
|
||||||
inc(L.bufpos, 2)
|
inc(L.bufpos, 2)
|
||||||
# read back into section
|
# read back into section
|
||||||
|
|
@ -240,14 +258,29 @@ proc readMergeInfo*(cfilename: string, m: BModule) =
|
||||||
skipWhite(L)
|
skipWhite(L)
|
||||||
var sectionA = CFileSectionNames.find(k)
|
var sectionA = CFileSectionNames.find(k)
|
||||||
if sectionA > 0 and sectionA <= high(TCFileSection).int:
|
if sectionA > 0 and sectionA <= high(TCFileSection).int:
|
||||||
m.s[TCFileSection(sectionA)] = verbatim
|
m.f[TCFileSection(sectionA)] = verbatim
|
||||||
else:
|
else:
|
||||||
var sectionB = CProcSectionNames.find(k)
|
var sectionB = CProcSectionNames.find(k)
|
||||||
if sectionB >= 0 and sectionB <= high(TCProcSection).int:
|
if sectionB >= 0 and sectionB <= high(TCProcSection).int:
|
||||||
m.initProc.s[TCProcSection(sectionB)] = verbatim
|
m.p[TCProcSection(sectionB)] = verbatim
|
||||||
else:
|
else:
|
||||||
InternalError("ccgmerge: unknown section: " & k)
|
InternalError("ccgmerge: unknown section: " & k)
|
||||||
else:
|
else:
|
||||||
InternalError("ccgmerge: */ expected")
|
InternalError("ccgmerge: '*/' expected")
|
||||||
closeBaseLexer(L)
|
|
||||||
|
proc mergeRequired*(m: BModule): bool =
|
||||||
|
for i in low(TCFileSection)..high(TCFileSection):
|
||||||
|
if m.s[i] != nil: return true
|
||||||
|
for i in low(TCProcSection)..high(TCProcSection):
|
||||||
|
if m.initProc.s[i] != nil: return true
|
||||||
|
|
||||||
|
proc mergeFiles*(cfilename: string, m: BModule) =
|
||||||
|
## merges the C file with the old version on hard disc.
|
||||||
|
var old: TMergeSections
|
||||||
|
readMergeSections(cfilename, old)
|
||||||
|
# do the merge; old section before new section:
|
||||||
|
for i in low(TCFileSection)..high(TCFileSection):
|
||||||
|
m.s[i] = con(old.f[i], m.s[i])
|
||||||
|
for i in low(TCProcSection)..high(TCProcSection):
|
||||||
|
m.initProc.s[i] = con(old.p[i], m.initProc.s[i])
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,7 @@
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
#
|
#
|
||||||
|
|
||||||
# This is the new C code generator; much cleaner and faster
|
## This module implements the C code generator.
|
||||||
# than the old one. It also generates better code.
|
|
||||||
|
|
||||||
import
|
import
|
||||||
ast, astalgo, strutils, hashes, trees, platform, magicsys, extccomp,
|
ast, astalgo, strutils, hashes, trees, platform, magicsys, extccomp,
|
||||||
|
|
@ -855,29 +854,15 @@ proc myOpen(module: PSym, filename: string): PPassContext =
|
||||||
|
|
||||||
proc myOpenCached(module: PSym, filename: string,
|
proc myOpenCached(module: PSym, filename: string,
|
||||||
rd: PRodReader): PPassContext =
|
rd: PRodReader): PPassContext =
|
||||||
if gNimDat == nil:
|
if gNimDat == nil:
|
||||||
registerTypeInfoModule()
|
registerTypeInfoModule()
|
||||||
# XXX load old nimcache data here!
|
|
||||||
gNimDat.fromCache = true
|
gNimDat.fromCache = true
|
||||||
result = newModule(module, filename)
|
readMergeInfo(completeCFilePath(gNimDat.cfilename), gNimDat)
|
||||||
#if gNimDat == nil: registerTypeInfoModule()
|
|
||||||
#var cfile = changeFileExt(completeCFilePath(filename), cExt)
|
var m = newModule(module, filename)
|
||||||
#var cfilenoext = changeFileExt(cfile, "")
|
readMergeInfo(completeCFilePath(m.cfilename), m)
|
||||||
#addFileToLink(cfilenoext)
|
result = m
|
||||||
#registerModuleToMain(module)
|
|
||||||
# XXX: this cannot be right here, initalization has to be appended during
|
|
||||||
# the ``myClose`` call
|
|
||||||
#result = nil
|
|
||||||
|
|
||||||
proc shouldRecompile(code: PRope, cfile, cfilenoext: string): bool =
|
|
||||||
result = true
|
|
||||||
if not (optForceFullMake in gGlobalOptions):
|
|
||||||
var objFile = toObjFile(cfilenoext)
|
|
||||||
if writeRopeIfNotEqual(code, cfile): return
|
|
||||||
if ExistsFile(objFile) and os.FileNewer(objFile, cfile): result = false
|
|
||||||
else:
|
|
||||||
writeRope(code, cfile)
|
|
||||||
|
|
||||||
proc myProcess(b: PPassContext, n: PNode): PNode =
|
proc myProcess(b: PPassContext, n: PNode): PNode =
|
||||||
result = n
|
result = n
|
||||||
if b == nil or passes.skipCodegen(n): return
|
if b == nil or passes.skipCodegen(n): return
|
||||||
|
|
@ -899,26 +884,41 @@ proc finishModule(m: BModule) =
|
||||||
dec(gForwardedProcsCounter, i)
|
dec(gForwardedProcsCounter, i)
|
||||||
setlen(m.forwardedProcs, 0)
|
setlen(m.forwardedProcs, 0)
|
||||||
|
|
||||||
|
proc shouldRecompile(code: PRope, cfile, cfilenoext: string): bool =
|
||||||
|
result = true
|
||||||
|
if optForceFullMake notin gGlobalOptions:
|
||||||
|
var objFile = toObjFile(cfilenoext)
|
||||||
|
if writeRopeIfNotEqual(code, cfile): return
|
||||||
|
if ExistsFile(objFile) and os.FileNewer(objFile, cfile): result = false
|
||||||
|
else:
|
||||||
|
writeRope(code, cfile)
|
||||||
|
|
||||||
proc writeModule(m: BModule) =
|
proc writeModule(m: BModule) =
|
||||||
# generate code for the init statements of the module:
|
# generate code for the init statements of the module:
|
||||||
genInitCode(m)
|
|
||||||
finishTypeDescriptions(m)
|
|
||||||
var cfile = completeCFilePath(m.cfilename)
|
var cfile = completeCFilePath(m.cfilename)
|
||||||
var cfilenoext = changeFileExt(cfile, "")
|
var cfilenoext = changeFileExt(cfile, "")
|
||||||
|
|
||||||
|
genInitCode(m)
|
||||||
|
finishTypeDescriptions(m)
|
||||||
if sfMainModule in m.module.flags:
|
if sfMainModule in m.module.flags:
|
||||||
# generate main file:
|
# generate main file:
|
||||||
app(m.s[cfsProcHeaders], mainModProcs)
|
app(m.s[cfsProcHeaders], mainModProcs)
|
||||||
GenerateThreadVarsSize(m)
|
GenerateThreadVarsSize(m)
|
||||||
var code = genModule(m, cfilenoext)
|
|
||||||
|
if not m.fromCache or optForceFullMake in gGlobalOptions:
|
||||||
when hasTinyCBackend:
|
var code = genModule(m, cfilenoext)
|
||||||
if gCmd == cmdRun:
|
when hasTinyCBackend:
|
||||||
tccgen.compileCCode(ropeToStr(code))
|
if gCmd == cmdRun:
|
||||||
return
|
tccgen.compileCCode(ropeToStr(code))
|
||||||
|
return
|
||||||
if not m.fromCache:
|
|
||||||
if shouldRecompile(code, changeFileExt(cfile, cExt), cfilenoext):
|
if shouldRecompile(code, changeFileExt(cfile, cExt), cfilenoext):
|
||||||
addFileToCompile(cfilenoext)
|
addFileToCompile(cfilenoext)
|
||||||
|
elif mergeRequired(m):
|
||||||
|
mergeFiles(cfile, m)
|
||||||
|
var code = genModule(m, cfilenoext)
|
||||||
|
writeRope(code, cfile)
|
||||||
|
addFileToCompile(cfilenoext)
|
||||||
addFileToLink(cfilenoext)
|
addFileToLink(cfilenoext)
|
||||||
|
|
||||||
proc myClose(b: PPassContext, n: PNode): PNode =
|
proc myClose(b: PPassContext, n: PNode): PNode =
|
||||||
|
|
|
||||||
|
|
@ -40,12 +40,12 @@ type
|
||||||
ctVoid, ctChar, ctBool, ctUInt, ctUInt8, ctUInt16, ctUInt32, ctUInt64,
|
ctVoid, ctChar, ctBool, ctUInt, ctUInt8, ctUInt16, ctUInt32, ctUInt64,
|
||||||
ctInt, ctInt8, ctInt16, ctInt32, ctInt64, ctFloat, ctFloat32, ctFloat64,
|
ctInt, ctInt8, ctInt16, ctInt32, ctInt64, ctFloat, ctFloat32, ctFloat64,
|
||||||
ctFloat128, ctArray, ctStruct, ctPtr, ctNimStr, ctNimSeq, ctProc, ctCString
|
ctFloat128, ctArray, ctStruct, ctPtr, ctNimStr, ctNimSeq, ctProc, ctCString
|
||||||
TCFileSections = array[TCFileSection, PRope] # represents a generated C file
|
TCFileSections* = array[TCFileSection, PRope] # represents a generated C file
|
||||||
TCProcSection* = enum # the sections a generated C proc consists of
|
TCProcSection* = enum # the sections a generated C proc consists of
|
||||||
cpsLocals, # section of local variables for C proc
|
cpsLocals, # section of local variables for C proc
|
||||||
cpsInit, # section for init of variables for C proc
|
cpsInit, # section for init of variables for C proc
|
||||||
cpsStmts # section of local statements for C proc
|
cpsStmts # section of local statements for C proc
|
||||||
TCProcSections = array[TCProcSection, PRope] # represents a generated C proc
|
TCProcSections* = array[TCProcSection, PRope] # represents a generated C proc
|
||||||
BModule* = ref TCGen
|
BModule* = ref TCGen
|
||||||
BProc* = ref TCProc
|
BProc* = ref TCProc
|
||||||
TBlock{.final.} = object
|
TBlock{.final.} = object
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue