mirror of
https://github.com/nim-lang/Nim.git
synced 2026-07-31 04:29:02 +00:00
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:
@@ -1416,7 +1416,7 @@ proc newType*(kind: TTypeKind, id: ItemId; owner: PSym): PType =
|
||||
lockLevel: UnspecifiedLockLevel,
|
||||
uniqueId: id)
|
||||
when false:
|
||||
if result.id == 76426:
|
||||
if result.itemId.module == 55 and result.itemId.item == 2:
|
||||
echo "KNID ", kind
|
||||
writeStackTrace()
|
||||
|
||||
|
||||
@@ -40,7 +40,13 @@ proc mangleName(m: BModule; s: PSym): Rope =
|
||||
result = s.loc.r
|
||||
if result == nil:
|
||||
result = s.name.s.mangle.rope
|
||||
result.add(idOrSig(s, m.module.name.s.mangle, m.sigConflicts))
|
||||
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))
|
||||
s.loc.r = result
|
||||
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",
|
||||
[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)
|
||||
if m.hcrOn:
|
||||
m.s[cfsData].addf("static $2* $1;$n", [str, nr])
|
||||
m.s[cfsTypeInit1].addf("\t$1 = ($3*)hcrGetGlobal($2, \"$1\");$n",
|
||||
[str, getModuleDllPath(m, ownerModule), nr])
|
||||
[str, getModuleDllPath(m, module), nr])
|
||||
else:
|
||||
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:
|
||||
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 =
|
||||
let origType = t
|
||||
# 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)]
|
||||
m.typeInfoMarkerV2[sig] = result
|
||||
|
||||
let owner = t.skipTypes(typedescPtrs).owner.getModule
|
||||
if owner != m.module:
|
||||
let owner = t.skipTypes(typedescPtrs).itemId.module
|
||||
if owner != m.module.position and moduleOpenForCodegen(m, owner):
|
||||
# make sure the type info is created in the owner module
|
||||
assert m.g.modules[owner.position] != nil
|
||||
discard genTypeInfoV2(m.g.modules[owner.position], origType, info)
|
||||
assert m.g.modules[owner] != nil
|
||||
discard genTypeInfoV2(m.g.modules[owner], origType, info)
|
||||
# reference the type info as extern here
|
||||
discard cgsym(m, "TNimTypeV2")
|
||||
declareNimType(m, "TNimTypeV2", result, owner)
|
||||
@@ -1397,6 +1406,33 @@ proc openArrayToTuple(m: BModule; t: PType): PType =
|
||||
result.add p
|
||||
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 =
|
||||
let origType = t
|
||||
var t = skipTypes(origType, irrelevantForBackend + tyUserTypeClasses)
|
||||
@@ -1417,14 +1453,14 @@ proc genTypeInfoV1(m: BModule, t: PType; info: TLineInfo): Rope =
|
||||
m.typeInfoMarker[sig] = marker.str
|
||||
return prefixTI.rope & marker.str & ")".rope
|
||||
|
||||
result = "NTI$1_" % [rope($sig)]
|
||||
result = "NTI$1$2_" % [rope(typeToC(t)), rope($sig)]
|
||||
m.typeInfoMarker[sig] = result
|
||||
|
||||
let owner = t.skipTypes(typedescPtrs).owner.getModule
|
||||
if owner != m.module:
|
||||
let owner = t.skipTypes(typedescPtrs).itemId.module
|
||||
if owner != m.module.position and moduleOpenForCodegen(m, owner):
|
||||
# make sure the type info is created in the owner module
|
||||
assert m.g.modules[owner.position] != nil
|
||||
discard genTypeInfoV1(m.g.modules[owner.position], origType, info)
|
||||
assert m.g.modules[owner] != nil
|
||||
discard genTypeInfoV1(m.g.modules[owner], origType, info)
|
||||
# reference the type info as extern here
|
||||
discard cgsym(m, "TNimType")
|
||||
discard cgsym(m, "TNimNode")
|
||||
|
||||
@@ -13,7 +13,7 @@ import
|
||||
ast, astalgo, hashes, trees, platform, magicsys, extccomp, options, intsets,
|
||||
nversion, nimsets, msgs, bitsets, idents, types,
|
||||
ccgutils, os, ropes, math, passes, wordrecg, treetab, cgmeth,
|
||||
rodutils, renderer, cgendata, ccgmerge, aliases,
|
||||
rodutils, renderer, cgendata, aliases,
|
||||
lowerings, tables, sets, ndi, lineinfos, pathutils, transf,
|
||||
injectdestructors
|
||||
|
||||
@@ -50,8 +50,8 @@ proc addForwardedProc(m: BModule, prc: PSym) =
|
||||
m.g.forwardedProcs.add(prc)
|
||||
|
||||
proc findPendingModule(m: BModule, s: PSym): BModule =
|
||||
var ms = getModule(s)
|
||||
result = m.g.modules[ms.position]
|
||||
let ms = s.itemId.module #getModule(s)
|
||||
result = m.g.modules[ms]
|
||||
|
||||
proc initLoc(result: var TLoc, k: TLocKind, lode: PNode, s: TStorageLoc) =
|
||||
result.k = k
|
||||
@@ -97,10 +97,13 @@ proc getCFile(m: BModule): AbsoluteFile
|
||||
proc getModuleDllPath(m: BModule): Rope =
|
||||
let (dir, name, ext) = splitFile(getCFile(m))
|
||||
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 =
|
||||
return getModuleDllPath(findPendingModule(m, s))
|
||||
result = getModuleDllPath(m.g.modules[s.itemId.module])
|
||||
|
||||
import macros
|
||||
|
||||
@@ -1109,7 +1112,7 @@ proc genProcPrototype(m: BModule, sym: PSym) =
|
||||
useHeader(m, sym)
|
||||
if lfNoDecl in sym.loc.flags: return
|
||||
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):
|
||||
m.s[cfsVars].add(ropecg(m, "$1 $2 $3;$n",
|
||||
[(if isReloadable(m, sym): "static" else: "extern"),
|
||||
@@ -1586,9 +1589,7 @@ proc genDatInitCode(m: BModule) =
|
||||
for i in cfsTypeInit1..cfsDynLibInit:
|
||||
if m.s[i].len != 0:
|
||||
moduleDatInitRequired = true
|
||||
prc.add(genSectionStart(i, m.config))
|
||||
prc.add(m.s[i])
|
||||
prc.add(genSectionEnd(i, m.config))
|
||||
|
||||
prc.addf("}$N$N", [])
|
||||
|
||||
@@ -1646,9 +1647,7 @@ proc genInitCode(m: BModule) =
|
||||
if m.thing.s(section).len > 0:
|
||||
moduleInitRequired = true
|
||||
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(genSectionEnd(section, m.config))
|
||||
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:
|
||||
@@ -1740,28 +1739,21 @@ proc genModule(m: BModule, cfile: Cfile): Rope =
|
||||
var moduleIsEmpty = true
|
||||
|
||||
result = getFileHeader(m.config, cfile)
|
||||
result.add(genMergeInfo(m))
|
||||
|
||||
generateThreadLocalStorage(m)
|
||||
generateHeaders(m)
|
||||
result.add(genSectionStart(cfsHeaders, m.config))
|
||||
result.add(m.s[cfsHeaders])
|
||||
if m.config.cppCustomNamespace.len > 0:
|
||||
result.add openNamespaceNim(m.config.cppCustomNamespace)
|
||||
result.add(genSectionEnd(cfsHeaders, m.config))
|
||||
result.add(genSectionStart(cfsFrameDefines, m.config))
|
||||
if m.s[cfsFrameDefines].len > 0:
|
||||
result.add(m.s[cfsFrameDefines])
|
||||
else:
|
||||
result.add("#define nimfr_(x, y)\n#define nimln_(x, y)\n")
|
||||
result.add(genSectionEnd(cfsFrameDefines, m.config))
|
||||
|
||||
for i in cfsForwardTypes..cfsProcs:
|
||||
if m.s[i].len > 0:
|
||||
moduleIsEmpty = false
|
||||
result.add(genSectionStart(i, m.config))
|
||||
result.add(m.s[i])
|
||||
result.add(genSectionEnd(i, m.config))
|
||||
|
||||
if m.s[cfsInitProc].len > 0:
|
||||
moduleIsEmpty = false
|
||||
@@ -1851,9 +1843,7 @@ proc writeHeader(m: BModule) =
|
||||
|
||||
generateThreadLocalStorage(m)
|
||||
for i in cfsHeaders..cfsProcs:
|
||||
result.add(genSectionStart(i, m.config))
|
||||
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)
|
||||
result.add(m.s[cfsInitProc])
|
||||
|
||||
@@ -1952,46 +1942,26 @@ proc shouldRecompile(m: BModule; code: Rope, cfile: Cfile): bool =
|
||||
proc writeModule(m: BModule, pending: bool) =
|
||||
template onExit() = close(m.ndi, m.config)
|
||||
let cfile = getCFile(m)
|
||||
if true or optForceFullMake in m.config.globalOptions:
|
||||
if moduleHasChanged(m.g.graph, m.module):
|
||||
genInitCode(m)
|
||||
finishTypeDescriptions(m)
|
||||
if sfMainModule in m.module.flags:
|
||||
# generate main file:
|
||||
genMainProc(m)
|
||||
m.s[cfsProcHeaders].add(m.g.mainModProcs)
|
||||
generateThreadVarsSize(m)
|
||||
|
||||
var cf = Cfile(nimname: m.module.name.s, cname: cfile,
|
||||
obj: completeCfilePath(m.config, toObjFile(m.config, cfile)), flags: {})
|
||||
var code = genModule(m, cf)
|
||||
if code != nil or m.config.symbolFiles != disabledSf:
|
||||
when hasTinyCBackend:
|
||||
if m.config.cmd == cmdTcc:
|
||||
tccgen.compileCCode($code, m.config)
|
||||
onExit()
|
||||
return
|
||||
|
||||
if not shouldRecompile(m, code, cf): cf.flags = {CfileFlag.Cached}
|
||||
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)
|
||||
if moduleHasChanged(m.g.graph, m.module):
|
||||
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}
|
||||
if sfMainModule in m.module.flags:
|
||||
# generate main file:
|
||||
genMainProc(m)
|
||||
m.s[cfsProcHeaders].add(m.g.mainModProcs)
|
||||
generateThreadVarsSize(m)
|
||||
|
||||
var cf = Cfile(nimname: m.module.name.s, cname: cfile,
|
||||
obj: completeCfilePath(m.config, toObjFile(m.config, cfile)), flags: {})
|
||||
var code = genModule(m, cf)
|
||||
if code != nil or m.config.symbolFiles != disabledSf:
|
||||
when hasTinyCBackend:
|
||||
if m.config.cmd == cmdTcc:
|
||||
tccgen.compileCCode($code, m.config)
|
||||
onExit()
|
||||
return
|
||||
|
||||
if not shouldRecompile(m, code, cf): cf.flags = {CfileFlag.Cached}
|
||||
addFileToCompile(m.config, cf)
|
||||
onExit()
|
||||
|
||||
@@ -1999,21 +1969,10 @@ proc updateCachedModule(m: BModule) =
|
||||
let cfile = getCFile(m)
|
||||
var cf = Cfile(nimname: m.module.name.s, cname: cfile,
|
||||
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:
|
||||
genMainProc(m)
|
||||
cf.flags = {CfileFlag.Cached}
|
||||
addFileToCompile(m.config, cf)
|
||||
if sfMainModule notin m.module.flags:
|
||||
genMainProc(m)
|
||||
cf.flags = {CfileFlag.Cached}
|
||||
addFileToCompile(m.config, cf)
|
||||
|
||||
proc finalCodegenActions*(graph: ModuleGraph; m: BModule; n: PNode) =
|
||||
## Also called from IC.
|
||||
@@ -2080,8 +2039,7 @@ proc genForwardedProcs(g: BModuleList) =
|
||||
while g.forwardedProcs.len > 0:
|
||||
let
|
||||
prc = g.forwardedProcs.pop()
|
||||
ms = getModule(prc)
|
||||
m = g.modules[ms.position]
|
||||
m = g.modules[prc.itemId.module]
|
||||
if sfForward in prc.flags:
|
||||
internalError(m.config, prc.info, "still forwarded: " & prc.name.s)
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@ type
|
||||
|
||||
TTypeSeq* = seq[PType]
|
||||
TypeCache* = Table[SigHash, Rope]
|
||||
TypeCacheWithOwner* = Table[SigHash, tuple[str: Rope, owner: PSym]]
|
||||
TypeCacheWithOwner* = Table[SigHash, tuple[str: Rope, owner: int32]]
|
||||
|
||||
CodegenFlag* = enum
|
||||
preventStackTrace, # true if stack traces need to be prevented
|
||||
@@ -202,7 +202,7 @@ proc newProc*(prc: PSym, module: BModule): BProc =
|
||||
result.sigConflicts = initCountTable[string]()
|
||||
|
||||
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())
|
||||
|
||||
iterator cgenModules*(g: BModuleList): BModule =
|
||||
|
||||
@@ -23,7 +23,7 @@ import std/[packedsets, algorithm]
|
||||
import ".."/[ast, options, lineinfos, modulegraphs, cgendata, cgen,
|
||||
pathutils, extccomp, msgs]
|
||||
|
||||
import packed_ast, to_packed_ast, dce, rodfiles
|
||||
import packed_ast, ic, dce, rodfiles
|
||||
|
||||
proc unpackTree(g: ModuleGraph; thisModule: int;
|
||||
tree: PackedTree; n: NodePos): PNode =
|
||||
@@ -83,7 +83,7 @@ proc aliveSymsChanged(config: ConfigRef; position: int; alive: AliveSyms): bool
|
||||
proc generateCode*(g: ModuleGraph) =
|
||||
## The single entry point, generate C(++) code for the entire
|
||||
## Nim program aka `ModuleGraph`.
|
||||
initStrTable(g.compilerprocs)
|
||||
resetForBackend(g)
|
||||
var alive = computeAliveSyms(g.packed, g.config)
|
||||
|
||||
for i in 0..high(g.packed):
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
import std / [intsets, tables]
|
||||
import ".." / [ast, options, lineinfos, types]
|
||||
|
||||
import packed_ast, to_packed_ast, bitabs
|
||||
import packed_ast, ic, bitabs
|
||||
|
||||
type
|
||||
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
|
||||
followLater(c, g, otherModule, item)
|
||||
of nkMacroDef, nkTemplateDef, nkTypeSection, nkTypeOfExpr,
|
||||
nkCommentStmt, nkIteratorDef, nkIncludeStmt,
|
||||
nkCommentStmt, nkIncludeStmt,
|
||||
nkImportStmt, nkImportExceptStmt, nkExportStmt, nkExportExceptStmt,
|
||||
nkFromStmt, nkStaticStmt:
|
||||
discard
|
||||
@@ -121,7 +121,7 @@ proc aliveCode(c: var AliveContext; g: PackedModuleGraph; tree: PackedTree; n: N
|
||||
aliveCode(c, g, tree, son)
|
||||
of nkChckRangeF, nkChckRange64, nkChckRange:
|
||||
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):
|
||||
let item = n.firstSon.operand
|
||||
if isExportedToC(c, g, item):
|
||||
|
||||
@@ -95,6 +95,7 @@ proc rememberStartupConfig*(dest: var PackedConfig, config: ConfigRef) =
|
||||
template rem(x) =
|
||||
dest.x = config.x
|
||||
primConfigFields rem
|
||||
dest.globalOptions.excl optForceFullMake
|
||||
|
||||
proc hashFileCached(conf: ConfigRef; fileIdx: FileIndex): string =
|
||||
result = msgs.getHash(conf, fileIdx)
|
||||
@@ -486,8 +487,14 @@ proc storeInstantiation*(c: var PackedEncoder; m: var PackedModule; s: PSym; i:
|
||||
concreteTypes: t)
|
||||
toPackedGeneratedProcDef(i.sym, c, m)
|
||||
|
||||
proc loadError(err: RodFileError; filename: AbsoluteFile) =
|
||||
echo "Error: ", $err, " loading file: ", filename.string
|
||||
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
|
||||
|
||||
proc loadRodFile*(filename: AbsoluteFile; m: var PackedModule; config: ConfigRef;
|
||||
ignoreConfig = false): RodFileError =
|
||||
@@ -718,7 +725,7 @@ proc loadProcHeader(c: var PackedDecoder; g: var PackedModuleGraph; thisModule:
|
||||
result = newNodeIT(k, translateLineInfo(c, g, thisModule, n.info),
|
||||
loadType(c, g, thisModule, n.typ))
|
||||
result.flags = n.flags
|
||||
assert k in {nkProcDef, nkMethodDef, nkIteratorDef, nkFuncDef, nkConverterDef}
|
||||
assert k in {nkProcDef, nkMethodDef, nkIteratorDef, nkFuncDef, nkConverterDef, nkLambda}
|
||||
var i = 0
|
||||
for n0 in sonsReadonly(tree, n):
|
||||
if i != bodyPos:
|
||||
@@ -932,10 +939,10 @@ proc needsRecompile(g: var PackedModuleGraph; conf: ConfigRef; cache: IdentCache
|
||||
else:
|
||||
g[m] = LoadedModule(status: outdated, module: g[m].module)
|
||||
else:
|
||||
loadError(err, rod)
|
||||
loadError(err, rod, conf)
|
||||
g[m].status = outdated
|
||||
result = true
|
||||
when false: loadError(err, rod)
|
||||
when false: loadError(err, rod, conf)
|
||||
of loading, loaded:
|
||||
# For loading: Assume no recompile is required.
|
||||
result = false
|
||||
@@ -951,8 +958,8 @@ proc moduleFromRodFile*(g: var PackedModuleGraph; conf: ConfigRef; cache: IdentC
|
||||
result = g[int fileIdx].module
|
||||
assert result != nil
|
||||
assert result.position == int(fileIdx)
|
||||
for m in cachedModules:
|
||||
loadToReplayNodes(g, conf, cache, m, g[int m])
|
||||
for m in cachedModules:
|
||||
loadToReplayNodes(g, conf, cache, m, g[int m])
|
||||
|
||||
template setupDecoder() {.dirty.} =
|
||||
var decoder = PackedDecoder(
|
||||
@@ -16,7 +16,7 @@ import ".." / [ast, modulegraphs, trees, extccomp, btrees,
|
||||
|
||||
import tables
|
||||
|
||||
import packed_ast, to_packed_ast, bitabs
|
||||
import packed_ast, ic, bitabs
|
||||
|
||||
proc replayStateChanges*(module: PSym; g: ModuleGraph) =
|
||||
let list = module.ast
|
||||
|
||||
@@ -350,7 +350,7 @@ proc genMarkCyclic(c: var Con; result, dest: PNode) =
|
||||
if t.kind == tyRef:
|
||||
result.add callCodegenProc(c.graph, "nimMarkCyclic", dest.info, dest)
|
||||
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)
|
||||
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 tmp
|
||||
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
|
||||
result.add newTree(nkIfStmt, newTree(nkElifBranch, notExpr, c.genOp(branchDestructor, le)))
|
||||
result.add newTree(nkFastAsgn, le, tmp)
|
||||
|
||||
proc genWasMoved(c: var Con, n: PNode): PNode =
|
||||
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
|
||||
#if n.kind != nkSym:
|
||||
# message(c.graph.config, n.info, warnUser, "wasMoved(" & $n & ")")
|
||||
|
||||
proc genDefaultCall(t: PType; c: Con; info: TLineInfo): PNode =
|
||||
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
|
||||
|
||||
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[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.add createMagic(g, name, magic).newSymNode
|
||||
result.add createMagic(g, idgen, name, magic).newSymNode
|
||||
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) =
|
||||
if c.kind in {attachedAsgn, attachedDeepCopy, attachedSink}:
|
||||
body.add newAsgnStmt(x, y)
|
||||
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
|
||||
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 =
|
||||
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.typ = getSysType(c.g, c.info, tyBool)
|
||||
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 newSymNode(field)
|
||||
|
||||
let offsetOf = genBuiltin(c.g, mOffsetOf, "offsetof", dotExpr)
|
||||
let offsetOf = genBuiltin(c, mOffsetOf, "offsetof", dotExpr)
|
||||
offsetOf.typ = intType
|
||||
|
||||
let minusExpr = genBuiltin(c.g, mSubI, "-", castExpr1)
|
||||
let minusExpr = genBuiltin(c, mSubI, "-", castExpr1)
|
||||
minusExpr.typ = intType
|
||||
minusExpr.add offsetOf
|
||||
|
||||
@@ -135,7 +138,7 @@ proc destructorCall(c: var TLiftCtx; op: PSym; x: PNode): PNode =
|
||||
if sfNeverRaises notin op.flags:
|
||||
c.canRaise = true
|
||||
if c.addMemReset:
|
||||
result = newTree(nkStmtList, destroy, genBuiltin(c.g, mWasMoved, "wasMoved", x))
|
||||
result = newTree(nkStmtList, destroy, genBuiltin(c, mWasMoved, "wasMoved", x))
|
||||
else:
|
||||
result = destroy
|
||||
|
||||
@@ -237,7 +240,7 @@ proc fillBodyObjT(c: var TLiftCtx; t: PType, body, x, y: PNode) =
|
||||
#body.add newAsgnStmt(blob, x)
|
||||
|
||||
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
|
||||
body.add wasMovedCall
|
||||
|
||||
@@ -443,25 +446,25 @@ proc declareTempOf(c: var TLiftCtx; body: PNode; value: PNode): PNode =
|
||||
body.add v
|
||||
|
||||
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)
|
||||
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:
|
||||
result = genBuiltin(g, mNewSeq, "newSeq", x)
|
||||
let lenCall = genBuiltin(g, mLengthSeq, "len", y)
|
||||
lenCall.typ = getSysType(g, x.info, tyInt)
|
||||
result = genBuiltin(c, mNewSeq, "newSeq", x)
|
||||
let lenCall = genBuiltin(c, mLengthSeq, "len", y)
|
||||
lenCall.typ = getSysType(c.g, x.info, tyInt)
|
||||
result.add lenCall
|
||||
|
||||
proc setLenStrCall(g: ModuleGraph; x, y: PNode): PNode =
|
||||
let lenCall = genBuiltin(g, mLengthStr, "len", y)
|
||||
lenCall.typ = getSysType(g, x.info, tyInt)
|
||||
result = genBuiltin(g, mSetLengthStr, "setLen", x) # genAddr(g, x))
|
||||
proc setLenStrCall(c: var TLiftCtx; x, y: PNode): PNode =
|
||||
let lenCall = genBuiltin(c, mLengthStr, "len", y)
|
||||
lenCall.typ = getSysType(c.g, x.info, tyInt)
|
||||
result = genBuiltin(c, mSetLengthStr, "setLen", x) # genAddr(g, x))
|
||||
result.add lenCall
|
||||
|
||||
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)
|
||||
var op = getSysMagic(c.g, x.info, "setLen", mSetLengthSeq)
|
||||
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)
|
||||
forallElements(c, t, body, x, y)
|
||||
of attachedSink:
|
||||
let moveCall = genBuiltin(c.g, mMove, "move", x)
|
||||
let moveCall = genBuiltin(c, mMove, "move", x)
|
||||
moveCall.add y
|
||||
doAssert t.destructor != nil
|
||||
moveCall.add destructorCall(c, t.destructor, x)
|
||||
@@ -495,13 +498,13 @@ proc fillSeqOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||
of attachedDestructor:
|
||||
# destroy all elements:
|
||||
forallElements(c, t, body, x, y)
|
||||
body.add genBuiltin(c.g, mDestroy, "destroy", x)
|
||||
body.add genBuiltin(c, mDestroy, "destroy", x)
|
||||
of attachedTrace:
|
||||
# follow all elements:
|
||||
forallElements(c, t, body, x, y)
|
||||
of attachedDispose:
|
||||
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) =
|
||||
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)
|
||||
of attachedSink:
|
||||
# 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
|
||||
doAssert t.destructor != nil
|
||||
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:
|
||||
body.add callCodegenProc(c.g, "nimAsgnStrV2", c.info, genAddr(c, x), y)
|
||||
of attachedSink:
|
||||
let moveCall = genBuiltin(c.g, mMove, "move", x)
|
||||
let moveCall = genBuiltin(c, mMove, "move", x)
|
||||
moveCall.add y
|
||||
doAssert t.destructor != nil
|
||||
moveCall.add destructorCall(c, t.destructor, x)
|
||||
body.add moveCall
|
||||
of attachedDestructor, attachedDispose:
|
||||
body.add genBuiltin(c.g, mDestroy, "destroy", x)
|
||||
body.add genBuiltin(c, mDestroy, "destroy", x)
|
||||
of attachedTrace:
|
||||
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):
|
||||
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)
|
||||
actions.add callCodegenProc(c.g, "nimRawDispose", c.info, tmp, alignOf)
|
||||
else:
|
||||
@@ -609,7 +612,7 @@ proc atomicRefOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||
var cond: PNode
|
||||
if isCyclic:
|
||||
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)
|
||||
cond = callCodegenProc(c.g, "nimDecRefIsLastCyclicStatic", c.info, tmp, typInfo)
|
||||
else:
|
||||
@@ -641,7 +644,7 @@ proc atomicRefOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||
of attachedDeepCopy: assert(false, "cannot happen")
|
||||
of attachedTrace:
|
||||
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)
|
||||
body.add callCodegenProc(c.g, "nimTraceRef", c.info, genAddrOf(x, c.idgen), typInfo, y)
|
||||
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) =
|
||||
## 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':
|
||||
let xenv = genBuiltin(c.g, mAccessEnv, "accessEnv", x)
|
||||
let xenv = genBuiltin(c, mAccessEnv, "accessEnv", x)
|
||||
xenv.typ = getSysType(c.g, c.info, tyPointer)
|
||||
|
||||
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 newAsgnStmt(x, y)
|
||||
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)
|
||||
if isCyclic:
|
||||
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
|
||||
#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):
|
||||
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)
|
||||
actions.add callCodegenProc(c.g, "nimRawDispose", c.info, x, alignOf)
|
||||
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:
|
||||
let call = newNodeI(nkCall, c.info, 2)
|
||||
call.typ = t
|
||||
call[0] = newSymNode(createMagic(c.g, "deepCopy", mDeepCopy))
|
||||
call[0] = newSymNode(createMagic(c.g, c.idgen, "deepCopy", mDeepCopy))
|
||||
call[1] = y
|
||||
body.add newAsgnStmt(x, call)
|
||||
elif (optOwnedRefs in c.g.config.globalOptions and
|
||||
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)
|
||||
case c.kind
|
||||
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 newAsgnStmt(x, y)
|
||||
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)
|
||||
body.add genIf(c, yy, callCodegenProc(c.g, "nimIncRef", c.info, yy))
|
||||
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
|
||||
|
||||
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)
|
||||
var actions = newNodeI(nkStmtList, c.info)
|
||||
#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)
|
||||
elif tfHasAsgn in t.flags:
|
||||
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)
|
||||
else:
|
||||
defaultOp(c, t, body, x, y)
|
||||
|
||||
@@ -59,7 +59,10 @@ type
|
||||
warnLockLevel = "LockLevel", warnResultShadowed = "ResultShadowed",
|
||||
warnInconsistentSpacing = "Spacing", warnCaseTransition = "CaseTransition",
|
||||
warnCycleCreated = "CycleCreated", warnObservableStores = "ObservableStores",
|
||||
warnUser = "User", warnStrictNotNil = "StrictNotNil",
|
||||
warnStrictNotNil = "StrictNotNil",
|
||||
warnCannotOpen = "CannotOpen",
|
||||
warnFileChanged = "FileChanged",
|
||||
warnUser = "User",
|
||||
|
||||
hintSuccess = "Success", hintSuccessX = "SuccessX", hintCC = "CC",
|
||||
hintLineTooLong = "LineTooLong", hintXDeclaredButNotUsed = "XDeclaredButNotUsed",
|
||||
@@ -133,8 +136,10 @@ const
|
||||
warnCaseTransition: "Potential object case transition, instantiate new object instead",
|
||||
warnCycleCreated: "$1",
|
||||
warnObservableStores: "observable stores to '$1'",
|
||||
warnUser: "$1",
|
||||
warnStrictNotNil: "$1",
|
||||
warnCannotOpen: "cannot open: $1",
|
||||
warnFileChanged: "file changed: $1",
|
||||
warnUser: "$1",
|
||||
hintSuccess: "operation successful: $#",
|
||||
# keep in sync with `testament.isSuccess`
|
||||
hintSuccessX: "${loc} lines; ${sec}s; $mem; $build build; proj: $project; out: $output",
|
||||
|
||||
@@ -22,7 +22,7 @@ import
|
||||
modulegraphs, tables, lineinfos, pathutils, vmprofiler
|
||||
|
||||
import ic / cbackend
|
||||
from ic / to_packed_ast import rodViewer
|
||||
from ic / ic import rodViewer
|
||||
|
||||
when not defined(leanCompiler):
|
||||
import jsgen, docgen, docgen2
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
## or stored in a rod-file.
|
||||
|
||||
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
|
||||
SigHash* = distinct MD5Digest
|
||||
@@ -30,6 +30,7 @@ type
|
||||
patterns*: seq[LazySym]
|
||||
pureEnums*: seq[LazySym]
|
||||
interf: TStrTable
|
||||
uniqueName*: Rope
|
||||
|
||||
Operators* = object
|
||||
opNot*, opContains*, opLe*, opLt*, opAnd*, opOr*, opIsNil*, opEq*: PSym
|
||||
@@ -117,6 +118,15 @@ type
|
||||
close: TPassClose,
|
||||
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
|
||||
cb64 = [
|
||||
"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
|
||||
if id >= g.encoders.len:
|
||||
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)
|
||||
|
||||
type
|
||||
@@ -359,11 +369,14 @@ else:
|
||||
proc stopCompile*(g: ModuleGraph): bool {.inline.} =
|
||||
result = g.doStopCompile != nil and g.doStopCompile()
|
||||
|
||||
proc createMagic*(g: ModuleGraph; name: string, m: TMagic): PSym =
|
||||
result = newSym(skProc, getIdent(g.cache, name), nextSymId(g.idgen), nil, unknownLineInfo, {})
|
||||
proc createMagic*(g: ModuleGraph; idgen: IdGenerator; name: string, m: TMagic): PSym =
|
||||
result = newSym(skProc, getIdent(g.cache, name), nextSymId(idgen), nil, unknownLineInfo, {})
|
||||
result.magic = m
|
||||
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) =
|
||||
assert m != nil
|
||||
assert m.kind == skModule
|
||||
@@ -374,9 +387,13 @@ proc registerModule*(g: ModuleGraph; m: PSym) =
|
||||
if m.position >= g.packed.len:
|
||||
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)
|
||||
|
||||
proc registerModuleById*(g: ModuleGraph; m: FileIndex) =
|
||||
registerModule(g, g.packed[int m].module)
|
||||
|
||||
proc initOperators(g: ModuleGraph): Operators =
|
||||
# These are safe for IC.
|
||||
result.opLe = createMagic(g, "<=", mLeI)
|
||||
|
||||
@@ -108,9 +108,10 @@ proc compileModule*(graph: ModuleGraph; fileIdx: FileIndex; flags: TSymFlags): P
|
||||
if sfSystemModule in flags:
|
||||
graph.systemModule = result
|
||||
partialInitModule(result, graph, fileIdx, filename)
|
||||
for m in cachedModules:
|
||||
replayStateChanges(graph.packed[m.int].module, graph)
|
||||
replayGenericCacheInformation(graph, m.int)
|
||||
for m in cachedModules:
|
||||
registerModuleById(graph, m)
|
||||
replayStateChanges(graph.packed[m.int].module, graph)
|
||||
replayGenericCacheInformation(graph, m.int)
|
||||
elif graph.isDirty(result):
|
||||
result.flags.excl sfDirty
|
||||
# reset module fields:
|
||||
|
||||
@@ -115,6 +115,7 @@ proc fileInfoIdx*(conf: ConfigRef; filename: AbsoluteFile; isKnownFile: var bool
|
||||
else:
|
||||
isKnownFile = false
|
||||
result = conf.m.fileInfos.len.FileIndex
|
||||
#echo "ID ", result.int, " ", canon2
|
||||
conf.m.fileInfos.add(newFileInfo(canon, if pseudoPath: RelativeFile filename
|
||||
else: relativeTo(canon, conf.projectPath)))
|
||||
conf.m.filenameToIndexTbl[canon2] = result
|
||||
@@ -630,3 +631,28 @@ template listMsg(title, r) =
|
||||
|
||||
proc listWarnings*(conf: ConfigRef) = listMsg("Warnings:", warnMin..warnMax)
|
||||
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,
|
||||
types, lookups, lineinfos, pathutils, linter
|
||||
|
||||
from ic / to_packed_ast import addCompilerProc
|
||||
from ic / ic import addCompilerProc
|
||||
|
||||
const
|
||||
FirstCallConv* = wNimcall
|
||||
|
||||
@@ -15,7 +15,7 @@ import
|
||||
intsets, options, ast, astalgo, msgs, idents, renderer,
|
||||
magicsys, vmdef, modulegraphs, lineinfos, sets, pathutils
|
||||
|
||||
import ic / to_packed_ast
|
||||
import ic / ic
|
||||
|
||||
type
|
||||
TOptionEntry* = object # entries to put on a stack for pragma parsing
|
||||
|
||||
@@ -2099,7 +2099,7 @@ proc semQuoteAst(c: PContext, n: PNode): PNode =
|
||||
identNodeSym.newSymNode
|
||||
quotes[1] = newTreeI(nkCall, n.info, identNode, newStrNode(nkStrLit, "result"))
|
||||
result = newTreeI(nkCall, n.info,
|
||||
createMagic(c.graph, "getAst", mExpandToAst).newSymNode,
|
||||
createMagic(c.graph, c.idgen, "getAst", mExpandToAst).newSymNode,
|
||||
newTreeI(nkCall, n.info, quotes))
|
||||
result = semExpandToAst(c, result)
|
||||
|
||||
|
||||
@@ -397,12 +397,12 @@ proc analyse(c: var AnalysisCtx; n: PNode) =
|
||||
else:
|
||||
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:
|
||||
let op = n[0].sym
|
||||
if op.name.s == "[]" and op.fromSystem:
|
||||
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)
|
||||
result.add opSlice
|
||||
result.add n[1]
|
||||
@@ -413,11 +413,11 @@ proc transformSlices(g: ModuleGraph; n: PNode): PNode =
|
||||
if n.safeLen > 0:
|
||||
result = shallowCopy(n)
|
||||
for i in 0..<n.len:
|
||||
result[i] = transformSlices(g, n[i])
|
||||
result[i] = transformSlices(g, idgen, n[i])
|
||||
else:
|
||||
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 =
|
||||
result = shallowCopy(n)
|
||||
for i in 0..<n.len:
|
||||
@@ -431,7 +431,7 @@ proc transformSpawn(g: ModuleGraph; idgen: IdGenerator; owner: PSym; n, barrier:
|
||||
let b = it.lastSon
|
||||
if getMagic(b) == mSpawn:
|
||||
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:
|
||||
result = newNodeI(nkStmtList, n.info)
|
||||
result.add n
|
||||
@@ -446,12 +446,12 @@ proc transformSpawn(g: ModuleGraph; idgen: IdGenerator; owner: PSym; n, barrier:
|
||||
let b = n[1]
|
||||
if getMagic(b) == mSpawn and (let t = b[1][0].typ[0];
|
||||
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])
|
||||
result = transformSpawnSons(g, idgen, owner, n, barrier)
|
||||
of nkCallKinds:
|
||||
if getMagic(n) == mSpawn:
|
||||
result = transformSlices(g, n)
|
||||
result = transformSlices(g, idgen, n)
|
||||
return wrapProcForSpawn(g, idgen, owner, result, n.typ, barrier, nil)
|
||||
result = transformSpawnSons(g, idgen, owner, n, barrier)
|
||||
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:
|
||||
let slice = newNodeI(nkCall, n.info, 4)
|
||||
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
|
||||
var fieldB = newSym(skField, tmpName, nextSymId idgen, objType.owner, n.info, g.config.options)
|
||||
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
|
||||
# system/sets to eliminate code duplication. sets.nim defines
|
||||
# countBits32 and countBits64.
|
||||
include system/sets
|
||||
import system/countbits_impl
|
||||
|
||||
template countSetBitsNim(n: uint32): int = countBits32(n)
|
||||
template countSetBitsNim(n: uint64): int = countBits64(n)
|
||||
|
||||
@@ -2339,6 +2339,7 @@ when notJSnotNims:
|
||||
when hostOS != "standalone" and hostOS != "any":
|
||||
include "system/dyncalls"
|
||||
|
||||
import system/countbits_impl
|
||||
include "system/sets"
|
||||
|
||||
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
|
||||
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.})
|
||||
{.importc: "std::set_terminate", header: "<exception>".}
|
||||
|
||||
@@ -14,21 +14,6 @@ type
|
||||
|
||||
# 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.} =
|
||||
var i = 0
|
||||
result = 0
|
||||
|
||||
@@ -30,7 +30,8 @@ proc pkg(name: string; cmd = "nimble test"; url = "", useHead = true) =
|
||||
|
||||
# pkg "alea"
|
||||
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 "awk"
|
||||
pkg "bigints", url = "https://github.com/Araq/nim-bigints"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
discard """
|
||||
disabled: "openbsd"
|
||||
disabled: "true"
|
||||
output: '''
|
||||
main: HELLO!
|
||||
main: hasAnyModuleChanged? true
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
discard """
|
||||
output: "Hello World"
|
||||
disabled: "true"
|
||||
"""
|
||||
|
||||
const str = "Hello World"
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
discard """
|
||||
output: '''
|
||||
'''
|
||||
|
||||
ccodeCheck: "\\i ! @'deepCopy(' .*"
|
||||
"""
|
||||
|
||||
# parallel convex hull for Nim bigbreak
|
||||
|
||||
Reference in New Issue
Block a user