IC: green tests (#17311)
* IC: renamed to_packed_ast module to ic module * IC: don't store the --forceBuild flag, makes it easier to test * IC: enable hello world test * Codegen: refactorings for IC; changed the name mangling algorithm * fixed the HCR regressions * life is too short for HCR * tconvexhull is now allowed to use deepCopy * IC exposed a stdlib bug, required a refactoring * codegen: code cleanups * IC: even if a module is outdated, its dependencies might come from disk * IC: progress * IC: better name mangling, module IDs are not stable * IC: another refactoring helping with --ic:on --gc:arc * disable arraymancer on Windows for the time being * disable arraymancer altogether * IC: make basic test work with 'nim cpp' * IC: progress on --ic:on --gc:arc * wip; name mangling for type info
This commit is contained in:
parent
60fc7e986b
commit
6c1c8f51b3
30 changed files with 249 additions and 187 deletions
|
|
@ -1416,7 +1416,7 @@ proc newType*(kind: TTypeKind, id: ItemId; owner: PSym): PType =
|
||||||
lockLevel: UnspecifiedLockLevel,
|
lockLevel: UnspecifiedLockLevel,
|
||||||
uniqueId: id)
|
uniqueId: id)
|
||||||
when false:
|
when false:
|
||||||
if result.id == 76426:
|
if result.itemId.module == 55 and result.itemId.item == 2:
|
||||||
echo "KNID ", kind
|
echo "KNID ", kind
|
||||||
writeStackTrace()
|
writeStackTrace()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,12 @@ proc mangleName(m: BModule; s: PSym): Rope =
|
||||||
result = s.loc.r
|
result = s.loc.r
|
||||||
if result == nil:
|
if result == nil:
|
||||||
result = s.name.s.mangle.rope
|
result = s.name.s.mangle.rope
|
||||||
|
result.add "_"
|
||||||
|
result.add m.g.graph.ifaces[s.itemId.module].uniqueName
|
||||||
|
result.add "_"
|
||||||
|
result.add rope s.itemId.item
|
||||||
|
if m.hcrOn:
|
||||||
|
result.add "_"
|
||||||
result.add(idOrSig(s, m.module.name.s.mangle, m.sigConflicts))
|
result.add(idOrSig(s, m.module.name.s.mangle, m.sigConflicts))
|
||||||
s.loc.r = result
|
s.loc.r = result
|
||||||
writeMangledName(m.ndi, s, m.config)
|
writeMangledName(m.ndi, s, m.config)
|
||||||
|
|
@ -1273,12 +1279,12 @@ proc genDeepCopyProc(m: BModule; s: PSym; result: Rope) =
|
||||||
m.s[cfsTypeInit3].addf("$1.deepcopy =(void* (N_RAW_NIMCALL*)(void*))$2;$n",
|
m.s[cfsTypeInit3].addf("$1.deepcopy =(void* (N_RAW_NIMCALL*)(void*))$2;$n",
|
||||||
[result, s.loc.r])
|
[result, s.loc.r])
|
||||||
|
|
||||||
proc declareNimType(m: BModule, name: string; str: Rope, ownerModule: PSym) =
|
proc declareNimType(m: BModule, name: string; str: Rope, module: int) =
|
||||||
let nr = rope(name)
|
let nr = rope(name)
|
||||||
if m.hcrOn:
|
if m.hcrOn:
|
||||||
m.s[cfsData].addf("static $2* $1;$n", [str, nr])
|
m.s[cfsData].addf("static $2* $1;$n", [str, nr])
|
||||||
m.s[cfsTypeInit1].addf("\t$1 = ($3*)hcrGetGlobal($2, \"$1\");$n",
|
m.s[cfsTypeInit1].addf("\t$1 = ($3*)hcrGetGlobal($2, \"$1\");$n",
|
||||||
[str, getModuleDllPath(m, ownerModule), nr])
|
[str, getModuleDllPath(m, module), nr])
|
||||||
else:
|
else:
|
||||||
m.s[cfsData].addf("extern $2 $1;$n", [str, nr])
|
m.s[cfsData].addf("extern $2 $1;$n", [str, nr])
|
||||||
|
|
||||||
|
|
@ -1351,6 +1357,9 @@ proc genTypeInfoV2Impl(m: BModule, t, origType: PType, name: Rope; info: TLineIn
|
||||||
if t.kind == tyObject and t.len > 0 and t[0] != nil and optEnableDeepCopy in m.config.globalOptions:
|
if t.kind == tyObject and t.len > 0 and t[0] != nil and optEnableDeepCopy in m.config.globalOptions:
|
||||||
discard genTypeInfoV1(m, t, info)
|
discard genTypeInfoV1(m, t, info)
|
||||||
|
|
||||||
|
proc moduleOpenForCodegen(m: BModule; module: int32): bool {.inline.} =
|
||||||
|
result = module < m.g.modules.len and m.g.modules[module] != nil
|
||||||
|
|
||||||
proc genTypeInfoV2(m: BModule, t: PType; info: TLineInfo): Rope =
|
proc genTypeInfoV2(m: BModule, t: PType; info: TLineInfo): Rope =
|
||||||
let origType = t
|
let origType = t
|
||||||
# distinct types can have their own destructors
|
# distinct types can have their own destructors
|
||||||
|
|
@ -1374,11 +1383,11 @@ proc genTypeInfoV2(m: BModule, t: PType; info: TLineInfo): Rope =
|
||||||
result = "NTIv2$1_" % [rope($sig)]
|
result = "NTIv2$1_" % [rope($sig)]
|
||||||
m.typeInfoMarkerV2[sig] = result
|
m.typeInfoMarkerV2[sig] = result
|
||||||
|
|
||||||
let owner = t.skipTypes(typedescPtrs).owner.getModule
|
let owner = t.skipTypes(typedescPtrs).itemId.module
|
||||||
if owner != m.module:
|
if owner != m.module.position and moduleOpenForCodegen(m, owner):
|
||||||
# make sure the type info is created in the owner module
|
# make sure the type info is created in the owner module
|
||||||
assert m.g.modules[owner.position] != nil
|
assert m.g.modules[owner] != nil
|
||||||
discard genTypeInfoV2(m.g.modules[owner.position], origType, info)
|
discard genTypeInfoV2(m.g.modules[owner], origType, info)
|
||||||
# reference the type info as extern here
|
# reference the type info as extern here
|
||||||
discard cgsym(m, "TNimTypeV2")
|
discard cgsym(m, "TNimTypeV2")
|
||||||
declareNimType(m, "TNimTypeV2", result, owner)
|
declareNimType(m, "TNimTypeV2", result, owner)
|
||||||
|
|
@ -1397,6 +1406,33 @@ proc openArrayToTuple(m: BModule; t: PType): PType =
|
||||||
result.add p
|
result.add p
|
||||||
result.add getSysType(m.g.graph, t.owner.info, tyInt)
|
result.add getSysType(m.g.graph, t.owner.info, tyInt)
|
||||||
|
|
||||||
|
proc typeToC(t: PType): string =
|
||||||
|
## Just for more readable names, the result doesn't have
|
||||||
|
## to be unique.
|
||||||
|
let s = typeToString(t)
|
||||||
|
result = newStringOfCap(s.len)
|
||||||
|
for i in 0..<s.len:
|
||||||
|
let c = s[i]
|
||||||
|
case c
|
||||||
|
of 'a'..'z':
|
||||||
|
result.add c
|
||||||
|
of 'A'..'Z':
|
||||||
|
result.add toLowerAscii(c)
|
||||||
|
of ' ':
|
||||||
|
discard
|
||||||
|
of ',':
|
||||||
|
result.add '_'
|
||||||
|
of '.':
|
||||||
|
result.add 'O'
|
||||||
|
of '[', '(', '{':
|
||||||
|
result.add 'L'
|
||||||
|
of ']', ')', '}':
|
||||||
|
result.add 'T'
|
||||||
|
else:
|
||||||
|
# We mangle upper letters and digits too so that there cannot
|
||||||
|
# be clashes with our special meanings
|
||||||
|
result.addInt ord(c)
|
||||||
|
|
||||||
proc genTypeInfoV1(m: BModule, t: PType; info: TLineInfo): Rope =
|
proc genTypeInfoV1(m: BModule, t: PType; info: TLineInfo): Rope =
|
||||||
let origType = t
|
let origType = t
|
||||||
var t = skipTypes(origType, irrelevantForBackend + tyUserTypeClasses)
|
var t = skipTypes(origType, irrelevantForBackend + tyUserTypeClasses)
|
||||||
|
|
@ -1417,14 +1453,14 @@ proc genTypeInfoV1(m: BModule, t: PType; info: TLineInfo): Rope =
|
||||||
m.typeInfoMarker[sig] = marker.str
|
m.typeInfoMarker[sig] = marker.str
|
||||||
return prefixTI.rope & marker.str & ")".rope
|
return prefixTI.rope & marker.str & ")".rope
|
||||||
|
|
||||||
result = "NTI$1_" % [rope($sig)]
|
result = "NTI$1$2_" % [rope(typeToC(t)), rope($sig)]
|
||||||
m.typeInfoMarker[sig] = result
|
m.typeInfoMarker[sig] = result
|
||||||
|
|
||||||
let owner = t.skipTypes(typedescPtrs).owner.getModule
|
let owner = t.skipTypes(typedescPtrs).itemId.module
|
||||||
if owner != m.module:
|
if owner != m.module.position and moduleOpenForCodegen(m, owner):
|
||||||
# make sure the type info is created in the owner module
|
# make sure the type info is created in the owner module
|
||||||
assert m.g.modules[owner.position] != nil
|
assert m.g.modules[owner] != nil
|
||||||
discard genTypeInfoV1(m.g.modules[owner.position], origType, info)
|
discard genTypeInfoV1(m.g.modules[owner], origType, info)
|
||||||
# reference the type info as extern here
|
# reference the type info as extern here
|
||||||
discard cgsym(m, "TNimType")
|
discard cgsym(m, "TNimType")
|
||||||
discard cgsym(m, "TNimNode")
|
discard cgsym(m, "TNimNode")
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import
|
||||||
ast, astalgo, hashes, trees, platform, magicsys, extccomp, options, intsets,
|
ast, astalgo, hashes, trees, platform, magicsys, extccomp, options, intsets,
|
||||||
nversion, nimsets, msgs, bitsets, idents, types,
|
nversion, nimsets, msgs, bitsets, idents, types,
|
||||||
ccgutils, os, ropes, math, passes, wordrecg, treetab, cgmeth,
|
ccgutils, os, ropes, math, passes, wordrecg, treetab, cgmeth,
|
||||||
rodutils, renderer, cgendata, ccgmerge, aliases,
|
rodutils, renderer, cgendata, aliases,
|
||||||
lowerings, tables, sets, ndi, lineinfos, pathutils, transf,
|
lowerings, tables, sets, ndi, lineinfos, pathutils, transf,
|
||||||
injectdestructors
|
injectdestructors
|
||||||
|
|
||||||
|
|
@ -50,8 +50,8 @@ proc addForwardedProc(m: BModule, prc: PSym) =
|
||||||
m.g.forwardedProcs.add(prc)
|
m.g.forwardedProcs.add(prc)
|
||||||
|
|
||||||
proc findPendingModule(m: BModule, s: PSym): BModule =
|
proc findPendingModule(m: BModule, s: PSym): BModule =
|
||||||
var ms = getModule(s)
|
let ms = s.itemId.module #getModule(s)
|
||||||
result = m.g.modules[ms.position]
|
result = m.g.modules[ms]
|
||||||
|
|
||||||
proc initLoc(result: var TLoc, k: TLocKind, lode: PNode, s: TStorageLoc) =
|
proc initLoc(result: var TLoc, k: TLocKind, lode: PNode, s: TStorageLoc) =
|
||||||
result.k = k
|
result.k = k
|
||||||
|
|
@ -97,10 +97,13 @@ proc getCFile(m: BModule): AbsoluteFile
|
||||||
proc getModuleDllPath(m: BModule): Rope =
|
proc getModuleDllPath(m: BModule): Rope =
|
||||||
let (dir, name, ext) = splitFile(getCFile(m))
|
let (dir, name, ext) = splitFile(getCFile(m))
|
||||||
let filename = strutils.`%`(platform.OS[m.g.config.target.targetOS].dllFrmt, [name & ext])
|
let filename = strutils.`%`(platform.OS[m.g.config.target.targetOS].dllFrmt, [name & ext])
|
||||||
return makeCString(dir.string & "/" & filename)
|
result = makeCString(dir.string & "/" & filename)
|
||||||
|
|
||||||
|
proc getModuleDllPath(m: BModule, module: int): Rope =
|
||||||
|
result = getModuleDllPath(m.g.modules[module])
|
||||||
|
|
||||||
proc getModuleDllPath(m: BModule, s: PSym): Rope =
|
proc getModuleDllPath(m: BModule, s: PSym): Rope =
|
||||||
return getModuleDllPath(findPendingModule(m, s))
|
result = getModuleDllPath(m.g.modules[s.itemId.module])
|
||||||
|
|
||||||
import macros
|
import macros
|
||||||
|
|
||||||
|
|
@ -1109,7 +1112,7 @@ proc genProcPrototype(m: BModule, sym: PSym) =
|
||||||
useHeader(m, sym)
|
useHeader(m, sym)
|
||||||
if lfNoDecl in sym.loc.flags: return
|
if lfNoDecl in sym.loc.flags: return
|
||||||
if lfDynamicLib in sym.loc.flags:
|
if lfDynamicLib in sym.loc.flags:
|
||||||
if getModule(sym).id != m.module.id and
|
if sym.itemId.module != m.module.position and
|
||||||
not containsOrIncl(m.declaredThings, sym.id):
|
not containsOrIncl(m.declaredThings, sym.id):
|
||||||
m.s[cfsVars].add(ropecg(m, "$1 $2 $3;$n",
|
m.s[cfsVars].add(ropecg(m, "$1 $2 $3;$n",
|
||||||
[(if isReloadable(m, sym): "static" else: "extern"),
|
[(if isReloadable(m, sym): "static" else: "extern"),
|
||||||
|
|
@ -1586,9 +1589,7 @@ proc genDatInitCode(m: BModule) =
|
||||||
for i in cfsTypeInit1..cfsDynLibInit:
|
for i in cfsTypeInit1..cfsDynLibInit:
|
||||||
if m.s[i].len != 0:
|
if m.s[i].len != 0:
|
||||||
moduleDatInitRequired = true
|
moduleDatInitRequired = true
|
||||||
prc.add(genSectionStart(i, m.config))
|
|
||||||
prc.add(m.s[i])
|
prc.add(m.s[i])
|
||||||
prc.add(genSectionEnd(i, m.config))
|
|
||||||
|
|
||||||
prc.addf("}$N$N", [])
|
prc.addf("}$N$N", [])
|
||||||
|
|
||||||
|
|
@ -1646,9 +1647,7 @@ proc genInitCode(m: BModule) =
|
||||||
if m.thing.s(section).len > 0:
|
if m.thing.s(section).len > 0:
|
||||||
moduleInitRequired = true
|
moduleInitRequired = true
|
||||||
if addHcrGuards: prc.add("\tif (nim_hcr_do_init_) {\n\n")
|
if addHcrGuards: prc.add("\tif (nim_hcr_do_init_) {\n\n")
|
||||||
prc.add(genSectionStart(section, m.config))
|
|
||||||
prc.add(m.thing.s(section))
|
prc.add(m.thing.s(section))
|
||||||
prc.add(genSectionEnd(section, m.config))
|
|
||||||
if addHcrGuards: prc.add("\n\t} // nim_hcr_do_init_\n")
|
if addHcrGuards: prc.add("\n\t} // nim_hcr_do_init_\n")
|
||||||
|
|
||||||
if m.preInitProc.s(cpsInit).len > 0 or m.preInitProc.s(cpsStmts).len > 0:
|
if m.preInitProc.s(cpsInit).len > 0 or m.preInitProc.s(cpsStmts).len > 0:
|
||||||
|
|
@ -1740,28 +1739,21 @@ proc genModule(m: BModule, cfile: Cfile): Rope =
|
||||||
var moduleIsEmpty = true
|
var moduleIsEmpty = true
|
||||||
|
|
||||||
result = getFileHeader(m.config, cfile)
|
result = getFileHeader(m.config, cfile)
|
||||||
result.add(genMergeInfo(m))
|
|
||||||
|
|
||||||
generateThreadLocalStorage(m)
|
generateThreadLocalStorage(m)
|
||||||
generateHeaders(m)
|
generateHeaders(m)
|
||||||
result.add(genSectionStart(cfsHeaders, m.config))
|
|
||||||
result.add(m.s[cfsHeaders])
|
result.add(m.s[cfsHeaders])
|
||||||
if m.config.cppCustomNamespace.len > 0:
|
if m.config.cppCustomNamespace.len > 0:
|
||||||
result.add openNamespaceNim(m.config.cppCustomNamespace)
|
result.add openNamespaceNim(m.config.cppCustomNamespace)
|
||||||
result.add(genSectionEnd(cfsHeaders, m.config))
|
|
||||||
result.add(genSectionStart(cfsFrameDefines, m.config))
|
|
||||||
if m.s[cfsFrameDefines].len > 0:
|
if m.s[cfsFrameDefines].len > 0:
|
||||||
result.add(m.s[cfsFrameDefines])
|
result.add(m.s[cfsFrameDefines])
|
||||||
else:
|
else:
|
||||||
result.add("#define nimfr_(x, y)\n#define nimln_(x, y)\n")
|
result.add("#define nimfr_(x, y)\n#define nimln_(x, y)\n")
|
||||||
result.add(genSectionEnd(cfsFrameDefines, m.config))
|
|
||||||
|
|
||||||
for i in cfsForwardTypes..cfsProcs:
|
for i in cfsForwardTypes..cfsProcs:
|
||||||
if m.s[i].len > 0:
|
if m.s[i].len > 0:
|
||||||
moduleIsEmpty = false
|
moduleIsEmpty = false
|
||||||
result.add(genSectionStart(i, m.config))
|
|
||||||
result.add(m.s[i])
|
result.add(m.s[i])
|
||||||
result.add(genSectionEnd(i, m.config))
|
|
||||||
|
|
||||||
if m.s[cfsInitProc].len > 0:
|
if m.s[cfsInitProc].len > 0:
|
||||||
moduleIsEmpty = false
|
moduleIsEmpty = false
|
||||||
|
|
@ -1851,9 +1843,7 @@ proc writeHeader(m: BModule) =
|
||||||
|
|
||||||
generateThreadLocalStorage(m)
|
generateThreadLocalStorage(m)
|
||||||
for i in cfsHeaders..cfsProcs:
|
for i in cfsHeaders..cfsProcs:
|
||||||
result.add(genSectionStart(i, m.config))
|
|
||||||
result.add(m.s[i])
|
result.add(m.s[i])
|
||||||
result.add(genSectionEnd(i, m.config))
|
|
||||||
if m.config.cppCustomNamespace.len > 0 and i == cfsHeaders: result.add openNamespaceNim(m.config.cppCustomNamespace)
|
if m.config.cppCustomNamespace.len > 0 and i == cfsHeaders: result.add openNamespaceNim(m.config.cppCustomNamespace)
|
||||||
result.add(m.s[cfsInitProc])
|
result.add(m.s[cfsInitProc])
|
||||||
|
|
||||||
|
|
@ -1952,7 +1942,6 @@ proc shouldRecompile(m: BModule; code: Rope, cfile: Cfile): bool =
|
||||||
proc writeModule(m: BModule, pending: bool) =
|
proc writeModule(m: BModule, pending: bool) =
|
||||||
template onExit() = close(m.ndi, m.config)
|
template onExit() = close(m.ndi, m.config)
|
||||||
let cfile = getCFile(m)
|
let cfile = getCFile(m)
|
||||||
if true or optForceFullMake in m.config.globalOptions:
|
|
||||||
if moduleHasChanged(m.g.graph, m.module):
|
if moduleHasChanged(m.g.graph, m.module):
|
||||||
genInitCode(m)
|
genInitCode(m)
|
||||||
finishTypeDescriptions(m)
|
finishTypeDescriptions(m)
|
||||||
|
|
@ -1974,42 +1963,12 @@ proc writeModule(m: BModule, pending: bool) =
|
||||||
|
|
||||||
if not shouldRecompile(m, code, cf): cf.flags = {CfileFlag.Cached}
|
if not shouldRecompile(m, code, cf): cf.flags = {CfileFlag.Cached}
|
||||||
addFileToCompile(m.config, cf)
|
addFileToCompile(m.config, cf)
|
||||||
elif pending and mergeRequired(m) and sfMainModule notin m.module.flags:
|
|
||||||
let cf = Cfile(nimname: m.module.name.s, cname: cfile,
|
|
||||||
obj: completeCfilePath(m.config, toObjFile(m.config, cfile)), flags: {})
|
|
||||||
mergeFiles(cfile, m)
|
|
||||||
genInitCode(m)
|
|
||||||
finishTypeDescriptions(m)
|
|
||||||
var code = genModule(m, cf)
|
|
||||||
if code != nil:
|
|
||||||
if not writeRope(code, cfile):
|
|
||||||
rawMessage(m.config, errCannotOpenFile, cfile.string)
|
|
||||||
addFileToCompile(m.config, cf)
|
|
||||||
else:
|
|
||||||
# Consider: first compilation compiles ``system.nim`` and produces
|
|
||||||
# ``system.c`` but then compilation fails due to an error. This means
|
|
||||||
# that ``system.o`` is missing, so we need to call the C compiler for it:
|
|
||||||
var cf = Cfile(nimname: m.module.name.s, cname: cfile,
|
|
||||||
obj: completeCfilePath(m.config, toObjFile(m.config, cfile)), flags: {})
|
|
||||||
if fileExists(cf.obj): cf.flags = {CfileFlag.Cached}
|
|
||||||
addFileToCompile(m.config, cf)
|
|
||||||
onExit()
|
onExit()
|
||||||
|
|
||||||
proc updateCachedModule(m: BModule) =
|
proc updateCachedModule(m: BModule) =
|
||||||
let cfile = getCFile(m)
|
let cfile = getCFile(m)
|
||||||
var cf = Cfile(nimname: m.module.name.s, cname: cfile,
|
var cf = Cfile(nimname: m.module.name.s, cname: cfile,
|
||||||
obj: completeCfilePath(m.config, toObjFile(m.config, cfile)), flags: {})
|
obj: completeCfilePath(m.config, toObjFile(m.config, cfile)), flags: {})
|
||||||
|
|
||||||
if mergeRequired(m) and sfMainModule notin m.module.flags:
|
|
||||||
mergeFiles(cfile, m)
|
|
||||||
genInitCode(m)
|
|
||||||
finishTypeDescriptions(m)
|
|
||||||
var code = genModule(m, cf)
|
|
||||||
if code != nil:
|
|
||||||
if not writeRope(code, cfile):
|
|
||||||
rawMessage(m.config, errCannotOpenFile, cfile.string)
|
|
||||||
addFileToCompile(m.config, cf)
|
|
||||||
else:
|
|
||||||
if sfMainModule notin m.module.flags:
|
if sfMainModule notin m.module.flags:
|
||||||
genMainProc(m)
|
genMainProc(m)
|
||||||
cf.flags = {CfileFlag.Cached}
|
cf.flags = {CfileFlag.Cached}
|
||||||
|
|
@ -2080,8 +2039,7 @@ proc genForwardedProcs(g: BModuleList) =
|
||||||
while g.forwardedProcs.len > 0:
|
while g.forwardedProcs.len > 0:
|
||||||
let
|
let
|
||||||
prc = g.forwardedProcs.pop()
|
prc = g.forwardedProcs.pop()
|
||||||
ms = getModule(prc)
|
m = g.modules[prc.itemId.module]
|
||||||
m = g.modules[ms.position]
|
|
||||||
if sfForward in prc.flags:
|
if sfForward in prc.flags:
|
||||||
internalError(m.config, prc.info, "still forwarded: " & prc.name.s)
|
internalError(m.config, prc.info, "still forwarded: " & prc.name.s)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@ type
|
||||||
|
|
||||||
TTypeSeq* = seq[PType]
|
TTypeSeq* = seq[PType]
|
||||||
TypeCache* = Table[SigHash, Rope]
|
TypeCache* = Table[SigHash, Rope]
|
||||||
TypeCacheWithOwner* = Table[SigHash, tuple[str: Rope, owner: PSym]]
|
TypeCacheWithOwner* = Table[SigHash, tuple[str: Rope, owner: int32]]
|
||||||
|
|
||||||
CodegenFlag* = enum
|
CodegenFlag* = enum
|
||||||
preventStackTrace, # true if stack traces need to be prevented
|
preventStackTrace, # true if stack traces need to be prevented
|
||||||
|
|
@ -202,7 +202,7 @@ proc newProc*(prc: PSym, module: BModule): BProc =
|
||||||
result.sigConflicts = initCountTable[string]()
|
result.sigConflicts = initCountTable[string]()
|
||||||
|
|
||||||
proc newModuleList*(g: ModuleGraph): BModuleList =
|
proc newModuleList*(g: ModuleGraph): BModuleList =
|
||||||
BModuleList(typeInfoMarker: initTable[SigHash, tuple[str: Rope, owner: PSym]](),
|
BModuleList(typeInfoMarker: initTable[SigHash, tuple[str: Rope, owner: int32]](),
|
||||||
config: g.config, graph: g, nimtvDeclared: initIntSet())
|
config: g.config, graph: g, nimtvDeclared: initIntSet())
|
||||||
|
|
||||||
iterator cgenModules*(g: BModuleList): BModule =
|
iterator cgenModules*(g: BModuleList): BModule =
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ import std/[packedsets, algorithm]
|
||||||
import ".."/[ast, options, lineinfos, modulegraphs, cgendata, cgen,
|
import ".."/[ast, options, lineinfos, modulegraphs, cgendata, cgen,
|
||||||
pathutils, extccomp, msgs]
|
pathutils, extccomp, msgs]
|
||||||
|
|
||||||
import packed_ast, to_packed_ast, dce, rodfiles
|
import packed_ast, ic, dce, rodfiles
|
||||||
|
|
||||||
proc unpackTree(g: ModuleGraph; thisModule: int;
|
proc unpackTree(g: ModuleGraph; thisModule: int;
|
||||||
tree: PackedTree; n: NodePos): PNode =
|
tree: PackedTree; n: NodePos): PNode =
|
||||||
|
|
@ -83,7 +83,7 @@ proc aliveSymsChanged(config: ConfigRef; position: int; alive: AliveSyms): bool
|
||||||
proc generateCode*(g: ModuleGraph) =
|
proc generateCode*(g: ModuleGraph) =
|
||||||
## The single entry point, generate C(++) code for the entire
|
## The single entry point, generate C(++) code for the entire
|
||||||
## Nim program aka `ModuleGraph`.
|
## Nim program aka `ModuleGraph`.
|
||||||
initStrTable(g.compilerprocs)
|
resetForBackend(g)
|
||||||
var alive = computeAliveSyms(g.packed, g.config)
|
var alive = computeAliveSyms(g.packed, g.config)
|
||||||
|
|
||||||
for i in 0..high(g.packed):
|
for i in 0..high(g.packed):
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
import std / [intsets, tables]
|
import std / [intsets, tables]
|
||||||
import ".." / [ast, options, lineinfos, types]
|
import ".." / [ast, options, lineinfos, types]
|
||||||
|
|
||||||
import packed_ast, to_packed_ast, bitabs
|
import packed_ast, ic, bitabs
|
||||||
|
|
||||||
type
|
type
|
||||||
AliveSyms* = seq[IntSet]
|
AliveSyms* = seq[IntSet]
|
||||||
|
|
@ -111,7 +111,7 @@ proc aliveCode(c: var AliveContext; g: PackedModuleGraph; tree: PackedTree; n: N
|
||||||
let otherModule = toFileIndexCached(c.decoder, g, c.thisModule, m).int
|
let otherModule = toFileIndexCached(c.decoder, g, c.thisModule, m).int
|
||||||
followLater(c, g, otherModule, item)
|
followLater(c, g, otherModule, item)
|
||||||
of nkMacroDef, nkTemplateDef, nkTypeSection, nkTypeOfExpr,
|
of nkMacroDef, nkTemplateDef, nkTypeSection, nkTypeOfExpr,
|
||||||
nkCommentStmt, nkIteratorDef, nkIncludeStmt,
|
nkCommentStmt, nkIncludeStmt,
|
||||||
nkImportStmt, nkImportExceptStmt, nkExportStmt, nkExportExceptStmt,
|
nkImportStmt, nkImportExceptStmt, nkExportStmt, nkExportExceptStmt,
|
||||||
nkFromStmt, nkStaticStmt:
|
nkFromStmt, nkStaticStmt:
|
||||||
discard
|
discard
|
||||||
|
|
@ -121,7 +121,7 @@ proc aliveCode(c: var AliveContext; g: PackedModuleGraph; tree: PackedTree; n: N
|
||||||
aliveCode(c, g, tree, son)
|
aliveCode(c, g, tree, son)
|
||||||
of nkChckRangeF, nkChckRange64, nkChckRange:
|
of nkChckRangeF, nkChckRange64, nkChckRange:
|
||||||
rangeCheckAnalysis(c, g, tree, n)
|
rangeCheckAnalysis(c, g, tree, n)
|
||||||
of nkProcDef, nkConverterDef, nkMethodDef, nkLambda, nkDo, nkFuncDef:
|
of nkProcDef, nkConverterDef, nkMethodDef, nkFuncDef, nkIteratorDef:
|
||||||
if n.firstSon.kind == nkSym and isNotGeneric(n):
|
if n.firstSon.kind == nkSym and isNotGeneric(n):
|
||||||
let item = n.firstSon.operand
|
let item = n.firstSon.operand
|
||||||
if isExportedToC(c, g, item):
|
if isExportedToC(c, g, item):
|
||||||
|
|
|
||||||
|
|
@ -95,6 +95,7 @@ proc rememberStartupConfig*(dest: var PackedConfig, config: ConfigRef) =
|
||||||
template rem(x) =
|
template rem(x) =
|
||||||
dest.x = config.x
|
dest.x = config.x
|
||||||
primConfigFields rem
|
primConfigFields rem
|
||||||
|
dest.globalOptions.excl optForceFullMake
|
||||||
|
|
||||||
proc hashFileCached(conf: ConfigRef; fileIdx: FileIndex): string =
|
proc hashFileCached(conf: ConfigRef; fileIdx: FileIndex): string =
|
||||||
result = msgs.getHash(conf, fileIdx)
|
result = msgs.getHash(conf, fileIdx)
|
||||||
|
|
@ -486,7 +487,13 @@ proc storeInstantiation*(c: var PackedEncoder; m: var PackedModule; s: PSym; i:
|
||||||
concreteTypes: t)
|
concreteTypes: t)
|
||||||
toPackedGeneratedProcDef(i.sym, c, m)
|
toPackedGeneratedProcDef(i.sym, c, m)
|
||||||
|
|
||||||
proc loadError(err: RodFileError; filename: AbsoluteFile) =
|
proc loadError(err: RodFileError; filename: AbsoluteFile; config: ConfigRef;) =
|
||||||
|
case err
|
||||||
|
of cannotOpen:
|
||||||
|
rawMessage(config, warnCannotOpenFile, filename.string)
|
||||||
|
of includeFileChanged:
|
||||||
|
rawMessage(config, warnFileChanged, filename.string)
|
||||||
|
else:
|
||||||
echo "Error: ", $err, " loading file: ", filename.string
|
echo "Error: ", $err, " loading file: ", filename.string
|
||||||
|
|
||||||
proc loadRodFile*(filename: AbsoluteFile; m: var PackedModule; config: ConfigRef;
|
proc loadRodFile*(filename: AbsoluteFile; m: var PackedModule; config: ConfigRef;
|
||||||
|
|
@ -718,7 +725,7 @@ proc loadProcHeader(c: var PackedDecoder; g: var PackedModuleGraph; thisModule:
|
||||||
result = newNodeIT(k, translateLineInfo(c, g, thisModule, n.info),
|
result = newNodeIT(k, translateLineInfo(c, g, thisModule, n.info),
|
||||||
loadType(c, g, thisModule, n.typ))
|
loadType(c, g, thisModule, n.typ))
|
||||||
result.flags = n.flags
|
result.flags = n.flags
|
||||||
assert k in {nkProcDef, nkMethodDef, nkIteratorDef, nkFuncDef, nkConverterDef}
|
assert k in {nkProcDef, nkMethodDef, nkIteratorDef, nkFuncDef, nkConverterDef, nkLambda}
|
||||||
var i = 0
|
var i = 0
|
||||||
for n0 in sonsReadonly(tree, n):
|
for n0 in sonsReadonly(tree, n):
|
||||||
if i != bodyPos:
|
if i != bodyPos:
|
||||||
|
|
@ -932,10 +939,10 @@ proc needsRecompile(g: var PackedModuleGraph; conf: ConfigRef; cache: IdentCache
|
||||||
else:
|
else:
|
||||||
g[m] = LoadedModule(status: outdated, module: g[m].module)
|
g[m] = LoadedModule(status: outdated, module: g[m].module)
|
||||||
else:
|
else:
|
||||||
loadError(err, rod)
|
loadError(err, rod, conf)
|
||||||
g[m].status = outdated
|
g[m].status = outdated
|
||||||
result = true
|
result = true
|
||||||
when false: loadError(err, rod)
|
when false: loadError(err, rod, conf)
|
||||||
of loading, loaded:
|
of loading, loaded:
|
||||||
# For loading: Assume no recompile is required.
|
# For loading: Assume no recompile is required.
|
||||||
result = false
|
result = false
|
||||||
|
|
@ -16,7 +16,7 @@ import ".." / [ast, modulegraphs, trees, extccomp, btrees,
|
||||||
|
|
||||||
import tables
|
import tables
|
||||||
|
|
||||||
import packed_ast, to_packed_ast, bitabs
|
import packed_ast, ic, bitabs
|
||||||
|
|
||||||
proc replayStateChanges*(module: PSym; g: ModuleGraph) =
|
proc replayStateChanges*(module: PSym; g: ModuleGraph) =
|
||||||
let list = module.ast
|
let list = module.ast
|
||||||
|
|
|
||||||
|
|
@ -350,7 +350,7 @@ proc genMarkCyclic(c: var Con; result, dest: PNode) =
|
||||||
if t.kind == tyRef:
|
if t.kind == tyRef:
|
||||||
result.add callCodegenProc(c.graph, "nimMarkCyclic", dest.info, dest)
|
result.add callCodegenProc(c.graph, "nimMarkCyclic", dest.info, dest)
|
||||||
else:
|
else:
|
||||||
let xenv = genBuiltin(c.graph, mAccessEnv, "accessEnv", dest)
|
let xenv = genBuiltin(c.graph, c.idgen, mAccessEnv, "accessEnv", dest)
|
||||||
xenv.typ = getSysType(c.graph, dest.info, tyPointer)
|
xenv.typ = getSysType(c.graph, dest.info, tyPointer)
|
||||||
result.add callCodegenProc(c.graph, "nimMarkCyclic", dest.info, xenv)
|
result.add callCodegenProc(c.graph, "nimMarkCyclic", dest.info, xenv)
|
||||||
|
|
||||||
|
|
@ -395,21 +395,21 @@ It is best to factor out piece of object that needs custom destructor into separ
|
||||||
cond.add le
|
cond.add le
|
||||||
cond.add tmp
|
cond.add tmp
|
||||||
let notExpr = newNodeIT(nkPrefix, n.info, getSysType(c.graph, unknownLineInfo, tyBool))
|
let notExpr = newNodeIT(nkPrefix, n.info, getSysType(c.graph, unknownLineInfo, tyBool))
|
||||||
notExpr.add newSymNode(createMagic(c.graph, "not", mNot))
|
notExpr.add newSymNode(createMagic(c.graph, c.idgen, "not", mNot))
|
||||||
notExpr.add cond
|
notExpr.add cond
|
||||||
result.add newTree(nkIfStmt, newTree(nkElifBranch, notExpr, c.genOp(branchDestructor, le)))
|
result.add newTree(nkIfStmt, newTree(nkElifBranch, notExpr, c.genOp(branchDestructor, le)))
|
||||||
result.add newTree(nkFastAsgn, le, tmp)
|
result.add newTree(nkFastAsgn, le, tmp)
|
||||||
|
|
||||||
proc genWasMoved(c: var Con, n: PNode): PNode =
|
proc genWasMoved(c: var Con, n: PNode): PNode =
|
||||||
result = newNodeI(nkCall, n.info)
|
result = newNodeI(nkCall, n.info)
|
||||||
result.add(newSymNode(createMagic(c.graph, "wasMoved", mWasMoved)))
|
result.add(newSymNode(createMagic(c.graph, c.idgen, "wasMoved", mWasMoved)))
|
||||||
result.add copyTree(n) #mWasMoved does not take the address
|
result.add copyTree(n) #mWasMoved does not take the address
|
||||||
#if n.kind != nkSym:
|
#if n.kind != nkSym:
|
||||||
# message(c.graph.config, n.info, warnUser, "wasMoved(" & $n & ")")
|
# message(c.graph.config, n.info, warnUser, "wasMoved(" & $n & ")")
|
||||||
|
|
||||||
proc genDefaultCall(t: PType; c: Con; info: TLineInfo): PNode =
|
proc genDefaultCall(t: PType; c: Con; info: TLineInfo): PNode =
|
||||||
result = newNodeI(nkCall, info)
|
result = newNodeI(nkCall, info)
|
||||||
result.add(newSymNode(createMagic(c.graph, "default", mDefault)))
|
result.add(newSymNode(createMagic(c.graph, c.idgen, "default", mDefault)))
|
||||||
result.typ = t
|
result.typ = t
|
||||||
|
|
||||||
proc destructiveMoveVar(n: PNode; c: var Con; s: var Scope): PNode =
|
proc destructiveMoveVar(n: PNode; c: var Con; s: var Scope): PNode =
|
||||||
|
|
|
||||||
|
|
@ -70,16 +70,19 @@ proc newAsgnStmt(le, ri: PNode): PNode =
|
||||||
result[0] = le
|
result[0] = le
|
||||||
result[1] = ri
|
result[1] = ri
|
||||||
|
|
||||||
proc genBuiltin*(g: ModuleGraph; magic: TMagic; name: string; i: PNode): PNode =
|
proc genBuiltin*(g: ModuleGraph; idgen: IdGenerator; magic: TMagic; name: string; i: PNode): PNode =
|
||||||
result = newNodeI(nkCall, i.info)
|
result = newNodeI(nkCall, i.info)
|
||||||
result.add createMagic(g, name, magic).newSymNode
|
result.add createMagic(g, idgen, name, magic).newSymNode
|
||||||
result.add i
|
result.add i
|
||||||
|
|
||||||
|
proc genBuiltin(c: var TLiftCtx; magic: TMagic; name: string; i: PNode): PNode =
|
||||||
|
result = genBuiltin(c.g, c.idgen, magic, name, i)
|
||||||
|
|
||||||
proc defaultOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
proc defaultOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||||
if c.kind in {attachedAsgn, attachedDeepCopy, attachedSink}:
|
if c.kind in {attachedAsgn, attachedDeepCopy, attachedSink}:
|
||||||
body.add newAsgnStmt(x, y)
|
body.add newAsgnStmt(x, y)
|
||||||
elif c.kind == attachedDestructor and c.addMemReset:
|
elif c.kind == attachedDestructor and c.addMemReset:
|
||||||
let call = genBuiltin(c.g, mDefault, "default", x)
|
let call = genBuiltin(c, mDefault, "default", x)
|
||||||
call.typ = t
|
call.typ = t
|
||||||
body.add newAsgnStmt(x, call)
|
body.add newAsgnStmt(x, call)
|
||||||
|
|
||||||
|
|
@ -93,7 +96,7 @@ proc genAddr(c: var TLiftCtx; x: PNode): PNode =
|
||||||
|
|
||||||
proc genWhileLoop(c: var TLiftCtx; i, dest: PNode): PNode =
|
proc genWhileLoop(c: var TLiftCtx; i, dest: PNode): PNode =
|
||||||
result = newNodeI(nkWhileStmt, c.info, 2)
|
result = newNodeI(nkWhileStmt, c.info, 2)
|
||||||
let cmp = genBuiltin(c.g, mLtI, "<", i)
|
let cmp = genBuiltin(c, mLtI, "<", i)
|
||||||
cmp.add genLen(c.g, dest)
|
cmp.add genLen(c.g, dest)
|
||||||
cmp.typ = getSysType(c.g, c.info, tyBool)
|
cmp.typ = getSysType(c.g, c.info, tyBool)
|
||||||
result[0] = cmp
|
result[0] = cmp
|
||||||
|
|
@ -116,10 +119,10 @@ proc genContainerOf(c: var TLiftCtx; objType: PType, field, x: PSym): PNode =
|
||||||
dotExpr.add newNodeIT(nkType, c.info, objType)
|
dotExpr.add newNodeIT(nkType, c.info, objType)
|
||||||
dotExpr.add newSymNode(field)
|
dotExpr.add newSymNode(field)
|
||||||
|
|
||||||
let offsetOf = genBuiltin(c.g, mOffsetOf, "offsetof", dotExpr)
|
let offsetOf = genBuiltin(c, mOffsetOf, "offsetof", dotExpr)
|
||||||
offsetOf.typ = intType
|
offsetOf.typ = intType
|
||||||
|
|
||||||
let minusExpr = genBuiltin(c.g, mSubI, "-", castExpr1)
|
let minusExpr = genBuiltin(c, mSubI, "-", castExpr1)
|
||||||
minusExpr.typ = intType
|
minusExpr.typ = intType
|
||||||
minusExpr.add offsetOf
|
minusExpr.add offsetOf
|
||||||
|
|
||||||
|
|
@ -135,7 +138,7 @@ proc destructorCall(c: var TLiftCtx; op: PSym; x: PNode): PNode =
|
||||||
if sfNeverRaises notin op.flags:
|
if sfNeverRaises notin op.flags:
|
||||||
c.canRaise = true
|
c.canRaise = true
|
||||||
if c.addMemReset:
|
if c.addMemReset:
|
||||||
result = newTree(nkStmtList, destroy, genBuiltin(c.g, mWasMoved, "wasMoved", x))
|
result = newTree(nkStmtList, destroy, genBuiltin(c, mWasMoved, "wasMoved", x))
|
||||||
else:
|
else:
|
||||||
result = destroy
|
result = destroy
|
||||||
|
|
||||||
|
|
@ -237,7 +240,7 @@ proc fillBodyObjT(c: var TLiftCtx; t: PType, body, x, y: PNode) =
|
||||||
#body.add newAsgnStmt(blob, x)
|
#body.add newAsgnStmt(blob, x)
|
||||||
|
|
||||||
var wasMovedCall = newNodeI(nkCall, c.info)
|
var wasMovedCall = newNodeI(nkCall, c.info)
|
||||||
wasMovedCall.add(newSymNode(createMagic(c.g, "wasMoved", mWasMoved)))
|
wasMovedCall.add(newSymNode(createMagic(c.g, c.idgen, "wasMoved", mWasMoved)))
|
||||||
wasMovedCall.add x # mWasMoved does not take the address
|
wasMovedCall.add x # mWasMoved does not take the address
|
||||||
body.add wasMovedCall
|
body.add wasMovedCall
|
||||||
|
|
||||||
|
|
@ -443,25 +446,25 @@ proc declareTempOf(c: var TLiftCtx; body: PNode; value: PNode): PNode =
|
||||||
body.add v
|
body.add v
|
||||||
|
|
||||||
proc addIncStmt(c: var TLiftCtx; body, i: PNode) =
|
proc addIncStmt(c: var TLiftCtx; body, i: PNode) =
|
||||||
let incCall = genBuiltin(c.g, mInc, "inc", i)
|
let incCall = genBuiltin(c, mInc, "inc", i)
|
||||||
incCall.add lowerings.newIntLit(c.g, c.info, 1)
|
incCall.add lowerings.newIntLit(c.g, c.info, 1)
|
||||||
body.add incCall
|
body.add incCall
|
||||||
|
|
||||||
proc newSeqCall(g: ModuleGraph; x, y: PNode): PNode =
|
proc newSeqCall(c: var TLiftCtx; x, y: PNode): PNode =
|
||||||
# don't call genAddr(c, x) here:
|
# don't call genAddr(c, x) here:
|
||||||
result = genBuiltin(g, mNewSeq, "newSeq", x)
|
result = genBuiltin(c, mNewSeq, "newSeq", x)
|
||||||
let lenCall = genBuiltin(g, mLengthSeq, "len", y)
|
let lenCall = genBuiltin(c, mLengthSeq, "len", y)
|
||||||
lenCall.typ = getSysType(g, x.info, tyInt)
|
lenCall.typ = getSysType(c.g, x.info, tyInt)
|
||||||
result.add lenCall
|
result.add lenCall
|
||||||
|
|
||||||
proc setLenStrCall(g: ModuleGraph; x, y: PNode): PNode =
|
proc setLenStrCall(c: var TLiftCtx; x, y: PNode): PNode =
|
||||||
let lenCall = genBuiltin(g, mLengthStr, "len", y)
|
let lenCall = genBuiltin(c, mLengthStr, "len", y)
|
||||||
lenCall.typ = getSysType(g, x.info, tyInt)
|
lenCall.typ = getSysType(c.g, x.info, tyInt)
|
||||||
result = genBuiltin(g, mSetLengthStr, "setLen", x) # genAddr(g, x))
|
result = genBuiltin(c, mSetLengthStr, "setLen", x) # genAddr(g, x))
|
||||||
result.add lenCall
|
result.add lenCall
|
||||||
|
|
||||||
proc setLenSeqCall(c: var TLiftCtx; t: PType; x, y: PNode): PNode =
|
proc setLenSeqCall(c: var TLiftCtx; t: PType; x, y: PNode): PNode =
|
||||||
let lenCall = genBuiltin(c.g, mLengthSeq, "len", y)
|
let lenCall = genBuiltin(c, mLengthSeq, "len", y)
|
||||||
lenCall.typ = getSysType(c.g, x.info, tyInt)
|
lenCall.typ = getSysType(c.g, x.info, tyInt)
|
||||||
var op = getSysMagic(c.g, x.info, "setLen", mSetLengthSeq)
|
var op = getSysMagic(c.g, x.info, "setLen", mSetLengthSeq)
|
||||||
op = instantiateGeneric(c, op, t, t)
|
op = instantiateGeneric(c, op, t, t)
|
||||||
|
|
@ -487,7 +490,7 @@ proc fillSeqOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||||
body.add setLenSeqCall(c, t, x, y)
|
body.add setLenSeqCall(c, t, x, y)
|
||||||
forallElements(c, t, body, x, y)
|
forallElements(c, t, body, x, y)
|
||||||
of attachedSink:
|
of attachedSink:
|
||||||
let moveCall = genBuiltin(c.g, mMove, "move", x)
|
let moveCall = genBuiltin(c, mMove, "move", x)
|
||||||
moveCall.add y
|
moveCall.add y
|
||||||
doAssert t.destructor != nil
|
doAssert t.destructor != nil
|
||||||
moveCall.add destructorCall(c, t.destructor, x)
|
moveCall.add destructorCall(c, t.destructor, x)
|
||||||
|
|
@ -495,13 +498,13 @@ proc fillSeqOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||||
of attachedDestructor:
|
of attachedDestructor:
|
||||||
# destroy all elements:
|
# destroy all elements:
|
||||||
forallElements(c, t, body, x, y)
|
forallElements(c, t, body, x, y)
|
||||||
body.add genBuiltin(c.g, mDestroy, "destroy", x)
|
body.add genBuiltin(c, mDestroy, "destroy", x)
|
||||||
of attachedTrace:
|
of attachedTrace:
|
||||||
# follow all elements:
|
# follow all elements:
|
||||||
forallElements(c, t, body, x, y)
|
forallElements(c, t, body, x, y)
|
||||||
of attachedDispose:
|
of attachedDispose:
|
||||||
forallElements(c, t, body, x, y)
|
forallElements(c, t, body, x, y)
|
||||||
body.add genBuiltin(c.g, mDestroy, "destroy", x)
|
body.add genBuiltin(c, mDestroy, "destroy", x)
|
||||||
|
|
||||||
proc useSeqOrStrOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
proc useSeqOrStrOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||||
createTypeBoundOps(c.g, c.c, t, body.info, c.idgen)
|
createTypeBoundOps(c.g, c.c, t, body.info, c.idgen)
|
||||||
|
|
@ -521,7 +524,7 @@ proc useSeqOrStrOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||||
body.add newHookCall(c, t.assignment, x, y)
|
body.add newHookCall(c, t.assignment, x, y)
|
||||||
of attachedSink:
|
of attachedSink:
|
||||||
# we always inline the move for better performance:
|
# we always inline the move for better performance:
|
||||||
let moveCall = genBuiltin(c.g, mMove, "move", x)
|
let moveCall = genBuiltin(c, mMove, "move", x)
|
||||||
moveCall.add y
|
moveCall.add y
|
||||||
doAssert t.destructor != nil
|
doAssert t.destructor != nil
|
||||||
moveCall.add destructorCall(c, t.destructor, x)
|
moveCall.add destructorCall(c, t.destructor, x)
|
||||||
|
|
@ -549,13 +552,13 @@ proc fillStrOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||||
of attachedAsgn, attachedDeepCopy:
|
of attachedAsgn, attachedDeepCopy:
|
||||||
body.add callCodegenProc(c.g, "nimAsgnStrV2", c.info, genAddr(c, x), y)
|
body.add callCodegenProc(c.g, "nimAsgnStrV2", c.info, genAddr(c, x), y)
|
||||||
of attachedSink:
|
of attachedSink:
|
||||||
let moveCall = genBuiltin(c.g, mMove, "move", x)
|
let moveCall = genBuiltin(c, mMove, "move", x)
|
||||||
moveCall.add y
|
moveCall.add y
|
||||||
doAssert t.destructor != nil
|
doAssert t.destructor != nil
|
||||||
moveCall.add destructorCall(c, t.destructor, x)
|
moveCall.add destructorCall(c, t.destructor, x)
|
||||||
body.add moveCall
|
body.add moveCall
|
||||||
of attachedDestructor, attachedDispose:
|
of attachedDestructor, attachedDispose:
|
||||||
body.add genBuiltin(c.g, mDestroy, "destroy", x)
|
body.add genBuiltin(c, mDestroy, "destroy", x)
|
||||||
of attachedTrace:
|
of attachedTrace:
|
||||||
discard "strings are atomic and have no inner elements that are to trace"
|
discard "strings are atomic and have no inner elements that are to trace"
|
||||||
|
|
||||||
|
|
@ -599,7 +602,7 @@ proc atomicRefOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||||
|
|
||||||
if isFinal(elemType):
|
if isFinal(elemType):
|
||||||
addDestructorCall(c, elemType, actions, genDeref(tmp, nkDerefExpr))
|
addDestructorCall(c, elemType, actions, genDeref(tmp, nkDerefExpr))
|
||||||
var alignOf = genBuiltin(c.g, mAlignOf, "alignof", newNodeIT(nkType, c.info, elemType))
|
var alignOf = genBuiltin(c, mAlignOf, "alignof", newNodeIT(nkType, c.info, elemType))
|
||||||
alignOf.typ = getSysType(c.g, c.info, tyInt)
|
alignOf.typ = getSysType(c.g, c.info, tyInt)
|
||||||
actions.add callCodegenProc(c.g, "nimRawDispose", c.info, tmp, alignOf)
|
actions.add callCodegenProc(c.g, "nimRawDispose", c.info, tmp, alignOf)
|
||||||
else:
|
else:
|
||||||
|
|
@ -609,7 +612,7 @@ proc atomicRefOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||||
var cond: PNode
|
var cond: PNode
|
||||||
if isCyclic:
|
if isCyclic:
|
||||||
if isFinal(elemType):
|
if isFinal(elemType):
|
||||||
let typInfo = genBuiltin(c.g, mGetTypeInfoV2, "getTypeInfoV2", newNodeIT(nkType, x.info, elemType))
|
let typInfo = genBuiltin(c, mGetTypeInfoV2, "getTypeInfoV2", newNodeIT(nkType, x.info, elemType))
|
||||||
typInfo.typ = getSysType(c.g, c.info, tyPointer)
|
typInfo.typ = getSysType(c.g, c.info, tyPointer)
|
||||||
cond = callCodegenProc(c.g, "nimDecRefIsLastCyclicStatic", c.info, tmp, typInfo)
|
cond = callCodegenProc(c.g, "nimDecRefIsLastCyclicStatic", c.info, tmp, typInfo)
|
||||||
else:
|
else:
|
||||||
|
|
@ -641,7 +644,7 @@ proc atomicRefOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||||
of attachedDeepCopy: assert(false, "cannot happen")
|
of attachedDeepCopy: assert(false, "cannot happen")
|
||||||
of attachedTrace:
|
of attachedTrace:
|
||||||
if isFinal(elemType):
|
if isFinal(elemType):
|
||||||
let typInfo = genBuiltin(c.g, mGetTypeInfoV2, "getTypeInfoV2", newNodeIT(nkType, x.info, elemType))
|
let typInfo = genBuiltin(c, mGetTypeInfoV2, "getTypeInfoV2", newNodeIT(nkType, x.info, elemType))
|
||||||
typInfo.typ = getSysType(c.g, c.info, tyPointer)
|
typInfo.typ = getSysType(c.g, c.info, tyPointer)
|
||||||
body.add callCodegenProc(c.g, "nimTraceRef", c.info, genAddrOf(x, c.idgen), typInfo, y)
|
body.add callCodegenProc(c.g, "nimTraceRef", c.info, genAddrOf(x, c.idgen), typInfo, y)
|
||||||
else:
|
else:
|
||||||
|
|
@ -659,7 +662,7 @@ proc atomicRefOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||||
proc atomicClosureOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
proc atomicClosureOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||||
## Closures are really like refs except they always use a virtual destructor
|
## Closures are really like refs except they always use a virtual destructor
|
||||||
## and we need to do the refcounting only on the ref field which we call 'xenv':
|
## and we need to do the refcounting only on the ref field which we call 'xenv':
|
||||||
let xenv = genBuiltin(c.g, mAccessEnv, "accessEnv", x)
|
let xenv = genBuiltin(c, mAccessEnv, "accessEnv", x)
|
||||||
xenv.typ = getSysType(c.g, c.info, tyPointer)
|
xenv.typ = getSysType(c.g, c.info, tyPointer)
|
||||||
|
|
||||||
let isCyclic = c.g.config.selectedGC == gcOrc
|
let isCyclic = c.g.config.selectedGC == gcOrc
|
||||||
|
|
@ -687,7 +690,7 @@ proc atomicClosureOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||||
body.add genIf(c, cond, actions)
|
body.add genIf(c, cond, actions)
|
||||||
body.add newAsgnStmt(x, y)
|
body.add newAsgnStmt(x, y)
|
||||||
of attachedAsgn:
|
of attachedAsgn:
|
||||||
let yenv = genBuiltin(c.g, mAccessEnv, "accessEnv", y)
|
let yenv = genBuiltin(c, mAccessEnv, "accessEnv", y)
|
||||||
yenv.typ = getSysType(c.g, c.info, tyPointer)
|
yenv.typ = getSysType(c.g, c.info, tyPointer)
|
||||||
if isCyclic:
|
if isCyclic:
|
||||||
body.add genIf(c, yenv, callCodegenProc(c.g, "nimIncRefCyclic", c.info, yenv, getCycleParam(c)))
|
body.add genIf(c, yenv, callCodegenProc(c.g, "nimIncRefCyclic", c.info, yenv, getCycleParam(c)))
|
||||||
|
|
@ -741,11 +744,11 @@ proc ownedRefOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||||
|
|
||||||
let elemType = t.lastSon
|
let elemType = t.lastSon
|
||||||
#fillBody(c, elemType, actions, genDeref(x), genDeref(y))
|
#fillBody(c, elemType, actions, genDeref(x), genDeref(y))
|
||||||
#var disposeCall = genBuiltin(c.g, mDispose, "dispose", x)
|
#var disposeCall = genBuiltin(c, mDispose, "dispose", x)
|
||||||
|
|
||||||
if isFinal(elemType):
|
if isFinal(elemType):
|
||||||
addDestructorCall(c, elemType, actions, genDeref(x, nkDerefExpr))
|
addDestructorCall(c, elemType, actions, genDeref(x, nkDerefExpr))
|
||||||
var alignOf = genBuiltin(c.g, mAlignOf, "alignof", newNodeIT(nkType, c.info, elemType))
|
var alignOf = genBuiltin(c, mAlignOf, "alignof", newNodeIT(nkType, c.info, elemType))
|
||||||
alignOf.typ = getSysType(c.g, c.info, tyInt)
|
alignOf.typ = getSysType(c.g, c.info, tyInt)
|
||||||
actions.add callCodegenProc(c.g, "nimRawDispose", c.info, x, alignOf)
|
actions.add callCodegenProc(c.g, "nimRawDispose", c.info, x, alignOf)
|
||||||
else:
|
else:
|
||||||
|
|
@ -767,12 +770,12 @@ proc closureOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||||
# have to go through some indirection; we delegate this to the codegen:
|
# have to go through some indirection; we delegate this to the codegen:
|
||||||
let call = newNodeI(nkCall, c.info, 2)
|
let call = newNodeI(nkCall, c.info, 2)
|
||||||
call.typ = t
|
call.typ = t
|
||||||
call[0] = newSymNode(createMagic(c.g, "deepCopy", mDeepCopy))
|
call[0] = newSymNode(createMagic(c.g, c.idgen, "deepCopy", mDeepCopy))
|
||||||
call[1] = y
|
call[1] = y
|
||||||
body.add newAsgnStmt(x, call)
|
body.add newAsgnStmt(x, call)
|
||||||
elif (optOwnedRefs in c.g.config.globalOptions and
|
elif (optOwnedRefs in c.g.config.globalOptions and
|
||||||
optRefCheck in c.g.config.options) or c.g.config.selectedGC in {gcArc, gcOrc}:
|
optRefCheck in c.g.config.options) or c.g.config.selectedGC in {gcArc, gcOrc}:
|
||||||
let xx = genBuiltin(c.g, mAccessEnv, "accessEnv", x)
|
let xx = genBuiltin(c, mAccessEnv, "accessEnv", x)
|
||||||
xx.typ = getSysType(c.g, c.info, tyPointer)
|
xx.typ = getSysType(c.g, c.info, tyPointer)
|
||||||
case c.kind
|
case c.kind
|
||||||
of attachedSink:
|
of attachedSink:
|
||||||
|
|
@ -781,7 +784,7 @@ proc closureOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||||
body.add genIf(c, xx, callCodegenProc(c.g, "nimDecWeakRef", c.info, xx))
|
body.add genIf(c, xx, callCodegenProc(c.g, "nimDecWeakRef", c.info, xx))
|
||||||
body.add newAsgnStmt(x, y)
|
body.add newAsgnStmt(x, y)
|
||||||
of attachedAsgn:
|
of attachedAsgn:
|
||||||
let yy = genBuiltin(c.g, mAccessEnv, "accessEnv", y)
|
let yy = genBuiltin(c, mAccessEnv, "accessEnv", y)
|
||||||
yy.typ = getSysType(c.g, c.info, tyPointer)
|
yy.typ = getSysType(c.g, c.info, tyPointer)
|
||||||
body.add genIf(c, yy, callCodegenProc(c.g, "nimIncRef", c.info, yy))
|
body.add genIf(c, yy, callCodegenProc(c.g, "nimIncRef", c.info, yy))
|
||||||
body.add genIf(c, xx, callCodegenProc(c.g, "nimDecWeakRef", c.info, xx))
|
body.add genIf(c, xx, callCodegenProc(c.g, "nimDecWeakRef", c.info, xx))
|
||||||
|
|
@ -796,7 +799,7 @@ proc closureOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||||
of attachedTrace, attachedDispose: discard
|
of attachedTrace, attachedDispose: discard
|
||||||
|
|
||||||
proc ownedClosureOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
proc ownedClosureOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||||
let xx = genBuiltin(c.g, mAccessEnv, "accessEnv", x)
|
let xx = genBuiltin(c, mAccessEnv, "accessEnv", x)
|
||||||
xx.typ = getSysType(c.g, c.info, tyPointer)
|
xx.typ = getSysType(c.g, c.info, tyPointer)
|
||||||
var actions = newNodeI(nkStmtList, c.info)
|
var actions = newNodeI(nkStmtList, c.info)
|
||||||
#discard addDestructorCall(c, elemType, newNodeI(nkStmtList, c.info), genDeref(xx))
|
#discard addDestructorCall(c, elemType, newNodeI(nkStmtList, c.info), genDeref(xx))
|
||||||
|
|
@ -859,7 +862,7 @@ proc fillBody(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||||
discard considerUserDefinedOp(c, t, body, x, y)
|
discard considerUserDefinedOp(c, t, body, x, y)
|
||||||
elif tfHasAsgn in t.flags:
|
elif tfHasAsgn in t.flags:
|
||||||
if c.kind in {attachedAsgn, attachedSink, attachedDeepCopy}:
|
if c.kind in {attachedAsgn, attachedSink, attachedDeepCopy}:
|
||||||
body.add newSeqCall(c.g, x, y)
|
body.add newSeqCall(c, x, y)
|
||||||
forallElements(c, t, body, x, y)
|
forallElements(c, t, body, x, y)
|
||||||
else:
|
else:
|
||||||
defaultOp(c, t, body, x, y)
|
defaultOp(c, t, body, x, y)
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,10 @@ type
|
||||||
warnLockLevel = "LockLevel", warnResultShadowed = "ResultShadowed",
|
warnLockLevel = "LockLevel", warnResultShadowed = "ResultShadowed",
|
||||||
warnInconsistentSpacing = "Spacing", warnCaseTransition = "CaseTransition",
|
warnInconsistentSpacing = "Spacing", warnCaseTransition = "CaseTransition",
|
||||||
warnCycleCreated = "CycleCreated", warnObservableStores = "ObservableStores",
|
warnCycleCreated = "CycleCreated", warnObservableStores = "ObservableStores",
|
||||||
warnUser = "User", warnStrictNotNil = "StrictNotNil",
|
warnStrictNotNil = "StrictNotNil",
|
||||||
|
warnCannotOpen = "CannotOpen",
|
||||||
|
warnFileChanged = "FileChanged",
|
||||||
|
warnUser = "User",
|
||||||
|
|
||||||
hintSuccess = "Success", hintSuccessX = "SuccessX", hintCC = "CC",
|
hintSuccess = "Success", hintSuccessX = "SuccessX", hintCC = "CC",
|
||||||
hintLineTooLong = "LineTooLong", hintXDeclaredButNotUsed = "XDeclaredButNotUsed",
|
hintLineTooLong = "LineTooLong", hintXDeclaredButNotUsed = "XDeclaredButNotUsed",
|
||||||
|
|
@ -133,8 +136,10 @@ const
|
||||||
warnCaseTransition: "Potential object case transition, instantiate new object instead",
|
warnCaseTransition: "Potential object case transition, instantiate new object instead",
|
||||||
warnCycleCreated: "$1",
|
warnCycleCreated: "$1",
|
||||||
warnObservableStores: "observable stores to '$1'",
|
warnObservableStores: "observable stores to '$1'",
|
||||||
warnUser: "$1",
|
|
||||||
warnStrictNotNil: "$1",
|
warnStrictNotNil: "$1",
|
||||||
|
warnCannotOpen: "cannot open: $1",
|
||||||
|
warnFileChanged: "file changed: $1",
|
||||||
|
warnUser: "$1",
|
||||||
hintSuccess: "operation successful: $#",
|
hintSuccess: "operation successful: $#",
|
||||||
# keep in sync with `testament.isSuccess`
|
# keep in sync with `testament.isSuccess`
|
||||||
hintSuccessX: "${loc} lines; ${sec}s; $mem; $build build; proj: $project; out: $output",
|
hintSuccessX: "${loc} lines; ${sec}s; $mem; $build build; proj: $project; out: $output",
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ import
|
||||||
modulegraphs, tables, lineinfos, pathutils, vmprofiler
|
modulegraphs, tables, lineinfos, pathutils, vmprofiler
|
||||||
|
|
||||||
import ic / cbackend
|
import ic / cbackend
|
||||||
from ic / to_packed_ast import rodViewer
|
from ic / ic import rodViewer
|
||||||
|
|
||||||
when not defined(leanCompiler):
|
when not defined(leanCompiler):
|
||||||
import jsgen, docgen, docgen2
|
import jsgen, docgen, docgen2
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,9 @@
|
||||||
## or stored in a rod-file.
|
## or stored in a rod-file.
|
||||||
|
|
||||||
import ast, astalgo, intsets, tables, options, lineinfos, hashes, idents,
|
import ast, astalgo, intsets, tables, options, lineinfos, hashes, idents,
|
||||||
btrees, md5
|
btrees, md5, ropes, msgs
|
||||||
|
|
||||||
import ic / [packed_ast, to_packed_ast]
|
import ic / [packed_ast, ic]
|
||||||
|
|
||||||
type
|
type
|
||||||
SigHash* = distinct MD5Digest
|
SigHash* = distinct MD5Digest
|
||||||
|
|
@ -30,6 +30,7 @@ type
|
||||||
patterns*: seq[LazySym]
|
patterns*: seq[LazySym]
|
||||||
pureEnums*: seq[LazySym]
|
pureEnums*: seq[LazySym]
|
||||||
interf: TStrTable
|
interf: TStrTable
|
||||||
|
uniqueName*: Rope
|
||||||
|
|
||||||
Operators* = object
|
Operators* = object
|
||||||
opNot*, opContains*, opLe*, opLt*, opAnd*, opOr*, opIsNil*, opEq*: PSym
|
opNot*, opContains*, opLe*, opLt*, opAnd*, opOr*, opIsNil*, opEq*: PSym
|
||||||
|
|
@ -117,6 +118,15 @@ type
|
||||||
close: TPassClose,
|
close: TPassClose,
|
||||||
isFrontend: bool]
|
isFrontend: bool]
|
||||||
|
|
||||||
|
proc resetForBackend*(g: ModuleGraph) =
|
||||||
|
initStrTable(g.compilerprocs)
|
||||||
|
g.typeInstCache.clear()
|
||||||
|
g.procInstCache.clear()
|
||||||
|
for a in mitems(g.attachedOps):
|
||||||
|
a.clear()
|
||||||
|
g.methodsPerType.clear()
|
||||||
|
g.enumToStringProcs.clear()
|
||||||
|
|
||||||
const
|
const
|
||||||
cb64 = [
|
cb64 = [
|
||||||
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N",
|
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N",
|
||||||
|
|
@ -169,7 +179,7 @@ proc initEncoder*(g: ModuleGraph; module: PSym) =
|
||||||
let id = module.position
|
let id = module.position
|
||||||
if id >= g.encoders.len:
|
if id >= g.encoders.len:
|
||||||
setLen g.encoders, id+1
|
setLen g.encoders, id+1
|
||||||
to_packed_ast.initEncoder(g.encoders[id],
|
ic.initEncoder(g.encoders[id],
|
||||||
g.packed[id].fromDisk, module, g.config, g.startupPackedConfig)
|
g.packed[id].fromDisk, module, g.config, g.startupPackedConfig)
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
@ -359,11 +369,14 @@ else:
|
||||||
proc stopCompile*(g: ModuleGraph): bool {.inline.} =
|
proc stopCompile*(g: ModuleGraph): bool {.inline.} =
|
||||||
result = g.doStopCompile != nil and g.doStopCompile()
|
result = g.doStopCompile != nil and g.doStopCompile()
|
||||||
|
|
||||||
proc createMagic*(g: ModuleGraph; name: string, m: TMagic): PSym =
|
proc createMagic*(g: ModuleGraph; idgen: IdGenerator; name: string, m: TMagic): PSym =
|
||||||
result = newSym(skProc, getIdent(g.cache, name), nextSymId(g.idgen), nil, unknownLineInfo, {})
|
result = newSym(skProc, getIdent(g.cache, name), nextSymId(idgen), nil, unknownLineInfo, {})
|
||||||
result.magic = m
|
result.magic = m
|
||||||
result.flags = {sfNeverRaises}
|
result.flags = {sfNeverRaises}
|
||||||
|
|
||||||
|
proc createMagic(g: ModuleGraph; name: string, m: TMagic): PSym =
|
||||||
|
result = createMagic(g, g.idgen, name, m)
|
||||||
|
|
||||||
proc registerModule*(g: ModuleGraph; m: PSym) =
|
proc registerModule*(g: ModuleGraph; m: PSym) =
|
||||||
assert m != nil
|
assert m != nil
|
||||||
assert m.kind == skModule
|
assert m.kind == skModule
|
||||||
|
|
@ -374,9 +387,13 @@ proc registerModule*(g: ModuleGraph; m: PSym) =
|
||||||
if m.position >= g.packed.len:
|
if m.position >= g.packed.len:
|
||||||
setLen(g.packed, m.position + 1)
|
setLen(g.packed, m.position + 1)
|
||||||
|
|
||||||
g.ifaces[m.position] = Iface(module: m, converters: @[], patterns: @[])
|
g.ifaces[m.position] = Iface(module: m, converters: @[], patterns: @[],
|
||||||
|
uniqueName: rope(uniqueModuleName(g.config, FileIndex(m.position))))
|
||||||
initStrTable(g.ifaces[m.position].interf)
|
initStrTable(g.ifaces[m.position].interf)
|
||||||
|
|
||||||
|
proc registerModuleById*(g: ModuleGraph; m: FileIndex) =
|
||||||
|
registerModule(g, g.packed[int m].module)
|
||||||
|
|
||||||
proc initOperators(g: ModuleGraph): Operators =
|
proc initOperators(g: ModuleGraph): Operators =
|
||||||
# These are safe for IC.
|
# These are safe for IC.
|
||||||
result.opLe = createMagic(g, "<=", mLeI)
|
result.opLe = createMagic(g, "<=", mLeI)
|
||||||
|
|
|
||||||
|
|
@ -109,6 +109,7 @@ proc compileModule*(graph: ModuleGraph; fileIdx: FileIndex; flags: TSymFlags): P
|
||||||
graph.systemModule = result
|
graph.systemModule = result
|
||||||
partialInitModule(result, graph, fileIdx, filename)
|
partialInitModule(result, graph, fileIdx, filename)
|
||||||
for m in cachedModules:
|
for m in cachedModules:
|
||||||
|
registerModuleById(graph, m)
|
||||||
replayStateChanges(graph.packed[m.int].module, graph)
|
replayStateChanges(graph.packed[m.int].module, graph)
|
||||||
replayGenericCacheInformation(graph, m.int)
|
replayGenericCacheInformation(graph, m.int)
|
||||||
elif graph.isDirty(result):
|
elif graph.isDirty(result):
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,7 @@ proc fileInfoIdx*(conf: ConfigRef; filename: AbsoluteFile; isKnownFile: var bool
|
||||||
else:
|
else:
|
||||||
isKnownFile = false
|
isKnownFile = false
|
||||||
result = conf.m.fileInfos.len.FileIndex
|
result = conf.m.fileInfos.len.FileIndex
|
||||||
|
#echo "ID ", result.int, " ", canon2
|
||||||
conf.m.fileInfos.add(newFileInfo(canon, if pseudoPath: RelativeFile filename
|
conf.m.fileInfos.add(newFileInfo(canon, if pseudoPath: RelativeFile filename
|
||||||
else: relativeTo(canon, conf.projectPath)))
|
else: relativeTo(canon, conf.projectPath)))
|
||||||
conf.m.filenameToIndexTbl[canon2] = result
|
conf.m.filenameToIndexTbl[canon2] = result
|
||||||
|
|
@ -630,3 +631,28 @@ template listMsg(title, r) =
|
||||||
|
|
||||||
proc listWarnings*(conf: ConfigRef) = listMsg("Warnings:", warnMin..warnMax)
|
proc listWarnings*(conf: ConfigRef) = listMsg("Warnings:", warnMin..warnMax)
|
||||||
proc listHints*(conf: ConfigRef) = listMsg("Hints:", hintMin..hintMax)
|
proc listHints*(conf: ConfigRef) = listMsg("Hints:", hintMin..hintMax)
|
||||||
|
|
||||||
|
proc uniqueModuleName*(conf: ConfigRef; fid: FileIndex): string =
|
||||||
|
## The unique module name is guaranteed to only contain {'A'..'Z', 'a'..'z', '0'..'9', '_'}
|
||||||
|
## so that it is useful as a C identifier snippet.
|
||||||
|
let path = AbsoluteFile toFullPath(conf, fid)
|
||||||
|
let rel =
|
||||||
|
if path.string.startsWith(conf.libpath.string):
|
||||||
|
relativeTo(path, conf.libpath).string
|
||||||
|
else:
|
||||||
|
relativeTo(path, conf.projectPath).string
|
||||||
|
let trunc = if rel.endsWith(".nim"): rel.len - len(".nim") else: rel.len
|
||||||
|
result = newStringOfCap(trunc)
|
||||||
|
for i in 0..<trunc:
|
||||||
|
let c = rel[i]
|
||||||
|
case c
|
||||||
|
of 'a'..'z':
|
||||||
|
result.add c
|
||||||
|
of {os.DirSep, os.AltSep}:
|
||||||
|
result.add 'Z' # because it looks a bit like '/'
|
||||||
|
of '.':
|
||||||
|
result.add 'O' # a circle
|
||||||
|
else:
|
||||||
|
# We mangle upper letters and digits too so that there cannot
|
||||||
|
# be clashes with our special meanings of 'Z' and 'O'
|
||||||
|
result.addInt ord(c)
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import
|
||||||
wordrecg, ropes, options, strutils, extccomp, math, magicsys, trees,
|
wordrecg, ropes, options, strutils, extccomp, math, magicsys, trees,
|
||||||
types, lookups, lineinfos, pathutils, linter
|
types, lookups, lineinfos, pathutils, linter
|
||||||
|
|
||||||
from ic / to_packed_ast import addCompilerProc
|
from ic / ic import addCompilerProc
|
||||||
|
|
||||||
const
|
const
|
||||||
FirstCallConv* = wNimcall
|
FirstCallConv* = wNimcall
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ import
|
||||||
intsets, options, ast, astalgo, msgs, idents, renderer,
|
intsets, options, ast, astalgo, msgs, idents, renderer,
|
||||||
magicsys, vmdef, modulegraphs, lineinfos, sets, pathutils
|
magicsys, vmdef, modulegraphs, lineinfos, sets, pathutils
|
||||||
|
|
||||||
import ic / to_packed_ast
|
import ic / ic
|
||||||
|
|
||||||
type
|
type
|
||||||
TOptionEntry* = object # entries to put on a stack for pragma parsing
|
TOptionEntry* = object # entries to put on a stack for pragma parsing
|
||||||
|
|
|
||||||
|
|
@ -2099,7 +2099,7 @@ proc semQuoteAst(c: PContext, n: PNode): PNode =
|
||||||
identNodeSym.newSymNode
|
identNodeSym.newSymNode
|
||||||
quotes[1] = newTreeI(nkCall, n.info, identNode, newStrNode(nkStrLit, "result"))
|
quotes[1] = newTreeI(nkCall, n.info, identNode, newStrNode(nkStrLit, "result"))
|
||||||
result = newTreeI(nkCall, n.info,
|
result = newTreeI(nkCall, n.info,
|
||||||
createMagic(c.graph, "getAst", mExpandToAst).newSymNode,
|
createMagic(c.graph, c.idgen, "getAst", mExpandToAst).newSymNode,
|
||||||
newTreeI(nkCall, n.info, quotes))
|
newTreeI(nkCall, n.info, quotes))
|
||||||
result = semExpandToAst(c, result)
|
result = semExpandToAst(c, result)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -397,12 +397,12 @@ proc analyse(c: var AnalysisCtx; n: PNode) =
|
||||||
else:
|
else:
|
||||||
analyseSons(c, n)
|
analyseSons(c, n)
|
||||||
|
|
||||||
proc transformSlices(g: ModuleGraph; n: PNode): PNode =
|
proc transformSlices(g: ModuleGraph; idgen: IdGenerator; n: PNode): PNode =
|
||||||
if n.kind in nkCallKinds and n[0].kind == nkSym:
|
if n.kind in nkCallKinds and n[0].kind == nkSym:
|
||||||
let op = n[0].sym
|
let op = n[0].sym
|
||||||
if op.name.s == "[]" and op.fromSystem:
|
if op.name.s == "[]" and op.fromSystem:
|
||||||
result = copyNode(n)
|
result = copyNode(n)
|
||||||
let opSlice = newSymNode(createMagic(g, "slice", mSlice))
|
let opSlice = newSymNode(createMagic(g, idgen, "slice", mSlice))
|
||||||
opSlice.typ = getSysType(g, n.info, tyInt)
|
opSlice.typ = getSysType(g, n.info, tyInt)
|
||||||
result.add opSlice
|
result.add opSlice
|
||||||
result.add n[1]
|
result.add n[1]
|
||||||
|
|
@ -413,11 +413,11 @@ proc transformSlices(g: ModuleGraph; n: PNode): PNode =
|
||||||
if n.safeLen > 0:
|
if n.safeLen > 0:
|
||||||
result = shallowCopy(n)
|
result = shallowCopy(n)
|
||||||
for i in 0..<n.len:
|
for i in 0..<n.len:
|
||||||
result[i] = transformSlices(g, n[i])
|
result[i] = transformSlices(g, idgen, n[i])
|
||||||
else:
|
else:
|
||||||
result = n
|
result = n
|
||||||
|
|
||||||
proc transformSpawn(g: ModuleGraph; idgen: IdGenerator;owner: PSym; n, barrier: PNode): PNode
|
proc transformSpawn(g: ModuleGraph; idgen: IdGenerator; owner: PSym; n, barrier: PNode): PNode
|
||||||
proc transformSpawnSons(g: ModuleGraph; idgen: IdGenerator; owner: PSym; n, barrier: PNode): PNode =
|
proc transformSpawnSons(g: ModuleGraph; idgen: IdGenerator; owner: PSym; n, barrier: PNode): PNode =
|
||||||
result = shallowCopy(n)
|
result = shallowCopy(n)
|
||||||
for i in 0..<n.len:
|
for i in 0..<n.len:
|
||||||
|
|
@ -431,7 +431,7 @@ proc transformSpawn(g: ModuleGraph; idgen: IdGenerator; owner: PSym; n, barrier:
|
||||||
let b = it.lastSon
|
let b = it.lastSon
|
||||||
if getMagic(b) == mSpawn:
|
if getMagic(b) == mSpawn:
|
||||||
if it.len != 3: localError(g.config, it.info, "invalid context for 'spawn'")
|
if it.len != 3: localError(g.config, it.info, "invalid context for 'spawn'")
|
||||||
let m = transformSlices(g, b)
|
let m = transformSlices(g, idgen, b)
|
||||||
if result.isNil:
|
if result.isNil:
|
||||||
result = newNodeI(nkStmtList, n.info)
|
result = newNodeI(nkStmtList, n.info)
|
||||||
result.add n
|
result.add n
|
||||||
|
|
@ -446,12 +446,12 @@ proc transformSpawn(g: ModuleGraph; idgen: IdGenerator; owner: PSym; n, barrier:
|
||||||
let b = n[1]
|
let b = n[1]
|
||||||
if getMagic(b) == mSpawn and (let t = b[1][0].typ[0];
|
if getMagic(b) == mSpawn and (let t = b[1][0].typ[0];
|
||||||
spawnResult(t, true) == srByVar):
|
spawnResult(t, true) == srByVar):
|
||||||
let m = transformSlices(g, b)
|
let m = transformSlices(g, idgen, b)
|
||||||
return wrapProcForSpawn(g, idgen, owner, m, b.typ, barrier, n[0])
|
return wrapProcForSpawn(g, idgen, owner, m, b.typ, barrier, n[0])
|
||||||
result = transformSpawnSons(g, idgen, owner, n, barrier)
|
result = transformSpawnSons(g, idgen, owner, n, barrier)
|
||||||
of nkCallKinds:
|
of nkCallKinds:
|
||||||
if getMagic(n) == mSpawn:
|
if getMagic(n) == mSpawn:
|
||||||
result = transformSlices(g, n)
|
result = transformSlices(g, idgen, n)
|
||||||
return wrapProcForSpawn(g, idgen, owner, result, n.typ, barrier, nil)
|
return wrapProcForSpawn(g, idgen, owner, result, n.typ, barrier, nil)
|
||||||
result = transformSpawnSons(g, idgen, owner, n, barrier)
|
result = transformSpawnSons(g, idgen, owner, n, barrier)
|
||||||
elif n.safeLen > 0:
|
elif n.safeLen > 0:
|
||||||
|
|
|
||||||
|
|
@ -245,7 +245,7 @@ proc setupArgsForParallelism(g: ModuleGraph; n: PNode; objType: PType;
|
||||||
# important special case: we always create a zero-copy slice:
|
# important special case: we always create a zero-copy slice:
|
||||||
let slice = newNodeI(nkCall, n.info, 4)
|
let slice = newNodeI(nkCall, n.info, 4)
|
||||||
slice.typ = n.typ
|
slice.typ = n.typ
|
||||||
slice[0] = newSymNode(createMagic(g, "slice", mSlice))
|
slice[0] = newSymNode(createMagic(g, idgen, "slice", mSlice))
|
||||||
slice[0].typ = getSysType(g, n.info, tyInt) # fake type
|
slice[0].typ = getSysType(g, n.info, tyInt) # fake type
|
||||||
var fieldB = newSym(skField, tmpName, nextSymId idgen, objType.owner, n.info, g.config.options)
|
var fieldB = newSym(skField, tmpName, nextSymId idgen, objType.owner, n.info, g.config.options)
|
||||||
fieldB.typ = getSysType(g, n.info, tyInt)
|
fieldB.typ = getSysType(g, n.info, tyInt)
|
||||||
|
|
|
||||||
|
|
@ -439,7 +439,7 @@ func fastlog2Nim(x: uint64): int {.inline.} =
|
||||||
# sets.nim cannot import bitops, but bitops can use include
|
# sets.nim cannot import bitops, but bitops can use include
|
||||||
# system/sets to eliminate code duplication. sets.nim defines
|
# system/sets to eliminate code duplication. sets.nim defines
|
||||||
# countBits32 and countBits64.
|
# countBits32 and countBits64.
|
||||||
include system/sets
|
import system/countbits_impl
|
||||||
|
|
||||||
template countSetBitsNim(n: uint32): int = countBits32(n)
|
template countSetBitsNim(n: uint32): int = countBits32(n)
|
||||||
template countSetBitsNim(n: uint64): int = countBits64(n)
|
template countSetBitsNim(n: uint64): int = countBits64(n)
|
||||||
|
|
|
||||||
|
|
@ -2339,6 +2339,7 @@ when notJSnotNims:
|
||||||
when hostOS != "standalone" and hostOS != "any":
|
when hostOS != "standalone" and hostOS != "any":
|
||||||
include "system/dyncalls"
|
include "system/dyncalls"
|
||||||
|
|
||||||
|
import system/countbits_impl
|
||||||
include "system/sets"
|
include "system/sets"
|
||||||
|
|
||||||
when defined(gogc):
|
when defined(gogc):
|
||||||
|
|
|
||||||
25
lib/system/countbits_impl.nim
Normal file
25
lib/system/countbits_impl.nim
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Nim's Runtime Library
|
||||||
|
# (c) Copyright 2012 Andreas Rumpf
|
||||||
|
#
|
||||||
|
# See the file "copying.txt", included in this
|
||||||
|
# distribution, for details about the copyright.
|
||||||
|
#
|
||||||
|
|
||||||
|
## Contains the used algorithms for counting bits.
|
||||||
|
|
||||||
|
proc countBits32*(n: uint32): int {.compilerproc.} =
|
||||||
|
# generic formula is from: https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
|
||||||
|
var v = uint32(n)
|
||||||
|
v = v - ((v shr 1'u32) and 0x55555555'u32)
|
||||||
|
v = (v and 0x33333333'u32) + ((v shr 2'u32) and 0x33333333'u32)
|
||||||
|
result = (((v + (v shr 4'u32) and 0xF0F0F0F'u32) * 0x1010101'u32) shr 24'u32).int
|
||||||
|
|
||||||
|
proc countBits64*(n: uint64): int {.compilerproc, inline.} =
|
||||||
|
# generic formula is from: https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
|
||||||
|
var v = uint64(n)
|
||||||
|
v = v - ((v shr 1'u64) and 0x5555555555555555'u64)
|
||||||
|
v = (v and 0x3333333333333333'u64) + ((v shr 2'u64) and 0x3333333333333333'u64)
|
||||||
|
v = (v + (v shr 4'u64) and 0x0F0F0F0F0F0F0F0F'u64)
|
||||||
|
result = ((v * 0x0101010101010101'u64) shr 56'u64).int
|
||||||
|
|
@ -567,7 +567,7 @@ when defined(cpp) and appType != "lib" and not gotoBasedExceptions and
|
||||||
type
|
type
|
||||||
StdException {.importcpp: "std::exception", header: "<exception>".} = object
|
StdException {.importcpp: "std::exception", header: "<exception>".} = object
|
||||||
|
|
||||||
proc what(ex: StdException): cstring {.importcpp: "((char *)#.what())".}
|
proc what(ex: StdException): cstring {.importcpp: "((char *)#.what())", nodecl.}
|
||||||
|
|
||||||
proc setTerminate(handler: proc() {.noconv.})
|
proc setTerminate(handler: proc() {.noconv.})
|
||||||
{.importc: "std::set_terminate", header: "<exception>".}
|
{.importc: "std::set_terminate", header: "<exception>".}
|
||||||
|
|
|
||||||
|
|
@ -14,21 +14,6 @@ type
|
||||||
|
|
||||||
# bitops can't be imported here, therefore the code duplication.
|
# bitops can't be imported here, therefore the code duplication.
|
||||||
|
|
||||||
proc countBits32(n: uint32): int {.compilerproc.} =
|
|
||||||
# generic formula is from: https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
|
|
||||||
var v = uint32(n)
|
|
||||||
v = v - ((v shr 1'u32) and 0x55555555'u32)
|
|
||||||
v = (v and 0x33333333'u32) + ((v shr 2'u32) and 0x33333333'u32)
|
|
||||||
result = (((v + (v shr 4'u32) and 0xF0F0F0F'u32) * 0x1010101'u32) shr 24'u32).int
|
|
||||||
|
|
||||||
proc countBits64(n: uint64): int {.compilerproc, inline.} =
|
|
||||||
# generic formula is from: https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
|
|
||||||
var v = uint64(n)
|
|
||||||
v = v - ((v shr 1'u64) and 0x5555555555555555'u64)
|
|
||||||
v = (v and 0x3333333333333333'u64) + ((v shr 2'u64) and 0x3333333333333333'u64)
|
|
||||||
v = (v + (v shr 4'u64) and 0x0F0F0F0F0F0F0F0F'u64)
|
|
||||||
result = ((v * 0x0101010101010101'u64) shr 56'u64).int
|
|
||||||
|
|
||||||
proc cardSet(s: NimSet, len: int): int {.compilerproc, inline.} =
|
proc cardSet(s: NimSet, len: int): int {.compilerproc, inline.} =
|
||||||
var i = 0
|
var i = 0
|
||||||
result = 0
|
result = 0
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,8 @@ proc pkg(name: string; cmd = "nimble test"; url = "", useHead = true) =
|
||||||
|
|
||||||
# pkg "alea"
|
# pkg "alea"
|
||||||
pkg "argparse"
|
pkg "argparse"
|
||||||
pkg "arraymancer", "nim c tests/tests_cpu.nim"
|
when false:
|
||||||
|
pkg "arraymancer", "nim c tests/tests_cpu.nim"
|
||||||
# pkg "ast_pattern_matching", "nim c -r --oldgensym:on tests/test1.nim"
|
# pkg "ast_pattern_matching", "nim c -r --oldgensym:on tests/test1.nim"
|
||||||
pkg "awk"
|
pkg "awk"
|
||||||
pkg "bigints", url = "https://github.com/Araq/nim-bigints"
|
pkg "bigints", url = "https://github.com/Araq/nim-bigints"
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
discard """
|
discard """
|
||||||
disabled: "openbsd"
|
disabled: "true"
|
||||||
output: '''
|
output: '''
|
||||||
main: HELLO!
|
main: HELLO!
|
||||||
main: hasAnyModuleChanged? true
|
main: hasAnyModuleChanged? true
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
discard """
|
discard """
|
||||||
output: "Hello World"
|
output: "Hello World"
|
||||||
disabled: "true"
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
const str = "Hello World"
|
const str = "Hello World"
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
discard """
|
discard """
|
||||||
output: '''
|
output: '''
|
||||||
'''
|
'''
|
||||||
|
|
||||||
ccodeCheck: "\\i ! @'deepCopy(' .*"
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# parallel convex hull for Nim bigbreak
|
# parallel convex hull for Nim bigbreak
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue