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:
Andreas Rumpf
2021-03-19 16:53:38 +01:00
committed by GitHub
parent 60fc7e986b
commit 6c1c8f51b3
30 changed files with 249 additions and 187 deletions

View File

@@ -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()

View File

@@ -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")

View File

@@ -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)

View File

@@ -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 =

View File

@@ -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):

View File

@@ -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):

View File

@@ -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(

View File

@@ -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

View File

@@ -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 =

View File

@@ -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)

View File

@@ -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",

View File

@@ -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

View File

@@ -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)

View File

@@ -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:

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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:

View File

@@ -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)

View File

@@ -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)

View File

@@ -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):

View 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

View File

@@ -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>".}

View File

@@ -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

View File

@@ -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"

View File

@@ -1,5 +1,5 @@
discard """
disabled: "openbsd"
disabled: "true"
output: '''
main: HELLO!
main: hasAnyModuleChanged? true

View File

@@ -1,6 +1,5 @@
discard """
output: "Hello World"
disabled: "true"
"""
const str = "Hello World"

View File

@@ -1,8 +1,6 @@
discard """
output: '''
'''
ccodeCheck: "\\i ! @'deepCopy(' .*"
"""
# parallel convex hull for Nim bigbreak