explicit ID generation for easier IC (#15559)
* refactoring: idents don't need inheritance * refactoring: adding an IdGenerator (part 1) * refactoring: adding an IdGenerator (part 2) * refactoring: adding an IdGenerator (part 3) * refactoring: adding an IdGenerator (part 4) * refactoring: adding an IdGenerator (part 5) * refactoring: adding an IdGenerator (part 5) * IdGenerator must be a ref type; hello world works again * make bootstrapping work again * progress: add back the 'exactReplica' ideas * added back the missing exactReplica hacks * make tcompilerapi work again * make important packages green * attempt to fix the build for 32 bit machines (probably need a better solution here)
This commit is contained in:
parent
7252a50fef
commit
226595515c
67 changed files with 853 additions and 903 deletions
|
|
@ -10,7 +10,7 @@
|
|||
# abstract syntax tree + symbol table
|
||||
|
||||
import
|
||||
lineinfos, hashes, options, ropes, idents, idgen, int128
|
||||
lineinfos, hashes, options, ropes, idents, int128
|
||||
from strutils import toLowerAscii
|
||||
|
||||
export int128
|
||||
|
|
@ -717,6 +717,14 @@ const
|
|||
mInSet, mRepr}
|
||||
|
||||
type
|
||||
ItemId* = object
|
||||
module*: int32
|
||||
item*: int32
|
||||
|
||||
TIdObj* = object of RootObj
|
||||
itemId*: ItemId
|
||||
PIdObj* = ref TIdObj
|
||||
|
||||
PNode* = ref TNode
|
||||
TNodeSeq* = seq[PNode]
|
||||
PType* = ref TType
|
||||
|
|
@ -926,7 +934,7 @@ type
|
|||
loc*: TLoc
|
||||
typeInst*: PType # for generic instantiations the tyGenericInst that led to this
|
||||
# type.
|
||||
uniqueId*: int # due to a design mistake, we need to keep the real ID here as it
|
||||
uniqueId*: ItemId # due to a design mistake, we need to keep the real ID here as it
|
||||
# required by the --incremental:on mode.
|
||||
|
||||
TPair* = object
|
||||
|
|
@ -1060,6 +1068,35 @@ proc getnimblePkg*(a: PSym): PSym =
|
|||
else:
|
||||
assert false, $result.kind
|
||||
|
||||
const
|
||||
moduleShift = when defined(cpu32): 20 else: 24
|
||||
|
||||
template id*(a: PIdObj): int =
|
||||
let x = a
|
||||
(x.itemId.module.int shl moduleShift) + x.itemId.item.int
|
||||
|
||||
type
|
||||
IdGenerator* = ref ItemId # unfortunately, we really need the 'shared mutable' aspect here.
|
||||
|
||||
const
|
||||
PackageModuleId* = -3'i32
|
||||
|
||||
proc idGeneratorFromModule*(m: PSym): IdGenerator =
|
||||
assert m.kind == skModule
|
||||
result = IdGenerator(module: m.itemId.module, item: m.itemId.item)
|
||||
|
||||
proc nextId*(x: IdGenerator): ItemId {.inline.} =
|
||||
inc x.item
|
||||
result = x[]
|
||||
|
||||
when false:
|
||||
proc storeBack*(dest: var IdGenerator; src: IdGenerator) {.inline.} =
|
||||
assert dest.ItemId.module == src.ItemId.module
|
||||
if dest.ItemId.item > src.ItemId.item:
|
||||
echo dest.ItemId.item, " ", src.ItemId.item, " ", src.ItemId.module
|
||||
assert dest.ItemId.item <= src.ItemId.item
|
||||
dest = src
|
||||
|
||||
proc getnimblePkgId*(a: PSym): int =
|
||||
let b = a.getnimblePkg
|
||||
result = if b == nil: -1 else: b.id
|
||||
|
|
@ -1164,13 +1201,11 @@ proc newTreeIT*(kind: TNodeKind; info: TLineInfo; typ: PType; children: varargs[
|
|||
template previouslyInferred*(t: PType): PType =
|
||||
if t.sons.len > 1: t.lastSon else: nil
|
||||
|
||||
proc newSym*(symKind: TSymKind, name: PIdent, owner: PSym,
|
||||
proc newSym*(symKind: TSymKind, name: PIdent, id: ItemId, owner: PSym,
|
||||
info: TLineInfo; options: TOptions = {}): PSym =
|
||||
# generates a symbol and initializes the hash field too
|
||||
result = PSym(name: name, kind: symKind, flags: {}, info: info, id: getID(),
|
||||
result = PSym(name: name, kind: symKind, flags: {}, info: info, itemId: id,
|
||||
options: options, owner: owner, offset: defaultOffset)
|
||||
when debugIds:
|
||||
registerId(result)
|
||||
|
||||
proc astdef*(s: PSym): PNode =
|
||||
# get only the definition (initializer) portion of the ast
|
||||
|
|
@ -1344,13 +1379,11 @@ proc `$`*(s: PSym): string =
|
|||
else:
|
||||
result = "<nil>"
|
||||
|
||||
proc newType*(kind: TTypeKind, owner: PSym): PType =
|
||||
let id = getID()
|
||||
proc newType*(kind: TTypeKind, id: ItemId; owner: PSym): PType =
|
||||
result = PType(kind: kind, owner: owner, size: defaultSize,
|
||||
align: defaultAlignment, id: id, uniqueId: id,
|
||||
lockLevel: UnspecifiedLockLevel)
|
||||
when debugIds:
|
||||
registerId(result)
|
||||
align: defaultAlignment, itemId: id,
|
||||
lockLevel: UnspecifiedLockLevel,
|
||||
uniqueId: id)
|
||||
when false:
|
||||
if result.id == 76426:
|
||||
echo "KNID ", kind
|
||||
|
|
@ -1392,22 +1425,18 @@ proc assignType*(dest, src: PType) =
|
|||
newSons(dest, src.len)
|
||||
for i in 0..<src.len: dest[i] = src[i]
|
||||
|
||||
proc copyType*(t: PType, owner: PSym, keepId: bool): PType =
|
||||
result = newType(t.kind, owner)
|
||||
proc copyType*(t: PType, id: ItemId, owner: PSym): PType =
|
||||
result = newType(t.kind, id, owner)
|
||||
assignType(result, t)
|
||||
if keepId:
|
||||
result.id = t.id
|
||||
else:
|
||||
when debugIds: registerId(result)
|
||||
result.sym = t.sym # backend-info should not be copied
|
||||
|
||||
proc exactReplica*(t: PType): PType = copyType(t, t.owner, true)
|
||||
proc exactReplica*(t: PType): PType =
|
||||
result = copyType(t, t.itemId, t.owner)
|
||||
|
||||
proc copySym*(s: PSym): PSym =
|
||||
result = newSym(s.kind, s.name, s.owner, s.info, s.options)
|
||||
proc copySym*(s: PSym; id: ItemId): PSym =
|
||||
result = newSym(s.kind, s.name, id, s.owner, s.info, s.options)
|
||||
#result.ast = nil # BUGFIX; was: s.ast which made problems
|
||||
result.typ = s.typ
|
||||
when debugIds: registerId(result)
|
||||
result.flags = s.flags
|
||||
result.magic = s.magic
|
||||
if s.kind == skModule:
|
||||
|
|
@ -1421,12 +1450,12 @@ proc copySym*(s: PSym): PSym =
|
|||
result.bitsize = s.bitsize
|
||||
result.alignment = s.alignment
|
||||
|
||||
proc createModuleAlias*(s: PSym, newIdent: PIdent, info: TLineInfo;
|
||||
proc createModuleAlias*(s: PSym, id: ItemId, newIdent: PIdent, info: TLineInfo;
|
||||
options: TOptions): PSym =
|
||||
result = newSym(s.kind, newIdent, s.owner, info, options)
|
||||
result = newSym(s.kind, newIdent, id, s.owner, info, options)
|
||||
# keep ID!
|
||||
result.ast = s.ast
|
||||
result.id = s.id
|
||||
#result.id = s.id # XXX figure out what to do with the ID.
|
||||
result.flags = s.flags
|
||||
system.shallowCopy(result.tab, s.tab)
|
||||
result.options = s.options
|
||||
|
|
@ -1576,7 +1605,7 @@ proc transitionNoneToSym*(n: PNode) =
|
|||
|
||||
template transitionSymKindCommon*(k: TSymKind) =
|
||||
let obj {.inject.} = s[]
|
||||
s[] = TSym(kind: k, id: obj.id, magic: obj.magic, typ: obj.typ, name: obj.name,
|
||||
s[] = TSym(kind: k, itemId: obj.itemId, magic: obj.magic, typ: obj.typ, name: obj.name,
|
||||
info: obj.info, owner: obj.owner, flags: obj.flags, ast: obj.ast,
|
||||
options: obj.options, position: obj.position, offset: obj.offset,
|
||||
loc: obj.loc, annex: obj.annex, constraint: obj.constraint)
|
||||
|
|
@ -1797,19 +1826,19 @@ proc skipStmtList*(n: PNode): PNode =
|
|||
else:
|
||||
result = n
|
||||
|
||||
proc toVar*(typ: PType; kind: TTypeKind): PType =
|
||||
proc toVar*(typ: PType; kind: TTypeKind; idgen: IdGenerator): PType =
|
||||
## If ``typ`` is not a tyVar then it is converted into a `var <typ>` and
|
||||
## returned. Otherwise ``typ`` is simply returned as-is.
|
||||
result = typ
|
||||
if typ.kind != kind:
|
||||
result = newType(kind, typ.owner)
|
||||
result = newType(kind, nextId(idgen), typ.owner)
|
||||
rawAddSon(result, typ)
|
||||
|
||||
proc toRef*(typ: PType): PType =
|
||||
proc toRef*(typ: PType; idgen: IdGenerator): PType =
|
||||
## If ``typ`` is a tyObject then it is converted into a `ref <typ>` and
|
||||
## returned. Otherwise ``typ`` is simply returned as-is.
|
||||
if typ.skipTypes({tyAlias, tyGenericInst}).kind == tyObject:
|
||||
result = newType(tyRef, typ.owner)
|
||||
result = newType(tyRef, nextId(idgen), typ.owner)
|
||||
rawAddSon(result, typ)
|
||||
|
||||
proc toObject*(typ: PType): PType =
|
||||
|
|
@ -1888,8 +1917,8 @@ proc isSinkParam*(s: PSym): bool {.inline.} =
|
|||
proc isSinkType*(t: PType): bool {.inline.} =
|
||||
t.kind == tySink or tfHasOwned in t.flags
|
||||
|
||||
proc newProcType*(info: TLineInfo; owner: PSym): PType =
|
||||
result = newType(tyProc, owner)
|
||||
proc newProcType*(info: TLineInfo; id: ItemId; owner: PSym): PType =
|
||||
result = newType(tyProc, id, owner)
|
||||
result.n = newNodeI(nkFormalParams, info)
|
||||
rawAddSon(result, nil) # return type
|
||||
# result.n[0] used to be `nkType`, but now it's `nkEffectList` because
|
||||
|
|
|
|||
|
|
@ -1765,20 +1765,20 @@ proc genArrayLen(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
|
|||
else: putIntoDest(p, d, e, rope(lengthOrd(p.config, typ)))
|
||||
else: internalError(p.config, e.info, "genArrayLen()")
|
||||
|
||||
proc makePtrType(baseType: PType): PType =
|
||||
result = newType(tyPtr, baseType.owner)
|
||||
addSonSkipIntLit(result, baseType)
|
||||
proc makePtrType(baseType: PType; idgen: IdGenerator): PType =
|
||||
result = newType(tyPtr, nextId idgen, baseType.owner)
|
||||
addSonSkipIntLit(result, baseType, idgen)
|
||||
|
||||
proc makeAddr(n: PNode): PNode =
|
||||
proc makeAddr(n: PNode; idgen: IdGenerator): PNode =
|
||||
if n.kind == nkHiddenAddr:
|
||||
result = n
|
||||
else:
|
||||
result = newTree(nkHiddenAddr, n)
|
||||
result.typ = makePtrType(n.typ)
|
||||
result.typ = makePtrType(n.typ, idgen)
|
||||
|
||||
proc genSetLengthSeq(p: BProc, e: PNode, d: var TLoc) =
|
||||
if optSeqDestructors in p.config.globalOptions:
|
||||
e[1] = makeAddr(e[1])
|
||||
e[1] = makeAddr(e[1], p.module.idgen)
|
||||
genCall(p, e, d)
|
||||
return
|
||||
var a, b, call: TLoc
|
||||
|
|
@ -2240,7 +2240,7 @@ proc genEnumToStr(p: BProc, e: PNode, d: var TLoc) =
|
|||
toStrProc = p
|
||||
break
|
||||
if toStrProc == nil:
|
||||
toStrProc = genEnumToStrProc(t, e.info, p.module.g.graph)
|
||||
toStrProc = genEnumToStrProc(t, e.info, p.module.g.graph, p.module.idgen)
|
||||
t.methods.add((ToStringProcSlot, toStrProc))
|
||||
var n = copyTree(e)
|
||||
n[0] = newSymNode(toStrProc)
|
||||
|
|
@ -2294,7 +2294,7 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
|
|||
of mAppendStrStr: genStrAppend(p, e, d)
|
||||
of mAppendSeqElem:
|
||||
if optSeqDestructors in p.config.globalOptions:
|
||||
e[1] = makeAddr(e[1])
|
||||
e[1] = makeAddr(e[1], p.module.idgen)
|
||||
genCall(p, e, d)
|
||||
else:
|
||||
genSeqElemAppend(p, e, d)
|
||||
|
|
@ -2393,13 +2393,13 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
|
|||
when defined(leanCompiler):
|
||||
quit "compiler built without support for the 'spawn' statement"
|
||||
else:
|
||||
let n = spawn.wrapProcForSpawn(p.module.g.graph, p.module.module, e, e.typ, nil, nil)
|
||||
let n = spawn.wrapProcForSpawn(p.module.g.graph, p.module.idgen, p.module.module, e, e.typ, nil, nil)
|
||||
expr(p, n, d)
|
||||
of mParallel:
|
||||
when defined(leanCompiler):
|
||||
quit "compiler built without support for the 'parallel' statement"
|
||||
else:
|
||||
let n = semparallel.liftParallel(p.module.g.graph, p.module.module, e)
|
||||
let n = semparallel.liftParallel(p.module.g.graph, p.module.idgen, p.module.module, e)
|
||||
expr(p, n, d)
|
||||
of mDeepCopy:
|
||||
if p.config.selectedGC in {gcArc, gcOrc} and optEnableDeepCopy notin p.config.globalOptions:
|
||||
|
|
|
|||
|
|
@ -180,10 +180,6 @@ proc readKey(L: var TBaseLexer, result: var string) =
|
|||
if L.buf[pos] != ':': doAssert(false, "ccgmerge: ':' expected")
|
||||
L.bufpos = pos + 1 # skip ':'
|
||||
|
||||
proc newFakeType(id: int): PType =
|
||||
new(result)
|
||||
result.id = id
|
||||
|
||||
proc readTypeCache(L: var TBaseLexer, result: var TypeCache) =
|
||||
if ^L.bufpos != '{': doAssert(false, "ccgmerge: '{' expected")
|
||||
inc L.bufpos
|
||||
|
|
@ -192,10 +188,7 @@ proc readTypeCache(L: var TBaseLexer, result: var TypeCache) =
|
|||
var key = decodeStr(L.buf, L.bufpos)
|
||||
if ^L.bufpos != ':': doAssert(false, "ccgmerge: ':' expected")
|
||||
inc L.bufpos
|
||||
var value = decodeStr(L.buf, L.bufpos)
|
||||
# XXX implement me
|
||||
when false:
|
||||
idTablePut(result, newFakeType(key), value.rope)
|
||||
discard decodeStr(L.buf, L.bufpos)
|
||||
inc L.bufpos
|
||||
|
||||
proc readIntSet(L: var TBaseLexer, result: var IntSet) =
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ proc genVarTuple(p: BProc, n: PNode) =
|
|||
# if we have a something that's been captured, use the lowering instead:
|
||||
for i in 0..<n.len-2:
|
||||
if n[i].kind != nkSym:
|
||||
genStmts(p, lowerTupleUnpacking(p.module.g.graph, n, p.prc))
|
||||
genStmts(p, lowerTupleUnpacking(p.module.g.graph, n, p.module.idgen, p.prc))
|
||||
return
|
||||
|
||||
# check only the first son
|
||||
|
|
@ -1525,7 +1525,7 @@ proc genCaseObjDiscMapping(p: BProc, e: PNode, t: PType, field: PSym; d: var TLo
|
|||
theProc = p
|
||||
break
|
||||
if theProc == nil:
|
||||
theProc = genCaseObjDiscMapping(t, field, e.info, p.module.g.graph)
|
||||
theProc = genCaseObjDiscMapping(t, field, e.info, p.module.g.graph, p.module.idgen)
|
||||
t.methods.add((ObjDiscMappingProcSlot, theProc))
|
||||
var call = newNodeIT(nkCall, e.info, getSysType(p.module.g.graph, e.info, tyUInt8))
|
||||
call.add newSymNode(theProc)
|
||||
|
|
|
|||
|
|
@ -1266,10 +1266,10 @@ proc genArrayInfo(m: BModule, typ: PType, name: Rope; info: TLineInfo) =
|
|||
|
||||
proc fakeClosureType(m: BModule; owner: PSym): PType =
|
||||
# we generate the same RTTI as for a tuple[pointer, ref tuple[]]
|
||||
result = newType(tyTuple, owner)
|
||||
result.rawAddSon(newType(tyPointer, owner))
|
||||
var r = newType(tyRef, owner)
|
||||
let obj = createObj(m.g.graph, owner, owner.info, final=false)
|
||||
result = newType(tyTuple, nextId m.idgen, owner)
|
||||
result.rawAddSon(newType(tyPointer, nextId m.idgen, owner))
|
||||
var r = newType(tyRef, nextId m.idgen, owner)
|
||||
let obj = createObj(m.g.graph, m.idgen, owner, owner.info, final=false)
|
||||
r.rawAddSon(obj)
|
||||
result.rawAddSon(r)
|
||||
|
||||
|
|
@ -1395,9 +1395,9 @@ proc genTypeInfoV2(m: BModule, t: PType; info: TLineInfo): Rope =
|
|||
result = prefixTI.rope & result & ")".rope
|
||||
|
||||
proc openArrayToTuple(m: BModule; t: PType): PType =
|
||||
result = newType(tyTuple, t.owner)
|
||||
let p = newType(tyPtr, t.owner)
|
||||
let a = newType(tyUncheckedArray, t.owner)
|
||||
result = newType(tyTuple, nextId m.idgen, t.owner)
|
||||
let p = newType(tyPtr, nextId m.idgen, t.owner)
|
||||
let a = newType(tyUncheckedArray, nextId m.idgen, t.owner)
|
||||
a.add t.lastSon
|
||||
p.add a
|
||||
result.add p
|
||||
|
|
|
|||
|
|
@ -996,9 +996,9 @@ proc genProcAux(m: BModule, prc: PSym) =
|
|||
var returnStmt: Rope = nil
|
||||
assert(prc.ast != nil)
|
||||
|
||||
var procBody = transformBody(m.g.graph, prc, cache = false)
|
||||
var procBody = transformBody(m.g.graph, m.idgen, prc, cache = false)
|
||||
if sfInjectDestructors in prc.flags:
|
||||
procBody = injectDestructorCalls(m.g.graph, prc, procBody)
|
||||
procBody = injectDestructorCalls(m.g.graph, m.idgen, prc, procBody)
|
||||
|
||||
if sfPure notin prc.flags and prc.typ[0] != nil:
|
||||
if resultPos >= prc.ast.len:
|
||||
|
|
@ -1844,9 +1844,10 @@ template injectG() {.dirty.} =
|
|||
when not defined(nimHasSinkInference):
|
||||
{.pragma: nosinks.}
|
||||
|
||||
proc myOpen(graph: ModuleGraph; module: PSym): PPassContext {.nosinks.} =
|
||||
proc myOpen(graph: ModuleGraph; module: PSym; idgen: IdGenerator): PPassContext {.nosinks.} =
|
||||
injectG()
|
||||
result = newModule(g, module, graph.config)
|
||||
result.idgen = idgen
|
||||
if optGenIndex in graph.config.globalOptions and g.generatedHeader == nil:
|
||||
let f = if graph.config.headerFile.len > 0: AbsoluteFile graph.config.headerFile
|
||||
else: graph.config.projectFull
|
||||
|
|
@ -1920,9 +1921,9 @@ proc myProcess(b: PPassContext, n: PNode): PNode =
|
|||
m.initProc.options = initProcOptions(m)
|
||||
#softRnl = if optLineDir in m.config.options: noRnl else: rnl
|
||||
# XXX replicate this logic!
|
||||
var transformedN = transformStmt(m.g.graph, m.module, n)
|
||||
var transformedN = transformStmt(m.g.graph, m.idgen, m.module, n)
|
||||
if sfInjectDestructors in m.module.flags:
|
||||
transformedN = injectDestructorCalls(m.g.graph, m.module, transformedN)
|
||||
transformedN = injectDestructorCalls(m.g.graph, m.idgen, m.module, transformedN)
|
||||
|
||||
if m.hcrOn:
|
||||
addHcrInitGuards(m.initProc, transformedN, m.inHcrInitGuard)
|
||||
|
|
|
|||
|
|
@ -107,11 +107,11 @@ proc attachDispatcher(s: PSym, dispatcher: PNode) =
|
|||
s.ast[resultPos] = newNodeI(nkEmpty, s.info)
|
||||
s.ast[dispatcherPos] = dispatcher
|
||||
|
||||
proc createDispatcher(s: PSym): PSym =
|
||||
var disp = copySym(s)
|
||||
proc createDispatcher(s: PSym; idgen: IdGenerator): PSym =
|
||||
var disp = copySym(s, nextId(idgen))
|
||||
incl(disp.flags, sfDispatcher)
|
||||
excl(disp.flags, sfExported)
|
||||
disp.typ = copyType(disp.typ, disp.typ.owner, false)
|
||||
disp.typ = copyType(disp.typ, nextId(idgen), disp.typ.owner)
|
||||
# we can't inline the dispatcher itself (for now):
|
||||
if disp.typ.callConv == ccInline: disp.typ.callConv = ccNimCall
|
||||
disp.ast = copyTree(s.ast)
|
||||
|
|
@ -119,7 +119,7 @@ proc createDispatcher(s: PSym): PSym =
|
|||
disp.loc.r = nil
|
||||
if s.typ[0] != nil:
|
||||
if disp.ast.len > resultPos:
|
||||
disp.ast[resultPos].sym = copySym(s.ast[resultPos].sym)
|
||||
disp.ast[resultPos].sym = copySym(s.ast[resultPos].sym, nextId(idgen))
|
||||
else:
|
||||
# We've encountered a method prototype without a filled-in
|
||||
# resultPos slot. We put a placeholder in there that will
|
||||
|
|
@ -157,7 +157,7 @@ proc fixupDispatcher(meth, disp: PSym; conf: ConfigRef) =
|
|||
if disp.typ.lockLevel < meth.typ.lockLevel:
|
||||
disp.typ.lockLevel = meth.typ.lockLevel
|
||||
|
||||
proc methodDef*(g: ModuleGraph; s: PSym, fromCache: bool) =
|
||||
proc methodDef*(g: ModuleGraph; idgen: IdGenerator; s: PSym, fromCache: bool) =
|
||||
var witness: PSym
|
||||
for i in 0..<g.methods.len:
|
||||
let disp = g.methods[i].dispatcher
|
||||
|
|
@ -177,7 +177,7 @@ proc methodDef*(g: ModuleGraph; s: PSym, fromCache: bool) =
|
|||
of Invalid:
|
||||
if witness.isNil: witness = g.methods[i].methods[0]
|
||||
# create a new dispatcher:
|
||||
g.methods.add((methods: @[s], dispatcher: createDispatcher(s)))
|
||||
g.methods.add((methods: @[s], dispatcher: createDispatcher(s, idgen)))
|
||||
#echo "adding ", s.info
|
||||
#if fromCache:
|
||||
# internalError(s.info, "no method dispatcher found")
|
||||
|
|
|
|||
|
|
@ -153,6 +153,7 @@ type
|
|||
curExcHandlingState: int # Negative for except, positive for finally
|
||||
nearestFinally: int # Index of the nearest finally block. For try/except it
|
||||
# is their finally. For finally it is parent finally. Otherwise -1
|
||||
idgen: IdGenerator
|
||||
|
||||
const
|
||||
nkSkip = {nkEmpty..nkNilLit, nkTemplateDef, nkTypeSection, nkStaticStmt,
|
||||
|
|
@ -176,7 +177,7 @@ proc newStateAssgn(ctx: var Ctx, stateNo: int = -2): PNode =
|
|||
ctx.newStateAssgn(newIntTypeNode(stateNo, ctx.g.getSysType(TLineInfo(), tyInt)))
|
||||
|
||||
proc newEnvVar(ctx: var Ctx, name: string, typ: PType): PSym =
|
||||
result = newSym(skVar, getIdent(ctx.g.cache, name), ctx.fn, ctx.fn.info)
|
||||
result = newSym(skVar, getIdent(ctx.g.cache, name), nextId(ctx.idgen), ctx.fn, ctx.fn.info)
|
||||
result.typ = typ
|
||||
assert(not typ.isNil)
|
||||
|
||||
|
|
@ -189,7 +190,7 @@ proc newEnvVar(ctx: var Ctx, name: string, typ: PType): PSym =
|
|||
else:
|
||||
let envParam = getEnvParam(ctx.fn)
|
||||
# let obj = envParam.typ.lastSon
|
||||
result = addUniqueField(envParam.typ.lastSon, result, ctx.g.cache)
|
||||
result = addUniqueField(envParam.typ.lastSon, result, ctx.g.cache, ctx.idgen)
|
||||
|
||||
proc newEnvVarAccess(ctx: Ctx, s: PSym): PNode =
|
||||
if ctx.stateVarSym.isNil:
|
||||
|
|
@ -804,7 +805,7 @@ proc newEndFinallyNode(ctx: var Ctx, info: TLineInfo): PNode =
|
|||
cmp.typ = ctx.g.getSysType(info, tyBool)
|
||||
|
||||
let asgn = newTree(nkFastAsgn,
|
||||
newSymNode(getClosureIterResult(ctx.g, ctx.fn), info),
|
||||
newSymNode(getClosureIterResult(ctx.g, ctx.fn, ctx.idgen), info),
|
||||
ctx.newTmpResultAccess())
|
||||
|
||||
let retStmt = newTree(nkReturnStmt, asgn)
|
||||
|
|
@ -1044,7 +1045,7 @@ proc transformStateAssignments(ctx: var Ctx, n: PNode): PNode =
|
|||
if n[0][0].kind != nkEmpty:
|
||||
var a = newNodeI(nkAsgn, n[0][0].info)
|
||||
var retVal = n[0][0] #liftCapturedVars(n[0], owner, d, c)
|
||||
a.add newSymNode(getClosureIterResult(ctx.g, ctx.fn))
|
||||
a.add newSymNode(getClosureIterResult(ctx.g, ctx.fn, ctx.idgen))
|
||||
a.add retVal
|
||||
retStmt.add(a)
|
||||
else:
|
||||
|
|
@ -1116,10 +1117,10 @@ proc skipThroughEmptyStates(ctx: var Ctx, n: PNode): PNode=
|
|||
for i in 0..<n.len:
|
||||
n[i] = ctx.skipThroughEmptyStates(n[i])
|
||||
|
||||
proc newArrayType(g: ModuleGraph; n: int, t: PType, owner: PSym): PType =
|
||||
result = newType(tyArray, owner)
|
||||
proc newArrayType(g: ModuleGraph; n: int, t: PType; idgen: IdGenerator; owner: PSym): PType =
|
||||
result = newType(tyArray, nextId(idgen), owner)
|
||||
|
||||
let rng = newType(tyRange, owner)
|
||||
let rng = newType(tyRange, nextId(idgen), owner)
|
||||
rng.n = newTree(nkRange, g.newIntLit(owner.info, 0), g.newIntLit(owner.info, n))
|
||||
rng.rawAddSon(t)
|
||||
|
||||
|
|
@ -1128,7 +1129,7 @@ proc newArrayType(g: ModuleGraph; n: int, t: PType, owner: PSym): PType =
|
|||
|
||||
proc createExceptionTable(ctx: var Ctx): PNode {.inline.} =
|
||||
result = newNodeI(nkBracket, ctx.fn.info)
|
||||
result.typ = ctx.g.newArrayType(ctx.exceptionTable.len, ctx.g.getSysType(ctx.fn.info, tyInt16), ctx.fn)
|
||||
result.typ = ctx.g.newArrayType(ctx.exceptionTable.len, ctx.g.getSysType(ctx.fn.info, tyInt16), ctx.idgen, ctx.fn)
|
||||
|
||||
for i in ctx.exceptionTable:
|
||||
let elem = newIntNode(nkIntLit, i)
|
||||
|
|
@ -1289,10 +1290,12 @@ type
|
|||
finallys: seq[PNode]
|
||||
config: ConfigRef
|
||||
blocks: seq[(PNode, int)]
|
||||
idgen: IdGenerator
|
||||
FreshVarsContext = object
|
||||
tab: Table[int, PSym]
|
||||
config: ConfigRef
|
||||
info: TLineInfo
|
||||
idgen: IdGenerator
|
||||
|
||||
proc freshVars(n: PNode; c: var FreshVarsContext): PNode =
|
||||
case n.kind
|
||||
|
|
@ -1311,7 +1314,7 @@ proc freshVars(n: PNode; c: var FreshVarsContext): PNode =
|
|||
let idefs = copyNode(it)
|
||||
for v in 0..it.len-3:
|
||||
if it[v].kind == nkSym:
|
||||
let x = copySym(it[v].sym)
|
||||
let x = copySym(it[v].sym, nextId(c.idgen))
|
||||
c.tab[it[v].sym.id] = x
|
||||
idefs.add newSymNode(x)
|
||||
else:
|
||||
|
|
@ -1371,27 +1374,29 @@ proc preprocess(c: var PreprocessContext; n: PNode): PNode =
|
|||
if fin >= 0:
|
||||
result = newNodeI(nkStmtList, n.info)
|
||||
for i in countdown(c.finallys.high, fin):
|
||||
var vars = FreshVarsContext(tab: initTable[int, PSym](), config: c.config, info: n.info)
|
||||
var vars = FreshVarsContext(tab: initTable[int, PSym](), config: c.config, info: n.info, idgen: c.idgen)
|
||||
result.add freshVars(preprocess(c, c.finallys[i]), vars)
|
||||
c.idgen = vars.idgen
|
||||
result.add n
|
||||
of nkSkip: discard
|
||||
else:
|
||||
for i in 0 ..< n.len:
|
||||
result[i] = preprocess(c, n[i])
|
||||
|
||||
proc transformClosureIterator*(g: ModuleGraph; fn: PSym, n: PNode): PNode =
|
||||
proc transformClosureIterator*(g: ModuleGraph; idgen: IdGenerator; fn: PSym, n: PNode): PNode =
|
||||
var ctx: Ctx
|
||||
ctx.g = g
|
||||
ctx.fn = fn
|
||||
ctx.idgen = idgen
|
||||
|
||||
if getEnvParam(fn).isNil:
|
||||
# Lambda lifting was not done yet. Use temporary :state sym, which will
|
||||
# be handled specially by lambda lifting. Local temp vars (if needed)
|
||||
# should follow the same logic.
|
||||
ctx.stateVarSym = newSym(skVar, getIdent(ctx.g.cache, ":state"), fn, fn.info)
|
||||
ctx.stateVarSym.typ = g.createClosureIterStateType(fn)
|
||||
ctx.stateLoopLabel = newSym(skLabel, getIdent(ctx.g.cache, ":stateLoop"), fn, fn.info)
|
||||
var pc = PreprocessContext(finallys: @[], config: g.config)
|
||||
ctx.stateVarSym = newSym(skVar, getIdent(ctx.g.cache, ":state"), nextId(idgen), fn, fn.info)
|
||||
ctx.stateVarSym.typ = g.createClosureIterStateType(fn, idgen)
|
||||
ctx.stateLoopLabel = newSym(skLabel, getIdent(ctx.g.cache, ":stateLoop"), nextId(idgen), fn, fn.info)
|
||||
var pc = PreprocessContext(finallys: @[], config: g.config, idgen: idgen)
|
||||
var n = preprocess(pc, n.toStmtList)
|
||||
#echo "transformed into ", n
|
||||
#var n = n.toStmtList
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ proc loadConfigsAndRunMainCommand*(self: NimProg, cache: IdentCache; conf: Confi
|
|||
graph: ModuleGraph): bool =
|
||||
if self.suggestMode:
|
||||
conf.command = "nimsuggest"
|
||||
loadConfigs(DefaultConfig, cache, conf) # load all config files
|
||||
loadConfigs(DefaultConfig, cache, conf, graph.idgen) # load all config files
|
||||
|
||||
if not self.suggestMode:
|
||||
let scriptFile = conf.projectFull.changeFileExt("nims")
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ proc generateDot*(graph: ModuleGraph; project: AbsoluteFile) =
|
|||
when not defined(nimHasSinkInference):
|
||||
{.pragma: nosinks.}
|
||||
|
||||
proc myOpen(graph: ModuleGraph; module: PSym): PPassContext {.nosinks.} =
|
||||
proc myOpen(graph: ModuleGraph; module: PSym; idgen: IdGenerator): PPassContext {.nosinks.} =
|
||||
var g: PGen
|
||||
new(g)
|
||||
g.module = module
|
||||
|
|
|
|||
|
|
@ -68,10 +68,10 @@ template myOpenImpl(ext: untyped) {.dirty.} =
|
|||
g.doc = d
|
||||
result = g
|
||||
|
||||
proc myOpen(graph: ModuleGraph; module: PSym): PPassContext =
|
||||
proc myOpen(graph: ModuleGraph; module: PSym; idgen: IdGenerator): PPassContext =
|
||||
myOpenImpl(HtmlExt)
|
||||
|
||||
proc myOpenJson(graph: ModuleGraph; module: PSym): PPassContext =
|
||||
proc myOpenJson(graph: ModuleGraph; module: PSym; idgen: IdGenerator): PPassContext =
|
||||
myOpenImpl(JsonExt)
|
||||
|
||||
const docgen2Pass* = makePass(open = myOpen, process = processNode, close = close)
|
||||
|
|
|
|||
|
|
@ -1,16 +1,16 @@
|
|||
|
||||
import ast, idents, lineinfos, modulegraphs, magicsys
|
||||
|
||||
proc genEnumToStrProc*(t: PType; info: TLineInfo; g: ModuleGraph): PSym =
|
||||
result = newSym(skProc, getIdent(g.cache, "$"), t.owner, info)
|
||||
proc genEnumToStrProc*(t: PType; info: TLineInfo; g: ModuleGraph; idgen: IdGenerator): PSym =
|
||||
result = newSym(skProc, getIdent(g.cache, "$"), nextId idgen, t.owner, info)
|
||||
|
||||
let dest = newSym(skParam, getIdent(g.cache, "e"), result, info)
|
||||
let dest = newSym(skParam, getIdent(g.cache, "e"), nextId idgen, result, info)
|
||||
dest.typ = t
|
||||
|
||||
let res = newSym(skResult, getIdent(g.cache, "result"), result, info)
|
||||
let res = newSym(skResult, getIdent(g.cache, "result"), nextId idgen, result, info)
|
||||
res.typ = getSysType(g, info, tyString)
|
||||
|
||||
result.typ = newType(tyProc, t.owner)
|
||||
result.typ = newType(tyProc, nextId idgen, t.owner)
|
||||
result.typ.n = newNodeI(nkFormalParams, info)
|
||||
rawAddSon(result.typ, res.typ)
|
||||
result.typ.n.add newNodeI(nkEffectList, info)
|
||||
|
|
@ -62,16 +62,16 @@ proc searchObjCase(t: PType; field: PSym): PNode =
|
|||
result = searchObjCase(t[0].skipTypes({tyAlias, tyGenericInst, tyRef, tyPtr}), field)
|
||||
doAssert result != nil
|
||||
|
||||
proc genCaseObjDiscMapping*(t: PType; field: PSym; info: TLineInfo; g: ModuleGraph): PSym =
|
||||
result = newSym(skProc, getIdent(g.cache, "objDiscMapping"), t.owner, info)
|
||||
proc genCaseObjDiscMapping*(t: PType; field: PSym; info: TLineInfo; g: ModuleGraph; idgen: IdGenerator): PSym =
|
||||
result = newSym(skProc, getIdent(g.cache, "objDiscMapping"), nextId idgen, t.owner, info)
|
||||
|
||||
let dest = newSym(skParam, getIdent(g.cache, "e"), result, info)
|
||||
let dest = newSym(skParam, getIdent(g.cache, "e"), nextId idgen, result, info)
|
||||
dest.typ = field.typ
|
||||
|
||||
let res = newSym(skResult, getIdent(g.cache, "result"), result, info)
|
||||
let res = newSym(skResult, getIdent(g.cache, "result"), nextId idgen, result, info)
|
||||
res.typ = getSysType(g, info, tyUInt8)
|
||||
|
||||
result.typ = newType(tyProc, t.owner)
|
||||
result.typ = newType(tyProc, nextId idgen, t.owner)
|
||||
result.typ.n = newNodeI(nkFormalParams, info)
|
||||
rawAddSon(result.typ, res.typ)
|
||||
result.typ.n.add newNodeI(nkEffectList, info)
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ type
|
|||
config: ConfigRef
|
||||
ic: IdentCache
|
||||
instID: int
|
||||
idgen: IdGenerator
|
||||
|
||||
proc copyNode(ctx: TemplCtx, a, b: PNode): PNode =
|
||||
result = copyNode(a)
|
||||
|
|
@ -48,7 +49,7 @@ proc evalTemplateAux(templ, actual: PNode, c: var TemplCtx, result: PNode) =
|
|||
internalAssert c.config, sfGenSym in s.flags or s.kind == skType
|
||||
var x = PSym(idTableGet(c.mapping, s))
|
||||
if x == nil:
|
||||
x = copySym(s)
|
||||
x = copySym(s, nextId(c.idgen))
|
||||
# sem'check needs to set the owner properly later, see bug #9476
|
||||
x.owner = nil # c.genSymOwner
|
||||
#if x.kind == skParam and x.owner.kind == skModule:
|
||||
|
|
@ -168,6 +169,7 @@ proc wrapInComesFrom*(info: TLineInfo; sym: PSym; res: PNode): PNode =
|
|||
proc evalTemplate*(n: PNode, tmpl, genSymOwner: PSym;
|
||||
conf: ConfigRef;
|
||||
ic: IdentCache; instID: ref int;
|
||||
idgen: IdGenerator;
|
||||
fromHlo=false): PNode =
|
||||
inc(conf.evalTemplateCounter)
|
||||
if conf.evalTemplateCounter > evalTemplateLimit:
|
||||
|
|
@ -183,6 +185,7 @@ proc evalTemplate*(n: PNode, tmpl, genSymOwner: PSym;
|
|||
ctx.ic = ic
|
||||
initIdTable(ctx.mapping)
|
||||
ctx.instID = instID[]
|
||||
ctx.idgen = idgen
|
||||
|
||||
let body = tmpl.getBody
|
||||
#echo "instantion of ", renderTree(body, {renderIds})
|
||||
|
|
|
|||
|
|
@ -993,8 +993,9 @@ proc addFactLt*(m: var TModel; a, b: PNode) =
|
|||
addFactLe(m, a, bb)
|
||||
|
||||
proc settype(n: PNode): PType =
|
||||
result = newType(tySet, n.typ.owner)
|
||||
addSonSkipIntLit(result, n.typ)
|
||||
result = newType(tySet, ItemId(module: -1, item: -1), n.typ.owner)
|
||||
var idgen: IdGenerator
|
||||
addSonSkipIntLit(result, n.typ, idgen)
|
||||
|
||||
proc buildOf(it, loc: PNode; o: Operators): PNode =
|
||||
var s = newNodeI(nkCurly, it.info, it.len-1)
|
||||
|
|
|
|||
|
|
@ -86,9 +86,9 @@ proc hlo(c: PContext, n: PNode): PNode =
|
|||
else:
|
||||
result = fitNode(c, n.typ, result, n.info)
|
||||
# optimization has been applied so check again:
|
||||
result = commonOptimizations(c.graph, c.module, result)
|
||||
result = commonOptimizations(c.graph, c.idgen, c.module, result)
|
||||
result = hlo(c, result)
|
||||
result = commonOptimizations(c.graph, c.module, result)
|
||||
result = commonOptimizations(c.graph, c.idgen, c.module, result)
|
||||
|
||||
proc hloBody(c: PContext, n: PNode): PNode =
|
||||
# fast exit:
|
||||
|
|
|
|||
|
|
@ -15,12 +15,9 @@ import
|
|||
hashes, wordrecg
|
||||
|
||||
type
|
||||
TIdObj* = object of RootObj
|
||||
id*: int # unique id; use this for comparisons and not the pointers
|
||||
|
||||
PIdObj* = ref TIdObj
|
||||
PIdent* = ref TIdent
|
||||
TIdent*{.acyclic.} = object of TIdObj
|
||||
TIdent*{.acyclic.} = object
|
||||
id*: int # unique id; use this for comparisons and not the pointers
|
||||
s*: string
|
||||
next*: PIdent # for hash-table chaining
|
||||
h*: Hash # hash value of s
|
||||
|
|
|
|||
|
|
@ -1,59 +0,0 @@
|
|||
#
|
||||
#
|
||||
# The Nim Compiler
|
||||
# (c) Copyright 2012 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
## This module contains a simple persistent id generator.
|
||||
|
||||
import idents, strutils, options, pathutils
|
||||
|
||||
var gFrontEndId*: int
|
||||
|
||||
const
|
||||
debugIds* = false
|
||||
|
||||
when debugIds:
|
||||
import intsets
|
||||
|
||||
var usedIds = initIntSet()
|
||||
|
||||
proc registerID*(id: PIdObj) =
|
||||
when debugIds:
|
||||
if id.id == -1 or containsOrIncl(usedIds, id.id):
|
||||
internalError("ID already used: " & $id.id)
|
||||
|
||||
proc getID*(): int {.inline.} =
|
||||
result = gFrontEndId
|
||||
inc(gFrontEndId)
|
||||
|
||||
proc setId*(id: int) {.inline.} =
|
||||
gFrontEndId = max(gFrontEndId, id + 1)
|
||||
|
||||
proc idSynchronizationPoint*(idRange: int) =
|
||||
gFrontEndId = (gFrontEndId div idRange + 1) * idRange + 1
|
||||
|
||||
proc toGid(conf: ConfigRef; f: AbsoluteFile): string =
|
||||
# we used to use ``f.addFileExt("gid")`` (aka ``$project.gid``), but this
|
||||
# will cause strange bugs if multiple projects are in the same folder, so
|
||||
# we simply use a project independent name:
|
||||
result = options.completeGeneratedFilePath(conf, AbsoluteFile"nim.gid").string
|
||||
|
||||
proc saveMaxIds*(conf: ConfigRef; project: AbsoluteFile) =
|
||||
var f = open(toGid(conf, project), fmWrite)
|
||||
f.writeLine($gFrontEndId)
|
||||
f.close()
|
||||
|
||||
proc loadMaxIds*(conf: ConfigRef; project: AbsoluteFile) =
|
||||
var f: File
|
||||
if open(f, toGid(conf, project), fmRead):
|
||||
var line = newStringOfCap(20)
|
||||
if f.readLine(line):
|
||||
var frontEndId = parseInt(line)
|
||||
if f.readLine(line):
|
||||
# var backEndId = parseInt(line)
|
||||
gFrontEndId = max(gFrontEndId, frontEndId)
|
||||
f.close()
|
||||
|
|
@ -136,7 +136,7 @@ proc importModuleAs(c: PContext; n: PNode, realModule: PSym): PSym =
|
|||
localError(c.config, n.info, "module alias must be an identifier")
|
||||
elif n[1].ident.id != realModule.name.id:
|
||||
# some misguided guy will write 'import abc.foo as foo' ...
|
||||
result = createModuleAlias(realModule, n[1].ident, realModule.info,
|
||||
result = createModuleAlias(realModule, nextId c.idgen, n[1].ident, realModule.info,
|
||||
c.config.options)
|
||||
|
||||
proc myImportModule(c: PContext, n: PNode; importStmtResult: PNode): PSym =
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ type
|
|||
inLoop, inSpawn: int
|
||||
uninit: IntSet # set of uninit'ed vars
|
||||
uninitComputed: bool
|
||||
idgen: IdGenerator
|
||||
|
||||
ProcessMode = enum
|
||||
normal
|
||||
|
|
@ -61,7 +62,7 @@ template dbg(body) =
|
|||
body
|
||||
|
||||
proc getTemp(c: var Con; s: var Scope; typ: PType; info: TLineInfo): PNode =
|
||||
let sym = newSym(skTemp, getIdent(c.graph.cache, ":tmpD"), c.owner, info)
|
||||
let sym = newSym(skTemp, getIdent(c.graph.cache, ":tmpD"), nextId c.idgen, c.owner, info)
|
||||
sym.typ = typ
|
||||
s.vars.add(sym)
|
||||
result = newSymNode(sym)
|
||||
|
|
@ -250,16 +251,16 @@ proc checkForErrorPragma(c: Con; t: PType; ri: PNode; opname: string) =
|
|||
m.add c.owner.name.s
|
||||
localError(c.graph.config, ri.info, errGenerated, m)
|
||||
|
||||
proc makePtrType(c: Con, baseType: PType): PType =
|
||||
result = newType(tyPtr, c.owner)
|
||||
addSonSkipIntLit(result, baseType)
|
||||
proc makePtrType(c: var Con, baseType: PType): PType =
|
||||
result = newType(tyPtr, nextId c.idgen, c.owner)
|
||||
addSonSkipIntLit(result, baseType, c.idgen)
|
||||
|
||||
proc genOp(c: Con; op: PSym; dest: PNode): PNode =
|
||||
proc genOp(c: var Con; op: PSym; dest: PNode): PNode =
|
||||
let addrExp = newNodeIT(nkHiddenAddr, dest.info, makePtrType(c, dest.typ))
|
||||
addrExp.add(dest)
|
||||
result = newTree(nkCall, newSymNode(op), addrExp)
|
||||
|
||||
proc genOp(c: Con; t: PType; kind: TTypeAttachedOp; dest, ri: PNode): PNode =
|
||||
proc genOp(c: var Con; t: PType; kind: TTypeAttachedOp; dest, ri: PNode): PNode =
|
||||
var op = t.attachedOps[kind]
|
||||
if op == nil or op.ast[genericParamsPos].kind != nkEmpty:
|
||||
# give up and find the canonical type instead:
|
||||
|
|
@ -280,7 +281,7 @@ proc genOp(c: Con; t: PType; kind: TTypeAttachedOp; dest, ri: PNode): PNode =
|
|||
if sfError in op.flags: checkForErrorPragma(c, t, ri, AttachedOpToStr[kind])
|
||||
c.genOp(op, dest)
|
||||
|
||||
proc genDestroy(c: Con; dest: PNode): PNode =
|
||||
proc genDestroy(c: var Con; dest: PNode): PNode =
|
||||
let t = dest.typ.skipTypes({tyGenericInst, tyAlias, tySink})
|
||||
result = c.genOp(t, attachedDestructor, dest, nil)
|
||||
|
||||
|
|
@ -310,7 +311,7 @@ proc genSink(c: var Con; dest, ri: PNode, isDecl = false): PNode =
|
|||
# and copyMem(dest, source). This is efficient.
|
||||
result = newTree(nkStmtList, c.genDestroy(dest), newTree(nkFastAsgn, dest, ri))
|
||||
|
||||
proc genCopyNoCheck(c: Con; dest, ri: PNode): PNode =
|
||||
proc genCopyNoCheck(c: var Con; dest, ri: PNode): PNode =
|
||||
let t = dest.typ.skipTypes({tyGenericInst, tyAlias, tySink})
|
||||
result = c.genOp(t, attachedAsgn, dest, ri)
|
||||
|
||||
|
|
@ -346,7 +347,7 @@ It is best to factor out piece of object that needs custom destructor into separ
|
|||
return
|
||||
|
||||
# generate: if le != tmp: `=destroy`(le)
|
||||
let branchDestructor = produceDestructorForDiscriminator(c.graph, objType, leDotExpr[1].sym, n.info)
|
||||
let branchDestructor = produceDestructorForDiscriminator(c.graph, objType, leDotExpr[1].sym, n.info, c.idgen)
|
||||
let cond = newNodeIT(nkInfix, n.info, getSysType(c.graph, unknownLineInfo, tyBool))
|
||||
cond.add newSymNode(getMagicEqSymForType(c.graph, le.typ, n.info))
|
||||
cond.add le
|
||||
|
|
@ -377,7 +378,7 @@ proc destructiveMoveVar(n: PNode; c: var Con; s: var Scope): PNode =
|
|||
else:
|
||||
result = newNodeIT(nkStmtListExpr, n.info, n.typ)
|
||||
|
||||
var temp = newSym(skLet, getIdent(c.graph.cache, "blitTmp"), c.owner, n.info)
|
||||
var temp = newSym(skLet, getIdent(c.graph.cache, "blitTmp"), nextId c.idgen, c.owner, n.info)
|
||||
temp.typ = n.typ
|
||||
var v = newNodeI(nkLetSection, n.info)
|
||||
let tempAsNode = newSymNode(temp)
|
||||
|
|
@ -799,7 +800,7 @@ proc p(n: PNode; c: var Con; s: var Scope; mode: ProcessMode): PNode =
|
|||
for it in n:
|
||||
var ri = it[^1]
|
||||
if it.kind == nkVarTuple and hasDestructor(c, ri.typ):
|
||||
let x = lowerTupleUnpacking(c.graph, it, c.owner)
|
||||
let x = lowerTupleUnpacking(c.graph, it, c.idgen, c.owner)
|
||||
result.add p(x, c, s, consumed)
|
||||
elif it.kind == nkIdentDefs and hasDestructor(c, it[0].typ) and not isCursor(it[0], c):
|
||||
for j in 0..<it.len-2:
|
||||
|
|
@ -1010,10 +1011,10 @@ proc injectDefaultCalls(n: PNode, c: var Con) =
|
|||
for i in 0..<n.safeLen:
|
||||
injectDefaultCalls(n[i], c)
|
||||
|
||||
proc injectDestructorCalls*(g: ModuleGraph; owner: PSym; n: PNode): PNode =
|
||||
proc injectDestructorCalls*(g: ModuleGraph; idgen: IdGenerator; owner: PSym; n: PNode): PNode =
|
||||
if sfGeneratedOp in owner.flags or (owner.kind == skIterator and isInlineIterator(owner.typ)):
|
||||
return n
|
||||
var c = Con(owner: owner, graph: g, g: constructCfg(owner, n))
|
||||
var c = Con(owner: owner, graph: g, g: constructCfg(owner, n), idgen: idgen)
|
||||
dbg:
|
||||
echo "\n### ", owner.name.s, ":\nCFG:"
|
||||
echoCfg(c.g)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
## https://github.com/nim-lang/RFCs/issues/244 for more details.
|
||||
|
||||
import
|
||||
ast, types, renderer, idents, intsets
|
||||
ast, types, renderer, intsets
|
||||
|
||||
proc canAlias(arg, ret: PType; marker: var IntSet): bool
|
||||
|
||||
|
|
|
|||
|
|
@ -602,12 +602,12 @@ proc arithAux(p: PProc, n: PNode, r: var TCompRes, op: TMagic) =
|
|||
of mMulF64: applyFormat("($1 * $2)", "($1 * $2)")
|
||||
of mDivF64: applyFormat("($1 / $2)", "($1 / $2)")
|
||||
of mShrI: applyFormat("", "")
|
||||
of mShlI:
|
||||
of mShlI:
|
||||
if n[1].typ.size <= 4:
|
||||
applyFormat("($1 << $2)", "($1 << $2)")
|
||||
else:
|
||||
applyFormat("($1 * Math.pow(2,$2))", "($1 * Math.pow(2,$2))")
|
||||
of mAshrI:
|
||||
of mAshrI:
|
||||
if n[1].typ.size <= 4:
|
||||
applyFormat("($1 >> $2)", "($1 >> $2)")
|
||||
else:
|
||||
|
|
@ -1804,7 +1804,7 @@ proc genVarStmt(p: PProc, n: PNode) =
|
|||
var a = n[i]
|
||||
if a.kind != nkCommentStmt:
|
||||
if a.kind == nkVarTuple:
|
||||
let unpacked = lowerTupleUnpacking(p.module.graph, a, p.prc)
|
||||
let unpacked = lowerTupleUnpacking(p.module.graph, a, p.module.idgen, p.prc)
|
||||
genStmt(p, unpacked)
|
||||
else:
|
||||
assert(a.kind == nkIdentDefs)
|
||||
|
|
@ -2316,9 +2316,9 @@ proc genProc(oldProc: PProc, prc: PSym): Rope =
|
|||
else:
|
||||
returnStmt = "return $#;$n" % [a.res]
|
||||
|
||||
var transformedBody = transformBody(oldProc.module.graph, prc, cache = false)
|
||||
var transformedBody = transformBody(p.module.graph, p.module.idgen, prc, cache = false)
|
||||
if sfInjectDestructors in prc.flags:
|
||||
transformedBody = injectDestructorCalls(oldProc.module.graph, prc, transformedBody)
|
||||
transformedBody = injectDestructorCalls(p.module.graph, p.module.idgen, prc, transformedBody)
|
||||
|
||||
p.nested: genStmt(p, transformedBody)
|
||||
|
||||
|
|
@ -2607,9 +2607,9 @@ proc genModule(p: PProc, n: PNode) =
|
|||
p.body.add(frameCreate(p,
|
||||
makeJSString("module " & p.module.module.name.s),
|
||||
makeJSString(toFilenameOption(p.config, p.module.module.info.fileIndex, foStacktrace))))
|
||||
var transformedN = transformStmt(p.module.graph, p.module.module, n)
|
||||
var transformedN = transformStmt(p.module.graph, p.module.idgen, p.module.module, n)
|
||||
if sfInjectDestructors in p.module.module.flags:
|
||||
transformedN = injectDestructorCalls(p.module.graph, p.module.module, transformedN)
|
||||
transformedN = injectDestructorCalls(p.module.graph, p.module.idgen, p.module.module, transformedN)
|
||||
if p.config.hcrOn and n.kind == nkStmtList:
|
||||
let moduleSym = p.module.module
|
||||
var moduleLoadedVar = rope(moduleSym.name.s) & "_loaded" &
|
||||
|
|
@ -2686,7 +2686,9 @@ proc myClose(graph: ModuleGraph; b: PPassContext, n: PNode): PNode =
|
|||
writeFile(outFile.string & ".map", $(%map))
|
||||
discard writeRopeIfNotEqual(code, outFile)
|
||||
|
||||
proc myOpen(graph: ModuleGraph; s: PSym): PPassContext =
|
||||
|
||||
proc myOpen(graph: ModuleGraph; s: PSym; idgen: IdGenerator): PPassContext =
|
||||
result = newModule(graph, s)
|
||||
result.idgen = idgen
|
||||
|
||||
const JSgenPass* = makePass(myOpen, myProcess, myClose)
|
||||
|
|
|
|||
|
|
@ -126,32 +126,32 @@ proc newCall(a: PSym, b: PNode): PNode =
|
|||
result.add newSymNode(a)
|
||||
result.add b
|
||||
|
||||
proc createClosureIterStateType*(g: ModuleGraph; iter: PSym): PType =
|
||||
proc createClosureIterStateType*(g: ModuleGraph; iter: PSym; idgen: IdGenerator): PType =
|
||||
var n = newNodeI(nkRange, iter.info)
|
||||
n.add newIntNode(nkIntLit, -1)
|
||||
n.add newIntNode(nkIntLit, 0)
|
||||
result = newType(tyRange, iter)
|
||||
result = newType(tyRange, nextId(idgen), iter)
|
||||
result.n = n
|
||||
var intType = nilOrSysInt(g)
|
||||
if intType.isNil: intType = newType(tyInt, iter)
|
||||
if intType.isNil: intType = newType(tyInt, nextId(idgen), iter)
|
||||
rawAddSon(result, intType)
|
||||
|
||||
proc createStateField(g: ModuleGraph; iter: PSym): PSym =
|
||||
result = newSym(skField, getIdent(g.cache, ":state"), iter, iter.info)
|
||||
result.typ = createClosureIterStateType(g, iter)
|
||||
proc createStateField(g: ModuleGraph; iter: PSym; idgen: IdGenerator): PSym =
|
||||
result = newSym(skField, getIdent(g.cache, ":state"), nextId(idgen), iter, iter.info)
|
||||
result.typ = createClosureIterStateType(g, iter, idgen)
|
||||
|
||||
proc createEnvObj(g: ModuleGraph; owner: PSym; info: TLineInfo): PType =
|
||||
proc createEnvObj(g: ModuleGraph; idgen: IdGenerator; owner: PSym; info: TLineInfo): PType =
|
||||
# YYY meh, just add the state field for every closure for now, it's too
|
||||
# hard to figure out if it comes from a closure iterator:
|
||||
result = createObj(g, owner, info, final=false)
|
||||
rawAddField(result, createStateField(g, owner))
|
||||
result = createObj(g, idgen, owner, info, final=false)
|
||||
rawAddField(result, createStateField(g, owner, idgen))
|
||||
|
||||
proc getClosureIterResult*(g: ModuleGraph; iter: PSym): PSym =
|
||||
proc getClosureIterResult*(g: ModuleGraph; iter: PSym; idgen: IdGenerator): PSym =
|
||||
if resultPos < iter.ast.len:
|
||||
result = iter.ast[resultPos].sym
|
||||
else:
|
||||
# XXX a bit hacky:
|
||||
result = newSym(skResult, getIdent(g.cache, ":result"), iter, iter.info, {})
|
||||
result = newSym(skResult, getIdent(g.cache, ":result"), nextId(idgen), iter, iter.info, {})
|
||||
result.typ = iter.typ[0]
|
||||
incl(result.flags, sfUsed)
|
||||
iter.ast.add newSymNode(result)
|
||||
|
|
@ -209,7 +209,7 @@ proc newAsgnStmt(le, ri: PNode, info: TLineInfo): PNode =
|
|||
result[0] = le
|
||||
result[1] = ri
|
||||
|
||||
proc makeClosure*(g: ModuleGraph; prc: PSym; env: PNode; info: TLineInfo): PNode =
|
||||
proc makeClosure*(g: ModuleGraph; idgen: IdGenerator; prc: PSym; env: PNode; info: TLineInfo): PNode =
|
||||
result = newNodeIT(nkClosure, info, prc.typ)
|
||||
result.add(newSymNode(prc))
|
||||
if env == nil:
|
||||
|
|
@ -219,7 +219,7 @@ proc makeClosure*(g: ModuleGraph; prc: PSym; env: PNode; info: TLineInfo): PNode
|
|||
localError(g.config, info, "internal error: taking closure of closure")
|
||||
result.add(env)
|
||||
#if isClosureIterator(result.typ):
|
||||
createTypeBoundOps(g, nil, result.typ, info)
|
||||
createTypeBoundOps(g, nil, result.typ, info, idgen)
|
||||
if tfHasAsgn in result.typ.flags or optSeqDestructors in g.config.globalOptions:
|
||||
prc.flags.incl sfInjectDestructors
|
||||
|
||||
|
|
@ -237,13 +237,13 @@ proc liftingHarmful(conf: ConfigRef; owner: PSym): bool {.inline.} =
|
|||
let isCompileTime = sfCompileTime in owner.flags or owner.kind == skMacro
|
||||
result = conf.backend == backendJs and not isCompileTime
|
||||
|
||||
proc createTypeBoundOpsLL(g: ModuleGraph; refType: PType; info: TLineInfo; owner: PSym) =
|
||||
createTypeBoundOps(g, nil, refType.lastSon, info)
|
||||
createTypeBoundOps(g, nil, refType, info)
|
||||
proc createTypeBoundOpsLL(g: ModuleGraph; refType: PType; info: TLineInfo; idgen: IdGenerator; owner: PSym) =
|
||||
createTypeBoundOps(g, nil, refType.lastSon, info, idgen)
|
||||
createTypeBoundOps(g, nil, refType, info, idgen)
|
||||
if tfHasAsgn in refType.flags or optSeqDestructors in g.config.globalOptions:
|
||||
owner.flags.incl sfInjectDestructors
|
||||
|
||||
proc liftIterSym*(g: ModuleGraph; n: PNode; owner: PSym): PNode =
|
||||
proc liftIterSym*(g: ModuleGraph; n: PNode; idgen: IdGenerator; owner: PSym): PNode =
|
||||
# transforms (iter) to (let env = newClosure[iter](); (iter, env))
|
||||
if liftingHarmful(g.config, owner): return n
|
||||
let iter = n.sym
|
||||
|
|
@ -255,10 +255,10 @@ proc liftIterSym*(g: ModuleGraph; n: PNode; owner: PSym): PNode =
|
|||
var env: PNode
|
||||
if owner.isIterator:
|
||||
let it = getHiddenParam(g, owner)
|
||||
addUniqueField(it.typ.skipTypes({tyOwned})[0], hp, g.cache)
|
||||
addUniqueField(it.typ.skipTypes({tyOwned})[0], hp, g.cache, idgen)
|
||||
env = indirectAccess(newSymNode(it), hp, hp.info)
|
||||
else:
|
||||
let e = newSym(skLet, iter.name, owner, n.info)
|
||||
let e = newSym(skLet, iter.name, nextId(idgen), owner, n.info)
|
||||
e.typ = hp.typ
|
||||
e.flags = hp.flags
|
||||
env = newSymNode(e)
|
||||
|
|
@ -267,13 +267,13 @@ proc liftIterSym*(g: ModuleGraph; n: PNode; owner: PSym): PNode =
|
|||
result.add(v)
|
||||
# add 'new' statement:
|
||||
result.add newCall(getSysSym(g, n.info, "internalNew"), env)
|
||||
createTypeBoundOpsLL(g, env.typ, n.info, owner)
|
||||
result.add makeClosure(g, iter, env, n.info)
|
||||
createTypeBoundOpsLL(g, env.typ, n.info, idgen, owner)
|
||||
result.add makeClosure(g, idgen, iter, env, n.info)
|
||||
|
||||
proc freshVarForClosureIter*(g: ModuleGraph; s, owner: PSym): PNode =
|
||||
proc freshVarForClosureIter*(g: ModuleGraph; s: PSym; idgen: IdGenerator; owner: PSym): PNode =
|
||||
let envParam = getHiddenParam(g, owner)
|
||||
let obj = envParam.typ.skipTypes({tyOwned, tyRef, tyPtr})
|
||||
addField(obj, s, g.cache)
|
||||
addField(obj, s, g.cache, idgen)
|
||||
|
||||
var access = newSymNode(envParam)
|
||||
assert obj.kind == tyObject
|
||||
|
|
@ -305,13 +305,15 @@ type
|
|||
ownerToType: Table[int, PType]
|
||||
somethingToDo: bool
|
||||
graph: ModuleGraph
|
||||
idgen: IdGenerator
|
||||
|
||||
proc initDetectionPass(g: ModuleGraph; fn: PSym): DetectionPass =
|
||||
proc initDetectionPass(g: ModuleGraph; fn: PSym; idgen: IdGenerator): DetectionPass =
|
||||
result.processed = initIntSet()
|
||||
result.capturedVars = initIntSet()
|
||||
result.ownerToType = initTable[int, PType]()
|
||||
result.processed.incl(fn.id)
|
||||
result.graph = g
|
||||
result.idgen = idgen
|
||||
|
||||
discard """
|
||||
proc outer =
|
||||
|
|
@ -327,15 +329,15 @@ proc getEnvTypeForOwner(c: var DetectionPass; owner: PSym;
|
|||
info: TLineInfo): PType =
|
||||
result = c.ownerToType.getOrDefault(owner.id)
|
||||
if result.isNil:
|
||||
result = newType(tyRef, owner)
|
||||
let obj = createEnvObj(c.graph, owner, info)
|
||||
result = newType(tyRef, nextId(c.idgen), owner)
|
||||
let obj = createEnvObj(c.graph, c.idgen, owner, info)
|
||||
rawAddSon(result, obj)
|
||||
c.ownerToType[owner.id] = result
|
||||
|
||||
proc asOwnedRef(c: DetectionPass; t: PType): PType =
|
||||
proc asOwnedRef(c: var DetectionPass; t: PType): PType =
|
||||
if optOwnedRefs in c.graph.config.globalOptions:
|
||||
assert t.kind == tyRef
|
||||
result = newType(tyOwned, t.owner)
|
||||
result = newType(tyOwned, nextId(c.idgen), t.owner)
|
||||
result.flags.incl tfHasOwned
|
||||
result.rawAddSon t
|
||||
else:
|
||||
|
|
@ -344,7 +346,7 @@ proc asOwnedRef(c: DetectionPass; t: PType): PType =
|
|||
proc getEnvTypeForOwnerUp(c: var DetectionPass; owner: PSym;
|
||||
info: TLineInfo): PType =
|
||||
var r = c.getEnvTypeForOwner(owner, info)
|
||||
result = newType(tyPtr, owner)
|
||||
result = newType(tyPtr, nextId(c.idgen), owner)
|
||||
rawAddSon(result, r.skipTypes({tyOwned, tyRef, tyPtr}))
|
||||
|
||||
proc createUpField(c: var DetectionPass; dest, dep: PSym; info: TLineInfo) =
|
||||
|
|
@ -372,7 +374,7 @@ proc createUpField(c: var DetectionPass; dest, dep: PSym; info: TLineInfo) =
|
|||
if c.graph.config.selectedGC == gcDestructors and sfCursor notin upField.flags:
|
||||
localError(c.graph.config, dep.info, "internal error: up reference is not a .cursor")
|
||||
else:
|
||||
let result = newSym(skField, upIdent, obj.owner, obj.owner.info)
|
||||
let result = newSym(skField, upIdent, nextId(c.idgen), obj.owner, obj.owner.info)
|
||||
result.typ = fieldType
|
||||
when false:
|
||||
if c.graph.config.selectedGC == gcDestructors:
|
||||
|
|
@ -410,7 +412,7 @@ proc addClosureParam(c: var DetectionPass; fn: PSym; info: TLineInfo) =
|
|||
let owner = if fn.kind == skIterator: fn else: fn.skipGenericOwner
|
||||
let t = c.getEnvTypeForOwner(owner, info)
|
||||
if cp == nil:
|
||||
cp = newSym(skParam, getIdent(c.graph.cache, paramName), fn, fn.info)
|
||||
cp = newSym(skParam, getIdent(c.graph.cache, paramName), nextId(c.idgen), fn, fn.info)
|
||||
incl(cp.flags, sfFromGeneric)
|
||||
cp.typ = t
|
||||
addHiddenParam(fn, cp)
|
||||
|
|
@ -433,7 +435,7 @@ proc detectCapturedVars(n: PNode; owner: PSym; c: var DetectionPass) =
|
|||
if innerProc:
|
||||
if s.isIterator: c.somethingToDo = true
|
||||
if not c.processed.containsOrIncl(s.id):
|
||||
let body = transformBody(c.graph, s, cache = true)
|
||||
let body = transformBody(c.graph, c.idgen, s, cache = true)
|
||||
detectCapturedVars(body, s, c)
|
||||
let ow = s.skipGenericOwner
|
||||
if ow == owner:
|
||||
|
|
@ -446,9 +448,9 @@ proc detectCapturedVars(n: PNode; owner: PSym; c: var DetectionPass) =
|
|||
#let obj = c.getEnvTypeForOwner(s.owner).skipTypes({tyOwned, tyRef, tyPtr})
|
||||
|
||||
if s.name.id == getIdent(c.graph.cache, ":state").id:
|
||||
obj.n[0].sym.id = -s.id
|
||||
obj.n[0].sym.itemId = ItemId(module: s.itemId.module, item: -s.itemId.item)
|
||||
else:
|
||||
addField(obj, s, c.graph.cache)
|
||||
addField(obj, s, c.graph.cache, c.idgen)
|
||||
# direct or indirect dependency:
|
||||
elif (innerProc and s.typ.callConv == ccClosure) or interestingVar(s):
|
||||
discard """
|
||||
|
|
@ -470,7 +472,7 @@ proc detectCapturedVars(n: PNode; owner: PSym; c: var DetectionPass) =
|
|||
if interestingVar(s) and not c.capturedVars.containsOrIncl(s.id):
|
||||
let obj = c.getEnvTypeForOwner(ow, n.info).skipTypes({tyOwned, tyRef, tyPtr})
|
||||
#getHiddenParam(owner).typ.skipTypes({tyOwned, tyRef, tyPtr})
|
||||
addField(obj, s, c.graph.cache)
|
||||
addField(obj, s, c.graph.cache, c.idgen)
|
||||
# create required upFields:
|
||||
var w = owner.skipGenericOwner
|
||||
if isInnerProc(w) or owner.isIterator:
|
||||
|
|
@ -535,8 +537,8 @@ proc accessViaEnvParam(g: ModuleGraph; n: PNode; owner: PSym): PNode =
|
|||
localError(g.config, n.info, "internal error: environment misses: " & s.name.s)
|
||||
result = n
|
||||
|
||||
proc newEnvVar(cache: IdentCache; owner: PSym; typ: PType; info: TLineInfo): PNode =
|
||||
var v = newSym(skVar, getIdent(cache, envName), owner, info)
|
||||
proc newEnvVar(cache: IdentCache; owner: PSym; typ: PType; info: TLineInfo; idgen: IdGenerator): PNode =
|
||||
var v = newSym(skVar, getIdent(cache, envName), nextId(idgen), owner, info)
|
||||
v.flags = {sfShadowed, sfGeneratedOp}
|
||||
v.typ = typ
|
||||
result = newSymNode(v)
|
||||
|
|
@ -548,7 +550,7 @@ proc newEnvVar(cache: IdentCache; owner: PSym; typ: PType; info: TLineInfo): PNo
|
|||
else:
|
||||
result = newSymNode(v)
|
||||
|
||||
proc setupEnvVar(owner: PSym; d: DetectionPass;
|
||||
proc setupEnvVar(owner: PSym; d: var DetectionPass;
|
||||
c: var LiftingPass; info: TLineInfo): PNode =
|
||||
if owner.isIterator:
|
||||
return getHiddenParam(d.graph, owner).newSymNode
|
||||
|
|
@ -557,10 +559,10 @@ proc setupEnvVar(owner: PSym; d: DetectionPass;
|
|||
let envVarType = d.ownerToType.getOrDefault(owner.id)
|
||||
if envVarType.isNil:
|
||||
localError d.graph.config, owner.info, "internal error: could not determine closure type"
|
||||
result = newEnvVar(d.graph.cache, owner, asOwnedRef(d, envVarType), info)
|
||||
result = newEnvVar(d.graph.cache, owner, asOwnedRef(d, envVarType), info, d.idgen)
|
||||
c.envVars[owner.id] = result
|
||||
if optOwnedRefs in d.graph.config.globalOptions:
|
||||
var v = newSym(skVar, getIdent(d.graph.cache, envName & "Alt"), owner, info)
|
||||
var v = newSym(skVar, getIdent(d.graph.cache, envName & "Alt"), nextId d.idgen, owner, info)
|
||||
v.flags = {sfShadowed, sfGeneratedOp}
|
||||
v.typ = envVarType
|
||||
c.unownedEnvVars[owner.id] = newSymNode(v)
|
||||
|
|
@ -576,7 +578,7 @@ proc getUpViaParam(g: ModuleGraph; owner: PSym): PNode =
|
|||
result = rawIndirectAccess(result, upField, p.info)
|
||||
|
||||
proc rawClosureCreation(owner: PSym;
|
||||
d: DetectionPass; c: var LiftingPass;
|
||||
d: var DetectionPass; c: var LiftingPass;
|
||||
info: TLineInfo): PNode =
|
||||
result = newNodeI(nkStmtList, owner.info)
|
||||
|
||||
|
|
@ -602,7 +604,7 @@ proc rawClosureCreation(owner: PSym;
|
|||
let env2 = copyTree(env)
|
||||
env2.typ = unowned.typ
|
||||
result.add newAsgnStmt(unowned, env2, env.info)
|
||||
createTypeBoundOpsLL(d.graph, unowned.typ, env.info, owner)
|
||||
createTypeBoundOpsLL(d.graph, unowned.typ, env.info, d.idgen, owner)
|
||||
|
||||
# add assignment statements for captured parameters:
|
||||
for i in 1..<owner.typ.n.len:
|
||||
|
|
@ -611,7 +613,7 @@ proc rawClosureCreation(owner: PSym;
|
|||
let fieldAccess = indirectAccess(env, local, env.info)
|
||||
# add ``env.param = param``
|
||||
result.add(newAsgnStmt(fieldAccess, newSymNode(local), env.info))
|
||||
createTypeBoundOps(d.graph, nil, fieldAccess.typ, env.info)
|
||||
createTypeBoundOps(d.graph, nil, fieldAccess.typ, env.info, d.idgen)
|
||||
if tfHasAsgn in fieldAccess.typ.flags or optSeqDestructors in d.graph.config.globalOptions:
|
||||
owner.flags.incl sfInjectDestructors
|
||||
|
||||
|
|
@ -628,28 +630,28 @@ proc rawClosureCreation(owner: PSym;
|
|||
localError(d.graph.config, env.info, "internal error: cannot create up reference")
|
||||
# we are not in the sem'check phase anymore! so pass 'nil' for the PContext
|
||||
# and hope for the best:
|
||||
createTypeBoundOpsLL(d.graph, env.typ, owner.info, owner)
|
||||
createTypeBoundOpsLL(d.graph, env.typ, owner.info, d.idgen, owner)
|
||||
|
||||
proc finishClosureCreation(owner: PSym; d: DetectionPass; c: LiftingPass;
|
||||
proc finishClosureCreation(owner: PSym; d: var DetectionPass; c: LiftingPass;
|
||||
info: TLineInfo; res: PNode) =
|
||||
if optOwnedRefs in d.graph.config.globalOptions:
|
||||
let unowned = c.unownedEnvVars[owner.id]
|
||||
assert unowned != nil
|
||||
let nilLit = newNodeIT(nkNilLit, info, unowned.typ)
|
||||
res.add newAsgnStmt(unowned, nilLit, info)
|
||||
createTypeBoundOpsLL(d.graph, unowned.typ, info, owner)
|
||||
createTypeBoundOpsLL(d.graph, unowned.typ, info, d.idgen, owner)
|
||||
|
||||
proc closureCreationForIter(iter: PNode;
|
||||
d: DetectionPass; c: var LiftingPass): PNode =
|
||||
d: var DetectionPass; c: var LiftingPass): PNode =
|
||||
result = newNodeIT(nkStmtListExpr, iter.info, iter.sym.typ)
|
||||
let owner = iter.sym.skipGenericOwner
|
||||
var v = newSym(skVar, getIdent(d.graph.cache, envName), owner, iter.info)
|
||||
var v = newSym(skVar, getIdent(d.graph.cache, envName), nextId(d.idgen), owner, iter.info)
|
||||
incl(v.flags, sfShadowed)
|
||||
v.typ = asOwnedRef(d, getHiddenParam(d.graph, iter.sym).typ)
|
||||
var vnode: PNode
|
||||
if owner.isIterator:
|
||||
let it = getHiddenParam(d.graph, owner)
|
||||
addUniqueField(it.typ.skipTypes({tyOwned, tyRef, tyPtr}), v, d.graph.cache)
|
||||
addUniqueField(it.typ.skipTypes({tyOwned, tyRef, tyPtr}), v, d.graph.cache, d.idgen)
|
||||
vnode = indirectAccess(newSymNode(it), v, v.info)
|
||||
else:
|
||||
vnode = v.newSymNode
|
||||
|
|
@ -657,7 +659,7 @@ proc closureCreationForIter(iter: PNode;
|
|||
addVar(vs, vnode)
|
||||
result.add(vs)
|
||||
result.add(newCall(getSysSym(d.graph, iter.info, "internalNew"), vnode))
|
||||
createTypeBoundOpsLL(d.graph, vnode.typ, iter.info, owner)
|
||||
createTypeBoundOpsLL(d.graph, vnode.typ, iter.info, d.idgen, owner)
|
||||
|
||||
let upField = lookupInRecord(v.typ.skipTypes({tyOwned, tyRef, tyPtr}).n, getIdent(d.graph.cache, upName))
|
||||
if upField != nil:
|
||||
|
|
@ -667,9 +669,9 @@ proc closureCreationForIter(iter: PNode;
|
|||
u, iter.info))
|
||||
else:
|
||||
localError(d.graph.config, iter.info, "internal error: cannot create up reference for iter")
|
||||
result.add makeClosure(d.graph, iter.sym, vnode, iter.info)
|
||||
result.add makeClosure(d.graph, d.idgen, iter.sym, vnode, iter.info)
|
||||
|
||||
proc accessViaEnvVar(n: PNode; owner: PSym; d: DetectionPass;
|
||||
proc accessViaEnvVar(n: PNode; owner: PSym; d: var DetectionPass;
|
||||
c: var LiftingPass): PNode =
|
||||
var access = setupEnvVar(owner, d, c, n.info)
|
||||
if optOwnedRefs in d.graph.config.globalOptions:
|
||||
|
|
@ -685,21 +687,21 @@ proc accessViaEnvVar(n: PNode; owner: PSym; d: DetectionPass;
|
|||
proc getStateField*(g: ModuleGraph; owner: PSym): PSym =
|
||||
getHiddenParam(g, owner).typ.skipTypes({tyOwned, tyRef, tyPtr}).n[0].sym
|
||||
|
||||
proc liftCapturedVars(n: PNode; owner: PSym; d: DetectionPass;
|
||||
proc liftCapturedVars(n: PNode; owner: PSym; d: var DetectionPass;
|
||||
c: var LiftingPass): PNode
|
||||
|
||||
proc symToClosure(n: PNode; owner: PSym; d: DetectionPass;
|
||||
proc symToClosure(n: PNode; owner: PSym; d: var DetectionPass;
|
||||
c: var LiftingPass): PNode =
|
||||
let s = n.sym
|
||||
if s == owner:
|
||||
# recursive calls go through (lambda, hiddenParam):
|
||||
let available = getHiddenParam(d.graph, owner)
|
||||
result = makeClosure(d.graph, s, available.newSymNode, n.info)
|
||||
result = makeClosure(d.graph, d.idgen, s, available.newSymNode, n.info)
|
||||
elif s.isIterator:
|
||||
result = closureCreationForIter(n, d, c)
|
||||
elif s.skipGenericOwner == owner:
|
||||
# direct dependency, so use the outer's env variable:
|
||||
result = makeClosure(d.graph, s, setupEnvVar(owner, d, c, n.info), n.info)
|
||||
result = makeClosure(d.graph, d.idgen, s, setupEnvVar(owner, d, c, n.info), n.info)
|
||||
else:
|
||||
let available = getHiddenParam(d.graph, owner)
|
||||
let wanted = getHiddenParam(d.graph, s).typ
|
||||
|
|
@ -707,7 +709,7 @@ proc symToClosure(n: PNode; owner: PSym; d: DetectionPass;
|
|||
var access = newSymNode(available)
|
||||
while true:
|
||||
if access.typ == wanted:
|
||||
return makeClosure(d.graph, s, access, n.info)
|
||||
return makeClosure(d.graph, d.idgen, s, access, n.info)
|
||||
let obj = access.typ.skipTypes({tyOwned, tyRef, tyPtr})
|
||||
let upField = lookupInRecord(obj.n, getIdent(d.graph.cache, upName))
|
||||
if upField == nil:
|
||||
|
|
@ -715,7 +717,7 @@ proc symToClosure(n: PNode; owner: PSym; d: DetectionPass;
|
|||
return n
|
||||
access = rawIndirectAccess(access, upField, n.info)
|
||||
|
||||
proc liftCapturedVars(n: PNode; owner: PSym; d: DetectionPass;
|
||||
proc liftCapturedVars(n: PNode; owner: PSym; d: var DetectionPass;
|
||||
c: var LiftingPass): PNode =
|
||||
result = n
|
||||
case n.kind
|
||||
|
|
@ -727,7 +729,7 @@ proc liftCapturedVars(n: PNode; owner: PSym; d: DetectionPass;
|
|||
# echo renderTree(s.getBody, {renderIds})
|
||||
let oldInContainer = c.inContainer
|
||||
c.inContainer = 0
|
||||
var body = transformBody(d.graph, s, cache = false)
|
||||
var body = transformBody(d.graph, d.idgen, s, cache = false)
|
||||
body = liftCapturedVars(body, s, d, c)
|
||||
if c.envVars.getOrDefault(s.id).isNil:
|
||||
s.transformedBody = body
|
||||
|
|
@ -833,8 +835,9 @@ proc semCaptureSym*(s, owner: PSym) =
|
|||
# since the analysis is not entirely correct, we don't set 'tfCapturesEnv'
|
||||
# here
|
||||
|
||||
proc liftIterToProc*(g: ModuleGraph; fn: PSym; body: PNode; ptrType: PType): PNode =
|
||||
var d = initDetectionPass(g, fn)
|
||||
proc liftIterToProc*(g: ModuleGraph; fn: PSym; body: PNode; ptrType: PType;
|
||||
idgen: IdGenerator): PNode =
|
||||
var d = initDetectionPass(g, fn, idgen)
|
||||
var c = initLiftingPass(fn)
|
||||
# pretend 'fn' is a closure iterator for the analysis:
|
||||
let oldKind = fn.kind
|
||||
|
|
@ -847,7 +850,8 @@ proc liftIterToProc*(g: ModuleGraph; fn: PSym; body: PNode; ptrType: PType): PNo
|
|||
fn.transitionRoutineSymKind(oldKind)
|
||||
fn.typ.callConv = oldCC
|
||||
|
||||
proc liftLambdas*(g: ModuleGraph; fn: PSym, body: PNode; tooEarly: var bool): PNode =
|
||||
proc liftLambdas*(g: ModuleGraph; fn: PSym, body: PNode; tooEarly: var bool;
|
||||
idgen: IdGenerator): PNode =
|
||||
# XXX backend == backendJs does not suffice! The compiletime stuff needs
|
||||
# the transformation even when compiling to JS ...
|
||||
|
||||
|
|
@ -862,7 +866,7 @@ proc liftLambdas*(g: ModuleGraph; fn: PSym, body: PNode; tooEarly: var bool): PN
|
|||
result = body
|
||||
tooEarly = true
|
||||
else:
|
||||
var d = initDetectionPass(g, fn)
|
||||
var d = initDetectionPass(g, fn, idgen)
|
||||
detectCapturedVars(body, fn, d)
|
||||
if not d.somethingToDo and fn.isIterator:
|
||||
addClosureParam(d, fn, body.info)
|
||||
|
|
@ -886,7 +890,7 @@ proc liftLambdasForTopLevel*(module: PSym, body: PNode): PNode =
|
|||
|
||||
# ------------------- iterator transformation --------------------------------
|
||||
|
||||
proc liftForLoop*(g: ModuleGraph; body: PNode; owner: PSym): PNode =
|
||||
proc liftForLoop*(g: ModuleGraph; body: PNode; idgen: IdGenerator; owner: PSym): PNode =
|
||||
# problem ahead: the iterator could be invoked indirectly, but then
|
||||
# we don't know what environment to create here:
|
||||
#
|
||||
|
|
@ -931,7 +935,7 @@ proc liftForLoop*(g: ModuleGraph; body: PNode; owner: PSym): PNode =
|
|||
let iter = op.sym
|
||||
|
||||
let hp = getHiddenParam(g, iter)
|
||||
env = newSym(skLet, iter.name, owner, body.info)
|
||||
env = newSym(skLet, iter.name, nextId(idgen), owner, body.info)
|
||||
env.typ = hp.typ
|
||||
env.flags = hp.flags
|
||||
|
||||
|
|
@ -940,7 +944,7 @@ proc liftForLoop*(g: ModuleGraph; body: PNode; owner: PSym): PNode =
|
|||
result.add(v)
|
||||
# add 'new' statement:
|
||||
result.add(newCall(getSysSym(g, env.info, "internalNew"), env.newSymNode))
|
||||
createTypeBoundOpsLL(g, env.typ, body.info, owner)
|
||||
createTypeBoundOpsLL(g, env.typ, body.info, idgen, owner)
|
||||
|
||||
elif op.kind == nkStmtListExpr:
|
||||
let closure = op.lastSon
|
||||
|
|
@ -966,7 +970,7 @@ proc liftForLoop*(g: ModuleGraph; body: PNode; owner: PSym): PNode =
|
|||
|
||||
vpart.add newNodeI(nkEmpty, body.info) # no explicit type
|
||||
if not env.isNil:
|
||||
call[0] = makeClosure(g, call[0].sym, env.newSymNode, body.info)
|
||||
call[0] = makeClosure(g, idgen, call[0].sym, env.newSymNode, body.info)
|
||||
vpart.add call
|
||||
v2.add vpart
|
||||
|
||||
|
|
|
|||
|
|
@ -27,12 +27,14 @@ type
|
|||
canRaise: bool
|
||||
filterDiscriminator: PSym # we generating destructor for case branch
|
||||
c: PContext # c can be nil, then we are called from lambdalifting!
|
||||
idgen: IdGenerator
|
||||
|
||||
proc fillBody(c: var TLiftCtx; t: PType; body, x, y: PNode)
|
||||
proc produceSym(g: ModuleGraph; c: PContext; typ: PType; kind: TTypeAttachedOp;
|
||||
info: TLineInfo): PSym
|
||||
info: TLineInfo; idgen: IdGenerator): PSym
|
||||
|
||||
proc createTypeBoundOps*(g: ModuleGraph; c: PContext; orig: PType; info: TLineInfo)
|
||||
proc createTypeBoundOps*(g: ModuleGraph; c: PContext; orig: PType; info: TLineInfo;
|
||||
idgen: IdGenerator)
|
||||
|
||||
proc at(a, i: PNode, elemType: PType): PNode =
|
||||
result = newNodeI(nkBracketExpr, a.info, 2)
|
||||
|
|
@ -73,12 +75,12 @@ proc defaultOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
|||
call.typ = t
|
||||
body.add newAsgnStmt(x, call)
|
||||
|
||||
proc genAddr(g: ModuleGraph; x: PNode): PNode =
|
||||
proc genAddr(c: var TLiftCtx; x: PNode): PNode =
|
||||
if x.kind == nkHiddenDeref:
|
||||
checkSonsLen(x, 1, g.config)
|
||||
checkSonsLen(x, 1, c.g.config)
|
||||
result = x[0]
|
||||
else:
|
||||
result = newNodeIT(nkHiddenAddr, x.info, makeVarType(x.typ.owner, x.typ))
|
||||
result = newNodeIT(nkHiddenAddr, x.info, makeVarType(x.typ.owner, x.typ, c.idgen))
|
||||
result.add x
|
||||
|
||||
proc genWhileLoop(c: var TLiftCtx; i, dest: PNode): PNode =
|
||||
|
|
@ -92,11 +94,11 @@ proc genWhileLoop(c: var TLiftCtx; i, dest: PNode): PNode =
|
|||
proc genIf(c: var TLiftCtx; cond, action: PNode): PNode =
|
||||
result = newTree(nkIfStmt, newTree(nkElifBranch, cond, action))
|
||||
|
||||
proc genContainerOf(c: TLiftCtx; objType: PType, field, x: PSym): PNode =
|
||||
proc genContainerOf(c: var TLiftCtx; objType: PType, field, x: PSym): PNode =
|
||||
# generate: cast[ptr ObjType](cast[int](addr(x)) - offsetOf(objType.field))
|
||||
let intType = getSysType(c.g, unknownLineInfo, tyInt)
|
||||
|
||||
let addrOf = newNodeIT(nkAddr, c.info, makePtrType(x.owner, x.typ))
|
||||
let addrOf = newNodeIT(nkAddr, c.info, makePtrType(x.owner, x.typ, c.idgen))
|
||||
addrOf.add newDeref(newSymNode(x))
|
||||
let castExpr1 = newNodeIT(nkCast, c.info, intType)
|
||||
castExpr1.add newNodeIT(nkType, c.info, intType)
|
||||
|
|
@ -113,7 +115,7 @@ proc genContainerOf(c: TLiftCtx; objType: PType, field, x: PSym): PNode =
|
|||
minusExpr.typ = intType
|
||||
minusExpr.add offsetOf
|
||||
|
||||
let objPtr = makePtrType(objType.owner, objType)
|
||||
let objPtr = makePtrType(objType.owner, objType, c.idgen)
|
||||
result = newNodeIT(nkCast, c.info, objPtr)
|
||||
result.add newNodeIT(nkType, c.info, objPtr)
|
||||
result.add minusExpr
|
||||
|
|
@ -121,7 +123,7 @@ proc genContainerOf(c: TLiftCtx; objType: PType, field, x: PSym): PNode =
|
|||
proc destructorCall(c: var TLiftCtx; op: PSym; x: PNode): PNode =
|
||||
var destroy = newNodeIT(nkCall, x.info, op.typ[0])
|
||||
destroy.add(newSymNode(op))
|
||||
destroy.add genAddr(c.g, x)
|
||||
destroy.add genAddr(c, x)
|
||||
if sfNeverRaises notin op.flags:
|
||||
c.canRaise = true
|
||||
if c.addMemReset:
|
||||
|
|
@ -217,7 +219,7 @@ proc fillBodyObjT(c: var TLiftCtx; t: PType, body, x, y: PNode) =
|
|||
# for every field (dependent on dest.kind):
|
||||
# `=` dest.field, src.field
|
||||
# =destroy(blob)
|
||||
var temp = newSym(skTemp, getIdent(c.g.cache, lowerings.genPrefix), c.fn, c.info)
|
||||
var temp = newSym(skTemp, getIdent(c.g.cache, lowerings.genPrefix), nextId c.idgen, c.fn, c.info)
|
||||
temp.typ = x.typ
|
||||
incl(temp.flags, sfFromGeneric)
|
||||
var v = newNodeI(nkVarSection, c.info)
|
||||
|
|
@ -251,7 +253,7 @@ proc newHookCall(c: var TLiftCtx; op: PSym; x, y: PNode): PNode =
|
|||
if sfNeverRaises notin op.flags:
|
||||
c.canRaise = true
|
||||
if op.typ.sons[1].kind == tyVar:
|
||||
result.add genAddr(c.g, x)
|
||||
result.add genAddr(c, x)
|
||||
else:
|
||||
result.add x
|
||||
if y != nil:
|
||||
|
|
@ -311,7 +313,7 @@ proc considerAsgnOrSink(c: var TLiftCtx; t: PType; body, x, y: PNode;
|
|||
else:
|
||||
op = field
|
||||
if op == nil:
|
||||
op = produceSym(c.g, c.c, t, c.kind, c.info)
|
||||
op = produceSym(c.g, c.c, t, c.kind, c.info, c.idgen)
|
||||
if sfError in op.flags:
|
||||
incl c.fn.flags, sfError
|
||||
#else:
|
||||
|
|
@ -340,7 +342,7 @@ proc addDestructorCall(c: var TLiftCtx; orig: PType; body, x: PNode) =
|
|||
t.attachedOps[attachedDestructor] = op
|
||||
|
||||
if op == nil and (useNoGc(c, t) or requiresDestructor(c, t)):
|
||||
op = produceSym(c.g, c.c, t, attachedDestructor, c.info)
|
||||
op = produceSym(c.g, c.c, t, attachedDestructor, c.info, c.idgen)
|
||||
doAssert op != nil
|
||||
doAssert op == t.destructor
|
||||
|
||||
|
|
@ -381,7 +383,7 @@ proc considerUserDefinedOp(c: var TLiftCtx; t: PType; body, x, y: PNode): bool =
|
|||
result = true
|
||||
|
||||
proc declareCounter(c: var TLiftCtx; body: PNode; first: BiggestInt): PNode =
|
||||
var temp = newSym(skTemp, getIdent(c.g.cache, lowerings.genPrefix), c.fn, c.info)
|
||||
var temp = newSym(skTemp, getIdent(c.g.cache, lowerings.genPrefix), nextId(c.idgen), c.fn, c.info)
|
||||
temp.typ = getSysType(c.g, body.info, tyInt)
|
||||
incl(temp.flags, sfFromGeneric)
|
||||
|
||||
|
|
@ -452,7 +454,7 @@ proc fillSeqOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
|||
body.add genBuiltin(c.g, mDestroy, "destroy", x)
|
||||
|
||||
proc useSeqOrStrOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||
createTypeBoundOps(c.g, c.c, t, body.info)
|
||||
createTypeBoundOps(c.g, c.c, t, body.info, c.idgen)
|
||||
# recursions are tricky, so we might need to forward the generated
|
||||
# operation here:
|
||||
var t = t
|
||||
|
|
@ -493,7 +495,7 @@ proc useSeqOrStrOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
|||
proc fillStrOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||
case c.kind
|
||||
of attachedAsgn, attachedDeepCopy:
|
||||
body.add callCodegenProc(c.g, "nimAsgnStrV2", c.info, genAddr(c.g, x), y)
|
||||
body.add callCodegenProc(c.g, "nimAsgnStrV2", c.info, genAddr(c, x), y)
|
||||
of attachedSink:
|
||||
let moveCall = genBuiltin(c.g, mMove, "move", x)
|
||||
moveCall.add y
|
||||
|
|
@ -509,7 +511,7 @@ proc atomicRefOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
|||
var actions = newNodeI(nkStmtList, c.info)
|
||||
let elemType = t.lastSon
|
||||
|
||||
createTypeBoundOps(c.g, c.c, elemType, c.info)
|
||||
createTypeBoundOps(c.g, c.c, elemType, c.info, c.idgen)
|
||||
|
||||
if isFinal(elemType):
|
||||
addDestructorCall(c, elemType, actions, genDeref(x, nkDerefExpr))
|
||||
|
|
@ -548,10 +550,10 @@ proc atomicRefOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
|||
if isFinal(elemType):
|
||||
let typInfo = genBuiltin(c.g, 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), typInfo, y)
|
||||
body.add callCodegenProc(c.g, "nimTraceRef", c.info, genAddrOf(x, c.idgen), typInfo, y)
|
||||
else:
|
||||
# If the ref is polymorphic we have to account for this
|
||||
body.add callCodegenProc(c.g, "nimTraceRefDyn", c.info, genAddrOf(x), y)
|
||||
body.add callCodegenProc(c.g, "nimTraceRefDyn", c.info, genAddrOf(x, c.idgen), y)
|
||||
of attachedDispose:
|
||||
# this is crucial! dispose is like =destroy but we don't follow refs
|
||||
# as that is dealt within the cycle collector.
|
||||
|
|
@ -593,7 +595,7 @@ proc atomicClosureOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
|||
body.add genIf(c, cond, actions)
|
||||
of attachedDeepCopy: assert(false, "cannot happen")
|
||||
of attachedTrace:
|
||||
body.add callCodegenProc(c.g, "nimTraceRefDyn", c.info, genAddrOf(xenv), y)
|
||||
body.add callCodegenProc(c.g, "nimTraceRefDyn", c.info, genAddrOf(xenv, c.idgen), y)
|
||||
of attachedDispose:
|
||||
# this is crucial! dispose is like =destroy but we don't follow refs
|
||||
# as that is dealt within the cycle collector.
|
||||
|
|
@ -788,28 +790,30 @@ proc fillBody(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
|||
of tyOptDeprecated: doAssert false
|
||||
|
||||
proc produceSymDistinctType(g: ModuleGraph; c: PContext; typ: PType;
|
||||
kind: TTypeAttachedOp; info: TLineInfo): PSym =
|
||||
kind: TTypeAttachedOp; info: TLineInfo;
|
||||
idgen: IdGenerator): PSym =
|
||||
assert typ.kind == tyDistinct
|
||||
let baseType = typ[0]
|
||||
if baseType.attachedOps[kind] == nil:
|
||||
discard produceSym(g, c, baseType, kind, info)
|
||||
discard produceSym(g, c, baseType, kind, info, idgen)
|
||||
typ.attachedOps[kind] = baseType.attachedOps[kind]
|
||||
result = typ.attachedOps[kind]
|
||||
|
||||
proc symPrototype(g: ModuleGraph; typ: PType; owner: PSym; kind: TTypeAttachedOp;
|
||||
info: TLineInfo): PSym =
|
||||
info: TLineInfo; idgen: IdGenerator): PSym =
|
||||
|
||||
let procname = getIdent(g.cache, AttachedOpToStr[kind])
|
||||
result = newSym(skProc, procname, owner, info)
|
||||
let dest = newSym(skParam, getIdent(g.cache, "dest"), result, info)
|
||||
let src = newSym(skParam, getIdent(g.cache, if kind == attachedTrace: "env" else: "src"), result, info)
|
||||
dest.typ = makeVarType(typ.owner, typ)
|
||||
result = newSym(skProc, procname, nextId(idgen), owner, info)
|
||||
let dest = newSym(skParam, getIdent(g.cache, "dest"), nextId(idgen), result, info)
|
||||
let src = newSym(skParam, getIdent(g.cache, if kind == attachedTrace: "env" else: "src"),
|
||||
nextId(idgen), result, info)
|
||||
dest.typ = makeVarType(typ.owner, typ, idgen)
|
||||
if kind == attachedTrace:
|
||||
src.typ = getSysType(g, info, tyPointer)
|
||||
else:
|
||||
src.typ = typ
|
||||
|
||||
result.typ = newProcType(info, owner)
|
||||
result.typ = newProcType(info, nextId(idgen), owner)
|
||||
result.typ.addParam dest
|
||||
if kind notin {attachedDestructor, attachedDispose}:
|
||||
result.typ.addParam src
|
||||
|
|
@ -825,15 +829,15 @@ proc symPrototype(g: ModuleGraph; typ: PType; owner: PSym; kind: TTypeAttachedOp
|
|||
|
||||
|
||||
proc produceSym(g: ModuleGraph; c: PContext; typ: PType; kind: TTypeAttachedOp;
|
||||
info: TLineInfo): PSym =
|
||||
info: TLineInfo; idgen: IdGenerator): PSym =
|
||||
if typ.kind == tyDistinct:
|
||||
return produceSymDistinctType(g, c, typ, kind, info)
|
||||
return produceSymDistinctType(g, c, typ, kind, info, idgen)
|
||||
|
||||
result = typ.attachedOps[kind]
|
||||
if result == nil:
|
||||
result = symPrototype(g, typ, typ.owner, kind, info)
|
||||
result = symPrototype(g, typ, typ.owner, kind, info, idgen)
|
||||
|
||||
var a = TLiftCtx(info: info, g: g, kind: kind, c: c, asgnForType:typ)
|
||||
var a = TLiftCtx(info: info, g: g, kind: kind, c: c, asgnForType:typ, idgen: idgen)
|
||||
a.fn = result
|
||||
|
||||
let dest = result.typ.n[1].sym
|
||||
|
|
@ -866,18 +870,19 @@ proc produceSym(g: ModuleGraph; c: PContext; typ: PType; kind: TTypeAttachedOp;
|
|||
if not a.canRaise: incl result.flags, sfNeverRaises
|
||||
|
||||
|
||||
proc produceDestructorForDiscriminator*(g: ModuleGraph; typ: PType; field: PSym, info: TLineInfo): PSym =
|
||||
proc produceDestructorForDiscriminator*(g: ModuleGraph; typ: PType; field: PSym,
|
||||
info: TLineInfo; idgen: IdGenerator): PSym =
|
||||
assert(typ.skipTypes({tyAlias, tyGenericInst}).kind == tyObject)
|
||||
result = symPrototype(g, field.typ, typ.owner, attachedDestructor, info)
|
||||
var a = TLiftCtx(info: info, g: g, kind: attachedDestructor, asgnForType: typ)
|
||||
result = symPrototype(g, field.typ, typ.owner, attachedDestructor, info, idgen)
|
||||
var a = TLiftCtx(info: info, g: g, kind: attachedDestructor, asgnForType: typ, idgen: idgen)
|
||||
a.fn = result
|
||||
a.asgnForType = typ
|
||||
a.filterDiscriminator = field
|
||||
a.addMemReset = true
|
||||
let discrimantDest = result.typ.n[1].sym
|
||||
|
||||
let dst = newSym(skVar, getIdent(g.cache, "dest"), result, info)
|
||||
dst.typ = makePtrType(typ.owner, typ)
|
||||
let dst = newSym(skVar, getIdent(g.cache, "dest"), nextId(idgen), result, info)
|
||||
dst.typ = makePtrType(typ.owner, typ, idgen)
|
||||
let dstSym = newSymNode(dst)
|
||||
let d = newDeref(dstSym)
|
||||
let v = newNodeI(nkVarSection, info)
|
||||
|
|
@ -891,12 +896,12 @@ proc produceDestructorForDiscriminator*(g: ModuleGraph; typ: PType; field: PSym,
|
|||
template liftTypeBoundOps*(c: PContext; typ: PType; info: TLineInfo) =
|
||||
discard "now a nop"
|
||||
|
||||
proc patchBody(g: ModuleGraph; c: PContext; n: PNode; info: TLineInfo) =
|
||||
proc patchBody(g: ModuleGraph; c: PContext; n: PNode; info: TLineInfo; idgen: IdGenerator) =
|
||||
if n.kind in nkCallKinds:
|
||||
if n[0].kind == nkSym and n[0].sym.magic == mDestroy:
|
||||
let t = n[1].typ.skipTypes(abstractVar)
|
||||
if t.destructor == nil:
|
||||
discard produceSym(g, c, t, attachedDestructor, info)
|
||||
discard produceSym(g, c, t, attachedDestructor, info, idgen)
|
||||
|
||||
if t.destructor != nil:
|
||||
if t.destructor.ast[genericParamsPos].kind != nkEmpty:
|
||||
|
|
@ -904,9 +909,9 @@ proc patchBody(g: ModuleGraph; c: PContext; n: PNode; info: TLineInfo) =
|
|||
if t.destructor.magic == mDestroy:
|
||||
internalError(g.config, info, "patching mDestroy with mDestroy?")
|
||||
n[0] = newSymNode(t.destructor)
|
||||
for x in n: patchBody(g, c, x, info)
|
||||
for x in n: patchBody(g, c, x, info, idgen)
|
||||
|
||||
template inst(field, t) =
|
||||
template inst(field, t, idgen) =
|
||||
if field.ast != nil and field.ast[genericParamsPos].kind != nkEmpty:
|
||||
if t.typeInst != nil:
|
||||
var a: TLiftCtx
|
||||
|
|
@ -914,17 +919,19 @@ template inst(field, t) =
|
|||
a.g = g
|
||||
a.kind = k
|
||||
a.c = c
|
||||
a.idgen = idgen
|
||||
|
||||
field = instantiateGeneric(a, field, t, t.typeInst)
|
||||
if field.ast != nil:
|
||||
patchBody(g, c, field.ast, info)
|
||||
patchBody(g, c, field.ast, info, a.idgen)
|
||||
else:
|
||||
localError(g.config, info, "unresolved generic parameter")
|
||||
|
||||
proc isTrival(s: PSym): bool {.inline.} =
|
||||
s == nil or (s.ast != nil and s.ast[bodyPos].len == 0)
|
||||
|
||||
proc createTypeBoundOps(g: ModuleGraph; c: PContext; orig: PType; info: TLineInfo) =
|
||||
proc createTypeBoundOps(g: ModuleGraph; c: PContext; orig: PType; info: TLineInfo;
|
||||
idgen: IdGenerator) =
|
||||
## In the semantic pass this is called in strategic places
|
||||
## to ensure we lift assignment, destructors and moves properly.
|
||||
## The later 'injectdestructors' pass depends on it.
|
||||
|
|
@ -959,14 +966,14 @@ proc createTypeBoundOps(g: ModuleGraph; c: PContext; orig: PType; info: TLineInf
|
|||
for k in attachedDestructor..lastAttached:
|
||||
generics[k] = canon.attachedOps[k] != nil
|
||||
if not generics[k]:
|
||||
canon.attachedOps[k] = symPrototype(g, canon, canon.owner, k, info)
|
||||
canon.attachedOps[k] = symPrototype(g, canon, canon.owner, k, info, idgen)
|
||||
|
||||
# we generate the destructor first so that other operators can depend on it:
|
||||
for k in attachedDestructor..lastAttached:
|
||||
if not generics[k]:
|
||||
discard produceSym(g, c, canon, k, info)
|
||||
discard produceSym(g, c, canon, k, info, idgen)
|
||||
else:
|
||||
inst(canon.attachedOps[k], canon)
|
||||
inst(canon.attachedOps[k], canon, idgen)
|
||||
if canon != orig:
|
||||
orig.attachedOps[k] = canon.attachedOps[k]
|
||||
|
||||
|
|
|
|||
|
|
@ -21,13 +21,14 @@ type
|
|||
partialParam: PSym
|
||||
objType: PType
|
||||
cache: IdentCache
|
||||
idgen: IdGenerator
|
||||
|
||||
proc interestingVar(s: PSym): bool {.inline.} =
|
||||
result = s.kind in {skVar, skLet, skTemp, skForVar, skResult} and
|
||||
sfGlobal notin s.flags
|
||||
|
||||
proc lookupOrAdd(c: var Ctx; s: PSym; info: TLineInfo): PNode =
|
||||
let field = addUniqueField(c.objType, s, c.cache)
|
||||
let field = addUniqueField(c.objType, s, c.cache, c.idgen)
|
||||
var deref = newNodeI(nkHiddenDeref, info)
|
||||
deref.typ = c.objType
|
||||
deref.add(newSymNode(c.partialParam, info))
|
||||
|
|
@ -53,7 +54,8 @@ proc lookupParam(params, dest: PNode): PSym =
|
|||
if params[i].kind == nkSym and params[i].sym.name.id == dest.ident.id:
|
||||
return params[i].sym
|
||||
|
||||
proc liftLocalsIfRequested*(prc: PSym; n: PNode; cache: IdentCache; conf: ConfigRef): PNode =
|
||||
proc liftLocalsIfRequested*(prc: PSym; n: PNode; cache: IdentCache; conf: ConfigRef;
|
||||
idgen: IdGenerator): PNode =
|
||||
let liftDest = getPragmaVal(prc.ast, wLiftLocals)
|
||||
if liftDest == nil: return n
|
||||
let partialParam = lookupParam(prc.typ.n, liftDest)
|
||||
|
|
@ -65,7 +67,7 @@ proc liftLocalsIfRequested*(prc: PSym; n: PNode; cache: IdentCache; conf: Config
|
|||
if objType.kind != tyObject or tfPartial notin objType.flags:
|
||||
localError(conf, liftDest.info, "parameter '$1' is not a pointer to a partial object" % $liftDest)
|
||||
return n
|
||||
var c = Ctx(partialParam: partialParam, objType: objType, cache: cache)
|
||||
var c = Ctx(partialParam: partialParam, objType: objType, cache: cache, idgen: idgen)
|
||||
let w = newTree(nkStmtList, n)
|
||||
liftLocals(w, 0, c)
|
||||
result = w[0]
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ proc errorSym*(c: PContext, n: PNode): PSym =
|
|||
considerQuotedIdent(c, m)
|
||||
else:
|
||||
getIdent(c.cache, "err:" & renderTree(m))
|
||||
result = newSym(skError, ident, getCurrOwner(c), n.info, {})
|
||||
result = newSym(skError, ident, nextId(c.idgen), getCurrOwner(c), n.info, {})
|
||||
result.typ = errorType(c)
|
||||
incl(result.flags, sfDiscardable)
|
||||
# pretend it's imported from some unknown module to prevent cascading errors:
|
||||
|
|
|
|||
|
|
@ -66,12 +66,13 @@ proc newFastMoveStmt*(g: ModuleGraph, le, ri: PNode): PNode =
|
|||
result[1].add newSymNode(getSysMagic(g, ri.info, "move", mMove))
|
||||
result[1].add ri
|
||||
|
||||
proc lowerTupleUnpacking*(g: ModuleGraph; n: PNode; owner: PSym): PNode =
|
||||
proc lowerTupleUnpacking*(g: ModuleGraph; n: PNode; idgen: IdGenerator; owner: PSym): PNode =
|
||||
assert n.kind == nkVarTuple
|
||||
let value = n.lastSon
|
||||
result = newNodeI(nkStmtList, n.info)
|
||||
|
||||
var temp = newSym(skTemp, getIdent(g.cache, genPrefix), owner, value.info, g.config.options)
|
||||
var temp = newSym(skTemp, getIdent(g.cache, genPrefix), nextId(idgen),
|
||||
owner, value.info, g.config.options)
|
||||
temp.typ = skipTypes(value.typ, abstractInst)
|
||||
incl(temp.flags, sfFromGeneric)
|
||||
|
||||
|
|
@ -85,12 +86,13 @@ proc lowerTupleUnpacking*(g: ModuleGraph; n: PNode; owner: PSym): PNode =
|
|||
if n[i].kind == nkSym: v.addVar(n[i], val)
|
||||
else: result.add newAsgnStmt(n[i], val)
|
||||
|
||||
proc evalOnce*(g: ModuleGraph; value: PNode; owner: PSym): PNode =
|
||||
proc evalOnce*(g: ModuleGraph; value: PNode; idgen: IdGenerator; owner: PSym): PNode =
|
||||
## Turns (value) into (let tmp = value; tmp) so that 'value' can be re-used
|
||||
## freely, multiple times. This is frequently required and such a builtin would also be
|
||||
## handy to have in macros.nim. The value that can be reused is 'result.lastSon'!
|
||||
result = newNodeIT(nkStmtListExpr, value.info, value.typ)
|
||||
var temp = newSym(skTemp, getIdent(g.cache, genPrefix), owner, value.info, g.config.options)
|
||||
var temp = newSym(skTemp, getIdent(g.cache, genPrefix), nextId(idgen),
|
||||
owner, value.info, g.config.options)
|
||||
temp.typ = skipTypes(value.typ, abstractInst)
|
||||
incl(temp.flags, sfFromGeneric)
|
||||
|
||||
|
|
@ -111,11 +113,11 @@ proc newTupleAccessRaw*(tup: PNode, i: int): PNode =
|
|||
proc newTryFinally*(body, final: PNode): PNode =
|
||||
result = newTree(nkHiddenTryStmt, body, newTree(nkFinally, final))
|
||||
|
||||
proc lowerTupleUnpackingForAsgn*(g: ModuleGraph; n: PNode; owner: PSym): PNode =
|
||||
proc lowerTupleUnpackingForAsgn*(g: ModuleGraph; n: PNode; idgen: IdGenerator; owner: PSym): PNode =
|
||||
let value = n.lastSon
|
||||
result = newNodeI(nkStmtList, n.info)
|
||||
|
||||
var temp = newSym(skTemp, getIdent(g.cache, "_"), owner, value.info, owner.options)
|
||||
var temp = newSym(skTemp, getIdent(g.cache, "_"), nextId(idgen), owner, value.info, owner.options)
|
||||
var v = newNodeI(nkLetSection, value.info)
|
||||
let tempAsNode = newSymNode(temp) #newIdentNode(getIdent(genPrefix & $temp.id), value.info)
|
||||
|
||||
|
|
@ -130,10 +132,10 @@ proc lowerTupleUnpackingForAsgn*(g: ModuleGraph; n: PNode; owner: PSym): PNode =
|
|||
for i in 0..<lhs.len:
|
||||
result.add newAsgnStmt(lhs[i], newTupleAccessRaw(tempAsNode, i))
|
||||
|
||||
proc lowerSwap*(g: ModuleGraph; n: PNode; owner: PSym): PNode =
|
||||
proc lowerSwap*(g: ModuleGraph; n: PNode; idgen: IdGenerator; owner: PSym): PNode =
|
||||
result = newNodeI(nkStmtList, n.info)
|
||||
# note: cannot use 'skTemp' here cause we really need the copy for the VM :-(
|
||||
var temp = newSym(skVar, getIdent(g.cache, genPrefix), owner, n.info, owner.options)
|
||||
var temp = newSym(skVar, getIdent(g.cache, genPrefix), nextId(idgen), owner, n.info, owner.options)
|
||||
temp.typ = n[1].typ
|
||||
incl(temp.flags, sfFromGeneric)
|
||||
|
||||
|
|
@ -150,8 +152,8 @@ proc lowerSwap*(g: ModuleGraph; n: PNode; owner: PSym): PNode =
|
|||
result.add newFastAsgnStmt(n[1], n[2])
|
||||
result.add newFastAsgnStmt(n[2], tempAsNode)
|
||||
|
||||
proc createObj*(g: ModuleGraph; owner: PSym, info: TLineInfo; final=true): PType =
|
||||
result = newType(tyObject, owner)
|
||||
proc createObj*(g: ModuleGraph; idgen: IdGenerator; owner: PSym, info: TLineInfo; final=true): PType =
|
||||
result = newType(tyObject, nextId(idgen), owner)
|
||||
if final:
|
||||
rawAddSon(result, nil)
|
||||
incl result.flags, tfFinal
|
||||
|
|
@ -159,6 +161,7 @@ proc createObj*(g: ModuleGraph; owner: PSym, info: TLineInfo; final=true): PType
|
|||
rawAddSon(result, getCompilerProc(g, "RootObj").typ)
|
||||
result.n = newNodeI(nkRecList, info)
|
||||
let s = newSym(skType, getIdent(g.cache, "Env_" & toFilename(g.config, info) & "_" & $owner.name.s),
|
||||
nextId(idgen),
|
||||
owner, info, owner.options)
|
||||
incl s.flags, sfAnon
|
||||
s.typ = result
|
||||
|
|
@ -196,7 +199,7 @@ proc rawDirectAccess*(obj, field: PSym): PNode =
|
|||
result.add newSymNode(field)
|
||||
result.typ = field.typ
|
||||
|
||||
proc lookupInRecord(n: PNode, id: int): PSym =
|
||||
proc lookupInRecord(n: PNode, id: ItemId): PSym =
|
||||
result = nil
|
||||
case n.kind
|
||||
of nkRecList:
|
||||
|
|
@ -214,16 +217,16 @@ proc lookupInRecord(n: PNode, id: int): PSym =
|
|||
if result != nil: return
|
||||
else: discard
|
||||
of nkSym:
|
||||
if n.sym.id == -abs(id): result = n.sym
|
||||
if n.sym.itemId.module == id.module and n.sym.itemId.item == -abs(id.item): result = n.sym
|
||||
else: discard
|
||||
|
||||
proc addField*(obj: PType; s: PSym; cache: IdentCache) =
|
||||
proc addField*(obj: PType; s: PSym; cache: IdentCache; idgen: IdGenerator) =
|
||||
# because of 'gensym' support, we have to mangle the name with its ID.
|
||||
# This is hacky but the clean solution is much more complex than it looks.
|
||||
var field = newSym(skField, getIdent(cache, s.name.s & $obj.n.len), s.owner, s.info,
|
||||
s.options)
|
||||
field.id = -s.id
|
||||
let t = skipIntLit(s.typ)
|
||||
var field = newSym(skField, getIdent(cache, s.name.s & $obj.n.len),
|
||||
nextId(idgen), s.owner, s.info, s.options)
|
||||
field.itemId = ItemId(module: s.itemId.module, item: -s.itemId.item)
|
||||
let t = skipIntLit(s.typ, idgen)
|
||||
field.typ = t
|
||||
assert t.kind != tyTyped
|
||||
propagateToOwner(obj, t)
|
||||
|
|
@ -232,13 +235,13 @@ proc addField*(obj: PType; s: PSym; cache: IdentCache) =
|
|||
obj.n.add newSymNode(field)
|
||||
fieldCheck()
|
||||
|
||||
proc addUniqueField*(obj: PType; s: PSym; cache: IdentCache): PSym {.discardable.} =
|
||||
result = lookupInRecord(obj.n, s.id)
|
||||
proc addUniqueField*(obj: PType; s: PSym; cache: IdentCache; idgen: IdGenerator): PSym {.discardable.} =
|
||||
result = lookupInRecord(obj.n, s.itemId)
|
||||
if result == nil:
|
||||
var field = newSym(skField, getIdent(cache, s.name.s & $obj.n.len), s.owner, s.info,
|
||||
s.options)
|
||||
field.id = -s.id
|
||||
let t = skipIntLit(s.typ)
|
||||
var field = newSym(skField, getIdent(cache, s.name.s & $obj.n.len), nextId(idgen),
|
||||
s.owner, s.info, s.options)
|
||||
field.itemId = ItemId(module: s.itemId.module, item: -s.itemId.item)
|
||||
let t = skipIntLit(s.typ, idgen)
|
||||
field.typ = t
|
||||
assert t.kind != tyTyped
|
||||
propagateToOwner(obj, t)
|
||||
|
|
@ -248,13 +251,13 @@ proc addUniqueField*(obj: PType; s: PSym; cache: IdentCache): PSym {.discardable
|
|||
|
||||
proc newDotExpr*(obj, b: PSym): PNode =
|
||||
result = newNodeI(nkDotExpr, obj.info)
|
||||
let field = lookupInRecord(obj.typ.n, b.id)
|
||||
let field = lookupInRecord(obj.typ.n, b.itemId)
|
||||
assert field != nil, b.name.s
|
||||
result.add newSymNode(obj)
|
||||
result.add newSymNode(field)
|
||||
result.typ = field.typ
|
||||
|
||||
proc indirectAccess*(a: PNode, b: int, info: TLineInfo): PNode =
|
||||
proc indirectAccess*(a: PNode, b: ItemId, info: TLineInfo): PNode =
|
||||
# returns a[].b as a node
|
||||
var deref = newNodeI(nkHiddenDeref, info)
|
||||
deref.typ = a.typ.skipTypes(abstractInst)[0]
|
||||
|
|
@ -306,7 +309,7 @@ proc getFieldFromObj*(t: PType; v: PSym): PSym =
|
|||
var t = t
|
||||
while true:
|
||||
assert t.kind == tyObject
|
||||
result = lookupInRecord(t.n, v.id)
|
||||
result = lookupInRecord(t.n, v.itemId)
|
||||
if result != nil: break
|
||||
t = t[0]
|
||||
if t == nil: break
|
||||
|
|
@ -314,15 +317,15 @@ proc getFieldFromObj*(t: PType; v: PSym): PSym =
|
|||
|
||||
proc indirectAccess*(a: PNode, b: PSym, info: TLineInfo): PNode =
|
||||
# returns a[].b as a node
|
||||
result = indirectAccess(a, b.id, info)
|
||||
result = indirectAccess(a, b.itemId, info)
|
||||
|
||||
proc indirectAccess*(a, b: PSym, info: TLineInfo): PNode =
|
||||
result = indirectAccess(newSymNode(a), b, info)
|
||||
|
||||
proc genAddrOf*(n: PNode, typeKind = tyPtr): PNode =
|
||||
proc genAddrOf*(n: PNode; idgen: IdGenerator; typeKind = tyPtr): PNode =
|
||||
result = newNodeI(nkAddr, n.info, 1)
|
||||
result[0] = n
|
||||
result.typ = newType(typeKind, n.typ.owner)
|
||||
result.typ = newType(typeKind, nextId(idgen), n.typ.owner)
|
||||
result.typ.rawAddSon(n.typ)
|
||||
|
||||
proc genDeref*(n: PNode; k = nkHiddenDeref): PNode =
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ proc registerSysType*(g: ModuleGraph; t: PType) =
|
|||
if g.sysTypes[t.kind] == nil: g.sysTypes[t.kind] = t
|
||||
|
||||
proc newSysType(g: ModuleGraph; kind: TTypeKind, size: int): PType =
|
||||
result = newType(kind, g.systemModule)
|
||||
result = newType(kind, nextId(g.idgen), g.systemModule)
|
||||
result.size = size
|
||||
result.align = size.int16
|
||||
|
||||
|
|
@ -29,8 +29,8 @@ proc getSysSym*(g: ModuleGraph; info: TLineInfo; name: string): PSym =
|
|||
result = strTableGet(g.systemModule.tab, getIdent(g.cache, name))
|
||||
if result == nil:
|
||||
localError(g.config, info, "system module needs: " & name)
|
||||
result = newSym(skError, getIdent(g.cache, name), g.systemModule, g.systemModule.info, {})
|
||||
result.typ = newType(tyError, g.systemModule)
|
||||
result = newSym(skError, getIdent(g.cache, name), nextId(g.idgen), g.systemModule, g.systemModule.info, {})
|
||||
result.typ = newType(tyError, nextId(g.idgen), g.systemModule)
|
||||
if result.kind == skAlias: result = result.owner
|
||||
|
||||
proc getSysMagic*(g: ModuleGraph; info: TLineInfo; name: string, m: TMagic): PSym =
|
||||
|
|
@ -45,8 +45,8 @@ proc getSysMagic*(g: ModuleGraph; info: TLineInfo; name: string, m: TMagic): PSy
|
|||
r = nextIdentIter(ti, g.systemModule.tab)
|
||||
if result != nil: return result
|
||||
localError(g.config, info, "system module needs: " & name)
|
||||
result = newSym(skError, id, g.systemModule, g.systemModule.info, {})
|
||||
result.typ = newType(tyError, g.systemModule)
|
||||
result = newSym(skError, id, nextId(g.idgen), g.systemModule, g.systemModule.info, {})
|
||||
result.typ = newType(tyError, nextId(g.idgen), g.systemModule)
|
||||
|
||||
proc sysTypeFromName*(g: ModuleGraph; info: TLineInfo; name: string): PType =
|
||||
result = getSysSym(g, info, name).typ
|
||||
|
|
@ -101,12 +101,12 @@ proc getIntLitType*(g: ModuleGraph; literal: PNode): PType =
|
|||
result = g.intTypeCache[value.int]
|
||||
if result == nil:
|
||||
let ti = getSysType(g, literal.info, tyInt)
|
||||
result = copyType(ti, ti.owner, false)
|
||||
result = copyType(ti, nextId(g.idgen), ti.owner)
|
||||
result.n = literal
|
||||
g.intTypeCache[value.int] = result
|
||||
else:
|
||||
let ti = getSysType(g, literal.info, tyInt)
|
||||
result = copyType(ti, ti.owner, false)
|
||||
result = copyType(ti, nextId(g.idgen), ti.owner)
|
||||
result.n = literal
|
||||
|
||||
proc getFloatLitType*(g: ModuleGraph; literal: PNode): PType =
|
||||
|
|
@ -114,17 +114,17 @@ proc getFloatLitType*(g: ModuleGraph; literal: PNode): PType =
|
|||
result = newSysType(g, tyFloat, size=8)
|
||||
result.n = literal
|
||||
|
||||
proc skipIntLit*(t: PType): PType {.inline.} =
|
||||
proc skipIntLit*(t: PType; id: IdGenerator): PType {.inline.} =
|
||||
if t.n != nil and t.kind in {tyInt, tyFloat}:
|
||||
result = copyType(t, t.owner, false)
|
||||
result = copyType(t, nextId(id), t.owner)
|
||||
result.n = nil
|
||||
else:
|
||||
result = t
|
||||
|
||||
proc addSonSkipIntLit*(father, son: PType) =
|
||||
proc addSonSkipIntLit*(father, son: PType; id: IdGenerator) =
|
||||
when not defined(nimNoNilSeqs):
|
||||
if isNil(father.sons): father.sons = @[]
|
||||
let s = son.skipIntLit
|
||||
let s = son.skipIntLit(id)
|
||||
father.sons.add(s)
|
||||
propagateToOwner(father, s)
|
||||
|
||||
|
|
@ -181,13 +181,13 @@ proc resetNimScriptSymbols*(g: ModuleGraph) = initStrTable(g.exposed)
|
|||
proc getMagicEqSymForType*(g: ModuleGraph; t: PType; info: TLineInfo): PSym =
|
||||
case t.kind
|
||||
of tyInt, tyInt8, tyInt16, tyInt32, tyInt64,
|
||||
tyUInt, tyUInt8, tyUInt16, tyUInt32, tyUInt64:
|
||||
tyUInt, tyUInt8, tyUInt16, tyUInt32, tyUInt64:
|
||||
result = getSysMagic(g, info, "==", mEqI)
|
||||
of tyEnum:
|
||||
of tyEnum:
|
||||
result = getSysMagic(g, info, "==", mEqEnum)
|
||||
of tyBool:
|
||||
of tyBool:
|
||||
result = getSysMagic(g, info, "==", mEqB)
|
||||
of tyRef, tyPtr, tyPointer:
|
||||
of tyRef, tyPtr, tyPointer:
|
||||
result = getSysMagic(g, info, "==", mEqRef)
|
||||
of tyString:
|
||||
result = getSysMagic(g, info, "==", mEqStr)
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import
|
|||
condsyms, times,
|
||||
sem, idents, passes, extccomp,
|
||||
cgen, json, nversion,
|
||||
platform, nimconf, passaux, depends, vm, idgen,
|
||||
platform, nimconf, passaux, depends, vm,
|
||||
modules,
|
||||
modulegraphs, tables, rod, lineinfos, pathutils, vmprofiler
|
||||
|
||||
|
|
@ -137,12 +137,8 @@ proc commandInteractive(graph: ModuleGraph) =
|
|||
else:
|
||||
var m = graph.makeStdinModule()
|
||||
incl(m.flags, sfMainModule)
|
||||
processModule(graph, m, llStreamOpenStdIn())
|
||||
|
||||
const evalPasses = [verbosePass, semPass, evalPass]
|
||||
|
||||
proc evalNim(graph: ModuleGraph; nodes: PNode, module: PSym) =
|
||||
carryPasses(graph, nodes, module, evalPasses)
|
||||
var idgen = IdGenerator(module: m.itemId.module, item: m.itemId.item)
|
||||
processModule(graph, m, idgen, llStreamOpenStdIn())
|
||||
|
||||
proc commandScan(cache: IdentCache, config: ConfigRef) =
|
||||
var f = addFileExt(AbsoluteFile mainCommandArg(config), NimExt)
|
||||
|
|
@ -173,7 +169,6 @@ proc mainCommand*(graph: ModuleGraph) =
|
|||
clearPasses(graph)
|
||||
conf.lastCmdTime = epochTime()
|
||||
conf.searchPaths.add(conf.libpath)
|
||||
setId(100)
|
||||
|
||||
proc customizeForBackend(backend: TBackend) =
|
||||
## Sets backend specific options but don't compile to backend yet in
|
||||
|
|
@ -219,7 +214,7 @@ proc mainCommand*(graph: ModuleGraph) =
|
|||
else:
|
||||
wantMainModule(conf)
|
||||
conf.cmd = cmdDoc
|
||||
loadConfigs(DocConfig, cache, conf)
|
||||
loadConfigs(DocConfig, cache, conf, graph.idgen)
|
||||
defineSymbol(conf.symbols, "nimdoc")
|
||||
body
|
||||
|
||||
|
|
@ -277,14 +272,14 @@ proc mainCommand*(graph: ModuleGraph) =
|
|||
quit "compiler wasn't built with documentation generator"
|
||||
else:
|
||||
conf.cmd = cmdRst2html
|
||||
loadConfigs(DocConfig, cache, conf)
|
||||
loadConfigs(DocConfig, cache, conf, graph.idgen)
|
||||
commandRst2Html(cache, conf)
|
||||
of "rst2tex":
|
||||
when defined(leanCompiler):
|
||||
quit "compiler wasn't built with documentation generator"
|
||||
else:
|
||||
conf.cmd = cmdRst2tex
|
||||
loadConfigs(DocTexConfig, cache, conf)
|
||||
loadConfigs(DocTexConfig, cache, conf, graph.idgen)
|
||||
commandRst2TeX(cache, conf)
|
||||
of "jsondoc0": docLikeCmd commandJson(cache, conf)
|
||||
of "jsondoc2", "jsondoc": docLikeCmd commandDoc2(graph, true)
|
||||
|
|
|
|||
|
|
@ -74,11 +74,13 @@ type
|
|||
globalDestructors*: seq[PNode]
|
||||
strongSemCheck*: proc (graph: ModuleGraph; owner: PSym; body: PNode) {.nimcall.}
|
||||
compatibleProps*: proc (graph: ModuleGraph; formal, actual: PType): bool {.nimcall.}
|
||||
idgen*: IdGenerator
|
||||
|
||||
TPassContext* = object of RootObj # the pass's context
|
||||
idgen*: IdGenerator
|
||||
PPassContext* = ref TPassContext
|
||||
|
||||
TPassOpen* = proc (graph: ModuleGraph; module: PSym): PPassContext {.nimcall.}
|
||||
TPassOpen* = proc (graph: ModuleGraph; module: PSym; idgen: IdGenerator): PPassContext {.nimcall.}
|
||||
TPassClose* = proc (graph: ModuleGraph; p: PPassContext, n: PNode): PNode {.nimcall.}
|
||||
TPassProcess* = proc (p: PPassContext, topLevelStmt: PNode): PNode {.nimcall.}
|
||||
|
||||
|
|
@ -165,12 +167,13 @@ 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), nil, unknownLineInfo, {})
|
||||
result = newSym(skProc, getIdent(g.cache, name), nextId(g.idgen), nil, unknownLineInfo, {})
|
||||
result.magic = m
|
||||
result.flags = {sfNeverRaises}
|
||||
|
||||
proc newModuleGraph*(cache: IdentCache; config: ConfigRef): ModuleGraph =
|
||||
result = ModuleGraph()
|
||||
result.idgen = IdGenerator(module: -1'i32, item: 0'i32)
|
||||
initStrTable(result.packageSyms)
|
||||
result.deps = initIntSet()
|
||||
result.importDeps = initTable[FileIndex, seq[FileIndex]]()
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
import
|
||||
ast, astalgo, magicsys, msgs, options,
|
||||
idents, lexer, idgen, passes, syntaxes, llstream, modulegraphs, rod,
|
||||
idents, lexer, passes, syntaxes, llstream, modulegraphs, rod,
|
||||
lineinfos, pathutils, tables
|
||||
|
||||
proc resetSystemArtifacts*(g: ModuleGraph) =
|
||||
|
|
@ -20,6 +20,8 @@ proc resetSystemArtifacts*(g: ModuleGraph) =
|
|||
template getModuleIdent(graph: ModuleGraph, filename: AbsoluteFile): PIdent =
|
||||
getIdent(graph.cache, splitFile(filename).name)
|
||||
|
||||
template packageId(): untyped {.dirty.} = ItemId(module: PackageModuleId, item: int32(fileIdx))
|
||||
|
||||
proc getPackage(graph: ModuleGraph; fileIdx: FileIndex): PSym =
|
||||
## returns package symbol (skPackage) for yet to be defined module for fileIdx
|
||||
let filename = AbsoluteFile toFullPath(graph.config, fileIdx)
|
||||
|
|
@ -31,7 +33,7 @@ proc getPackage(graph: ModuleGraph; fileIdx: FileIndex): PSym =
|
|||
pack = getIdent(graph.cache, pck2)
|
||||
var packSym = graph.packageSyms.strTableGet(pack)
|
||||
if packSym == nil:
|
||||
packSym = newSym(skPackage, getIdent(graph.cache, pck2), nil, info)
|
||||
packSym = newSym(skPackage, getIdent(graph.cache, pck2), packageId(), nil, info)
|
||||
initStrTable(packSym.tab)
|
||||
graph.packageSyms.strTableAdd(packSym)
|
||||
else:
|
||||
|
|
@ -47,7 +49,7 @@ proc getPackage(graph: ModuleGraph; fileIdx: FileIndex): PSym =
|
|||
# to resolve the conflicts:
|
||||
let pck3 = fakePackageName(graph.config, filename)
|
||||
# this makes the new `packSym`'s owner be the original `packSym`
|
||||
packSym = newSym(skPackage, getIdent(graph.cache, pck3), packSym, info)
|
||||
packSym = newSym(skPackage, getIdent(graph.cache, pck3), packageId(), packSym, info)
|
||||
initStrTable(packSym.tab)
|
||||
graph.packageSyms.strTableAdd(packSym)
|
||||
result = packSym
|
||||
|
|
@ -69,7 +71,7 @@ proc newModule(graph: ModuleGraph; fileIdx: FileIndex): PSym =
|
|||
let filename = AbsoluteFile toFullPath(graph.config, fileIdx)
|
||||
# We cannot call ``newSym`` here, because we have to circumvent the ID
|
||||
# mechanism, which we do in order to assign each module a persistent ID.
|
||||
result = PSym(kind: skModule, id: -1, # for better error checking
|
||||
result = PSym(kind: skModule, itemId: ItemId(module: int32(fileIdx), item: 0'i32),
|
||||
name: getModuleIdent(graph, filename),
|
||||
info: newLineInfo(fileIdx, 1, 1))
|
||||
if not isNimIdentifier(result.name.s):
|
||||
|
|
@ -82,25 +84,21 @@ proc compileModule*(graph: ModuleGraph; fileIdx: FileIndex; flags: TSymFlags): P
|
|||
result = graph.getModule(fileIdx)
|
||||
if result == nil:
|
||||
let filename = AbsoluteFile toFullPath(graph.config, fileIdx)
|
||||
let (r, id) = loadModuleSym(graph, fileIdx, filename)
|
||||
result = r
|
||||
result = loadModuleSym(graph, fileIdx, filename)
|
||||
if result == nil:
|
||||
result = newModule(graph, fileIdx)
|
||||
result.flags.incl flags
|
||||
result.id = id
|
||||
registerModule(graph, result)
|
||||
else:
|
||||
partialInitModule(result, graph, fileIdx, filename)
|
||||
result.id = id
|
||||
assert result.id < 0
|
||||
discard processModule(graph, result,
|
||||
discard processModule(graph, result, idGeneratorFromModule(result),
|
||||
if sfMainModule in flags and graph.config.projectIsStdin: stdin.llStreamOpen else: nil)
|
||||
elif graph.isDirty(result):
|
||||
result.flags.excl sfDirty
|
||||
# reset module fields:
|
||||
initStrTable(result.tab)
|
||||
result.ast = nil
|
||||
discard processModule(graph, result,
|
||||
discard processModule(graph, result, idGeneratorFromModule(result),
|
||||
if sfMainModule in flags and graph.config.projectIsStdin: stdin.llStreamOpen else: nil)
|
||||
graph.markClientsDirty(fileIdx)
|
||||
|
||||
|
|
@ -161,7 +159,6 @@ proc compileProject*(graph: ModuleGraph; projectFileIdx = InvalidFileIdx) =
|
|||
|
||||
proc makeModule*(graph: ModuleGraph; filename: AbsoluteFile): PSym =
|
||||
result = graph.newModule(fileInfoIdx(graph.config, filename))
|
||||
result.id = getID()
|
||||
registerModule(graph, result)
|
||||
|
||||
proc makeModule*(graph: ModuleGraph; filename: string): PSym =
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
# This module handles the reading of the config file.
|
||||
|
||||
import
|
||||
llstream, commands, os, strutils, msgs, lexer,
|
||||
llstream, commands, os, strutils, msgs, lexer, ast,
|
||||
options, idents, wordrecg, strtabs, lineinfos, pathutils, scriptconfig
|
||||
|
||||
# ---------------- configuration file parser -----------------------------
|
||||
|
|
@ -238,7 +238,7 @@ proc getSystemConfigPath*(conf: ConfigRef; filename: RelativeFile): AbsoluteFile
|
|||
if not fileExists(result): result = p / RelativeDir"etc/nim" / filename
|
||||
if not fileExists(result): result = AbsoluteDir"/etc/nim" / filename
|
||||
|
||||
proc loadConfigs*(cfg: RelativeFile; cache: IdentCache; conf: ConfigRef) =
|
||||
proc loadConfigs*(cfg: RelativeFile; cache: IdentCache; conf: ConfigRef; idgen: IdGenerator) =
|
||||
setDefaultLibpath(conf)
|
||||
|
||||
var configFiles = newSeq[AbsoluteFile]()
|
||||
|
|
@ -252,7 +252,7 @@ proc loadConfigs*(cfg: RelativeFile; cache: IdentCache; conf: ConfigRef) =
|
|||
let p = path # eval once
|
||||
if fileExists(p):
|
||||
configFiles.add(p)
|
||||
runNimScript(cache, p, freshDefines = false, conf)
|
||||
runNimScript(cache, p, idgen, freshDefines = false, conf)
|
||||
|
||||
if optSkipSystemConfigFile notin conf.globalOptions:
|
||||
readConfigFile(getSystemConfigPath(conf, cfg))
|
||||
|
|
@ -291,13 +291,12 @@ proc loadConfigs*(cfg: RelativeFile; cache: IdentCache; conf: ConfigRef) =
|
|||
# delayed to here so that `hintConf` is honored
|
||||
rawMessage(conf, hintConf, filename.string)
|
||||
|
||||
block:
|
||||
let scriptFile = conf.projectFull.changeFileExt("nims")
|
||||
if conf.command != "nimsuggest":
|
||||
let scriptFile = conf.projectFull.changeFileExt("nims")
|
||||
if conf.command != "nimsuggest":
|
||||
runNimScriptIfExists(scriptFile)
|
||||
else:
|
||||
if scriptFile != conf.projectFull:
|
||||
runNimScriptIfExists(scriptFile)
|
||||
else:
|
||||
if scriptFile != conf.projectFull:
|
||||
runNimScriptIfExists(scriptFile)
|
||||
else:
|
||||
# 'nimsuggest foo.nims' means to just auto-complete the NimScript file
|
||||
discard
|
||||
# 'nimsuggest foo.nims' means to just auto-complete the NimScript file
|
||||
discard
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ type
|
|||
mainModule: PSym
|
||||
graph: ModuleGraph
|
||||
scriptName: string
|
||||
idgen: IdGenerator
|
||||
|
||||
iterator exportedSymbols*(i: Interpreter): PSym =
|
||||
assert i != nil
|
||||
|
|
@ -74,7 +75,7 @@ proc evalScript*(i: Interpreter; scriptStream: PLLStream = nil) =
|
|||
|
||||
let s = if scriptStream != nil: scriptStream
|
||||
else: llStreamOpen(findFile(i.graph.config, i.scriptName), fmRead)
|
||||
processModule(i.graph, i.mainModule, s)
|
||||
processModule(i.graph, i.mainModule, i.idgen, s)
|
||||
|
||||
proc findNimStdLib*(): string =
|
||||
## Tries to find a path to a valid "system.nim" file.
|
||||
|
|
@ -121,14 +122,15 @@ proc createInterpreter*(scriptName: string;
|
|||
|
||||
var m = graph.makeModule(scriptName)
|
||||
incl(m.flags, sfMainModule)
|
||||
var vm = newCtx(m, cache, graph)
|
||||
var idgen = idGeneratorFromModule(m)
|
||||
var vm = newCtx(m, cache, graph, idgen)
|
||||
vm.mode = emRepl
|
||||
vm.features = flags
|
||||
if registerOps:
|
||||
vm.registerAdditionalOps() # Required to register parts of stdlib modules
|
||||
graph.vm = vm
|
||||
graph.compileSystemModule()
|
||||
result = Interpreter(mainModule: m, graph: graph, scriptName: scriptName)
|
||||
result = Interpreter(mainModule: m, graph: graph, scriptName: scriptName, idgen: idgen)
|
||||
|
||||
proc destroyInterpreter*(i: Interpreter) =
|
||||
## destructor.
|
||||
|
|
@ -162,6 +164,8 @@ proc runRepl*(r: TLLRepl;
|
|||
registerPass(graph, evalPass)
|
||||
var m = graph.makeStdinModule()
|
||||
incl(m.flags, sfMainModule)
|
||||
if supportNimscript: graph.vm = setupVM(m, cache, "stdin", graph)
|
||||
var idgen = idGeneratorFromModule(m)
|
||||
|
||||
if supportNimscript: graph.vm = setupVM(m, cache, "stdin", graph, idgen)
|
||||
graph.compileSystemModule()
|
||||
processModule(graph, m, llStreamOpenStdIn(r))
|
||||
processModule(graph, m, idgen, llStreamOpenStdIn(r))
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
## implements some little helper passes
|
||||
|
||||
import
|
||||
ast, passes, idents, msgs, options, idgen, lineinfos
|
||||
ast, passes, idents, msgs, options, lineinfos
|
||||
|
||||
from modulegraphs import ModuleGraph, PPassContext
|
||||
|
||||
|
|
@ -18,9 +18,9 @@ type
|
|||
VerboseRef = ref object of PPassContext
|
||||
config: ConfigRef
|
||||
|
||||
proc verboseOpen(graph: ModuleGraph; s: PSym): PPassContext =
|
||||
proc verboseOpen(graph: ModuleGraph; s: PSym; idgen: IdGenerator): PPassContext =
|
||||
#MessageOut('compiling ' + s.name.s);
|
||||
result = VerboseRef(config: graph.config)
|
||||
result = VerboseRef(config: graph.config, idgen: idgen)
|
||||
rawMessage(graph.config, hintProcessing, s.name.s)
|
||||
|
||||
proc verboseProcess(context: PPassContext, n: PNode): PNode =
|
||||
|
|
@ -30,6 +30,6 @@ proc verboseProcess(context: PPassContext, n: PNode): PNode =
|
|||
# system.nim deactivates all hints, for verbosity:3 we want the processing
|
||||
# messages nonetheless, so we activate them again (but honor cmdlineNotes)
|
||||
v.config.setNote(hintProcessing)
|
||||
message(v.config, n.info, hintProcessing, $idgen.gFrontEndId)
|
||||
message(v.config, n.info, hintProcessing, $v.idgen[])
|
||||
|
||||
const verbosePass* = makePass(open = verboseOpen, process = verboseProcess)
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
import
|
||||
options, ast, llstream, msgs,
|
||||
idents,
|
||||
syntaxes, idgen, modulegraphs, reorder, rod,
|
||||
syntaxes, modulegraphs, reorder, rod,
|
||||
lineinfos, pathutils
|
||||
|
||||
type
|
||||
|
|
@ -51,31 +51,18 @@ proc registerPass*(g: ModuleGraph; p: TPass) =
|
|||
internalAssert g.config, g.passes.len < maxPasses
|
||||
g.passes.add(p)
|
||||
|
||||
proc carryPass*(g: ModuleGraph; p: TPass, module: PSym;
|
||||
m: TPassData): TPassData =
|
||||
var c = p.open(g, module)
|
||||
result.input = p.process(c, m.input)
|
||||
result.closeOutput = if p.close != nil: p.close(g, c, m.closeOutput)
|
||||
else: m.closeOutput
|
||||
|
||||
proc carryPasses*(g: ModuleGraph; nodes: PNode, module: PSym;
|
||||
passes: openArray[TPass]) =
|
||||
var passdata: TPassData
|
||||
passdata.input = nodes
|
||||
for pass in passes:
|
||||
passdata = carryPass(g, pass, module, passdata)
|
||||
|
||||
proc openPasses(g: ModuleGraph; a: var TPassContextArray;
|
||||
module: PSym) =
|
||||
module: PSym; idgen: IdGenerator) =
|
||||
for i in 0..<g.passes.len:
|
||||
if not isNil(g.passes[i].open):
|
||||
a[i] = g.passes[i].open(g, module)
|
||||
a[i] = g.passes[i].open(g, module, idgen)
|
||||
else: a[i] = nil
|
||||
|
||||
proc closePasses(graph: ModuleGraph; a: var TPassContextArray) =
|
||||
var m: PNode = nil
|
||||
for i in 0..<graph.passes.len:
|
||||
if not isNil(graph.passes[i].close): m = graph.passes[i].close(graph, a[i], m)
|
||||
if not isNil(graph.passes[i].close):
|
||||
m = graph.passes[i].close(graph, a[i], m)
|
||||
a[i] = nil # free the memory here
|
||||
|
||||
proc processTopLevelStmt(graph: ModuleGraph, n: PNode, a: var TPassContextArray): bool =
|
||||
|
|
@ -123,7 +110,8 @@ proc prepareConfigNotes(graph: ModuleGraph; module: PSym) =
|
|||
proc moduleHasChanged*(graph: ModuleGraph; module: PSym): bool {.inline.} =
|
||||
result = module.id >= 0 or isDefined(graph.config, "nimBackendAssumesChange")
|
||||
|
||||
proc processModule*(graph: ModuleGraph; module: PSym, stream: PLLStream): bool {.discardable.} =
|
||||
proc processModule*(graph: ModuleGraph; module: PSym; idgen: IdGenerator;
|
||||
stream: PLLStream): bool {.discardable.} =
|
||||
if graph.stopCompile(): return true
|
||||
var
|
||||
p: Parser
|
||||
|
|
@ -135,7 +123,7 @@ proc processModule*(graph: ModuleGraph; module: PSym, stream: PLLStream): bool {
|
|||
# new module caching mechanism:
|
||||
for i in 0..<graph.passes.len:
|
||||
if not isNil(graph.passes[i].open) and not graph.passes[i].isFrontend:
|
||||
a[i] = graph.passes[i].open(graph, module)
|
||||
a[i] = graph.passes[i].open(graph, module, idgen)
|
||||
else:
|
||||
a[i] = nil
|
||||
|
||||
|
|
@ -154,7 +142,7 @@ proc processModule*(graph: ModuleGraph; module: PSym, stream: PLLStream): bool {
|
|||
m = graph.passes[i].close(graph, a[i], m)
|
||||
a[i] = nil
|
||||
else:
|
||||
openPasses(graph, a, module)
|
||||
openPasses(graph, a, module, idgen)
|
||||
if stream == nil:
|
||||
let filename = toFullPathConsiderDirty(graph.config, fileIdx)
|
||||
s = llStreamOpen(filename, fmRead)
|
||||
|
|
@ -215,6 +203,4 @@ proc processModule*(graph: ModuleGraph; module: PSym, stream: PLLStream): bool {
|
|||
closeParser(p)
|
||||
if s.kind != llsStdIn: break
|
||||
closePasses(graph, a)
|
||||
# id synchronization point for more consistent code generation:
|
||||
idSynchronizationPoint(1000)
|
||||
result = true
|
||||
|
|
|
|||
|
|
@ -29,10 +29,10 @@ proc iterToProcImpl*(c: PContext, n: PNode): PNode =
|
|||
localError(c.config, n[2].info,
|
||||
"type must be a non-generic ref|ptr to object with state field")
|
||||
return
|
||||
let body = liftIterToProc(c.graph, iter.sym, iter.sym.getBody, t)
|
||||
let body = liftIterToProc(c.graph, iter.sym, iter.sym.getBody, t, c.idgen)
|
||||
|
||||
let prc = newSym(skProc, n[3].ident, iter.sym.owner, iter.sym.info)
|
||||
prc.typ = copyType(iter.sym.typ, prc, false)
|
||||
let prc = newSym(skProc, n[3].ident, nextId c.idgen, iter.sym.owner, iter.sym.info)
|
||||
prc.typ = copyType(iter.sym.typ, nextId c.idgen, prc)
|
||||
excl prc.typ.flags, tfCapturesEnv
|
||||
prc.typ.n.add newSymNode(getEnvParam(iter.sym))
|
||||
prc.typ.rawAddSon t
|
||||
|
|
|
|||
|
|
@ -27,13 +27,13 @@ proc semLocals*(c: PContext, n: PNode): PNode =
|
|||
{tyVarargs, tyOpenArray, tyTypeDesc, tyStatic, tyUntyped, tyTyped, tyEmpty}:
|
||||
|
||||
if it.owner == owner:
|
||||
var field = newSym(skField, it.name, owner, n.info)
|
||||
var field = newSym(skField, it.name, nextId c.idgen, owner, n.info)
|
||||
field.typ = it.typ.skipTypes({tyVar})
|
||||
field.position = counter
|
||||
inc(counter)
|
||||
|
||||
tupleType.n.add newSymNode(field)
|
||||
addSonSkipIntLit(tupleType, field.typ)
|
||||
addSonSkipIntLit(tupleType, field.typ, c.idgen)
|
||||
|
||||
var a = newSymNode(it, result.info)
|
||||
if it.typ.skipTypes({tyGenericInst}).kind == tyVar: a = newDeref(a)
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ proc pragmaEnsures(c: PContext, n: PNode) =
|
|||
openScope(c)
|
||||
let o = getCurrOwner(c)
|
||||
if o.kind in routineKinds and o.typ != nil and o.typ.sons[0] != nil:
|
||||
var s = newSym(skResult, getIdent(c.cache, "result"), o, n.info)
|
||||
var s = newSym(skResult, getIdent(c.cache, "result"), nextId(c.idgen), o, n.info)
|
||||
s.typ = o.typ.sons[0]
|
||||
incl(s.flags, sfUsed)
|
||||
addDecl(c, s)
|
||||
|
|
@ -636,7 +636,7 @@ proc processPragma(c: PContext, n: PNode, i: int) =
|
|||
elif it.safeLen != 2 or it[0].kind != nkIdent or it[1].kind != nkIdent:
|
||||
invalidPragma(c, n)
|
||||
|
||||
var userPragma = newSym(skTemplate, it[1].ident, nil, it.info, c.config.options)
|
||||
var userPragma = newSym(skTemplate, it[1].ident, nextId(c.idgen), nil, it.info, c.config.options)
|
||||
userPragma.ast = newTreeI(nkPragma, n.info, n.sons[i+1..^1])
|
||||
strTableAdd(c.userPragmas, userPragma)
|
||||
|
||||
|
|
@ -717,7 +717,7 @@ proc deprecatedStmt(c: PContext; outerPragma: PNode) =
|
|||
if dest == nil or dest.kind in routineKinds:
|
||||
localError(c.config, n.info, warnUser, "the .deprecated pragma is unreliable for routines")
|
||||
let src = considerQuotedIdent(c, n[0])
|
||||
let alias = newSym(skAlias, src, dest, n[0].info, c.config.options)
|
||||
let alias = newSym(skAlias, src, nextId(c.idgen), dest, n[0].info, c.config.options)
|
||||
incl(alias.flags, sfExported)
|
||||
if sfCompilerProc in dest.flags: markCompilerProc(c, alias)
|
||||
addInterfaceDecl(c, alias)
|
||||
|
|
@ -739,7 +739,7 @@ proc pragmaGuard(c: PContext; it: PNode; kind: TSymKind): PSym =
|
|||
# We return a dummy symbol; later passes over the type will repair it.
|
||||
# Generic instantiation needs to know about this too. But we're lazy
|
||||
# and perform the lookup on demand instead.
|
||||
result = newSym(skUnknown, considerQuotedIdent(c, n), nil, n.info,
|
||||
result = newSym(skUnknown, considerQuotedIdent(c, n), nextId(c.idgen), nil, n.info,
|
||||
c.config.options)
|
||||
else:
|
||||
result = qualifiedLookUp(c, n, {checkUndeclared})
|
||||
|
|
|
|||
|
|
@ -9,14 +9,14 @@
|
|||
|
||||
## This module implements the canonalization for the various caching mechanisms.
|
||||
|
||||
import ast, idgen, lineinfos, incremental, modulegraphs, pathutils
|
||||
import ast, lineinfos, incremental, modulegraphs, pathutils
|
||||
|
||||
when not nimIncremental:
|
||||
template setupModuleCache*(g: ModuleGraph) = discard
|
||||
template storeNode*(g: ModuleGraph; module: PSym; n: PNode) = discard
|
||||
template loadNode*(g: ModuleGraph; module: PSym): PNode = newNode(nkStmtList)
|
||||
|
||||
proc loadModuleSym*(g: ModuleGraph; fileIdx: FileIndex; fullpath: AbsoluteFile): (PSym, int) {.inline.} = (nil, getID())
|
||||
proc loadModuleSym*(g: ModuleGraph; fileIdx: FileIndex; fullpath: AbsoluteFile): (PSym) {.inline.} = nil
|
||||
|
||||
template addModuleDep*(g: ModuleGraph; module, fileIdx: FileIndex; isIncludeFile: bool) = discard
|
||||
|
||||
|
|
|
|||
|
|
@ -85,9 +85,9 @@ proc getModuleId(g: ModuleGraph; fileIdx: FileIndex; fullpath: AbsoluteFile): in
|
|||
db.exec(sql"delete from toplevelstmts where module = ?", module[0])
|
||||
db.exec(sql"delete from statics where module = ?", module[0])
|
||||
|
||||
proc loadModuleSym*(g: ModuleGraph; fileIdx: FileIndex; fullpath: AbsoluteFile): (PSym, int) =
|
||||
proc loadModuleSym*(g: ModuleGraph; fileIdx: FileIndex; fullpath: AbsoluteFile): PSym =
|
||||
let id = getModuleId(g, fileIdx, fullpath)
|
||||
result = (g.incr.r.syms.getOrDefault(abs id), id)
|
||||
result = g.incr.r.syms.getOrDefault(abs id)
|
||||
|
||||
proc pushType(w: var Writer, t: PType) =
|
||||
if not containsOrIncl(w.tmarks, t.uniqueId):
|
||||
|
|
|
|||
|
|
@ -27,9 +27,9 @@ proc listDirs(a: VmArgs, filter: set[PathComponent]) =
|
|||
setResult(a, result)
|
||||
|
||||
proc setupVM*(module: PSym; cache: IdentCache; scriptName: string;
|
||||
graph: ModuleGraph): PEvalContext =
|
||||
graph: ModuleGraph; idgen: IdGenerator): PEvalContext =
|
||||
# For Nimble we need to export 'setupVM'.
|
||||
result = newCtx(module, cache, graph)
|
||||
result = newCtx(module, cache, graph, idgen)
|
||||
result.mode = emRepl
|
||||
registerAdditionalOps(result)
|
||||
let conf = graph.config
|
||||
|
|
@ -198,6 +198,7 @@ proc setupVM*(module: PSym; cache: IdentCache; scriptName: string;
|
|||
setResult(a, stdin.readAll())
|
||||
|
||||
proc runNimScript*(cache: IdentCache; scriptName: AbsoluteFile;
|
||||
idgen: IdGenerator;
|
||||
freshDefines=true; conf: ConfigRef) =
|
||||
let oldSymbolFiles = conf.symbolFiles
|
||||
conf.symbolFiles = disabledSf
|
||||
|
|
@ -221,10 +222,11 @@ proc runNimScript*(cache: IdentCache; scriptName: AbsoluteFile;
|
|||
|
||||
var m = graph.makeModule(scriptName)
|
||||
incl(m.flags, sfMainModule)
|
||||
graph.vm = setupVM(m, cache, scriptName.string, graph)
|
||||
var vm = setupVM(m, cache, scriptName.string, graph, idgen)
|
||||
graph.vm = vm
|
||||
|
||||
graph.compileSystemModule()
|
||||
discard graph.processModule(m, llStreamOpen(scriptName, fmRead))
|
||||
discard graph.processModule(m, vm.idgen, llStreamOpen(scriptName, fmRead))
|
||||
|
||||
# watch out, "newruntime" can be set within NimScript itself and then we need
|
||||
# to remember this:
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import
|
|||
wordrecg, ropes, msgs, idents, renderer, types, platform, math,
|
||||
magicsys, nversion, nimsets, semfold, modulepaths, importer,
|
||||
procfind, lookups, pragmas, passes, semdata, semtypinst, sigmatch,
|
||||
intsets, transf, vmdef, vm, idgen, aliases, cgmeth, lambdalifting,
|
||||
intsets, transf, vmdef, vm, aliases, cgmeth, lambdalifting,
|
||||
evaltempl, patterns, parampatterns, sempass2, linter, semmacrosanity,
|
||||
lowerings, plugins/active, rod, lineinfos, strtabs, int128,
|
||||
isolation_check, typeallowed
|
||||
|
|
@ -83,7 +83,7 @@ proc fitNodePostMatch(c: PContext, formal: PType, arg: PNode): PNode =
|
|||
if x.kind in {nkPar, nkTupleConstr, nkCurly} and formal.kind != tyUntyped:
|
||||
changeType(c, x, formal, check=true)
|
||||
result = arg
|
||||
result = skipHiddenSubConv(result)
|
||||
result = skipHiddenSubConv(result, c.idgen)
|
||||
|
||||
|
||||
proc fitNode(c: PContext, formal: PType, arg: PNode; info: TLineInfo): PNode =
|
||||
|
|
@ -108,7 +108,7 @@ proc inferWithMetatype(c: PContext, formal: PType,
|
|||
|
||||
template commonTypeBegin*(): PType = PType(kind: tyUntyped)
|
||||
|
||||
proc commonType*(x, y: PType): PType =
|
||||
proc commonType*(c: PContext; x, y: PType): PType =
|
||||
# new type relation that is used for array constructors,
|
||||
# if expressions, etc.:
|
||||
if x == nil: return x
|
||||
|
|
@ -124,8 +124,8 @@ proc commonType*(x, y: PType): PType =
|
|||
# turn any concrete typedesc into the abstract typedesc type
|
||||
if a.len == 0: result = a
|
||||
else:
|
||||
result = newType(tyTypeDesc, a.owner)
|
||||
rawAddSon(result, newType(tyNone, a.owner))
|
||||
result = newType(tyTypeDesc, nextId(c.idgen), a.owner)
|
||||
rawAddSon(result, newType(tyNone, nextId(c.idgen), a.owner))
|
||||
elif b.kind in {tyArray, tySet, tySequence} and
|
||||
a.kind == b.kind:
|
||||
# check for seq[empty] vs. seq[int]
|
||||
|
|
@ -137,7 +137,7 @@ proc commonType*(x, y: PType): PType =
|
|||
let aEmpty = isEmptyContainer(a[i])
|
||||
let bEmpty = isEmptyContainer(b[i])
|
||||
if aEmpty != bEmpty:
|
||||
if nt.isNil: nt = copyType(a, a.owner, false)
|
||||
if nt.isNil: nt = copyType(a, nextId(c.idgen), a.owner)
|
||||
nt[i] = if aEmpty: b[i] else: a[i]
|
||||
if not nt.isNil: result = nt
|
||||
#elif b[idx].kind == tyEmpty: return x
|
||||
|
|
@ -149,7 +149,7 @@ proc commonType*(x, y: PType): PType =
|
|||
# type(if b: 0 else 1) == int and not range[0..1]. For now. In the long
|
||||
# run people expect ranges to work properly within a tuple.
|
||||
if not sameType(a, b):
|
||||
result = skipTypes(a, {tyRange}).skipIntLit
|
||||
result = skipTypes(a, {tyRange}).skipIntLit(c.idgen)
|
||||
when false:
|
||||
if a.kind != tyRange and b.kind == tyRange:
|
||||
# XXX This really needs a better solution, but a proper fix now breaks
|
||||
|
|
@ -176,8 +176,8 @@ proc commonType*(x, y: PType): PType =
|
|||
# ill-formed AST, no need for additional tyRef/tyPtr
|
||||
if k != tyNone and x.kind != tyGenericInst:
|
||||
let r = result
|
||||
result = newType(k, r.owner)
|
||||
result.addSonSkipIntLit(r)
|
||||
result = newType(k, nextId(c.idgen), r.owner)
|
||||
result.addSonSkipIntLit(r, c.idgen)
|
||||
|
||||
proc endsInNoReturn(n: PNode): bool =
|
||||
# check if expr ends in raise exception or call of noreturn proc
|
||||
|
|
@ -187,13 +187,13 @@ proc endsInNoReturn(n: PNode): bool =
|
|||
result = it.kind in nkLastBlockStmts or
|
||||
it.kind in nkCallKinds and it[0].kind == nkSym and sfNoReturn in it[0].sym.flags
|
||||
|
||||
proc commonType*(x: PType, y: PNode): PType =
|
||||
proc commonType*(c: PContext; x: PType, y: PNode): PType =
|
||||
# ignore exception raising branches in case/if expressions
|
||||
if endsInNoReturn(y): return x
|
||||
commonType(x, y.typ)
|
||||
commonType(c, x, y.typ)
|
||||
|
||||
proc newSymS(kind: TSymKind, n: PNode, c: PContext): PSym =
|
||||
result = newSym(kind, considerQuotedIdent(c, n), getCurrOwner(c), n.info)
|
||||
result = newSym(kind, considerQuotedIdent(c, n), nextId c.idgen, getCurrOwner(c), n.info)
|
||||
when defined(nimsuggest):
|
||||
suggestDecl(c, n, result)
|
||||
|
||||
|
|
@ -216,7 +216,7 @@ proc newSymG*(kind: TSymKind, n: PNode, c: PContext): PSym =
|
|||
# template; we must fix it here: see #909
|
||||
result.owner = getCurrOwner(c)
|
||||
else:
|
||||
result = newSym(kind, considerQuotedIdent(c, n), getCurrOwner(c), n.info)
|
||||
result = newSym(kind, considerQuotedIdent(c, n), nextId c.idgen, getCurrOwner(c), n.info)
|
||||
#if kind in {skForVar, skLet, skVar} and result.owner.kind == skModule:
|
||||
# incl(result.flags, sfGlobal)
|
||||
when defined(nimsuggest):
|
||||
|
|
@ -255,7 +255,7 @@ proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym,
|
|||
|
||||
proc symFromType(c: PContext; t: PType, info: TLineInfo): PSym =
|
||||
if t.sym != nil: return t.sym
|
||||
result = newSym(skType, getIdent(c.cache, "AnonType"), t.owner, info)
|
||||
result = newSym(skType, getIdent(c.cache, "AnonType"), nextId c.idgen, t.owner, info)
|
||||
result.flags.incl sfAnon
|
||||
result.typ = t
|
||||
|
||||
|
|
@ -316,7 +316,7 @@ proc tryConstExpr(c: PContext, n: PNode): PNode =
|
|||
var e = semExprWithType(c, n)
|
||||
if e == nil: return
|
||||
|
||||
result = getConstExpr(c.module, e, c.graph)
|
||||
result = getConstExpr(c.module, e, c.idgen, c.graph)
|
||||
if result != nil: return
|
||||
|
||||
let oldErrorCount = c.config.errorCounter
|
||||
|
|
@ -327,7 +327,7 @@ proc tryConstExpr(c: PContext, n: PNode): PNode =
|
|||
c.config.errorMax = high(int) # `setErrorMaxHighMaybe` not appropriate here
|
||||
|
||||
try:
|
||||
result = evalConstExpr(c.module, c.graph, e)
|
||||
result = evalConstExpr(c.module, c.idgen, c.graph, e)
|
||||
if result == nil or result.kind == nkEmpty:
|
||||
result = nil
|
||||
else:
|
||||
|
|
@ -348,10 +348,10 @@ proc semConstExpr(c: PContext, n: PNode): PNode =
|
|||
if e == nil:
|
||||
localError(c.config, n.info, errConstExprExpected)
|
||||
return n
|
||||
result = getConstExpr(c.module, e, c.graph)
|
||||
result = getConstExpr(c.module, e, c.idgen, c.graph)
|
||||
if result == nil:
|
||||
#if e.kind == nkEmpty: globalError(n.info, errConstExprExpected)
|
||||
result = evalConstExpr(c.module, c.graph, e)
|
||||
result = evalConstExpr(c.module, c.idgen, c.graph, e)
|
||||
if result == nil or result.kind == nkEmpty:
|
||||
if e.info != n.info:
|
||||
pushInfoContext(c.config, n.info)
|
||||
|
|
@ -373,7 +373,7 @@ proc semExprFlagDispatched(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
|||
else:
|
||||
result = semExprWithType(c, n, flags)
|
||||
if efPreferStatic in flags:
|
||||
var evaluated = getConstExpr(c.module, result, c.graph)
|
||||
var evaluated = getConstExpr(c.module, result, c.idgen, c.graph)
|
||||
if evaluated != nil: return evaluated
|
||||
evaluated = evalAtCompileTime(c, result)
|
||||
if evaluated != nil: return evaluated
|
||||
|
|
@ -399,7 +399,6 @@ proc semAfterMacroCall(c: PContext, call, macroResult: PNode,
|
|||
if c.config.evalTemplateCounter > evalTemplateLimit:
|
||||
globalError(c.config, s.info, "template instantiation too nested")
|
||||
c.friendModules.add(s.owner.getModule)
|
||||
idSynchronizationPoint(5000)
|
||||
result = macroResult
|
||||
resetSemFlag result
|
||||
if s.typ[0] == nil:
|
||||
|
|
@ -469,7 +468,7 @@ proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym,
|
|||
|
||||
#if c.evalContext == nil:
|
||||
# c.evalContext = c.createEvalContext(emStatic)
|
||||
result = evalMacroCall(c.module, c.graph, c.templInstCounter, n, nOrig, sym)
|
||||
result = evalMacroCall(c.module, c.idgen, c.graph, c.templInstCounter, n, nOrig, sym)
|
||||
if efNoSemCheck notin flags:
|
||||
result = semAfterMacroCall(c, n, result, sym, flags)
|
||||
if c.config.macrosToExpand.hasKey(sym.name.s):
|
||||
|
|
@ -502,8 +501,9 @@ proc addCodeForGenerics(c: PContext, n: PNode) =
|
|||
n.add prc.ast
|
||||
c.lastGenericIdx = c.generics.len
|
||||
|
||||
proc myOpen(graph: ModuleGraph; module: PSym): PPassContext {.nosinks.} =
|
||||
proc myOpen(graph: ModuleGraph; module: PSym; idgen: IdGenerator): PPassContext {.nosinks.} =
|
||||
var c = newContext(graph, module)
|
||||
c.idgen = idgen
|
||||
if c.p != nil: internalError(graph.config, module.info, "sem.myOpen")
|
||||
c.semConstExpr = semConstExpr
|
||||
c.semExpr = semExpr
|
||||
|
|
|
|||
|
|
@ -688,9 +688,9 @@ proc searchForBorrowProc(c: PContext, startScope: PScope, fn: PSym): PSym =
|
|||
var x: PType
|
||||
if param.typ.kind == tyVar:
|
||||
x = newTypeS(param.typ.kind, c)
|
||||
x.addSonSkipIntLit t.baseOfDistinct
|
||||
x.addSonSkipIntLit(t.baseOfDistinct(c.idgen), c.idgen)
|
||||
else:
|
||||
x = t.baseOfDistinct
|
||||
x = t.baseOfDistinct(c.idgen)
|
||||
call.add(newNodeIT(nkEmpty, fn.info, x))
|
||||
if hasDistinct:
|
||||
let filter = if fn.kind in {skProc, skFunc}: {skProc, skFunc} else: {fn.kind}
|
||||
|
|
|
|||
|
|
@ -277,14 +277,14 @@ proc addToLib*(lib: PLib, sym: PSym) =
|
|||
sym.annex = lib
|
||||
|
||||
proc newTypeS*(kind: TTypeKind, c: PContext): PType =
|
||||
result = newType(kind, getCurrOwner(c))
|
||||
result = newType(kind, nextId(c.idgen), getCurrOwner(c))
|
||||
|
||||
proc makePtrType*(owner: PSym, baseType: PType): PType =
|
||||
result = newType(tyPtr, owner)
|
||||
addSonSkipIntLit(result, baseType)
|
||||
proc makePtrType*(owner: PSym, baseType: PType; idgen: IdGenerator): PType =
|
||||
result = newType(tyPtr, nextId(idgen), owner)
|
||||
addSonSkipIntLit(result, baseType, idgen)
|
||||
|
||||
proc makePtrType*(c: PContext, baseType: PType): PType =
|
||||
makePtrType(getCurrOwner(c), baseType)
|
||||
makePtrType(getCurrOwner(c), baseType, c.idgen)
|
||||
|
||||
proc makeTypeWithModifier*(c: PContext,
|
||||
modifier: TTypeKind,
|
||||
|
|
@ -295,21 +295,21 @@ proc makeTypeWithModifier*(c: PContext,
|
|||
result = baseType
|
||||
else:
|
||||
result = newTypeS(modifier, c)
|
||||
addSonSkipIntLit(result, baseType)
|
||||
addSonSkipIntLit(result, baseType, c.idgen)
|
||||
|
||||
proc makeVarType*(c: PContext, baseType: PType; kind = tyVar): PType =
|
||||
if baseType.kind == kind:
|
||||
result = baseType
|
||||
else:
|
||||
result = newTypeS(kind, c)
|
||||
addSonSkipIntLit(result, baseType)
|
||||
addSonSkipIntLit(result, baseType, c.idgen)
|
||||
|
||||
proc makeVarType*(owner: PSym, baseType: PType; kind = tyVar): PType =
|
||||
proc makeVarType*(owner: PSym, baseType: PType; idgen: IdGenerator; kind = tyVar): PType =
|
||||
if baseType.kind == kind:
|
||||
result = baseType
|
||||
else:
|
||||
result = newType(kind, owner)
|
||||
addSonSkipIntLit(result, baseType)
|
||||
result = newType(kind, nextId(idgen), owner)
|
||||
addSonSkipIntLit(result, baseType, idgen)
|
||||
|
||||
proc makeTypeDesc*(c: PContext, typ: PType): PType =
|
||||
if typ.kind == tyTypeDesc:
|
||||
|
|
@ -317,14 +317,14 @@ proc makeTypeDesc*(c: PContext, typ: PType): PType =
|
|||
else:
|
||||
result = newTypeS(tyTypeDesc, c)
|
||||
incl result.flags, tfCheckedForDestructor
|
||||
result.addSonSkipIntLit(typ)
|
||||
result.addSonSkipIntLit(typ, c.idgen)
|
||||
|
||||
proc makeTypeSymNode*(c: PContext, typ: PType, info: TLineInfo): PNode =
|
||||
let typedesc = newTypeS(tyTypeDesc, c)
|
||||
incl typedesc.flags, tfCheckedForDestructor
|
||||
internalAssert(c.config, typ != nil)
|
||||
typedesc.addSonSkipIntLit(typ)
|
||||
let sym = newSym(skType, c.cache.idAnon, getCurrOwner(c), info,
|
||||
typedesc.addSonSkipIntLit(typ, c.idgen)
|
||||
let sym = newSym(skType, c.cache.idAnon, nextId(c.idgen), getCurrOwner(c), info,
|
||||
c.config.options).linkTo(typedesc)
|
||||
return newSymNode(sym, info)
|
||||
|
||||
|
|
@ -333,13 +333,14 @@ proc makeTypeFromExpr*(c: PContext, n: PNode): PType =
|
|||
assert n != nil
|
||||
result.n = n
|
||||
|
||||
proc newTypeWithSons*(owner: PSym, kind: TTypeKind, sons: seq[PType]): PType =
|
||||
result = newType(kind, owner)
|
||||
proc newTypeWithSons*(owner: PSym, kind: TTypeKind, sons: seq[PType];
|
||||
idgen: IdGenerator): PType =
|
||||
result = newType(kind, nextId(idgen), owner)
|
||||
result.sons = sons
|
||||
|
||||
proc newTypeWithSons*(c: PContext, kind: TTypeKind,
|
||||
sons: seq[PType]): PType =
|
||||
result = newType(kind, getCurrOwner(c))
|
||||
result = newType(kind, nextId(c.idgen), getCurrOwner(c))
|
||||
result.sons = sons
|
||||
|
||||
proc makeStaticExpr*(c: PContext, n: PNode): PNode =
|
||||
|
|
@ -418,7 +419,7 @@ proc makeRangeType*(c: PContext; first, last: BiggestInt;
|
|||
n.add newIntTypeNode(last, intType)
|
||||
result = newTypeS(tyRange, c)
|
||||
result.n = n
|
||||
addSonSkipIntLit(result, intType) # basetype of range
|
||||
addSonSkipIntLit(result, intType, c.idgen) # basetype of range
|
||||
|
||||
proc markIndirect*(c: PContext, s: PSym) {.inline.} =
|
||||
if s.kind in {skProc, skFunc, skConverter, skMethod, skIterator}:
|
||||
|
|
|
|||
|
|
@ -33,7 +33,8 @@ proc semTemplateExpr(c: PContext, n: PNode, s: PSym,
|
|||
# Note: This is n.info on purpose. It prevents template from creating an info
|
||||
# context when called from an another template
|
||||
pushInfoContext(c.config, n.info, s.detailedInfo)
|
||||
result = evalTemplate(n, s, getCurrOwner(c), c.config, c.cache, c.templInstCounter, efFromHlo in flags)
|
||||
result = evalTemplate(n, s, getCurrOwner(c), c.config, c.cache,
|
||||
c.templInstCounter, c.idgen, efFromHlo in flags)
|
||||
if efNoSemCheck notin flags: result = semAfterMacroCall(c, n, result, s, flags)
|
||||
popInfoContext(c.config)
|
||||
|
||||
|
|
@ -384,7 +385,7 @@ proc fixupStaticType(c: PContext, n: PNode) =
|
|||
# apply this measure only in code that is enlightened to work
|
||||
# with static types.
|
||||
if n.typ.kind != tyStatic:
|
||||
n.typ = newTypeWithSons(getCurrOwner(c), tyStatic, @[n.typ])
|
||||
n.typ = newTypeWithSons(getCurrOwner(c), tyStatic, @[n.typ], c.idgen)
|
||||
n.typ.n = n # XXX: cycles like the one here look dangerous.
|
||||
# Consider using `n.copyTree`
|
||||
|
||||
|
|
@ -555,7 +556,7 @@ proc arrayConstrType(c: PContext, n: PNode): PType =
|
|||
rawAddSon(typ, newTypeS(tyEmpty, c)) # needs an empty basetype!
|
||||
else:
|
||||
var t = skipTypes(n[0].typ, {tyGenericInst, tyVar, tyLent, tyOrdinal, tyAlias, tySink})
|
||||
addSonSkipIntLit(typ, t)
|
||||
addSonSkipIntLit(typ, t, c.idgen)
|
||||
typ[0] = makeRangeType(c, 0, n.len - 1, n.info)
|
||||
result = typ
|
||||
|
||||
|
|
@ -605,11 +606,11 @@ proc semArrayConstr(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
|||
|
||||
let xx = semExprWithType(c, x, flags*{efAllowDestructor})
|
||||
result.add xx
|
||||
typ = commonType(typ, xx.typ)
|
||||
typ = commonType(c, typ, xx.typ)
|
||||
#n[i] = semExprWithType(c, x, flags*{efAllowDestructor})
|
||||
#result.add fitNode(c, typ, n[i])
|
||||
inc(lastIndex)
|
||||
addSonSkipIntLit(result.typ, typ)
|
||||
addSonSkipIntLit(result.typ, typ, c.idgen)
|
||||
for i in 0..<result.len:
|
||||
result[i] = fitNode(c, typ, result[i], result[i].info)
|
||||
result.typ[0] = makeRangeType(c, toInt64(firstIndex), toInt64(lastIndex), n.info,
|
||||
|
|
@ -756,14 +757,14 @@ proc evalAtCompileTime(c: PContext, n: PNode): PNode =
|
|||
call.add(n[0])
|
||||
var allConst = true
|
||||
for i in 1..<n.len:
|
||||
var a = getConstExpr(c.module, n[i], c.graph)
|
||||
var a = getConstExpr(c.module, n[i], c.idgen, c.graph)
|
||||
if a == nil:
|
||||
allConst = false
|
||||
a = n[i]
|
||||
if a.kind == nkHiddenStdConv: a = a[1]
|
||||
call.add(a)
|
||||
if allConst:
|
||||
result = semfold.getConstExpr(c.module, call, c.graph)
|
||||
result = semfold.getConstExpr(c.module, call, c.idgen, c.graph)
|
||||
if result.isNil: result = n
|
||||
else: return result
|
||||
|
||||
|
|
@ -800,19 +801,19 @@ proc evalAtCompileTime(c: PContext, n: PNode): PNode =
|
|||
var call = newNodeIT(nkCall, n.info, n.typ)
|
||||
call.add(n[0])
|
||||
for i in 1..<n.len:
|
||||
let a = getConstExpr(c.module, n[i], c.graph)
|
||||
let a = getConstExpr(c.module, n[i], c.idgen, c.graph)
|
||||
if a == nil: return n
|
||||
call.add(a)
|
||||
|
||||
#echo "NOW evaluating at compile time: ", call.renderTree
|
||||
if c.inStaticContext == 0 or sfNoSideEffect in callee.flags:
|
||||
if sfCompileTime in callee.flags:
|
||||
result = evalStaticExpr(c.module, c.graph, call, c.p.owner)
|
||||
result = evalStaticExpr(c.module, c.idgen, c.graph, call, c.p.owner)
|
||||
if result.isNil:
|
||||
localError(c.config, n.info, errCannotInterpretNodeX % renderTree(call))
|
||||
else: result = fixupTypeAfterEval(c, result, n)
|
||||
else:
|
||||
result = evalConstExpr(c.module, c.graph, call)
|
||||
result = evalConstExpr(c.module, c.idgen, c.graph, call)
|
||||
if result.isNil: result = n
|
||||
else: result = fixupTypeAfterEval(c, result, n)
|
||||
else:
|
||||
|
|
@ -827,7 +828,7 @@ proc semStaticExpr(c: PContext, n: PNode): PNode =
|
|||
closeScope(c)
|
||||
dec c.inStaticContext
|
||||
if a.findUnresolvedStatic != nil: return a
|
||||
result = evalStaticExpr(c.module, c.graph, a, c.p.owner)
|
||||
result = evalStaticExpr(c.module, c.idgen, c.graph, a, c.p.owner)
|
||||
if result.isNil:
|
||||
localError(c.config, n.info, errCannotInterpretNodeX % renderTree(n))
|
||||
result = c.graph.emptyNode
|
||||
|
|
@ -1115,7 +1116,7 @@ proc readTypeParameter(c: PContext, typ: PType,
|
|||
# This seems semantically correct and then we'll be able
|
||||
# to return the section symbol directly here
|
||||
let foundType = makeTypeDesc(c, def[2].typ)
|
||||
return newSymNode(copySym(def[0].sym).linkTo(foundType), info)
|
||||
return newSymNode(copySym(def[0].sym, nextId c.idgen).linkTo(foundType), info)
|
||||
|
||||
of nkConstSection:
|
||||
for def in statement:
|
||||
|
|
@ -1140,7 +1141,7 @@ proc readTypeParameter(c: PContext, typ: PType,
|
|||
return c.graph.emptyNode
|
||||
else:
|
||||
let foundTyp = makeTypeDesc(c, rawTyp)
|
||||
return newSymNode(copySym(tParam.sym).linkTo(foundTyp), info)
|
||||
return newSymNode(copySym(tParam.sym, nextId c.idgen).linkTo(foundTyp), info)
|
||||
|
||||
return nil
|
||||
|
||||
|
|
@ -1700,7 +1701,7 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode =
|
|||
# unfortunately we need to rewrite ``(x, y) = foo()`` already here so
|
||||
# that overloading of the assignment operator still works. Usually we
|
||||
# prefer to do these rewritings in transf.nim:
|
||||
return semStmt(c, lowerTupleUnpackingForAsgn(c.graph, n, c.p.owner), {})
|
||||
return semStmt(c, lowerTupleUnpackingForAsgn(c.graph, n, c.idgen, c.p.owner), {})
|
||||
else:
|
||||
a = semExprWithType(c, a, {efLValue})
|
||||
else:
|
||||
|
|
@ -1930,7 +1931,7 @@ proc expectString(c: PContext, n: PNode): string =
|
|||
localError(c.config, n.info, errStringLiteralExpected)
|
||||
|
||||
proc newAnonSym(c: PContext; kind: TSymKind, info: TLineInfo): PSym =
|
||||
result = newSym(kind, c.cache.idAnon, getCurrOwner(c), info)
|
||||
result = newSym(kind, c.cache.idAnon, nextId c.idgen, getCurrOwner(c), info)
|
||||
|
||||
proc semExpandToAst(c: PContext, n: PNode): PNode =
|
||||
let macroCall = n[1]
|
||||
|
|
@ -2145,9 +2146,9 @@ proc semShallowCopy(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
|||
result = semDirectOp(c, n, flags)
|
||||
|
||||
proc createFlowVar(c: PContext; t: PType; info: TLineInfo): PType =
|
||||
result = newType(tyGenericInvocation, c.module)
|
||||
addSonSkipIntLit(result, magicsys.getCompilerProc(c.graph, "FlowVar").typ)
|
||||
addSonSkipIntLit(result, t)
|
||||
result = newType(tyGenericInvocation, nextId c.idgen, c.module)
|
||||
addSonSkipIntLit(result, magicsys.getCompilerProc(c.graph, "FlowVar").typ, c.idgen)
|
||||
addSonSkipIntLit(result, t, c.idgen)
|
||||
result = instGenericContainer(c, info, result, allowMetaTypes = false)
|
||||
|
||||
proc instantiateCreateFlowVarCall(c: PContext; t: PType;
|
||||
|
|
@ -2328,7 +2329,7 @@ proc semWhen(c: PContext, n: PNode, semCheck = true): PNode =
|
|||
if whenNimvm:
|
||||
if semCheck:
|
||||
it[1] = semExpr(c, it[1])
|
||||
typ = commonType(typ, it[1].typ)
|
||||
typ = commonType(c, typ, it[1].typ)
|
||||
result = n # when nimvm is not elimited until codegen
|
||||
else:
|
||||
let e = forceBool(c, semConstExpr(c, it[0]))
|
||||
|
|
@ -2343,17 +2344,13 @@ proc semWhen(c: PContext, n: PNode, semCheck = true): PNode =
|
|||
if result == nil or whenNimvm:
|
||||
if semCheck:
|
||||
it[0] = semExpr(c, it[0])
|
||||
typ = commonType(typ, it[0].typ)
|
||||
typ = commonType(c, typ, it[0].typ)
|
||||
if result == nil:
|
||||
result = it[0]
|
||||
else: illFormedAst(n, c.config)
|
||||
if result == nil:
|
||||
result = newNodeI(nkEmpty, n.info)
|
||||
if whenNimvm: result.typ = typ
|
||||
# The ``when`` statement implements the mechanism for platform dependent
|
||||
# code. Thus we try to ensure here consistent ID allocation after the
|
||||
# ``when`` statement.
|
||||
idSynchronizationPoint(200)
|
||||
|
||||
proc semSetConstr(c: PContext, n: PNode): PNode =
|
||||
result = newNodeI(nkCurly, n.info)
|
||||
|
|
@ -2386,7 +2383,7 @@ proc semSetConstr(c: PContext, n: PNode): PNode =
|
|||
typ = makeRangeType(c, 0, MaxSetElements-1, n.info)
|
||||
elif lengthOrd(c.config, typ) > MaxSetElements:
|
||||
typ = makeRangeType(c, 0, MaxSetElements-1, n.info)
|
||||
addSonSkipIntLit(result.typ, typ)
|
||||
addSonSkipIntLit(result.typ, typ, c.idgen)
|
||||
for i in 0..<n.len:
|
||||
var m: PNode
|
||||
let info = n[i].info
|
||||
|
|
@ -2467,7 +2464,7 @@ proc semTupleFieldsConstr(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
|||
n[i][1].typ = errorType(c)
|
||||
|
||||
var f = newSymS(skField, n[i][0], c)
|
||||
f.typ = skipIntLit(n[i][1].typ)
|
||||
f.typ = skipIntLit(n[i][1].typ, c.idgen)
|
||||
f.position = i
|
||||
rawAddSon(typ, f.typ)
|
||||
typ.n.add newSymNode(f)
|
||||
|
|
@ -2481,7 +2478,7 @@ proc semTuplePositionsConstr(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
|||
var typ = newTypeS(tyTuple, c) # leave typ.n nil!
|
||||
for i in 0..<n.len:
|
||||
n[i] = semExprWithType(c, n[i], flags*{efAllowDestructor})
|
||||
addSonSkipIntLit(typ, n[i].typ)
|
||||
addSonSkipIntLit(typ, n[i].typ, c.idgen)
|
||||
result.typ = typ
|
||||
|
||||
include semobjconstr
|
||||
|
|
@ -2608,7 +2605,8 @@ proc hoistParamsUsedInDefault(c: PContext, call, letSection, defExpr: var PNode)
|
|||
let paramPos = defExpr.sym.position + 1
|
||||
|
||||
if call[paramPos].kind != nkSym:
|
||||
let hoistedVarSym = newSym(skLet, getIdent(c.graph.cache, genPrefix), c.p.owner, letSection.info, c.p.owner.options)
|
||||
let hoistedVarSym = newSym(skLet, getIdent(c.graph.cache, genPrefix), nextId c.idgen,
|
||||
c.p.owner, letSection.info, c.p.owner.options)
|
||||
hoistedVarSym.typ = call[paramPos].typ
|
||||
|
||||
letSection.add newTreeI(nkIdentDefs, letSection.info,
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ proc semForFields(c: PContext, n: PNode, m: TMagic): PNode =
|
|||
var trueSymbol = strTableGet(c.graph.systemModule.tab, getIdent(c.cache, "true"))
|
||||
if trueSymbol == nil:
|
||||
localError(c.config, n.info, "system needs: 'true'")
|
||||
trueSymbol = newSym(skUnknown, getIdent(c.cache, "true"), getCurrOwner(c), n.info)
|
||||
trueSymbol = newSym(skUnknown, getIdent(c.cache, "true"), nextId c.idgen, getCurrOwner(c), n.info)
|
||||
trueSymbol.typ = getSysType(c.graph, n.info, tyBool)
|
||||
|
||||
result[0] = newSymNode(trueSymbol, n.info)
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import
|
|||
|
||||
proc errorType*(g: ModuleGraph): PType =
|
||||
## creates a type representing an error state
|
||||
result = newType(tyError, g.owners[^1])
|
||||
result = newType(tyError, nextId(g.idgen), g.owners[^1])
|
||||
result.flags.incl tfCheckedForDestructor
|
||||
|
||||
proc newIntNodeT*(intVal: Int128, n: PNode; g: ModuleGraph): PNode =
|
||||
|
|
@ -42,7 +42,7 @@ proc newStrNodeT*(strVal: string, n: PNode; g: ModuleGraph): PNode =
|
|||
result.typ = n.typ
|
||||
result.info = n.info
|
||||
|
||||
proc getConstExpr*(m: PSym, n: PNode; g: ModuleGraph): PNode
|
||||
proc getConstExpr*(m: PSym, n: PNode; idgen: IdGenerator; g: ModuleGraph): PNode
|
||||
# evaluates the constant expression or returns nil if it is no constant
|
||||
# expression
|
||||
proc evalOp*(m: TMagic, n, a, b, c: PNode; g: ModuleGraph): PNode
|
||||
|
|
@ -113,45 +113,6 @@ proc pickIntRange(a, b: PType): PType =
|
|||
proc isIntRangeOrLit(t: PType): bool =
|
||||
result = isIntRange(t) or isIntLit(t)
|
||||
|
||||
proc makeRange(typ: PType, first, last: BiggestInt; g: ModuleGraph): PType =
|
||||
let minA = min(first, last)
|
||||
let maxA = max(first, last)
|
||||
let lowerNode = newIntNode(nkIntLit, minA)
|
||||
if typ.kind == tyInt and minA == maxA:
|
||||
result = getIntLitType(g, lowerNode)
|
||||
elif typ.kind in {tyUInt, tyUInt64}:
|
||||
# these are not ordinal types, so you get no subrange type for these:
|
||||
result = typ
|
||||
else:
|
||||
var n = newNode(nkRange)
|
||||
n.add lowerNode
|
||||
n.add newIntNode(nkIntLit, maxA)
|
||||
result = newType(tyRange, typ.owner)
|
||||
result.n = n
|
||||
addSonSkipIntLit(result, skipTypes(typ, {tyRange}))
|
||||
|
||||
proc makeRangeF(typ: PType, first, last: BiggestFloat; g: ModuleGraph): PType =
|
||||
var n = newNode(nkRange)
|
||||
n.add newFloatNode(nkFloatLit, min(first.float, last.float))
|
||||
n.add newFloatNode(nkFloatLit, max(first.float, last.float))
|
||||
result = newType(tyRange, typ.owner)
|
||||
result.n = n
|
||||
addSonSkipIntLit(result, skipTypes(typ, {tyRange}))
|
||||
|
||||
proc fitLiteral(c: ConfigRef, n: PNode): PNode {.deprecated: "no substitute".} =
|
||||
# Trim the literal value in order to make it fit in the destination type
|
||||
if n == nil:
|
||||
# `n` may be nil if the overflow check kicks in
|
||||
return
|
||||
|
||||
doAssert n.kind in {nkIntLit, nkCharLit}
|
||||
|
||||
result = n
|
||||
|
||||
let typ = n.typ.skipTypes(abstractRange)
|
||||
if typ.kind in tyUInt..tyUInt32:
|
||||
result.intVal = result.intVal and castToInt64(lastOrd(c, typ))
|
||||
|
||||
proc evalOp(m: TMagic, n, a, b, c: PNode; g: ModuleGraph): PNode =
|
||||
# b and c may be nil
|
||||
result = nil
|
||||
|
|
@ -342,19 +303,19 @@ proc evalOp(m: TMagic, n, a, b, c: PNode; g: ModuleGraph): PNode =
|
|||
exprStructuralEquivalent(a, b, strictSymEquality=true))), n, g)
|
||||
else: discard
|
||||
|
||||
proc getConstIfExpr(c: PSym, n: PNode; g: ModuleGraph): PNode =
|
||||
proc getConstIfExpr(c: PSym, n: PNode; idgen: IdGenerator; g: ModuleGraph): PNode =
|
||||
result = nil
|
||||
for i in 0..<n.len:
|
||||
var it = n[i]
|
||||
if it.len == 2:
|
||||
var e = getConstExpr(c, it[0], g)
|
||||
var e = getConstExpr(c, it[0], idgen, g)
|
||||
if e == nil: return nil
|
||||
if getOrdValue(e) != 0:
|
||||
if result == nil:
|
||||
result = getConstExpr(c, it[1], g)
|
||||
result = getConstExpr(c, it[1], idgen, g)
|
||||
if result == nil: return
|
||||
elif it.len == 1:
|
||||
if result == nil: result = getConstExpr(c, it[0], g)
|
||||
if result == nil: result = getConstExpr(c, it[0], idgen, g)
|
||||
else: internalError(g.config, it.info, "getConstIfExpr()")
|
||||
|
||||
proc leValueConv*(a, b: PNode): bool =
|
||||
|
|
@ -372,18 +333,18 @@ proc leValueConv*(a, b: PNode): bool =
|
|||
else: result = false # internalError(a.info, "leValueConv")
|
||||
else: result = false # internalError(a.info, "leValueConv")
|
||||
|
||||
proc magicCall(m: PSym, n: PNode; g: ModuleGraph): PNode =
|
||||
proc magicCall(m: PSym, n: PNode; idgen: IdGenerator; g: ModuleGraph): PNode =
|
||||
if n.len <= 1: return
|
||||
|
||||
var s = n[0].sym
|
||||
var a = getConstExpr(m, n[1], g)
|
||||
var a = getConstExpr(m, n[1], idgen, g)
|
||||
var b, c: PNode
|
||||
if a == nil: return
|
||||
if n.len > 2:
|
||||
b = getConstExpr(m, n[2], g)
|
||||
b = getConstExpr(m, n[2], idgen, g)
|
||||
if b == nil: return
|
||||
if n.len > 3:
|
||||
c = getConstExpr(m, n[3], g)
|
||||
c = getConstExpr(m, n[3], idgen, g)
|
||||
if c == nil: return
|
||||
result = evalOp(s.magic, n, a, b, c, g)
|
||||
|
||||
|
|
@ -451,19 +412,19 @@ proc foldConv(n, a: PNode; g: ModuleGraph; check = false): PNode =
|
|||
result = a
|
||||
result.typ = n.typ
|
||||
|
||||
proc getArrayConstr(m: PSym, n: PNode; g: ModuleGraph): PNode =
|
||||
proc getArrayConstr(m: PSym, n: PNode; idgen: IdGenerator; g: ModuleGraph): PNode =
|
||||
if n.kind == nkBracket:
|
||||
result = n
|
||||
else:
|
||||
result = getConstExpr(m, n, g)
|
||||
result = getConstExpr(m, n, idgen, g)
|
||||
if result == nil: result = n
|
||||
|
||||
proc foldArrayAccess(m: PSym, n: PNode; g: ModuleGraph): PNode =
|
||||
var x = getConstExpr(m, n[0], g)
|
||||
proc foldArrayAccess(m: PSym, n: PNode; idgen: IdGenerator; g: ModuleGraph): PNode =
|
||||
var x = getConstExpr(m, n[0], idgen, g)
|
||||
if x == nil or x.typ.skipTypes({tyGenericInst, tyAlias, tySink}).kind == tyTypeDesc:
|
||||
return
|
||||
|
||||
var y = getConstExpr(m, n[1], g)
|
||||
var y = getConstExpr(m, n[1], idgen, g)
|
||||
if y == nil: return
|
||||
|
||||
var idx = toInt64(getOrdValue(y))
|
||||
|
|
@ -486,9 +447,9 @@ proc foldArrayAccess(m: PSym, n: PNode; g: ModuleGraph): PNode =
|
|||
localError(g.config, n.info, formatErrorIndexBound(idx, x.strVal.len-1) & $n)
|
||||
else: discard
|
||||
|
||||
proc foldFieldAccess(m: PSym, n: PNode; g: ModuleGraph): PNode =
|
||||
proc foldFieldAccess(m: PSym, n: PNode; idgen: IdGenerator; g: ModuleGraph): PNode =
|
||||
# a real field access; proc calls have already been transformed
|
||||
var x = getConstExpr(m, n[0], g)
|
||||
var x = getConstExpr(m, n[0], idgen, g)
|
||||
if x == nil or x.kind notin {nkObjConstr, nkPar, nkTupleConstr}: return
|
||||
|
||||
var field = n[1].sym
|
||||
|
|
@ -504,23 +465,23 @@ proc foldFieldAccess(m: PSym, n: PNode; g: ModuleGraph): PNode =
|
|||
return
|
||||
localError(g.config, n.info, "field not found: " & field.name.s)
|
||||
|
||||
proc foldConStrStr(m: PSym, n: PNode; g: ModuleGraph): PNode =
|
||||
proc foldConStrStr(m: PSym, n: PNode; idgen: IdGenerator; g: ModuleGraph): PNode =
|
||||
result = newNodeIT(nkStrLit, n.info, n.typ)
|
||||
result.strVal = ""
|
||||
for i in 1..<n.len:
|
||||
let a = getConstExpr(m, n[i], g)
|
||||
let a = getConstExpr(m, n[i], idgen, g)
|
||||
if a == nil: return nil
|
||||
result.strVal.add(getStrOrChar(a))
|
||||
|
||||
proc newSymNodeTypeDesc*(s: PSym; info: TLineInfo): PNode =
|
||||
proc newSymNodeTypeDesc*(s: PSym; idgen: IdGenerator; info: TLineInfo): PNode =
|
||||
result = newSymNode(s, info)
|
||||
if s.typ.kind != tyTypeDesc:
|
||||
result.typ = newType(tyTypeDesc, s.owner)
|
||||
result.typ.addSonSkipIntLit(s.typ)
|
||||
result.typ = newType(tyTypeDesc, idgen.nextId, s.owner)
|
||||
result.typ.addSonSkipIntLit(s.typ, idgen)
|
||||
else:
|
||||
result.typ = s.typ
|
||||
|
||||
proc getConstExpr(m: PSym, n: PNode; g: ModuleGraph): PNode =
|
||||
proc getConstExpr(m: PSym, n: PNode; idgen: IdGenerator; g: ModuleGraph): PNode =
|
||||
result = nil
|
||||
case n.kind
|
||||
of nkSym:
|
||||
|
|
@ -570,12 +531,12 @@ proc getConstExpr(m: PSym, n: PNode; g: ModuleGraph): PNode =
|
|||
result = n
|
||||
of skParam:
|
||||
if s.typ != nil and s.typ.kind == tyTypeDesc:
|
||||
result = newSymNodeTypeDesc(s, n.info)
|
||||
result = newSymNodeTypeDesc(s, idgen, n.info)
|
||||
of skType:
|
||||
# XXX gensym'ed symbols can come here and cannot be resolved. This is
|
||||
# dirty, but correct.
|
||||
if s.typ != nil:
|
||||
result = newSymNodeTypeDesc(s, n.info)
|
||||
result = newSymNodeTypeDesc(s, idgen, n.info)
|
||||
of skGenericParam:
|
||||
if s.typ.kind == tyStatic:
|
||||
if s.typ.n != nil and tfUnresolved notin s.typ.flags:
|
||||
|
|
@ -584,12 +545,12 @@ proc getConstExpr(m: PSym, n: PNode; g: ModuleGraph): PNode =
|
|||
elif s.typ.isIntLit:
|
||||
result = s.typ.n
|
||||
else:
|
||||
result = newSymNodeTypeDesc(s, n.info)
|
||||
result = newSymNodeTypeDesc(s, idgen, n.info)
|
||||
else: discard
|
||||
of nkCharLit..nkNilLit:
|
||||
result = copyNode(n)
|
||||
of nkIfExpr:
|
||||
result = getConstIfExpr(m, n, g)
|
||||
result = getConstIfExpr(m, n, idgen, g)
|
||||
of nkCallKinds:
|
||||
if n[0].kind != nkSym: return
|
||||
var s = n[0].sym
|
||||
|
|
@ -612,17 +573,17 @@ proc getConstExpr(m: PSym, n: PNode; g: ModuleGraph): PNode =
|
|||
else:
|
||||
result = newIntNodeT(lastOrd(g.config, skipTypes(n[1].typ, abstractVar)), n, g)
|
||||
else:
|
||||
var a = getArrayConstr(m, n[1], g)
|
||||
var a = getArrayConstr(m, n[1], idgen, g)
|
||||
if a.kind == nkBracket:
|
||||
# we can optimize it away:
|
||||
result = newIntNodeT(toInt128(a.len-1), n, g)
|
||||
of mLengthOpenArray:
|
||||
var a = getArrayConstr(m, n[1], g)
|
||||
var a = getArrayConstr(m, n[1], idgen, g)
|
||||
if a.kind == nkBracket:
|
||||
# we can optimize it away! This fixes the bug ``len(134)``.
|
||||
result = newIntNodeT(toInt128(a.len), n, g)
|
||||
else:
|
||||
result = magicCall(m, n, g)
|
||||
result = magicCall(m, n, idgen, g)
|
||||
of mLengthArray:
|
||||
# It doesn't matter if the argument is const or not for mLengthArray.
|
||||
# This fixes bug #544.
|
||||
|
|
@ -636,33 +597,33 @@ proc getConstExpr(m: PSym, n: PNode; g: ModuleGraph): PNode =
|
|||
of mAstToStr:
|
||||
result = newStrNodeT(renderTree(n[1], {renderNoComments}), n, g)
|
||||
of mConStrStr:
|
||||
result = foldConStrStr(m, n, g)
|
||||
result = foldConStrStr(m, n, idgen, g)
|
||||
of mIs:
|
||||
# The only kind of mIs node that comes here is one depending on some
|
||||
# generic parameter and that's (hopefully) handled at instantiation time
|
||||
discard
|
||||
else:
|
||||
result = magicCall(m, n, g)
|
||||
result = magicCall(m, n, idgen, g)
|
||||
except OverflowDefect:
|
||||
localError(g.config, n.info, "over- or underflow")
|
||||
except DivByZeroDefect:
|
||||
localError(g.config, n.info, "division by zero")
|
||||
of nkAddr:
|
||||
var a = getConstExpr(m, n[0], g)
|
||||
var a = getConstExpr(m, n[0], idgen, g)
|
||||
if a != nil:
|
||||
result = n
|
||||
n[0] = a
|
||||
of nkBracket, nkCurly:
|
||||
result = copyNode(n)
|
||||
for i, son in n.pairs:
|
||||
var a = getConstExpr(m, son, g)
|
||||
var a = getConstExpr(m, son, idgen, g)
|
||||
if a == nil: return nil
|
||||
result.add a
|
||||
incl(result.flags, nfAllConst)
|
||||
of nkRange:
|
||||
var a = getConstExpr(m, n[0], g)
|
||||
var a = getConstExpr(m, n[0], idgen, g)
|
||||
if a == nil: return
|
||||
var b = getConstExpr(m, n[1], g)
|
||||
var b = getConstExpr(m, n[1], idgen, g)
|
||||
if b == nil: return
|
||||
result = copyNode(n)
|
||||
result.add a
|
||||
|
|
@ -681,18 +642,18 @@ proc getConstExpr(m: PSym, n: PNode; g: ModuleGraph): PNode =
|
|||
for i, expr in n.pairs:
|
||||
let exprNew = copyNode(expr) # nkExprColonExpr
|
||||
exprNew.add expr[0]
|
||||
let a = getConstExpr(m, expr[1], g)
|
||||
let a = getConstExpr(m, expr[1], idgen, g)
|
||||
if a == nil: return nil
|
||||
exprNew.add a
|
||||
result.add exprNew
|
||||
else:
|
||||
for i, expr in n.pairs:
|
||||
let a = getConstExpr(m, expr, g)
|
||||
let a = getConstExpr(m, expr, idgen, g)
|
||||
if a == nil: return nil
|
||||
result.add a
|
||||
incl(result.flags, nfAllConst)
|
||||
of nkChckRangeF, nkChckRange64, nkChckRange:
|
||||
var a = getConstExpr(m, n[0], g)
|
||||
var a = getConstExpr(m, n[0], idgen, g)
|
||||
if a == nil: return
|
||||
if leValueConv(n[1], a) and leValueConv(a, n[2]):
|
||||
result = a # a <= x and x <= b
|
||||
|
|
@ -702,31 +663,31 @@ proc getConstExpr(m: PSym, n: PNode; g: ModuleGraph): PNode =
|
|||
"conversion from $1 to $2 is invalid" %
|
||||
[typeToString(n[0].typ), typeToString(n.typ)])
|
||||
of nkStringToCString, nkCStringToString:
|
||||
var a = getConstExpr(m, n[0], g)
|
||||
var a = getConstExpr(m, n[0], idgen, g)
|
||||
if a == nil: return
|
||||
result = a
|
||||
result.typ = n.typ
|
||||
of nkHiddenStdConv, nkHiddenSubConv, nkConv:
|
||||
var a = getConstExpr(m, n[1], g)
|
||||
var a = getConstExpr(m, n[1], idgen, g)
|
||||
if a == nil: return
|
||||
result = foldConv(n, a, g, check=true)
|
||||
of nkCast:
|
||||
var a = getConstExpr(m, n[1], g)
|
||||
var a = getConstExpr(m, n[1], idgen, g)
|
||||
if a == nil: return
|
||||
if n.typ != nil and n.typ.kind in NilableTypes:
|
||||
# we allow compile-time 'cast' for pointer types:
|
||||
result = a
|
||||
result.typ = n.typ
|
||||
of nkBracketExpr: result = foldArrayAccess(m, n, g)
|
||||
of nkDotExpr: result = foldFieldAccess(m, n, g)
|
||||
of nkBracketExpr: result = foldArrayAccess(m, n, idgen, g)
|
||||
of nkDotExpr: result = foldFieldAccess(m, n, idgen, g)
|
||||
of nkCheckedFieldExpr:
|
||||
result = foldFieldAccess(m, n[0], g)
|
||||
result = foldFieldAccess(m, n[0], idgen, g)
|
||||
of nkStmtListExpr:
|
||||
var i = 0
|
||||
while i <= n.len - 2:
|
||||
if n[i].kind in {nkComesFrom, nkCommentStmt, nkEmpty}: i.inc
|
||||
else: break
|
||||
if i == n.len - 1:
|
||||
result = getConstExpr(m, n[i], g)
|
||||
result = getConstExpr(m, n[i], idgen, g)
|
||||
else:
|
||||
discard
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym,
|
|||
else:
|
||||
result = n
|
||||
else:
|
||||
result = newSymNodeTypeDesc(s, n.info)
|
||||
result = newSymNodeTypeDesc(s, c.idgen, n.info)
|
||||
onUse(n.info, s)
|
||||
of skParam:
|
||||
result = n
|
||||
|
|
@ -103,7 +103,7 @@ proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym,
|
|||
of skType:
|
||||
if (s.typ != nil) and
|
||||
(s.typ.flags * {tfGenericTypeParam, tfImplicitTypeParam} == {}):
|
||||
result = newSymNodeTypeDesc(s, n.info)
|
||||
result = newSymNodeTypeDesc(s, c.idgen, n.info)
|
||||
else:
|
||||
result = n
|
||||
onUse(n.info, s)
|
||||
|
|
@ -267,13 +267,13 @@ proc semGenericStmt(c: PContext, n: PNode,
|
|||
if s.magic == mRunnableExamples:
|
||||
first = result.safeLen # see trunnableexamples.fun3
|
||||
of skGenericParam:
|
||||
result[0] = newSymNodeTypeDesc(s, fn.info)
|
||||
result[0] = newSymNodeTypeDesc(s, c.idgen, fn.info)
|
||||
onUse(fn.info, s)
|
||||
first = 1
|
||||
of skType:
|
||||
# bad hack for generics:
|
||||
if (s.typ != nil) and (s.typ.kind != tyGenericParam):
|
||||
result[0] = newSymNodeTypeDesc(s, fn.info)
|
||||
result[0] = newSymNodeTypeDesc(s, c.idgen, fn.info)
|
||||
onUse(fn.info, s)
|
||||
first = 1
|
||||
else:
|
||||
|
|
@ -470,7 +470,7 @@ proc semGenericStmt(c: PContext, n: PNode,
|
|||
flags, ctx)
|
||||
if n[paramsPos].kind != nkEmpty:
|
||||
if n[paramsPos][0].kind != nkEmpty:
|
||||
addPrelimDecl(c, newSym(skUnknown, getIdent(c.cache, "result"), nil, n.info))
|
||||
addPrelimDecl(c, newSym(skUnknown, getIdent(c.cache, "result"), nextId c.idgen, nil, n.info))
|
||||
n[paramsPos] = semGenericStmt(c, n[paramsPos], flags, ctx)
|
||||
n[pragmasPos] = semGenericStmt(c, n[pragmasPos], flags, ctx)
|
||||
var body: PNode
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ iterator instantiateGenericParamList(c: PContext, n: PNode, pt: TIdTable): PSym
|
|||
if q.typ.kind notin {tyTypeDesc, tyGenericParam, tyStatic}+tyTypeClasses:
|
||||
continue
|
||||
let symKind = if q.typ.kind == tyStatic: skConst else: skType
|
||||
var s = newSym(symKind, q.name, getCurrOwner(c), q.info)
|
||||
var s = newSym(symKind, q.name, nextId c.idgen, getCurrOwner(c), q.info)
|
||||
s.flags.incl {sfUsed, sfFromGeneric}
|
||||
var t = PType(idTableGet(pt, q.typ))
|
||||
if t == nil:
|
||||
|
|
@ -105,7 +105,7 @@ when false:
|
|||
proc `$`(x: PSym): string =
|
||||
result = x.name.s & " " & " id " & $x.id
|
||||
|
||||
proc freshGenSyms(n: PNode, owner, orig: PSym, symMap: var TIdTable) =
|
||||
proc freshGenSyms(c: PContext; n: PNode, owner, orig: PSym, symMap: var TIdTable) =
|
||||
# we need to create a fresh set of gensym'ed symbols:
|
||||
#if n.kind == nkSym and sfGenSym in n.sym.flags:
|
||||
# if n.sym.owner != orig:
|
||||
|
|
@ -118,12 +118,12 @@ proc freshGenSyms(n: PNode, owner, orig: PSym, symMap: var TIdTable) =
|
|||
n.sym = x
|
||||
elif s.owner == nil or s.owner.kind == skPackage:
|
||||
#echo "copied this ", s.name.s
|
||||
x = copySym(s)
|
||||
x = copySym(s, nextId c.idgen)
|
||||
x.owner = owner
|
||||
idTablePut(symMap, s, x)
|
||||
n.sym = x
|
||||
else:
|
||||
for i in 0..<n.safeLen: freshGenSyms(n[i], owner, orig, symMap)
|
||||
for i in 0..<n.safeLen: freshGenSyms(c, n[i], owner, orig, symMap)
|
||||
|
||||
proc addParamOrResult(c: PContext, param: PSym, kind: TSymKind)
|
||||
|
||||
|
|
@ -144,7 +144,7 @@ proc instantiateBody(c: PContext, n, params: PNode, result, orig: PSym) =
|
|||
let param = params[i].sym
|
||||
if sfGenSym in param.flags:
|
||||
idTablePut(symMap, params[i].sym, result.typ.n[param.position+1].sym)
|
||||
freshGenSyms(b, result, orig, symMap)
|
||||
freshGenSyms(c, b, result, orig, symMap)
|
||||
b = semProcBody(c, b)
|
||||
result.ast[bodyPos] = hloBody(c, b)
|
||||
trackProc(c, result, result.ast[bodyPos])
|
||||
|
|
@ -200,7 +200,7 @@ proc instGenericContainer(c: PContext, info: TLineInfo, header: PType,
|
|||
var param: PSym
|
||||
|
||||
template paramSym(kind): untyped =
|
||||
newSym(kind, genParam.sym.name, genericTyp.sym, genParam.sym.info)
|
||||
newSym(kind, genParam.sym.name, nextId c.idgen, genericTyp.sym, genParam.sym.info)
|
||||
|
||||
if genParam.kind == tyStatic:
|
||||
param = paramSym skConst
|
||||
|
|
@ -270,7 +270,7 @@ proc instantiateProcType(c: PContext, pt: TIdTable,
|
|||
|
||||
internalAssert c.config, originalParams[i].kind == nkSym
|
||||
let oldParam = originalParams[i].sym
|
||||
let param = copySym(oldParam)
|
||||
let param = copySym(oldParam, nextId c.idgen)
|
||||
param.owner = prc
|
||||
param.typ = result[i]
|
||||
|
||||
|
|
@ -314,7 +314,7 @@ proc instantiateProcType(c: PContext, pt: TIdTable,
|
|||
propagateToOwner(result, result[0])
|
||||
|
||||
eraseVoidParams(result)
|
||||
skipIntLiteralParams(result)
|
||||
skipIntLiteralParams(result, c.idgen)
|
||||
|
||||
prc.typ = result
|
||||
popInfoContext(c.config)
|
||||
|
|
@ -339,7 +339,7 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
|
|||
c.matchedConcept = nil
|
||||
let oldScope = c.currentScope
|
||||
while not isTopLevel(c): c.currentScope = c.currentScope.parent
|
||||
result = copySym(fn)
|
||||
result = copySym(fn, nextId c.idgen)
|
||||
incl(result.flags, sfFromGeneric)
|
||||
result.owner = fn
|
||||
result.ast = n
|
||||
|
|
|
|||
|
|
@ -118,8 +118,8 @@ proc uninstantiate(t: PType): PType =
|
|||
of tyCompositeTypeClass: uninstantiate t[1]
|
||||
else: t
|
||||
|
||||
proc getTypeDescNode(typ: PType, sym: PSym, info: TLineInfo): PNode =
|
||||
var resType = newType(tyTypeDesc, sym)
|
||||
proc getTypeDescNode(c: PContext; typ: PType, sym: PSym, info: TLineInfo): PNode =
|
||||
var resType = newType(tyTypeDesc, nextId c.idgen, sym)
|
||||
rawAddSon(resType, typ)
|
||||
result = toNode(resType, info)
|
||||
|
||||
|
|
@ -133,7 +133,7 @@ proc evalTypeTrait(c: PContext; traitCall: PNode, operand: PType, context: PSym)
|
|||
traitCall[2].typ.skipTypes({tyTypeDesc})
|
||||
|
||||
template typeWithSonsResult(kind, sons): PNode =
|
||||
newTypeWithSons(context, kind, sons).toNode(traitCall.info)
|
||||
newTypeWithSons(context, kind, sons, c.idgen).toNode(traitCall.info)
|
||||
|
||||
if operand.kind == tyGenericParam or (traitCall.len > 2 and operand2.kind == tyGenericParam):
|
||||
return traitCall ## too early to evaluate
|
||||
|
|
@ -160,19 +160,19 @@ proc evalTypeTrait(c: PContext; traitCall: PNode, operand: PType, context: PSym)
|
|||
result.info = traitCall.info
|
||||
of "arity":
|
||||
result = newIntNode(nkIntLit, operand.len - ord(operand.kind==tyProc))
|
||||
result.typ = newType(tyInt, context)
|
||||
result.typ = newType(tyInt, nextId c.idgen, context)
|
||||
result.info = traitCall.info
|
||||
of "genericHead":
|
||||
var arg = operand
|
||||
case arg.kind
|
||||
of tyGenericInst:
|
||||
result = getTypeDescNode(arg.base, operand.owner, traitCall.info)
|
||||
result = getTypeDescNode(c, arg.base, operand.owner, traitCall.info)
|
||||
# of tySequence: # this doesn't work
|
||||
# var resType = newType(tySequence, operand.owner)
|
||||
# result = toNode(resType, traitCall.info) # doesn't work yet
|
||||
else:
|
||||
localError(c.config, traitCall.info, "expected generic type, got: type $2 of kind $1" % [arg.kind.toHumanStr, typeToString(operand)])
|
||||
result = newType(tyError, context).toNode(traitCall.info)
|
||||
result = newType(tyError, nextId c.idgen, context).toNode(traitCall.info)
|
||||
of "stripGenericParams":
|
||||
result = uninstantiate(operand).toNode(traitCall.info)
|
||||
of "supportsCopyMem":
|
||||
|
|
@ -194,11 +194,11 @@ proc evalTypeTrait(c: PContext; traitCall: PNode, operand: PType, context: PSym)
|
|||
while arg.kind == tyDistinct:
|
||||
arg = arg.base
|
||||
arg = arg.skipTypes(skippedTypes + {tyGenericInst})
|
||||
result = getTypeDescNode(arg, operand.owner, traitCall.info)
|
||||
result = getTypeDescNode(c, arg, operand.owner, traitCall.info)
|
||||
else:
|
||||
localError(c.config, traitCall.info,
|
||||
"distinctBase expects a distinct type as argument. The given type was " & typeToString(operand))
|
||||
result = newType(tyError, context).toNode(traitCall.info)
|
||||
result = newType(tyError, nextId c.idgen, context).toNode(traitCall.info)
|
||||
else:
|
||||
localError(c.config, traitCall.info, "unknown trait: " & s)
|
||||
result = newNodeI(nkEmpty, traitCall.info)
|
||||
|
|
@ -286,7 +286,7 @@ proc semDynamicBindSym(c: PContext, n: PNode): PNode =
|
|||
return semBindSym(c, n)
|
||||
|
||||
if c.graph.vm.isNil:
|
||||
setupGlobalCtx(c.module, c.graph)
|
||||
setupGlobalCtx(c.module, c.graph, c.idgen)
|
||||
|
||||
let
|
||||
vm = PCtx c.graph.vm
|
||||
|
|
@ -370,7 +370,7 @@ proc semUnown(c: PContext; n: PNode): PNode =
|
|||
elems[i] = unownedType(c, t[i])
|
||||
if elems[i] != t[i]: someChange = true
|
||||
if someChange:
|
||||
result = newType(tyTuple, t.owner)
|
||||
result = newType(tyTuple, nextId c.idgen, t.owner)
|
||||
# we have to use 'rawAddSon' here so that type flags are
|
||||
# properly computed:
|
||||
for e in elems: result.rawAddSon(e)
|
||||
|
|
@ -381,7 +381,7 @@ proc semUnown(c: PContext; n: PNode): PNode =
|
|||
tyGenericInst, tyAlias:
|
||||
let b = unownedType(c, t[^1])
|
||||
if b != t[^1]:
|
||||
result = copyType(t, t.owner, keepId = false)
|
||||
result = copyType(t, nextId c.idgen, t.owner)
|
||||
result[^1] = b
|
||||
result.flags.excl tfHasOwned
|
||||
else:
|
||||
|
|
@ -399,7 +399,7 @@ proc turnFinalizerIntoDestructor(c: PContext; orig: PSym; info: TLineInfo): PSym
|
|||
# Replace nkDerefExpr by nkHiddenDeref
|
||||
# nkDeref is for 'ref T': x[].field
|
||||
# nkHiddenDeref is for 'var T': x<hidden deref [] here>.field
|
||||
proc transform(procSym: PSym; n: PNode; old, fresh: PType; oldParam, newParam: PSym): PNode =
|
||||
proc transform(c: PContext; procSym: PSym; n: PNode; old, fresh: PType; oldParam, newParam: PSym): PNode =
|
||||
result = shallowCopy(n)
|
||||
if sameTypeOrNil(n.typ, old):
|
||||
result.typ = fresh
|
||||
|
|
@ -407,26 +407,26 @@ proc turnFinalizerIntoDestructor(c: PContext; orig: PSym; info: TLineInfo): PSym
|
|||
if n.sym == oldParam:
|
||||
result.sym = newParam
|
||||
elif n.sym.owner == orig:
|
||||
result.sym = copySym(n.sym)
|
||||
result.sym = copySym(n.sym, nextId c.idgen)
|
||||
result.sym.owner = procSym
|
||||
for i in 0 ..< safeLen(n):
|
||||
result[i] = transform(procSym, n[i], old, fresh, oldParam, newParam)
|
||||
result[i] = transform(c, procSym, n[i], old, fresh, oldParam, newParam)
|
||||
#if n.kind == nkDerefExpr and sameType(n[0].typ, old):
|
||||
# result =
|
||||
|
||||
result = copySym(orig)
|
||||
result = copySym(orig, nextId c.idgen)
|
||||
result.info = info
|
||||
result.flags.incl sfFromGeneric
|
||||
result.owner = orig
|
||||
let origParamType = orig.typ[1]
|
||||
let newParamType = makeVarType(result, origParamType.skipTypes(abstractPtrs))
|
||||
let newParamType = makeVarType(result, origParamType.skipTypes(abstractPtrs), c.idgen)
|
||||
let oldParam = orig.typ.n[1].sym
|
||||
let newParam = newSym(skParam, oldParam.name, result, result.info)
|
||||
let newParam = newSym(skParam, oldParam.name, nextId c.idgen, result, result.info)
|
||||
newParam.typ = newParamType
|
||||
# proc body:
|
||||
result.ast = transform(result, orig.ast, origParamType, newParamType, oldParam, newParam)
|
||||
result.ast = transform(c, result, orig.ast, origParamType, newParamType, oldParam, newParam)
|
||||
# proc signature:
|
||||
result.typ = newProcType(result.info, result)
|
||||
result.typ = newProcType(result.info, nextId c.idgen, result)
|
||||
result.typ.addParam newParam
|
||||
|
||||
proc semQuantifier(c: PContext; n: PNode): PNode =
|
||||
|
|
|
|||
|
|
@ -416,13 +416,13 @@ proc transformSlices(g: ModuleGraph; n: PNode): PNode =
|
|||
else:
|
||||
result = n
|
||||
|
||||
proc transformSpawn(g: ModuleGraph; owner: PSym; n, barrier: PNode): PNode
|
||||
proc transformSpawnSons(g: ModuleGraph; 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:
|
||||
result[i] = transformSpawn(g, owner, n[i], barrier)
|
||||
result[i] = transformSpawn(g, idgen, owner, n[i], barrier)
|
||||
|
||||
proc transformSpawn(g: ModuleGraph; owner: PSym; n, barrier: PNode): PNode =
|
||||
proc transformSpawn(g: ModuleGraph; idgen: IdGenerator; owner: PSym; n, barrier: PNode): PNode =
|
||||
case n.kind
|
||||
of nkVarSection, nkLetSection:
|
||||
result = nil
|
||||
|
|
@ -436,25 +436,25 @@ proc transformSpawn(g: ModuleGraph; owner: PSym; n, barrier: PNode): PNode =
|
|||
result.add n
|
||||
let t = b[1][0].typ[0]
|
||||
if spawnResult(t, true) == srByVar:
|
||||
result.add wrapProcForSpawn(g, owner, m, b.typ, barrier, it[0])
|
||||
result.add wrapProcForSpawn(g, idgen, owner, m, b.typ, barrier, it[0])
|
||||
it[^1] = newNodeI(nkEmpty, it.info)
|
||||
else:
|
||||
it[^1] = wrapProcForSpawn(g, owner, m, b.typ, barrier, nil)
|
||||
it[^1] = wrapProcForSpawn(g, idgen, owner, m, b.typ, barrier, nil)
|
||||
if result.isNil: result = n
|
||||
of nkAsgn, nkFastAsgn:
|
||||
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)
|
||||
return wrapProcForSpawn(g, owner, m, b.typ, barrier, n[0])
|
||||
result = transformSpawnSons(g, owner, n, barrier)
|
||||
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)
|
||||
return wrapProcForSpawn(g, owner, result, n.typ, barrier, nil)
|
||||
result = transformSpawnSons(g, owner, n, barrier)
|
||||
return wrapProcForSpawn(g, idgen, owner, result, n.typ, barrier, nil)
|
||||
result = transformSpawnSons(g, idgen, owner, n, barrier)
|
||||
elif n.safeLen > 0:
|
||||
result = transformSpawnSons(g, owner, n, barrier)
|
||||
result = transformSpawnSons(g, idgen, owner, n, barrier)
|
||||
else:
|
||||
result = n
|
||||
|
||||
|
|
@ -464,7 +464,7 @@ proc checkArgs(a: var AnalysisCtx; n: PNode) =
|
|||
proc generateAliasChecks(a: AnalysisCtx; result: PNode) =
|
||||
discard "too implement"
|
||||
|
||||
proc liftParallel*(g: ModuleGraph; owner: PSym; n: PNode): PNode =
|
||||
proc liftParallel*(g: ModuleGraph; idgen: IdGenerator; owner: PSym; n: PNode): PNode =
|
||||
# this needs to be called after the 'for' loop elimination
|
||||
|
||||
# first pass:
|
||||
|
|
@ -482,16 +482,16 @@ proc liftParallel*(g: ModuleGraph; owner: PSym; n: PNode): PNode =
|
|||
checkArgs(a, body)
|
||||
|
||||
var varSection = newNodeI(nkVarSection, n.info)
|
||||
var temp = newSym(skTemp, getIdent(g.cache, "barrier"), owner, n.info)
|
||||
var temp = newSym(skTemp, getIdent(g.cache, "barrier"), nextId idgen, owner, n.info)
|
||||
temp.typ = magicsys.getCompilerProc(g, "Barrier").typ
|
||||
incl(temp.flags, sfFromGeneric)
|
||||
let tempNode = newSymNode(temp)
|
||||
varSection.addVar tempNode
|
||||
|
||||
let barrier = genAddrOf(tempNode)
|
||||
let barrier = genAddrOf(tempNode, idgen)
|
||||
result = newNodeI(nkStmtList, n.info)
|
||||
generateAliasChecks(a, result)
|
||||
result.add varSection
|
||||
result.add callCodegenProc(g, "openBarrier", barrier.info, barrier)
|
||||
result.add transformSpawn(g, owner, body, barrier)
|
||||
result.add transformSpawn(g, idgen, owner, body, barrier)
|
||||
result.add callCodegenProc(g, "closeBarrier", barrier.info, barrier)
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ proc createTypeBoundOps(tracked: PEffects, typ: PType; info: TLineInfo) =
|
|||
optSeqDestructors in tracked.config.globalOptions:
|
||||
createTypeBoundOps(tracked.graph, tracked.c, realType.lastSon, info)
|
||||
|
||||
createTypeBoundOps(tracked.graph, tracked.c, typ, info)
|
||||
createTypeBoundOps(tracked.graph, tracked.c, typ, info, tracked.c.idgen)
|
||||
if (tfHasAsgn in typ.flags) or
|
||||
optSeqDestructors in tracked.config.globalOptions:
|
||||
tracked.owner.flags.incl sfInjectDestructors
|
||||
|
|
@ -219,7 +219,7 @@ proc markGcUnsafe(a: PEffects; reason: PNode) =
|
|||
if reason.kind == nkSym:
|
||||
a.owner.gcUnsafetyReason = reason.sym
|
||||
else:
|
||||
a.owner.gcUnsafetyReason = newSym(skUnknown, a.owner.name,
|
||||
a.owner.gcUnsafetyReason = newSym(skUnknown, a.owner.name, nextId a.c.idgen,
|
||||
a.owner, reason.info, {})
|
||||
|
||||
when true:
|
||||
|
|
@ -755,7 +755,7 @@ proc trackCall(tracked: PEffects; n: PNode) =
|
|||
if n.typ != nil:
|
||||
if tracked.owner.kind != skMacro and n.typ.skipTypes(abstractVar).kind != tyOpenArray:
|
||||
createTypeBoundOps(tracked, n.typ, n.info)
|
||||
if getConstExpr(tracked.ownerModule, n, tracked.graph) != nil:
|
||||
if getConstExpr(tracked.ownerModule, n, tracked.c.idgen, tracked.graph) != nil:
|
||||
return
|
||||
if a.kind == nkCast and a[1].typ.kind == tyProc:
|
||||
a = a[1]
|
||||
|
|
@ -829,7 +829,7 @@ proc trackCall(tracked: PEffects; n: PNode) =
|
|||
case op[i].kind
|
||||
of tySink:
|
||||
createTypeBoundOps(tracked, op[i][0], n.info)
|
||||
checkForSink(tracked.config, tracked.owner, n[i])
|
||||
checkForSink(tracked.config, tracked.c.idgen, tracked.owner, n[i])
|
||||
of tyVar:
|
||||
tracked.hasDangerousAssign = true
|
||||
#of tyOut:
|
||||
|
|
@ -947,7 +947,7 @@ proc track(tracked: PEffects, n: PNode) =
|
|||
if tracked.owner.kind != skMacro:
|
||||
createTypeBoundOps(tracked, n[0].typ, n.info)
|
||||
if n[0].kind != nkSym or not isLocalVar(tracked, n[0].sym):
|
||||
checkForSink(tracked.config, tracked.owner, n[1])
|
||||
checkForSink(tracked.config, tracked.c.idgen, tracked.owner, n[1])
|
||||
if not tracked.hasDangerousAssign and n[0].kind != nkSym:
|
||||
tracked.hasDangerousAssign = true
|
||||
of nkVarSection, nkLetSection:
|
||||
|
|
@ -1054,9 +1054,9 @@ proc track(tracked: PEffects, n: PNode) =
|
|||
if x.kind == nkExprColonExpr:
|
||||
if x[0].kind == nkSym:
|
||||
notNilCheck(tracked, x[1], x[0].sym.typ)
|
||||
checkForSink(tracked.config, tracked.owner, x[1])
|
||||
checkForSink(tracked.config, tracked.c.idgen, tracked.owner, x[1])
|
||||
else:
|
||||
checkForSink(tracked.config, tracked.owner, x)
|
||||
checkForSink(tracked.config, tracked.c.idgen, tracked.owner, x)
|
||||
setLen(tracked.guards.s, oldFacts)
|
||||
if tracked.owner.kind != skMacro:
|
||||
# XXX n.typ can be nil in runnableExamples, we need to do something about it.
|
||||
|
|
@ -1071,7 +1071,7 @@ proc track(tracked: PEffects, n: PNode) =
|
|||
createTypeBoundOps(tracked, n[i][0].typ, n.info)
|
||||
else:
|
||||
createTypeBoundOps(tracked, n[i].typ, n.info)
|
||||
checkForSink(tracked.config, tracked.owner, n[i])
|
||||
checkForSink(tracked.config, tracked.c.idgen, tracked.owner, n[i])
|
||||
of nkPragmaBlock:
|
||||
let pragmaList = n[0]
|
||||
var bc = createBlockContext(tracked)
|
||||
|
|
@ -1122,7 +1122,7 @@ proc track(tracked: PEffects, n: PNode) =
|
|||
of nkBracket:
|
||||
for i in 0..<n.safeLen:
|
||||
track(tracked, n[i])
|
||||
checkForSink(tracked.config, tracked.owner, n[i])
|
||||
checkForSink(tracked.config, tracked.c.idgen, tracked.owner, n[i])
|
||||
if tracked.owner.kind != skMacro:
|
||||
createTypeBoundOps(tracked, n.typ, n.info)
|
||||
of nkBracketExpr:
|
||||
|
|
|
|||
|
|
@ -160,12 +160,12 @@ proc semIf(c: PContext, n: PNode; flags: TExprFlags): PNode =
|
|||
openScope(c)
|
||||
it[0] = forceBool(c, semExprWithType(c, it[0]))
|
||||
it[1] = semExprBranch(c, it[1], flags)
|
||||
typ = commonType(typ, it[1])
|
||||
typ = commonType(c, typ, it[1])
|
||||
closeScope(c)
|
||||
elif it.len == 1:
|
||||
hasElse = true
|
||||
it[0] = semExprBranchScope(c, it[0])
|
||||
typ = commonType(typ, it[0])
|
||||
typ = commonType(c, typ, it[0])
|
||||
else: illFormedAst(it, c.config)
|
||||
if isEmptyType(typ) or typ.kind in {tyNil, tyUntyped} or
|
||||
(not hasElse and efInTypeof notin flags):
|
||||
|
|
@ -203,7 +203,7 @@ proc semTry(c: PContext, n: PNode; flags: TExprFlags): PNode =
|
|||
|
||||
var typ = commonTypeBegin
|
||||
n[0] = semExprBranchScope(c, n[0])
|
||||
typ = commonType(typ, n[0].typ)
|
||||
typ = commonType(c, typ, n[0].typ)
|
||||
|
||||
var last = n.len - 1
|
||||
var catchAllExcepts = 0
|
||||
|
|
@ -223,7 +223,7 @@ proc semTry(c: PContext, n: PNode; flags: TExprFlags): PNode =
|
|||
let isImported = semExceptBranchType(a[0][1])
|
||||
let symbol = newSymG(skLet, a[0][2], c)
|
||||
symbol.typ = if isImported: a[0][1].typ
|
||||
else: a[0][1].typ.toRef()
|
||||
else: a[0][1].typ.toRef(c.idgen)
|
||||
addDecl(c, symbol)
|
||||
# Overwrite symbol in AST with the symbol in the symbol table.
|
||||
a[0][2] = newSymNode(symbol, a[0][2].info)
|
||||
|
|
@ -261,7 +261,7 @@ proc semTry(c: PContext, n: PNode; flags: TExprFlags): PNode =
|
|||
|
||||
# last child of an nkExcept/nkFinally branch is a statement:
|
||||
a[^1] = semExprBranchScope(c, a[^1])
|
||||
if a.kind != nkFinally: typ = commonType(typ, a[^1])
|
||||
if a.kind != nkFinally: typ = commonType(c, typ, a[^1])
|
||||
else: dec last
|
||||
closeScope(c)
|
||||
|
||||
|
|
@ -411,8 +411,8 @@ proc fillPartialObject(c: PContext; n: PNode; typ: PType) =
|
|||
let y = considerQuotedIdent(c, n[1])
|
||||
let obj = x.typ.skipTypes(abstractPtrs)
|
||||
if obj.kind == tyObject and tfPartial in obj.flags:
|
||||
let field = newSym(skField, getIdent(c.cache, y.s), obj.sym, n[1].info)
|
||||
field.typ = skipIntLit(typ)
|
||||
let field = newSym(skField, getIdent(c.cache, y.s), nextId c.idgen, obj.sym, n[1].info)
|
||||
field.typ = skipIntLit(typ, c.idgen)
|
||||
field.position = obj.n.len
|
||||
obj.n.add newSymNode(field)
|
||||
n[0] = makeDeref x
|
||||
|
|
@ -513,7 +513,7 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
|
|||
def = fitNode(c, typ, def, def.info)
|
||||
#changeType(def.skipConv, typ, check=true)
|
||||
else:
|
||||
typ = def.typ.skipTypes({tyStatic}).skipIntLit
|
||||
typ = def.typ.skipTypes({tyStatic}).skipIntLit(c.idgen)
|
||||
if typ.kind in tyUserTypeClasses and typ.isResolvedUserTypeClass:
|
||||
typ = typ.lastSon
|
||||
if hasEmpty(typ):
|
||||
|
|
@ -621,7 +621,7 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
|
|||
if sfCompileTime in v.flags:
|
||||
var x = newNodeI(result.kind, v.info)
|
||||
x.add result[i]
|
||||
vm.setupCompileTimeVar(c.module, c.graph, x)
|
||||
vm.setupCompileTimeVar(c.module, c.idgen, c.graph, x)
|
||||
if v.flags * {sfGlobal, sfThread} == {sfGlobal}:
|
||||
message(c.config, v.info, hintGlobalVar)
|
||||
|
||||
|
|
@ -969,19 +969,19 @@ proc semCase(c: PContext, n: PNode; flags: TExprFlags): PNode =
|
|||
semCaseBranch(c, n, x, i, covered)
|
||||
var last = x.len-1
|
||||
x[last] = semExprBranchScope(c, x[last])
|
||||
typ = commonType(typ, x[last])
|
||||
typ = commonType(c, typ, x[last])
|
||||
of nkElifBranch:
|
||||
chckCovered = false
|
||||
checkSonsLen(x, 2, c.config)
|
||||
openScope(c)
|
||||
x[0] = forceBool(c, semExprWithType(c, x[0]))
|
||||
x[1] = semExprBranch(c, x[1])
|
||||
typ = commonType(typ, x[1])
|
||||
typ = commonType(c, typ, x[1])
|
||||
closeScope(c)
|
||||
of nkElse:
|
||||
checkSonsLen(x, 1, c.config)
|
||||
x[0] = semExprBranchScope(c, x[0])
|
||||
typ = commonType(typ, x[0])
|
||||
typ = commonType(c, typ, x[0])
|
||||
if (chckCovered and covered == toCover(c, n[0].typ)) or hasElse:
|
||||
message(c.config, x.info, warnUnreachableElse)
|
||||
hasElse = true
|
||||
|
|
@ -1276,7 +1276,7 @@ proc typeSectionRightSidePass(c: PContext, n: PNode) =
|
|||
internalAssert c.config, st.lastSon.sym == nil
|
||||
incl st.flags, tfRefsAnonObj
|
||||
let obj = newSym(skType, getIdent(c.cache, s.name.s & ":ObjectType"),
|
||||
getCurrOwner(c), s.info)
|
||||
nextId c.idgen, getCurrOwner(c), s.info)
|
||||
obj.ast = a
|
||||
if sfPure in s.flags:
|
||||
obj.flags.incl sfPure
|
||||
|
|
@ -1337,11 +1337,11 @@ proc typeSectionFinalPass(c: PContext, n: PNode) =
|
|||
if s.typ != nil and s.typ.kind notin {tyAlias, tySink}:
|
||||
if t.kind in {tyProc, tyGenericInst} and not t.isMetaType:
|
||||
assignType(s.typ, t)
|
||||
s.typ.id = t.id
|
||||
s.typ.itemId = t.itemId
|
||||
elif t.kind in {tyObject, tyEnum, tyDistinct}:
|
||||
assert s.typ != nil
|
||||
assignType(s.typ, t)
|
||||
s.typ.id = t.id # same id
|
||||
s.typ.itemId = t.itemId # same id
|
||||
checkConstructedType(c.config, s.info, s.typ)
|
||||
if s.typ.kind in {tyObject, tyTuple} and not s.typ.n.isNil:
|
||||
checkForMetaFields(c, s.typ.n)
|
||||
|
|
@ -1437,7 +1437,7 @@ proc addResult(c: PContext, n: PNode, t: PType, owner: TSymKind) =
|
|||
localError(c.config, n.info, "incorrect result proc symbol")
|
||||
c.p.resultSym = n[resultPos].sym
|
||||
else:
|
||||
var s = newSym(skResult, getIdent(c.cache, "result"), getCurrOwner(c), n.info)
|
||||
var s = newSym(skResult, getIdent(c.cache, "result"), nextId c.idgen, getCurrOwner(c), n.info)
|
||||
s.typ = t
|
||||
incl(s.flags, sfUsed)
|
||||
c.p.resultSym = s
|
||||
|
|
@ -1535,7 +1535,7 @@ proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
|||
checkSonsLen(n, bodyPos + 1, c.config)
|
||||
var s: PSym
|
||||
if n[namePos].kind != nkSym:
|
||||
s = newSym(skProc, c.cache.idAnon, getCurrOwner(c), n.info)
|
||||
s = newSym(skProc, c.cache.idAnon, nextId c.idgen, getCurrOwner(c), n.info)
|
||||
s.ast = n
|
||||
n[namePos] = newSymNode(s)
|
||||
else:
|
||||
|
|
@ -1800,7 +1800,7 @@ proc hasObjParam(s: PSym): bool =
|
|||
|
||||
proc finishMethod(c: PContext, s: PSym) =
|
||||
if hasObjParam(s):
|
||||
methodDef(c.graph, s, false)
|
||||
methodDef(c.graph, c.idgen, s, false)
|
||||
|
||||
proc semMethodPrototype(c: PContext; s: PSym; n: PNode) =
|
||||
if isGenericRoutine(s):
|
||||
|
|
@ -1825,7 +1825,7 @@ proc semMethodPrototype(c: PContext; s: PSym; n: PNode) =
|
|||
# no sense either.
|
||||
# and result[bodyPos].kind != nkEmpty:
|
||||
if hasObjParam(s):
|
||||
methodDef(c.graph, s, fromCache=false)
|
||||
methodDef(c.graph, c.idgen, s, fromCache=false)
|
||||
else:
|
||||
localError(c.config, n.info, "'method' needs a parameter that has an object type")
|
||||
|
||||
|
|
@ -1843,7 +1843,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
|||
assert phase == stepRegisterSymbol
|
||||
|
||||
if n[namePos].kind == nkEmpty:
|
||||
s = newSym(kind, c.cache.idAnon, getCurrOwner(c), n.info)
|
||||
s = newSym(kind, c.cache.idAnon, nextId c.idgen, getCurrOwner(c), n.info)
|
||||
incl(s.flags, sfUsed)
|
||||
isAnon = true
|
||||
else:
|
||||
|
|
@ -1998,7 +1998,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
|
|||
if s.kind == skMethod: semMethodPrototype(c, s, n)
|
||||
else:
|
||||
if (s.typ[0] != nil and kind != skIterator) or kind == skMacro:
|
||||
addDecl(c, newSym(skUnknown, getIdent(c.cache, "result"), nil, n.info))
|
||||
addDecl(c, newSym(skUnknown, getIdent(c.cache, "result"), nextId c.idgen, nil, n.info))
|
||||
|
||||
openScope(c)
|
||||
n[bodyPos] = semGenericStmt(c, n[bodyPos])
|
||||
|
|
@ -2189,7 +2189,7 @@ proc semStaticStmt(c: PContext, n: PNode): PNode =
|
|||
closeScope(c)
|
||||
dec c.inStaticContext
|
||||
n[0] = a
|
||||
evalStaticStmt(c.module, c.graph, a, c.p.owner)
|
||||
evalStaticStmt(c.module, c.idgen, c.graph, a, c.p.owner)
|
||||
when false:
|
||||
# for incremental replays, keep the AST as required for replays:
|
||||
result = n
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@ proc onlyReplaceParams(c: var TemplCtx, n: PNode): PNode =
|
|||
result[i] = onlyReplaceParams(c, n[i])
|
||||
|
||||
proc newGenSym(kind: TSymKind, n: PNode, c: var TemplCtx): PSym =
|
||||
result = newSym(kind, considerQuotedIdent(c.c, n), c.owner, n.info)
|
||||
result = newSym(kind, considerQuotedIdent(c.c, n), nextId c.c.idgen, c.owner, n.info)
|
||||
incl(result.flags, sfGenSym)
|
||||
incl(result.flags, sfShadowed)
|
||||
|
||||
|
|
@ -239,12 +239,12 @@ proc semTemplSymbol(c: PContext, n: PNode, s: PSym; isField: bool): PNode =
|
|||
result = symChoice(c, n, s, scOpen, isField)
|
||||
of skGenericParam:
|
||||
if isField and sfGenSym in s.flags: result = n
|
||||
else: result = newSymNodeTypeDesc(s, n.info)
|
||||
else: result = newSymNodeTypeDesc(s, c.idgen, n.info)
|
||||
of skParam:
|
||||
result = n
|
||||
of skType:
|
||||
if isField and sfGenSym in s.flags: result = n
|
||||
else: result = newSymNodeTypeDesc(s, n.info)
|
||||
else: result = newSymNodeTypeDesc(s, c.idgen, n.info)
|
||||
else:
|
||||
if isField and sfGenSym in s.flags: result = n
|
||||
else: result = newSymNode(s, n.info)
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ proc newOrPrevType(kind: TTypeKind, prev: PType, c: PContext): PType =
|
|||
proc newConstraint(c: PContext, k: TTypeKind): PType =
|
||||
result = newTypeS(tyBuiltInTypeClass, c)
|
||||
result.flags.incl tfCheckedForDestructor
|
||||
result.addSonSkipIntLit(newTypeS(k, c))
|
||||
result.addSonSkipIntLit(newTypeS(k, c), c.idgen)
|
||||
|
||||
proc semEnum(c: PContext, n: PNode, prev: PType): PType =
|
||||
if n.len == 0: return newConstraint(c, tyEnum)
|
||||
|
|
@ -156,7 +156,7 @@ proc semSet(c: PContext, n: PNode, prev: PType): PType =
|
|||
result = newOrPrevType(tySet, prev, c)
|
||||
if n.len == 2 and n[1].kind != nkEmpty:
|
||||
var base = semTypeNode(c, n[1], nil)
|
||||
addSonSkipIntLit(result, base)
|
||||
addSonSkipIntLit(result, base, c.idgen)
|
||||
if base.kind in {tyGenericInst, tyAlias, tySink}: base = lastSon(base)
|
||||
if base.kind != tyGenericParam:
|
||||
if not isOrdinalType(base, allowEnumWithHoles = true):
|
||||
|
|
@ -165,17 +165,17 @@ proc semSet(c: PContext, n: PNode, prev: PType): PType =
|
|||
localError(c.config, n.info, errSetTooBig)
|
||||
else:
|
||||
localError(c.config, n.info, errXExpectsOneTypeParam % "set")
|
||||
addSonSkipIntLit(result, errorType(c))
|
||||
addSonSkipIntLit(result, errorType(c), c.idgen)
|
||||
|
||||
proc semContainerArg(c: PContext; n: PNode, kindStr: string; result: PType) =
|
||||
if n.len == 2:
|
||||
var base = semTypeNode(c, n[1], nil)
|
||||
if base.kind == tyVoid:
|
||||
localError(c.config, n.info, errTIsNotAConcreteType % typeToString(base))
|
||||
addSonSkipIntLit(result, base)
|
||||
addSonSkipIntLit(result, base, c.idgen)
|
||||
else:
|
||||
localError(c.config, n.info, errXExpectsOneTypeParam % kindStr)
|
||||
addSonSkipIntLit(result, errorType(c))
|
||||
addSonSkipIntLit(result, errorType(c), c.idgen)
|
||||
|
||||
proc semContainer(c: PContext, n: PNode, kind: TTypeKind, kindStr: string,
|
||||
prev: PType): PType =
|
||||
|
|
@ -186,12 +186,12 @@ proc semVarargs(c: PContext, n: PNode, prev: PType): PType =
|
|||
result = newOrPrevType(tyVarargs, prev, c)
|
||||
if n.len == 2 or n.len == 3:
|
||||
var base = semTypeNode(c, n[1], nil)
|
||||
addSonSkipIntLit(result, base)
|
||||
addSonSkipIntLit(result, base, c.idgen)
|
||||
if n.len == 3:
|
||||
result.n = newIdentNode(considerQuotedIdent(c, n[2]), n[2].info)
|
||||
else:
|
||||
localError(c.config, n.info, errXExpectsOneTypeParam % "varargs")
|
||||
addSonSkipIntLit(result, errorType(c))
|
||||
addSonSkipIntLit(result, errorType(c), c.idgen)
|
||||
|
||||
proc semVarOutType(c: PContext, n: PNode, prev: PType; kind: TTypeKind): PType =
|
||||
if n.len == 1:
|
||||
|
|
@ -200,14 +200,14 @@ proc semVarOutType(c: PContext, n: PNode, prev: PType; kind: TTypeKind): PType =
|
|||
if base.kind == tyVar:
|
||||
localError(c.config, n.info, "type 'var var' is not allowed")
|
||||
base = base[0]
|
||||
addSonSkipIntLit(result, base)
|
||||
addSonSkipIntLit(result, base, c.idgen)
|
||||
else:
|
||||
result = newConstraint(c, kind)
|
||||
|
||||
proc semDistinct(c: PContext, n: PNode, prev: PType): PType =
|
||||
if n.len == 0: return newConstraint(c, tyDistinct)
|
||||
result = newOrPrevType(tyDistinct, prev, c)
|
||||
addSonSkipIntLit(result, semTypeNode(c, n[0], nil))
|
||||
addSonSkipIntLit(result, semTypeNode(c, n[0], nil), c.idgen)
|
||||
if n.len > 1: result.n = n[1]
|
||||
|
||||
proc semRangeAux(c: PContext, n: PNode, prev: PType): PType =
|
||||
|
|
@ -217,7 +217,7 @@ proc semRangeAux(c: PContext, n: PNode, prev: PType): PType =
|
|||
result.n = newNodeI(nkRange, n.info)
|
||||
# always create a 'valid' range type, but overwrite it later
|
||||
# because 'semExprWithType' can raise an exception. See bug #6895.
|
||||
addSonSkipIntLit(result, errorType(c))
|
||||
addSonSkipIntLit(result, errorType(c), c.idgen)
|
||||
|
||||
if (n[1].kind == nkEmpty) or (n[2].kind == nkEmpty):
|
||||
localError(c.config, n.info, "range is empty")
|
||||
|
|
@ -228,7 +228,7 @@ proc semRangeAux(c: PContext, n: PNode, prev: PType): PType =
|
|||
|
||||
var rangeT: array[2, PType]
|
||||
for i in 0..1:
|
||||
rangeT[i] = range[i].typ.skipTypes({tyStatic}).skipIntLit
|
||||
rangeT[i] = range[i].typ.skipTypes({tyStatic}).skipIntLit(c.idgen)
|
||||
|
||||
let hasUnknownTypes = c.inGenericContext > 0 and
|
||||
rangeT[0].kind == tyFromExpr or rangeT[1].kind == tyFromExpr
|
||||
|
|
@ -345,7 +345,7 @@ proc semArray(c: PContext, n: PNode, prev: PType): PType =
|
|||
# bug #6682: Do not propagate initialization requirements etc for the
|
||||
# index type:
|
||||
rawAddSonNoPropagationOfTypeFlags(result, indx)
|
||||
addSonSkipIntLit(result, base)
|
||||
addSonSkipIntLit(result, base, c.idgen)
|
||||
else:
|
||||
localError(c.config, n.info, errArrayExpectsTwoTypeParams)
|
||||
result = newOrPrevType(tyError, prev, c)
|
||||
|
|
@ -357,7 +357,7 @@ proc semOrdinal(c: PContext, n: PNode, prev: PType): PType =
|
|||
if base.kind != tyGenericParam:
|
||||
if not isOrdinalType(base):
|
||||
localError(c.config, n[1].info, errOrdinalTypeExpected)
|
||||
addSonSkipIntLit(result, base)
|
||||
addSonSkipIntLit(result, base, c.idgen)
|
||||
else:
|
||||
localError(c.config, n.info, errXExpectsOneTypeParam % "ordinal")
|
||||
result = newOrPrevType(tyError, prev, c)
|
||||
|
|
@ -384,7 +384,7 @@ proc semTypeIdent(c: PContext, n: PNode): PSym =
|
|||
if result.typ.sym == nil:
|
||||
localError(c.config, n.info, errTypeExpected)
|
||||
return errorSym(c, n)
|
||||
result = result.typ.sym.copySym
|
||||
result = result.typ.sym.copySym(nextId c.idgen)
|
||||
result.typ = exactReplica(result.typ)
|
||||
result.typ.flags.incl tfUnresolved
|
||||
|
||||
|
|
@ -429,7 +429,7 @@ proc semAnonTuple(c: PContext, n: PNode, prev: PType): PType =
|
|||
localError(c.config, n.info, errTypeExpected)
|
||||
result = newOrPrevType(tyTuple, prev, c)
|
||||
for it in n:
|
||||
addSonSkipIntLit(result, semTypeNode(c, it, nil))
|
||||
addSonSkipIntLit(result, semTypeNode(c, it, nil), c.idgen)
|
||||
|
||||
proc semTuple(c: PContext, n: PNode, prev: PType): PType =
|
||||
var typ: PType
|
||||
|
|
@ -457,15 +457,13 @@ proc semTuple(c: PContext, n: PNode, prev: PType): PType =
|
|||
localError(c.config, a[j].info, "attempt to redefine: '" & field.name.s & "'")
|
||||
else:
|
||||
result.n.add newSymNode(field)
|
||||
addSonSkipIntLit(result, typ)
|
||||
addSonSkipIntLit(result, typ, c.idgen)
|
||||
styleCheckDef(c.config, a[j].info, field)
|
||||
onDef(field.info, field)
|
||||
if result.n.len == 0: result.n = nil
|
||||
if isTupleRecursive(result):
|
||||
localError(c.config, n.info, errIllegalRecursionInTypeX % typeToString(result))
|
||||
|
||||
|
||||
|
||||
proc semIdentVis(c: PContext, kind: TSymKind, n: PNode,
|
||||
allowed: TSymFlags): PSym =
|
||||
# identifier with visibility
|
||||
|
|
@ -925,11 +923,11 @@ proc semAnyRef(c: PContext; n: PNode; kind: TTypeKind; prev: PType): PType =
|
|||
elif region.skipTypes({tyGenericInst, tyAlias, tySink}).kind notin {
|
||||
tyError, tyObject}:
|
||||
message c.config, n[i].info, errGenerated, "region needs to be an object type"
|
||||
addSonSkipIntLit(result, region)
|
||||
addSonSkipIntLit(result, region, c.idgen)
|
||||
else:
|
||||
message(c.config, n.info, warnDeprecated, "region for pointer types is deprecated")
|
||||
addSonSkipIntLit(result, region)
|
||||
addSonSkipIntLit(result, t)
|
||||
addSonSkipIntLit(result, region, c.idgen)
|
||||
addSonSkipIntLit(result, t, c.idgen)
|
||||
if tfPartial in result.flags:
|
||||
if result.lastSon.kind == tyObject: incl(result.lastSon.flags, tfPartial)
|
||||
#if not isNilable: result.flags.incl tfNotNil
|
||||
|
|
@ -963,7 +961,7 @@ proc addParamOrResult(c: PContext, param: PSym, kind: TSymKind) =
|
|||
if kind == skMacro:
|
||||
let staticType = findEnforcedStaticType(param.typ)
|
||||
if staticType != nil:
|
||||
var a = copySym(param)
|
||||
var a = copySym(param, nextId c.idgen)
|
||||
a.typ = staticType.base
|
||||
addDecl(c, a)
|
||||
#elif param.typ != nil and param.typ.kind == tyTypeDesc:
|
||||
|
|
@ -971,7 +969,7 @@ proc addParamOrResult(c: PContext, param: PSym, kind: TSymKind) =
|
|||
else:
|
||||
# within a macro, every param has the type NimNode!
|
||||
let nn = getSysSym(c.graph, param.info, "NimNode")
|
||||
var a = copySym(param)
|
||||
var a = copySym(param, nextId c.idgen)
|
||||
a.typ = nn.typ
|
||||
addDecl(c, a)
|
||||
else:
|
||||
|
|
@ -1001,7 +999,7 @@ proc addImplicitGeneric(c: PContext; typeClass: PType, typId: PIdent;
|
|||
|
||||
let owner = if typeClass.sym != nil: typeClass.sym
|
||||
else: getCurrOwner(c)
|
||||
var s = newSym(skType, finalTypId, owner, info)
|
||||
var s = newSym(skType, finalTypId, nextId c.idgen, owner, info)
|
||||
if sfExplain in owner.flags: s.flags.incl sfExplain
|
||||
if typId == nil: s.flags.incl(sfAnon)
|
||||
s.linkTo(typeClass)
|
||||
|
|
@ -1107,7 +1105,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
|
|||
|
||||
of tyGenericInst:
|
||||
if paramType.lastSon.kind == tyUserTypeClass:
|
||||
var cp = copyType(paramType, getCurrOwner(c), false)
|
||||
var cp = copyType(paramType, nextId c.idgen, getCurrOwner(c))
|
||||
cp.kind = tyUserTypeClassInst
|
||||
return addImplicitGeneric(c, cp, paramTypId, info, genericParams, paramName)
|
||||
|
||||
|
|
@ -1144,7 +1142,7 @@ proc liftParamType(c: PContext, procKind: TSymKind, genericParams: PNode,
|
|||
of tyUserTypeClasses, tyBuiltInTypeClass, tyCompositeTypeClass,
|
||||
tyAnd, tyOr, tyNot:
|
||||
result = addImplicitGeneric(c,
|
||||
copyType(paramType, getCurrOwner(c), false), paramTypId,
|
||||
copyType(paramType, nextId c.idgen, getCurrOwner(c)), paramTypId,
|
||||
info, genericParams, paramName)
|
||||
|
||||
of tyGenericParam:
|
||||
|
|
@ -1274,7 +1272,7 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
|
|||
typ = errorType(c)
|
||||
let lifted = liftParamType(c, kind, genericParams, typ,
|
||||
arg.name.s, arg.info)
|
||||
let finalType = if lifted != nil: lifted else: typ.skipIntLit
|
||||
let finalType = if lifted != nil: lifted else: typ.skipIntLit(c.idgen)
|
||||
arg.typ = finalType
|
||||
arg.position = counter
|
||||
arg.constraint = constraint
|
||||
|
|
@ -1331,7 +1329,7 @@ proc semProcTypeNode(c: PContext, n, genericParams: PNode,
|
|||
#if r.kind != tyGenericParam:
|
||||
#echo "came here for ", typeToString(r)
|
||||
r.flags.incl tfRetType
|
||||
r = skipIntLit(r)
|
||||
r = skipIntLit(r, c.idgen)
|
||||
if kind == skIterator:
|
||||
# see tchainediterators
|
||||
# in cases like iterator foo(it: iterator): type(it)
|
||||
|
|
@ -1413,13 +1411,13 @@ proc semGeneric(c: PContext, n: PNode, s: PSym, prev: PType): PType =
|
|||
t = t.base
|
||||
|
||||
result = newOrPrevType(tyGenericInvocation, prev, c)
|
||||
addSonSkipIntLit(result, t)
|
||||
addSonSkipIntLit(result, t, c.idgen)
|
||||
|
||||
template addToResult(typ) =
|
||||
if typ.isNil:
|
||||
internalAssert c.config, false
|
||||
rawAddSon(result, typ)
|
||||
else: addSonSkipIntLit(result, typ)
|
||||
else: addSonSkipIntLit(result, typ, c.idgen)
|
||||
|
||||
if t.kind == tyForward:
|
||||
for i in 1..<n.len:
|
||||
|
|
@ -1518,9 +1516,9 @@ proc semTypeExpr(c: PContext, n: PNode; prev: PType): PType =
|
|||
localError(c.config, n.info, "expected type, but got: " & n.renderTree)
|
||||
result = errorType(c)
|
||||
|
||||
proc freshType(res, prev: PType): PType {.inline.} =
|
||||
proc freshType(c: PContext; res, prev: PType): PType {.inline.} =
|
||||
if prev.isNil:
|
||||
result = copyType(res, res.owner, keepId=false)
|
||||
result = copyType(res, nextId c.idgen, res.owner)
|
||||
else:
|
||||
result = res
|
||||
|
||||
|
|
@ -1542,7 +1540,7 @@ proc semTypeClass(c: PContext, n: PNode, prev: PType): PType =
|
|||
result = newOrPrevType(tyUserTypeClass, prev, c)
|
||||
result.flags.incl tfCheckedForDestructor
|
||||
var owner = getCurrOwner(c)
|
||||
var candidateTypeSlot = newTypeWithSons(owner, tyAlias, @[c.errorType])
|
||||
var candidateTypeSlot = newTypeWithSons(owner, tyAlias, @[c.errorType], c.idgen)
|
||||
result.sons = @[candidateTypeSlot]
|
||||
result.n = n
|
||||
|
||||
|
|
@ -1575,7 +1573,7 @@ proc semTypeClass(c: PContext, n: PNode, prev: PType): PType =
|
|||
|
||||
internalAssert c.config, dummyName.kind == nkIdent
|
||||
var dummyParam = newSym(if modifier == tyTypeDesc: skType else: skVar,
|
||||
dummyName.ident, owner, param.info)
|
||||
dummyName.ident, nextId c.idgen, owner, param.info)
|
||||
dummyParam.typ = dummyType
|
||||
incl dummyParam.flags, sfUsed
|
||||
addDecl(c, dummyParam)
|
||||
|
|
@ -1713,7 +1711,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
|||
result = semTypeNode(c, n[1], prev)
|
||||
if result.skipTypes({tyGenericInst, tyAlias, tySink, tyOwned}).kind in NilableTypes+GenericTypes:
|
||||
if tfNotNil in result.flags:
|
||||
result = freshType(result, prev)
|
||||
result = freshType(c, result, prev)
|
||||
result.flags.excl(tfNotNil)
|
||||
else:
|
||||
localError(c.config, n.info, errGenerated, "invalid type")
|
||||
|
|
@ -1774,7 +1772,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
|||
# to other types such as `Option[T]`.
|
||||
result = makeTypeFromExpr(c, newTree(nkStmtListType, n.copyTree))
|
||||
of NilableTypes + {tyGenericInvocation, tyForward}:
|
||||
result = freshType(result, prev)
|
||||
result = freshType(c, result, prev)
|
||||
result.flags.incl(tfNotNil)
|
||||
else:
|
||||
localError(c.config, n.info, errGenerated, "invalid type")
|
||||
|
|
@ -1828,19 +1826,19 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
|||
of mExpr:
|
||||
result = semTypeNode(c, n[0], nil)
|
||||
if result != nil:
|
||||
result = copyType(result, getCurrOwner(c), false)
|
||||
result = copyType(result, nextId c.idgen, getCurrOwner(c))
|
||||
for i in 1..<n.len:
|
||||
result.rawAddSon(semTypeNode(c, n[i], nil))
|
||||
of mDistinct:
|
||||
result = newOrPrevType(tyDistinct, prev, c)
|
||||
addSonSkipIntLit(result, semTypeNode(c, n[1], nil))
|
||||
addSonSkipIntLit(result, semTypeNode(c, n[1], nil), c.idgen)
|
||||
of mVar:
|
||||
result = newOrPrevType(tyVar, prev, c)
|
||||
var base = semTypeNode(c, n[1], nil)
|
||||
if base.kind in {tyVar, tyLent}:
|
||||
localError(c.config, n.info, "type 'var var' is not allowed")
|
||||
base = base[0]
|
||||
addSonSkipIntLit(result, base)
|
||||
addSonSkipIntLit(result, base, c.idgen)
|
||||
of mRef: result = semAnyRef(c, n, tyRef, prev)
|
||||
of mPtr: result = semAnyRef(c, n, tyPtr, prev)
|
||||
of mTuple: result = semTuple(c, n, prev)
|
||||
|
|
@ -1886,7 +1884,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
|||
# bugfix: keep the fresh id for aliases to integral types:
|
||||
if s.typ.kind notin {tyBool, tyChar, tyInt..tyInt64, tyFloat..tyFloat128,
|
||||
tyUInt..tyUInt64}:
|
||||
prev.id = s.typ.id
|
||||
prev.itemId = s.typ.itemId
|
||||
result = prev
|
||||
of nkSym:
|
||||
let s = getGenSym(c, n.sym)
|
||||
|
|
@ -1929,7 +1927,7 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
|||
result = newTypeS(tyBuiltInTypeClass, c)
|
||||
let child = newTypeS(tyProc, c)
|
||||
child.flags.incl tfIterator
|
||||
result.addSonSkipIntLit(child)
|
||||
result.addSonSkipIntLit(child, c.idgen)
|
||||
else:
|
||||
result = semProcTypeWithScope(c, n, prev, skIterator)
|
||||
if result.kind == tyProc:
|
||||
|
|
@ -2060,7 +2058,7 @@ proc semGenericConstraints(c: PContext, x: PType): PType =
|
|||
proc semGenericParamList(c: PContext, n: PNode, father: PType = nil): PNode =
|
||||
|
||||
template addSym(result: PNode, s: PSym): untyped =
|
||||
if father != nil: addSonSkipIntLit(father, s.typ)
|
||||
if father != nil: addSonSkipIntLit(father, s.typ, c.idgen)
|
||||
if sfGenSym notin s.flags: addDecl(c, s)
|
||||
result.add newSymNode(s)
|
||||
|
||||
|
|
@ -2107,7 +2105,7 @@ proc semGenericParamList(c: PContext, n: PNode, father: PType = nil): PNode =
|
|||
|
||||
for j in 0..<a.len-2:
|
||||
let finalType = if j == 0: typ
|
||||
else: copyType(typ, typ.owner, false)
|
||||
else: copyType(typ, nextId c.idgen, typ.owner)
|
||||
# it's important the we create an unique
|
||||
# type for each generic param. the index
|
||||
# of the parameter will be stored in the
|
||||
|
|
|
|||
|
|
@ -279,7 +279,7 @@ proc replaceTypeVarsS(cl: var TReplTypeVars, s: PSym): PSym =
|
|||
var g: G[string]
|
||||
|
||||
]#
|
||||
result = copySym(s)
|
||||
result = copySym(s, nextId cl.c.idgen)
|
||||
incl(result.flags, sfFromGeneric)
|
||||
#idTablePut(cl.symMap, s, result)
|
||||
result.owner = s.owner
|
||||
|
|
@ -302,7 +302,12 @@ proc lookupTypeVar(cl: var TReplTypeVars, t: PType): PType =
|
|||
|
||||
proc instCopyType*(cl: var TReplTypeVars, t: PType): PType =
|
||||
# XXX: relying on allowMetaTypes is a kludge
|
||||
result = copyType(t, t.owner, cl.allowMetaTypes)
|
||||
if cl.allowMetaTypes:
|
||||
result = t.exactReplica
|
||||
else:
|
||||
result = copyType(t, nextId(cl.c.idgen), t.owner)
|
||||
#cl.typeMap.topLayer.idTablePut(result, t)
|
||||
|
||||
if cl.allowMetaTypes: return
|
||||
result.flags.incl tfFromGeneric
|
||||
if not (t.kind in tyMetaTypes or
|
||||
|
|
@ -355,7 +360,7 @@ proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType =
|
|||
else:
|
||||
header = instCopyType(cl, t)
|
||||
|
||||
result = newType(tyGenericInst, t[0].owner)
|
||||
result = newType(tyGenericInst, nextId(cl.c.idgen), t[0].owner)
|
||||
result.flags = header.flags
|
||||
# be careful not to propagate unnecessary flags here (don't use rawAddSon)
|
||||
result.sons = @[header[0]]
|
||||
|
|
@ -459,11 +464,11 @@ proc eraseVoidParams*(t: PType) =
|
|||
setLen t.n.sons, pos
|
||||
break
|
||||
|
||||
proc skipIntLiteralParams*(t: PType) =
|
||||
proc skipIntLiteralParams*(t: PType; idgen: IdGenerator) =
|
||||
for i in 0..<t.len:
|
||||
let p = t[i]
|
||||
if p == nil: continue
|
||||
let skipped = p.skipIntLit
|
||||
let skipped = p.skipIntLit(idgen)
|
||||
if skipped != p:
|
||||
t[i] = skipped
|
||||
if i > 0: t.n[i].sym.typ = skipped
|
||||
|
|
@ -553,7 +558,7 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType =
|
|||
result = n.typ
|
||||
|
||||
of tyInt, tyFloat:
|
||||
result = skipIntLit(t)
|
||||
result = skipIntLit(t, cl.c.idgen)
|
||||
|
||||
of tyTypeDesc:
|
||||
let lookup = cl.typeMap.lookup(t)
|
||||
|
|
@ -617,7 +622,7 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType =
|
|||
|
||||
of tyProc:
|
||||
eraseVoidParams(result)
|
||||
skipIntLiteralParams(result)
|
||||
skipIntLiteralParams(result, cl.c.idgen)
|
||||
|
||||
of tyRange:
|
||||
result[0] = result[0].skipTypes({tyStatic, tyDistinct})
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ proc put(c: var TCandidate, key, val: PType) {.inline.} =
|
|||
writeStackTrace()
|
||||
if c.c.module.name.s == "temp3":
|
||||
echo "binding ", key, " -> ", val
|
||||
idTablePut(c.bindings, key, val.skipIntLit)
|
||||
idTablePut(c.bindings, key, val.skipIntLit(c.c.idgen))
|
||||
|
||||
proc initCandidate*(ctx: PContext, c: var TCandidate, callee: PSym,
|
||||
binding: PNode, calleeScope = -1,
|
||||
|
|
@ -726,7 +726,7 @@ proc matchUserTypeClass*(m: var TCandidate; ff, a: PType): PType =
|
|||
if alreadyBound != nil: typ = alreadyBound
|
||||
|
||||
template paramSym(kind): untyped =
|
||||
newSym(kind, typeParamName, typeClass.sym, typeClass.sym.info, {})
|
||||
newSym(kind, typeParamName, nextId(c.idgen), typeClass.sym, typeClass.sym.info, {})
|
||||
|
||||
block addTypeParam:
|
||||
for prev in typeParams:
|
||||
|
|
@ -739,6 +739,7 @@ proc matchUserTypeClass*(m: var TCandidate; ff, a: PType): PType =
|
|||
of tyStatic:
|
||||
param = paramSym skConst
|
||||
param.typ = typ.exactReplica
|
||||
#copyType(typ, nextId(c.idgen), typ.owner)
|
||||
if typ.n == nil:
|
||||
param.typ.flags.incl tfInferrableStatic
|
||||
else:
|
||||
|
|
@ -746,6 +747,7 @@ proc matchUserTypeClass*(m: var TCandidate; ff, a: PType): PType =
|
|||
of tyUnknown:
|
||||
param = paramSym skVar
|
||||
param.typ = typ.exactReplica
|
||||
#copyType(typ, nextId(c.idgen), typ.owner)
|
||||
else:
|
||||
param = paramSym skType
|
||||
param.typ = if typ.isMetaType:
|
||||
|
|
@ -796,7 +798,8 @@ proc matchUserTypeClass*(m: var TCandidate; ff, a: PType): PType =
|
|||
if ff.kind == tyUserTypeClassInst:
|
||||
result = generateTypeInstance(c, m.bindings, typeClass.sym.info, ff)
|
||||
else:
|
||||
result = copyType(ff, ff.owner, true)
|
||||
result = ff.exactReplica
|
||||
#copyType(ff, nextId(c.idgen), ff.owner)
|
||||
|
||||
result.n = checkedBody
|
||||
|
||||
|
|
@ -1086,7 +1089,7 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
|
|||
|
||||
template bindingRet(res) =
|
||||
if doBind:
|
||||
let bound = aOrig.skipTypes({tyRange}).skipIntLit
|
||||
let bound = aOrig.skipTypes({tyRange}).skipIntLit(c.c.idgen)
|
||||
put(c, f, bound)
|
||||
return res
|
||||
|
||||
|
|
@ -1500,14 +1503,15 @@ proc typeRel(c: var TCandidate, f, aOrig: PType,
|
|||
|
||||
of tyGenericInvocation:
|
||||
var x = a.skipGenericAlias
|
||||
|
||||
var preventHack = false
|
||||
if x.kind == tyOwned and f[0].kind != tyOwned:
|
||||
preventHack = true
|
||||
x = x.lastSon
|
||||
# XXX: This is very hacky. It should be moved back into liftTypeParam
|
||||
if x.kind in {tyGenericInst, tyArray} and
|
||||
c.calleeSym != nil and
|
||||
c.calleeSym.kind in {skProc, skFunc} and c.call != nil and not preventHack:
|
||||
c.calleeSym != nil and
|
||||
c.calleeSym.kind in {skProc, skFunc} and c.call != nil and not preventHack:
|
||||
let inst = prepareMetatypeForSigmatch(c.c, c.bindings, c.call.info, f)
|
||||
#echo "inferred ", typeToString(inst), " for ", f
|
||||
return typeRel(c, inst, a, flags)
|
||||
|
|
@ -2291,7 +2295,7 @@ proc arrayConstr(c: PContext, n: PNode): PType =
|
|||
result = newTypeS(tyArray, c)
|
||||
rawAddSon(result, makeRangeType(c, 0, 0, n.info))
|
||||
addSonSkipIntLit(result, skipTypes(n.typ,
|
||||
{tyGenericInst, tyVar, tyLent, tyOrdinal}))
|
||||
{tyGenericInst, tyVar, tyLent, tyOrdinal}), c.idgen)
|
||||
|
||||
proc arrayConstr(c: PContext, info: TLineInfo): PType =
|
||||
result = newTypeS(tyArray, c)
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
proc checkForSink*(config: ConfigRef; owner: PSym; arg: PNode) =
|
||||
proc checkForSink*(config: ConfigRef; idgen: IdGenerator; owner: PSym; arg: PNode) =
|
||||
#[ Patterns we seek to detect:
|
||||
|
||||
someLocation = p # ---> p: sink T
|
||||
|
|
@ -32,7 +32,7 @@ proc checkForSink*(config: ConfigRef; owner: PSym; arg: PNode) =
|
|||
if sfWasForwarded notin owner.flags:
|
||||
let argType = arg.sym.typ
|
||||
|
||||
let sinkType = newType(tySink, owner)
|
||||
let sinkType = newType(tySink, nextId(idgen), owner)
|
||||
sinkType.size = argType.size
|
||||
sinkType.align = argType.align
|
||||
sinkType.paddingAtEnd = argType.paddingAtEnd
|
||||
|
|
@ -52,18 +52,18 @@ proc checkForSink*(config: ConfigRef; owner: PSym; arg: PNode) =
|
|||
#echo config $ arg.info, " candidate for a sink parameter here"
|
||||
of nkStmtList, nkStmtListExpr, nkBlockStmt, nkBlockExpr:
|
||||
if not isEmptyType(arg.typ):
|
||||
checkForSink(config, owner, arg.lastSon)
|
||||
checkForSink(config, idgen, owner, arg.lastSon)
|
||||
of nkIfStmt, nkIfExpr, nkWhen:
|
||||
for branch in arg:
|
||||
let value = branch.lastSon
|
||||
if not isEmptyType(value.typ):
|
||||
checkForSink(config, owner, value)
|
||||
checkForSink(config, idgen, owner, value)
|
||||
of nkCaseStmt:
|
||||
for i in 1..<arg.len:
|
||||
let value = arg[i].lastSon
|
||||
if not isEmptyType(value.typ):
|
||||
checkForSink(config, owner, value)
|
||||
checkForSink(config, idgen, owner, value)
|
||||
of nkTryStmt:
|
||||
checkForSink(config, owner, arg[0])
|
||||
checkForSink(config, idgen, owner, arg[0])
|
||||
else:
|
||||
discard "nothing to do"
|
||||
|
|
|
|||
|
|
@ -53,9 +53,9 @@ proc typeNeedsNoDeepCopy(t: PType): bool =
|
|||
if t.kind in {tyVar, tyLent, tySequence}: t = t.lastSon
|
||||
result = not containsGarbageCollectedRef(t)
|
||||
|
||||
proc addLocalVar(g: ModuleGraph; varSection, varInit: PNode; owner: PSym; typ: PType;
|
||||
proc addLocalVar(g: ModuleGraph; varSection, varInit: PNode; idgen: IdGenerator; owner: PSym; typ: PType;
|
||||
v: PNode; useShallowCopy=false): PSym =
|
||||
result = newSym(skTemp, getIdent(g.cache, genPrefix), owner, varSection.info,
|
||||
result = newSym(skTemp, getIdent(g.cache, genPrefix), nextId idgen, owner, varSection.info,
|
||||
owner.options)
|
||||
result.typ = typ
|
||||
incl(result.flags, sfFromGeneric)
|
||||
|
|
@ -111,22 +111,23 @@ stmtList:
|
|||
|
||||
proc createWrapperProc(g: ModuleGraph; f: PNode; threadParam, argsParam: PSym;
|
||||
varSection, varInit, call, barrier, fv: PNode;
|
||||
idgen: IdGenerator;
|
||||
spawnKind: TSpawnResult, result: PSym) =
|
||||
var body = newNodeI(nkStmtList, f.info)
|
||||
var threadLocalBarrier: PSym
|
||||
if barrier != nil:
|
||||
var varSection2 = newNodeI(nkVarSection, barrier.info)
|
||||
threadLocalBarrier = addLocalVar(g, varSection2, nil, result,
|
||||
threadLocalBarrier = addLocalVar(g, varSection2, nil, idgen, result,
|
||||
barrier.typ, barrier)
|
||||
body.add varSection2
|
||||
body.add callCodegenProc(g, "barrierEnter", threadLocalBarrier.info,
|
||||
threadLocalBarrier.newSymNode)
|
||||
var threadLocalProm: PSym
|
||||
if spawnKind == srByVar:
|
||||
threadLocalProm = addLocalVar(g, varSection, nil, result, fv.typ, fv)
|
||||
threadLocalProm = addLocalVar(g, varSection, nil, idgen, result, fv.typ, fv)
|
||||
elif fv != nil:
|
||||
internalAssert g.config, fv.typ.kind == tyGenericInst
|
||||
threadLocalProm = addLocalVar(g, varSection, nil, result, fv.typ, fv)
|
||||
threadLocalProm = addLocalVar(g, varSection, nil, idgen, result, fv.typ, fv)
|
||||
body.add varSection
|
||||
body.add varInit
|
||||
if fv != nil and spawnKind != srByVar:
|
||||
|
|
@ -168,7 +169,7 @@ proc createWrapperProc(g: ModuleGraph; f: PNode; threadParam, argsParam: PSym;
|
|||
params.add threadParam.newSymNode
|
||||
params.add argsParam.newSymNode
|
||||
|
||||
var t = newType(tyProc, threadParam.owner)
|
||||
var t = newType(tyProc, nextId idgen, threadParam.owner)
|
||||
t.rawAddSon nil
|
||||
t.rawAddSon threadParam.typ
|
||||
t.rawAddSon argsParam.typ
|
||||
|
|
@ -184,15 +185,15 @@ proc createWrapperProc(g: ModuleGraph; f: PNode; threadParam, argsParam: PSym;
|
|||
exceptions = emptyNode)
|
||||
result.typ = t
|
||||
|
||||
proc createCastExpr(argsParam: PSym; objType: PType): PNode =
|
||||
proc createCastExpr(argsParam: PSym; objType: PType; idgen: IdGenerator): PNode =
|
||||
result = newNodeI(nkCast, argsParam.info)
|
||||
result.add newNodeI(nkEmpty, argsParam.info)
|
||||
result.add newSymNode(argsParam)
|
||||
result.typ = newType(tyPtr, objType.owner)
|
||||
result.typ = newType(tyPtr, nextId idgen, objType.owner)
|
||||
result.typ.rawAddSon(objType)
|
||||
|
||||
proc setupArgsForConcurrency(g: ModuleGraph; n: PNode; objType: PType;
|
||||
owner: PSym; scratchObj: PSym,
|
||||
idgen: IdGenerator; owner: PSym; scratchObj: PSym,
|
||||
castExpr, call,
|
||||
varSection, varInit, result: PNode) =
|
||||
let formals = n[0].typ.n
|
||||
|
|
@ -210,16 +211,17 @@ proc setupArgsForConcurrency(g: ModuleGraph; n: PNode; objType: PType;
|
|||
# localError(n[i].info, "'spawn'ed function cannot refer to 'ref'/closure")
|
||||
|
||||
let fieldname = if i < formals.len: formals[i].sym.name else: tmpName
|
||||
var field = newSym(skField, fieldname, objType.owner, n.info, g.config.options)
|
||||
var field = newSym(skField, fieldname, nextId idgen, objType.owner, n.info, g.config.options)
|
||||
field.typ = argType
|
||||
objType.addField(field, g.cache)
|
||||
objType.addField(field, g.cache, idgen)
|
||||
result.add newFastAsgnStmt(newDotExpr(scratchObj, field), n[i])
|
||||
|
||||
let temp = addLocalVar(g, varSection, varInit, owner, argType,
|
||||
let temp = addLocalVar(g, varSection, varInit, idgen, owner, argType,
|
||||
indirectAccess(castExpr, field, n.info))
|
||||
call.add(newSymNode(temp))
|
||||
|
||||
proc setupArgsForParallelism(g: ModuleGraph; n: PNode; objType: PType;
|
||||
idgen: IdGenerator;
|
||||
owner: PSym; scratchObj: PSym;
|
||||
castExpr, call,
|
||||
varSection, varInit, result: PNode) =
|
||||
|
|
@ -237,7 +239,7 @@ proc setupArgsForParallelism(g: ModuleGraph; n: PNode; objType: PType;
|
|||
# localError(n.info, "'spawn'ed function cannot refer to 'ref'/closure")
|
||||
|
||||
let fieldname = if i < formals.len: formals[i].sym.name else: tmpName
|
||||
var field = newSym(skField, fieldname, objType.owner, n.info, g.config.options)
|
||||
var field = newSym(skField, fieldname, nextId idgen, objType.owner, n.info, g.config.options)
|
||||
|
||||
if argType.kind in {tyVarargs, tyOpenArray}:
|
||||
# important special case: we always create a zero-copy slice:
|
||||
|
|
@ -245,30 +247,30 @@ proc setupArgsForParallelism(g: ModuleGraph; n: PNode; objType: PType;
|
|||
slice.typ = n.typ
|
||||
slice[0] = newSymNode(createMagic(g, "slice", mSlice))
|
||||
slice[0].typ = getSysType(g, n.info, tyInt) # fake type
|
||||
var fieldB = newSym(skField, tmpName, objType.owner, n.info, g.config.options)
|
||||
var fieldB = newSym(skField, tmpName, nextId idgen, objType.owner, n.info, g.config.options)
|
||||
fieldB.typ = getSysType(g, n.info, tyInt)
|
||||
objType.addField(fieldB, g.cache)
|
||||
objType.addField(fieldB, g.cache, idgen)
|
||||
|
||||
if getMagic(n) == mSlice:
|
||||
let a = genAddrOf(n[1])
|
||||
let a = genAddrOf(n[1], idgen)
|
||||
field.typ = a.typ
|
||||
objType.addField(field, g.cache)
|
||||
objType.addField(field, g.cache, idgen)
|
||||
result.add newFastAsgnStmt(newDotExpr(scratchObj, field), a)
|
||||
|
||||
var fieldA = newSym(skField, tmpName, objType.owner, n.info, g.config.options)
|
||||
var fieldA = newSym(skField, tmpName, nextId idgen, objType.owner, n.info, g.config.options)
|
||||
fieldA.typ = getSysType(g, n.info, tyInt)
|
||||
objType.addField(fieldA, g.cache)
|
||||
objType.addField(fieldA, g.cache, idgen)
|
||||
result.add newFastAsgnStmt(newDotExpr(scratchObj, fieldA), n[2])
|
||||
result.add newFastAsgnStmt(newDotExpr(scratchObj, fieldB), n[3])
|
||||
|
||||
let threadLocal = addLocalVar(g, varSection,nil, owner, fieldA.typ,
|
||||
let threadLocal = addLocalVar(g, varSection, nil, idgen, owner, fieldA.typ,
|
||||
indirectAccess(castExpr, fieldA, n.info),
|
||||
useShallowCopy=true)
|
||||
slice[2] = threadLocal.newSymNode
|
||||
else:
|
||||
let a = genAddrOf(n)
|
||||
let a = genAddrOf(n, idgen)
|
||||
field.typ = a.typ
|
||||
objType.addField(field, g.cache)
|
||||
objType.addField(field, g.cache, idgen)
|
||||
result.add newFastAsgnStmt(newDotExpr(scratchObj, field), a)
|
||||
result.add newFastAsgnStmt(newDotExpr(scratchObj, fieldB), genHigh(g, n))
|
||||
|
||||
|
|
@ -276,7 +278,7 @@ proc setupArgsForParallelism(g: ModuleGraph; n: PNode; objType: PType;
|
|||
# the array itself does not need to go through a thread local variable:
|
||||
slice[1] = genDeref(indirectAccess(castExpr, field, n.info))
|
||||
|
||||
let threadLocal = addLocalVar(g, varSection,nil, owner, fieldB.typ,
|
||||
let threadLocal = addLocalVar(g, varSection, nil, idgen, owner, fieldB.typ,
|
||||
indirectAccess(castExpr, fieldB, n.info),
|
||||
useShallowCopy=true)
|
||||
slice[3] = threadLocal.newSymNode
|
||||
|
|
@ -284,26 +286,26 @@ proc setupArgsForParallelism(g: ModuleGraph; n: PNode; objType: PType;
|
|||
elif (let size = computeSize(g.config, argType); size < 0 or size > 16) and
|
||||
n.getRoot != nil:
|
||||
# it is more efficient to pass a pointer instead:
|
||||
let a = genAddrOf(n)
|
||||
let a = genAddrOf(n, idgen)
|
||||
field.typ = a.typ
|
||||
objType.addField(field, g.cache)
|
||||
objType.addField(field, g.cache, idgen)
|
||||
result.add newFastAsgnStmt(newDotExpr(scratchObj, field), a)
|
||||
let threadLocal = addLocalVar(g, varSection,nil, owner, field.typ,
|
||||
let threadLocal = addLocalVar(g, varSection, nil, idgen, owner, field.typ,
|
||||
indirectAccess(castExpr, field, n.info),
|
||||
useShallowCopy=true)
|
||||
call.add(genDeref(threadLocal.newSymNode))
|
||||
else:
|
||||
# boring case
|
||||
field.typ = argType
|
||||
objType.addField(field, g.cache)
|
||||
objType.addField(field, g.cache, idgen)
|
||||
result.add newFastAsgnStmt(newDotExpr(scratchObj, field), n)
|
||||
let threadLocal = addLocalVar(g, varSection, varInit,
|
||||
owner, field.typ,
|
||||
idgen, owner, field.typ,
|
||||
indirectAccess(castExpr, field, n.info),
|
||||
useShallowCopy=true)
|
||||
call.add(threadLocal.newSymNode)
|
||||
|
||||
proc wrapProcForSpawn*(g: ModuleGraph; owner: PSym; spawnExpr: PNode; retType: PType;
|
||||
proc wrapProcForSpawn*(g: ModuleGraph; idgen: IdGenerator; owner: PSym; spawnExpr: PNode; retType: PType;
|
||||
barrier, dest: PNode = nil): PNode =
|
||||
# if 'barrier' != nil, then it is in a 'parallel' section and we
|
||||
# generate quite different code
|
||||
|
|
@ -330,9 +332,9 @@ proc wrapProcForSpawn*(g: ModuleGraph; owner: PSym; spawnExpr: PNode; retType: P
|
|||
var fn = n[0]
|
||||
let
|
||||
name = (if fn.kind == nkSym: fn.sym.name.s else: genPrefix) & "Wrapper"
|
||||
wrapperProc = newSym(skProc, getIdent(g.cache, name), owner, fn.info, g.config.options)
|
||||
threadParam = newSym(skParam, getIdent(g.cache, "thread"), wrapperProc, n.info, g.config.options)
|
||||
argsParam = newSym(skParam, getIdent(g.cache, "args"), wrapperProc, n.info, g.config.options)
|
||||
wrapperProc = newSym(skProc, getIdent(g.cache, name), nextId idgen, owner, fn.info, g.config.options)
|
||||
threadParam = newSym(skParam, getIdent(g.cache, "thread"), nextId idgen, wrapperProc, n.info, g.config.options)
|
||||
argsParam = newSym(skParam, getIdent(g.cache, "args"), nextId idgen, wrapperProc, n.info, g.config.options)
|
||||
|
||||
wrapperProc.flags.incl sfInjectDestructors
|
||||
block:
|
||||
|
|
@ -341,11 +343,11 @@ proc wrapProcForSpawn*(g: ModuleGraph; owner: PSym; spawnExpr: PNode; retType: P
|
|||
argsParam.typ = ptrType
|
||||
argsParam.position = 1
|
||||
|
||||
var objType = createObj(g, owner, n.info)
|
||||
var objType = createObj(g, idgen, owner, n.info)
|
||||
incl(objType.flags, tfFinal)
|
||||
let castExpr = createCastExpr(argsParam, objType)
|
||||
let castExpr = createCastExpr(argsParam, objType, idgen)
|
||||
|
||||
var scratchObj = newSym(skVar, getIdent(g.cache, "scratch"), owner, n.info, g.config.options)
|
||||
var scratchObj = newSym(skVar, getIdent(g.cache, "scratch"), nextId idgen, owner, n.info, g.config.options)
|
||||
block:
|
||||
scratchObj.typ = objType
|
||||
incl(scratchObj.flags, sfFromGeneric)
|
||||
|
|
@ -362,9 +364,9 @@ proc wrapProcForSpawn*(g: ModuleGraph; owner: PSym; spawnExpr: PNode; retType: P
|
|||
skFunc, skMethod, skConverter}):
|
||||
# for indirect calls we pass the function pointer in the scratchObj
|
||||
var argType = n[0].typ.skipTypes(abstractInst)
|
||||
var field = newSym(skField, getIdent(g.cache, "fn"), owner, n.info, g.config.options)
|
||||
var field = newSym(skField, getIdent(g.cache, "fn"), nextId idgen, owner, n.info, g.config.options)
|
||||
field.typ = argType
|
||||
objType.addField(field, g.cache)
|
||||
objType.addField(field, g.cache, idgen)
|
||||
result.add newFastAsgnStmt(newDotExpr(scratchObj, field), n[0])
|
||||
fn = indirectAccess(castExpr, field, n.info)
|
||||
elif fn.kind == nkSym and fn.sym.kind == skIterator:
|
||||
|
|
@ -376,49 +378,48 @@ proc wrapProcForSpawn*(g: ModuleGraph; owner: PSym; spawnExpr: PNode; retType: P
|
|||
var varSection = newNodeI(nkVarSection, n.info)
|
||||
var varInit = newNodeI(nkStmtList, n.info)
|
||||
if barrier.isNil:
|
||||
setupArgsForConcurrency(g, n, objType, wrapperProc, scratchObj, castExpr, call,
|
||||
setupArgsForConcurrency(g, n, objType, idgen, wrapperProc, scratchObj, castExpr, call,
|
||||
varSection, varInit, result)
|
||||
else:
|
||||
setupArgsForParallelism(g, n, objType, wrapperProc, scratchObj, castExpr, call,
|
||||
setupArgsForParallelism(g, n, objType, idgen, wrapperProc, scratchObj, castExpr, call,
|
||||
varSection, varInit, result)
|
||||
|
||||
var barrierAsExpr: PNode = nil
|
||||
if barrier != nil:
|
||||
let typ = newType(tyPtr, owner)
|
||||
let typ = newType(tyPtr, nextId idgen, owner)
|
||||
typ.rawAddSon(magicsys.getCompilerProc(g, "Barrier").typ)
|
||||
var field = newSym(skField, getIdent(g.cache, "barrier"), owner, n.info, g.config.options)
|
||||
var field = newSym(skField, getIdent(g.cache, "barrier"), nextId idgen, owner, n.info, g.config.options)
|
||||
field.typ = typ
|
||||
objType.addField(field, g.cache)
|
||||
objType.addField(field, g.cache, idgen)
|
||||
result.add newFastAsgnStmt(newDotExpr(scratchObj, field), barrier)
|
||||
barrierAsExpr = indirectAccess(castExpr, field, n.info)
|
||||
|
||||
var fvField, fvAsExpr: PNode = nil
|
||||
if spawnKind == srFlowVar:
|
||||
var field = newSym(skField, getIdent(g.cache, "fv"), owner, n.info, g.config.options)
|
||||
var field = newSym(skField, getIdent(g.cache, "fv"), nextId idgen, owner, n.info, g.config.options)
|
||||
field.typ = retType
|
||||
objType.addField(field, g.cache)
|
||||
objType.addField(field, g.cache, idgen)
|
||||
fvField = newDotExpr(scratchObj, field)
|
||||
fvAsExpr = indirectAccess(castExpr, field, n.info)
|
||||
# create flowVar:
|
||||
result.add newFastAsgnStmt(fvField, callProc(spawnExpr[^1]))
|
||||
if barrier == nil:
|
||||
result.add callCodegenProc(g, "nimFlowVarCreateSemaphore", fvField.info,
|
||||
fvField)
|
||||
result.add callCodegenProc(g, "nimFlowVarCreateSemaphore", fvField.info, fvField)
|
||||
|
||||
elif spawnKind == srByVar:
|
||||
var field = newSym(skField, getIdent(g.cache, "fv"), owner, n.info, g.config.options)
|
||||
field.typ = newType(tyPtr, objType.owner)
|
||||
var field = newSym(skField, getIdent(g.cache, "fv"), nextId idgen, owner, n.info, g.config.options)
|
||||
field.typ = newType(tyPtr, nextId idgen, objType.owner)
|
||||
field.typ.rawAddSon(retType)
|
||||
objType.addField(field, g.cache)
|
||||
objType.addField(field, g.cache, idgen)
|
||||
fvAsExpr = indirectAccess(castExpr, field, n.info)
|
||||
result.add newFastAsgnStmt(newDotExpr(scratchObj, field), genAddrOf(dest))
|
||||
result.add newFastAsgnStmt(newDotExpr(scratchObj, field), genAddrOf(dest, idgen))
|
||||
|
||||
createTypeBoundOps(g, nil, objType, n.info)
|
||||
createTypeBoundOps(g, nil, objType, n.info, idgen)
|
||||
createWrapperProc(g, fn, threadParam, argsParam,
|
||||
varSection, varInit, call,
|
||||
barrierAsExpr, fvAsExpr, spawnKind, wrapperProc)
|
||||
barrierAsExpr, fvAsExpr, idgen, spawnKind, wrapperProc)
|
||||
result.add callCodegenProc(g, "nimSpawn" & $spawnExpr.len, wrapperProc.info,
|
||||
wrapperProc.newSymNode, genAddrOf(scratchObj.newSymNode), nil, spawnExpr)
|
||||
wrapperProc.newSymNode, genAddrOf(scratchObj.newSymNode, idgen), nil, spawnExpr)
|
||||
|
||||
if spawnKind == srFlowVar: result.add fvField
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ import
|
|||
lowerings, liftlocals,
|
||||
modulegraphs, lineinfos
|
||||
|
||||
proc transformBody*(g: ModuleGraph, prc: PSym, cache: bool): PNode
|
||||
proc transformBody*(g: ModuleGraph; idgen: IdGenerator, prc: PSym, cache: bool): PNode
|
||||
|
||||
import closureiters, lambdalifting
|
||||
|
||||
|
|
@ -40,7 +40,7 @@ type
|
|||
# if we encounter the 2nd yield statement
|
||||
next: PTransCon # for stacking
|
||||
|
||||
TTransfContext = object of TPassContext
|
||||
TTransfContext = object
|
||||
module: PSym
|
||||
transCon: PTransCon # top of a TransCon stack
|
||||
inlining: int # > 0 if we are in inlining context (copy vars)
|
||||
|
|
@ -48,6 +48,7 @@ type
|
|||
contSyms, breakSyms: seq[PSym] # to transform 'continue' and 'break'
|
||||
deferDetected, tooEarly: bool
|
||||
graph: ModuleGraph
|
||||
idgen: IdGenerator
|
||||
PTransf = ref TTransfContext
|
||||
|
||||
proc newTransNode(a: PNode): PNode {.inline.} =
|
||||
|
|
@ -86,12 +87,12 @@ proc getCurrOwner(c: PTransf): PSym =
|
|||
else: result = c.module
|
||||
|
||||
proc newTemp(c: PTransf, typ: PType, info: TLineInfo): PNode =
|
||||
let r = newSym(skTemp, getIdent(c.graph.cache, genPrefix), getCurrOwner(c), info)
|
||||
let r = newSym(skTemp, getIdent(c.graph.cache, genPrefix), nextId(c.idgen), getCurrOwner(c), info)
|
||||
r.typ = typ #skipTypes(typ, {tyGenericInst, tyAlias, tySink})
|
||||
incl(r.flags, sfFromGeneric)
|
||||
let owner = getCurrOwner(c)
|
||||
if owner.isIterator and not c.tooEarly:
|
||||
result = freshVarForClosureIter(c.graph, r, owner)
|
||||
result = freshVarForClosureIter(c.graph, r, c.idgen, owner)
|
||||
else:
|
||||
result = newSymNode(r)
|
||||
|
||||
|
|
@ -111,13 +112,13 @@ proc transformSymAux(c: PTransf, n: PNode): PNode =
|
|||
let s = n.sym
|
||||
if s.typ != nil and s.typ.callConv == ccClosure:
|
||||
if s.kind in routineKinds:
|
||||
discard transformBody(c.graph, s, true)
|
||||
discard transformBody(c.graph, c.idgen, s, true)
|
||||
if s.kind == skIterator:
|
||||
if c.tooEarly: return n
|
||||
else: return liftIterSym(c.graph, n, getCurrOwner(c))
|
||||
else: return liftIterSym(c.graph, n, c.idgen, getCurrOwner(c))
|
||||
elif s.kind in {skProc, skFunc, skConverter, skMethod} and not c.tooEarly:
|
||||
# top level .closure procs are still somewhat supported for 'Nake':
|
||||
return makeClosure(c.graph, s, nil, n.info)
|
||||
return makeClosure(c.graph, c.idgen, s, nil, n.info)
|
||||
#elif n.sym.kind in {skVar, skLet} and n.sym.typ.callConv == ccClosure:
|
||||
# echo n.info, " come heer for ", c.tooEarly
|
||||
# if not c.tooEarly:
|
||||
|
|
@ -160,9 +161,9 @@ proc transformSym(c: PTransf, n: PNode): PNode =
|
|||
proc freshVar(c: PTransf; v: PSym): PNode =
|
||||
let owner = getCurrOwner(c)
|
||||
if owner.isIterator and not c.tooEarly:
|
||||
result = freshVarForClosureIter(c.graph, v, owner)
|
||||
result = freshVarForClosureIter(c.graph, v, c.idgen, owner)
|
||||
else:
|
||||
var newVar = copySym(v)
|
||||
var newVar = copySym(v, nextId(c.idgen))
|
||||
incl(newVar.flags, sfFromGeneric)
|
||||
newVar.owner = owner
|
||||
result = newSymNode(newVar)
|
||||
|
|
@ -232,7 +233,7 @@ proc hasContinue(n: PNode): bool =
|
|||
if hasContinue(n[i]): return true
|
||||
|
||||
proc newLabel(c: PTransf, n: PNode): PSym =
|
||||
result = newSym(skLabel, nil, getCurrOwner(c), n.info)
|
||||
result = newSym(skLabel, nil, nextId(c.idgen), getCurrOwner(c), n.info)
|
||||
result.name = getIdent(c.graph.cache, genPrefix)
|
||||
|
||||
proc transformBlock(c: PTransf, n: PNode): PNode =
|
||||
|
|
@ -423,7 +424,7 @@ proc transformAddrDeref(c: PTransf, n: PNode, a, b: TNodeKind): PNode =
|
|||
if n.typ.skipTypes(abstractVar).kind != tyOpenArray:
|
||||
result.typ = n.typ
|
||||
elif n.typ.skipTypes(abstractInst).kind in {tyVar}:
|
||||
result.typ = toVar(result.typ, n.typ.skipTypes(abstractInst).kind)
|
||||
result.typ = toVar(result.typ, n.typ.skipTypes(abstractInst).kind, c.idgen)
|
||||
of nkHiddenStdConv, nkHiddenSubConv, nkConv:
|
||||
var m = n[0][1]
|
||||
if m.kind == a or m.kind == b:
|
||||
|
|
@ -433,7 +434,7 @@ proc transformAddrDeref(c: PTransf, n: PNode, a, b: TNodeKind): PNode =
|
|||
if n.typ.skipTypes(abstractVar).kind != tyOpenArray:
|
||||
result.typ = n.typ
|
||||
elif n.typ.skipTypes(abstractInst).kind in {tyVar}:
|
||||
result.typ = toVar(result.typ, n.typ.skipTypes(abstractInst).kind)
|
||||
result.typ = toVar(result.typ, n.typ.skipTypes(abstractInst).kind, c.idgen)
|
||||
else:
|
||||
if n[0].kind == a or n[0].kind == b:
|
||||
# addr ( deref ( x )) --> x
|
||||
|
|
@ -495,7 +496,7 @@ proc transformConv(c: PTransf, n: PNode): PNode =
|
|||
of tyOpenArray, tyVarargs:
|
||||
result = transform(c, n[1])
|
||||
#result = transformSons(c, n)
|
||||
result.typ = takeType(n.typ, n[1].typ)
|
||||
result.typ = takeType(n.typ, n[1].typ, c.idgen)
|
||||
#echo n.info, " came here and produced ", typeToString(result.typ),
|
||||
# " from ", typeToString(n.typ), " and ", typeToString(n[1].typ)
|
||||
of tyCString:
|
||||
|
|
@ -629,7 +630,7 @@ proc transformFor(c: PTransf, n: PNode): PNode =
|
|||
result[1] = n
|
||||
result[1][^1] = transformLoopBody(c, n[^1])
|
||||
result[1][^2] = transform(c, n[^2])
|
||||
result[1] = lambdalifting.liftForLoop(c.graph, result[1], getCurrOwner(c))
|
||||
result[1] = lambdalifting.liftForLoop(c.graph, result[1], c.idgen, getCurrOwner(c))
|
||||
discard c.breakSyms.pop
|
||||
return result
|
||||
|
||||
|
|
@ -698,7 +699,7 @@ proc transformFor(c: PTransf, n: PNode): PNode =
|
|||
stmtList.add(newAsgnStmt(c, nkFastAsgn, temp, arg))
|
||||
idNodeTablePut(newC.mapping, formal, temp)
|
||||
|
||||
let body = transformBody(c.graph, iter, true)
|
||||
let body = transformBody(c.graph, c.idgen, iter, true)
|
||||
pushInfoContext(c.graph.config, n.info)
|
||||
inc(c.inlining)
|
||||
stmtList.add(transform(c, body))
|
||||
|
|
@ -830,7 +831,7 @@ proc transformExceptBranch(c: PTransf, n: PNode): PNode =
|
|||
let convNode = newTransNode(nkHiddenSubConv, n[1].info, 2)
|
||||
convNode[0] = newNodeI(nkEmpty, n.info)
|
||||
convNode[1] = excCall
|
||||
convNode.typ = excTypeNode.typ.toRef()
|
||||
convNode.typ = excTypeNode.typ.toRef(c.idgen)
|
||||
# -> let exc = ...
|
||||
let identDefs = newTransNode(nkIdentDefs, n[1].info, 3)
|
||||
identDefs[0] = n[0][2]
|
||||
|
|
@ -850,10 +851,10 @@ proc transformExceptBranch(c: PTransf, n: PNode): PNode =
|
|||
else:
|
||||
result = transformSons(c, n)
|
||||
|
||||
proc commonOptimizations*(g: ModuleGraph; c: PSym, n: PNode): PNode =
|
||||
proc commonOptimizations*(g: ModuleGraph; idgen: IdGenerator; c: PSym, n: PNode): PNode =
|
||||
result = n
|
||||
for i in 0..<n.safeLen:
|
||||
result[i] = commonOptimizations(g, c, n[i])
|
||||
result[i] = commonOptimizations(g, idgen, c, n[i])
|
||||
var op = getMergeOp(n)
|
||||
if (op != nil) and (op.magic != mNone) and (n.len >= 3):
|
||||
result = newNodeIT(nkCall, n.info, n.typ)
|
||||
|
|
@ -873,7 +874,7 @@ proc commonOptimizations*(g: ModuleGraph; c: PSym, n: PNode): PNode =
|
|||
result.add(a)
|
||||
if result.len == 2: result = result[1]
|
||||
else:
|
||||
var cnst = getConstExpr(c, n, g)
|
||||
var cnst = getConstExpr(c, n, idgen, g)
|
||||
# we inline constants if they are not complex constants:
|
||||
if cnst != nil and not dontInlineConstant(n, cnst):
|
||||
result = cnst
|
||||
|
|
@ -1012,7 +1013,7 @@ proc transform(c: PTransf, n: PNode): PNode =
|
|||
n.typ != nil and
|
||||
n.typ.kind == tyPointer
|
||||
if not exprIsPointerCast:
|
||||
var cnst = getConstExpr(c.module, result, c.graph)
|
||||
var cnst = getConstExpr(c.module, result, c.idgen, c.graph)
|
||||
# we inline constants if they are not complex constants:
|
||||
if cnst != nil and not dontInlineConstant(n, cnst):
|
||||
result = cnst # do not miss an optimization
|
||||
|
|
@ -1027,12 +1028,13 @@ proc processTransf(c: PTransf, n: PNode, owner: PSym): PNode =
|
|||
popTransCon(c)
|
||||
incl(result.flags, nfTransf)
|
||||
|
||||
proc openTransf(g: ModuleGraph; module: PSym, filename: string): PTransf =
|
||||
proc openTransf(g: ModuleGraph; module: PSym, filename: string; idgen: IdGenerator): PTransf =
|
||||
new(result)
|
||||
result.contSyms = @[]
|
||||
result.breakSyms = @[]
|
||||
result.module = module
|
||||
result.graph = g
|
||||
result.idgen = idgen
|
||||
|
||||
proc flattenStmts(n: PNode) =
|
||||
var goOn = true
|
||||
|
|
@ -1075,7 +1077,7 @@ template liftDefer(c, root) =
|
|||
if c.deferDetected:
|
||||
liftDeferAux(root)
|
||||
|
||||
proc transformBody*(g: ModuleGraph, prc: PSym, cache: bool): PNode =
|
||||
proc transformBody*(g: ModuleGraph; idgen: IdGenerator; prc: PSym; cache: bool): PNode =
|
||||
assert prc.kind in routineKinds
|
||||
|
||||
if prc.transformedBody != nil:
|
||||
|
|
@ -1084,14 +1086,14 @@ proc transformBody*(g: ModuleGraph, prc: PSym, cache: bool): PNode =
|
|||
result = prc.ast[bodyPos]
|
||||
else:
|
||||
prc.transformedBody = newNode(nkEmpty) # protects from recursion
|
||||
var c = openTransf(g, prc.getModule, "")
|
||||
result = liftLambdas(g, prc, prc.ast[bodyPos], c.tooEarly)
|
||||
var c = openTransf(g, prc.getModule, "", idgen)
|
||||
result = liftLambdas(g, prc, prc.ast[bodyPos], c.tooEarly, c.idgen)
|
||||
result = processTransf(c, result, prc)
|
||||
liftDefer(c, result)
|
||||
result = liftLocalsIfRequested(prc, result, g.cache, g.config)
|
||||
result = liftLocalsIfRequested(prc, result, g.cache, g.config, c.idgen)
|
||||
|
||||
if prc.isIterator:
|
||||
result = g.transformClosureIterator(prc, result)
|
||||
result = g.transformClosureIterator(c.idgen, prc, result)
|
||||
|
||||
incl(result.flags, nfTransf)
|
||||
|
||||
|
|
@ -1105,21 +1107,21 @@ proc transformBody*(g: ModuleGraph, prc: PSym, cache: bool): PNode =
|
|||
#if prc.name.s == "main":
|
||||
# echo "transformed into ", renderTree(result, {renderIds})
|
||||
|
||||
proc transformStmt*(g: ModuleGraph; module: PSym, n: PNode): PNode =
|
||||
proc transformStmt*(g: ModuleGraph; idgen: IdGenerator; module: PSym, n: PNode): PNode =
|
||||
if nfTransf in n.flags:
|
||||
result = n
|
||||
else:
|
||||
var c = openTransf(g, module, "")
|
||||
var c = openTransf(g, module, "", idgen)
|
||||
result = processTransf(c, n, module)
|
||||
liftDefer(c, result)
|
||||
#result = liftLambdasForTopLevel(module, result)
|
||||
incl(result.flags, nfTransf)
|
||||
|
||||
proc transformExpr*(g: ModuleGraph; module: PSym, n: PNode): PNode =
|
||||
proc transformExpr*(g: ModuleGraph; idgen: IdGenerator; module: PSym, n: PNode): PNode =
|
||||
if nfTransf in n.flags:
|
||||
result = n
|
||||
else:
|
||||
var c = openTransf(g, module, "")
|
||||
var c = openTransf(g, module, "", idgen)
|
||||
result = processTransf(c, n, module)
|
||||
liftDefer(c, result)
|
||||
# expressions are not to be injected with destructor calls as that
|
||||
|
|
|
|||
|
|
@ -1296,11 +1296,11 @@ proc containsGenericTypeIter(t: PType, closure: RootRef): bool =
|
|||
proc containsGenericType*(t: PType): bool =
|
||||
result = iterOverType(t, containsGenericTypeIter, nil)
|
||||
|
||||
proc baseOfDistinct*(t: PType): PType =
|
||||
proc baseOfDistinct*(t: PType; idgen: IdGenerator): PType =
|
||||
if t.kind == tyDistinct:
|
||||
result = t[0]
|
||||
else:
|
||||
result = copyType(t, t.owner, false)
|
||||
result = copyType(t, nextId idgen, t.owner)
|
||||
var parent: PType = nil
|
||||
var it = result
|
||||
while it.kind in {tyPtr, tyRef, tyOwned}:
|
||||
|
|
@ -1438,7 +1438,7 @@ proc isEmptyContainer*(t: PType): bool =
|
|||
of tyGenericInst, tyAlias, tySink: result = isEmptyContainer(t.lastSon)
|
||||
else: result = false
|
||||
|
||||
proc takeType*(formal, arg: PType): PType =
|
||||
proc takeType*(formal, arg: PType; idgen: IdGenerator): PType =
|
||||
# param: openArray[string] = []
|
||||
# [] is an array constructor of length 0 of type string!
|
||||
if arg.kind == tyNil:
|
||||
|
|
@ -1446,7 +1446,7 @@ proc takeType*(formal, arg: PType): PType =
|
|||
result = formal
|
||||
elif formal.kind in {tyOpenArray, tyVarargs, tySequence} and
|
||||
arg.isEmptyContainer:
|
||||
let a = copyType(arg.skipTypes({tyGenericInst, tyAlias}), arg.owner, keepId=false)
|
||||
let a = copyType(arg.skipTypes({tyGenericInst, tyAlias}), nextId(idgen), arg.owner)
|
||||
a[ord(arg.kind == tyArray)] = formal[0]
|
||||
result = a
|
||||
elif formal.kind in {tyTuple, tySet} and arg.kind == formal.kind:
|
||||
|
|
@ -1454,14 +1454,14 @@ proc takeType*(formal, arg: PType): PType =
|
|||
else:
|
||||
result = arg
|
||||
|
||||
proc skipHiddenSubConv*(n: PNode): PNode =
|
||||
proc skipHiddenSubConv*(n: PNode; idgen: IdGenerator): PNode =
|
||||
if n.kind == nkHiddenSubConv:
|
||||
# param: openArray[string] = []
|
||||
# [] is an array constructor of length 0 of type string!
|
||||
let formal = n.typ
|
||||
result = n[1]
|
||||
let arg = result.typ
|
||||
let dest = takeType(formal, arg)
|
||||
let dest = takeType(formal, arg, idgen)
|
||||
if dest == arg and formal.kind != tyUntyped:
|
||||
#echo n.info, " came here for ", formal.typeToString
|
||||
result = n
|
||||
|
|
|
|||
|
|
@ -1105,7 +1105,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
|||
let ast = a.sym.ast.shallowCopy
|
||||
for i in 0..<a.sym.ast.len:
|
||||
ast[i] = a.sym.ast[i]
|
||||
ast[bodyPos] = transformBody(c.graph, a.sym, cache=true)
|
||||
ast[bodyPos] = transformBody(c.graph, c.idgen, a.sym, cache=true)
|
||||
ast.copyTree()
|
||||
of opcSymOwner:
|
||||
decodeB(rkNode)
|
||||
|
|
@ -1233,7 +1233,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
|||
let node = regs[rb+i].regToNode
|
||||
node.info = c.debug[pc]
|
||||
macroCall.add(node)
|
||||
var a = evalTemplate(macroCall, prc, genSymOwner, c.config, c.cache, c.templInstCounter)
|
||||
var a = evalTemplate(macroCall, prc, genSymOwner, c.config, c.cache, c.templInstCounter, c.idgen)
|
||||
if a.kind == nkStmtList and a.len == 1: a = a[0]
|
||||
a.recSetFlagIsRef
|
||||
ensureKind(rkNode)
|
||||
|
|
@ -1599,9 +1599,9 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
|||
# getType opcode:
|
||||
ensureKind(rkNode)
|
||||
if regs[rb].kind == rkNode and regs[rb].node.typ != nil:
|
||||
regs[ra].node = opMapTypeToAst(c.cache, regs[rb].node.typ, c.debug[pc])
|
||||
regs[ra].node = opMapTypeToAst(c.cache, regs[rb].node.typ, c.debug[pc], c.idgen)
|
||||
elif regs[rb].kind == rkNode and regs[rb].node.kind == nkSym and regs[rb].node.sym.typ != nil:
|
||||
regs[ra].node = opMapTypeToAst(c.cache, regs[rb].node.sym.typ, c.debug[pc])
|
||||
regs[ra].node = opMapTypeToAst(c.cache, regs[rb].node.sym.typ, c.debug[pc], c.idgen)
|
||||
else:
|
||||
stackTrace(c, tos, pc, "node has no type")
|
||||
of 1:
|
||||
|
|
@ -1617,18 +1617,18 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
|||
# getTypeInst opcode:
|
||||
ensureKind(rkNode)
|
||||
if regs[rb].kind == rkNode and regs[rb].node.typ != nil:
|
||||
regs[ra].node = opMapTypeInstToAst(c.cache, regs[rb].node.typ, c.debug[pc])
|
||||
regs[ra].node = opMapTypeInstToAst(c.cache, regs[rb].node.typ, c.debug[pc], c.idgen)
|
||||
elif regs[rb].kind == rkNode and regs[rb].node.kind == nkSym and regs[rb].node.sym.typ != nil:
|
||||
regs[ra].node = opMapTypeInstToAst(c.cache, regs[rb].node.sym.typ, c.debug[pc])
|
||||
regs[ra].node = opMapTypeInstToAst(c.cache, regs[rb].node.sym.typ, c.debug[pc], c.idgen)
|
||||
else:
|
||||
stackTrace(c, tos, pc, "node has no type")
|
||||
else:
|
||||
# getTypeImpl opcode:
|
||||
ensureKind(rkNode)
|
||||
if regs[rb].kind == rkNode and regs[rb].node.typ != nil:
|
||||
regs[ra].node = opMapTypeImplToAst(c.cache, regs[rb].node.typ, c.debug[pc])
|
||||
regs[ra].node = opMapTypeImplToAst(c.cache, regs[rb].node.typ, c.debug[pc], c.idgen)
|
||||
elif regs[rb].kind == rkNode and regs[rb].node.kind == nkSym and regs[rb].node.sym.typ != nil:
|
||||
regs[ra].node = opMapTypeImplToAst(c.cache, regs[rb].node.sym.typ, c.debug[pc])
|
||||
regs[ra].node = opMapTypeImplToAst(c.cache, regs[rb].node.sym.typ, c.debug[pc], c.idgen)
|
||||
else:
|
||||
stackTrace(c, tos, pc, "node has no type")
|
||||
of opcNGetSize:
|
||||
|
|
@ -1938,7 +1938,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
|||
else: regs[rc].node.strVal
|
||||
if k < 0 or k > ord(high(TSymKind)):
|
||||
internalError(c.config, c.debug[pc], "request to create symbol of invalid kind")
|
||||
var sym = newSym(k.TSymKind, getIdent(c.cache, name), c.module.owner, c.debug[pc])
|
||||
var sym = newSym(k.TSymKind, getIdent(c.cache, name), nextId c.idgen, c.module.owner, c.debug[pc])
|
||||
incl(sym.flags, sfGenSym)
|
||||
regs[ra].node = newSymNode(sym)
|
||||
regs[ra].node.flags.incl nfIsRef
|
||||
|
|
@ -2058,7 +2058,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
|||
let rb = instr.regB
|
||||
inc pc
|
||||
let typ = c.types[c.code[pc].regBx - wordExcess]
|
||||
putIntoReg(regs[ra], loadAny(regs[rb].node.strVal, typ, c.cache, c.config))
|
||||
putIntoReg(regs[ra], loadAny(regs[rb].node.strVal, typ, c.cache, c.config, c.idgen))
|
||||
of opcMarshalStore:
|
||||
decodeB(rkNode)
|
||||
inc pc
|
||||
|
|
@ -2103,7 +2103,7 @@ proc execProc*(c: PCtx; sym: PSym; args: openArray[PNode]): PNode =
|
|||
"NimScript: attempt to call non-routine: " & sym.name.s)
|
||||
|
||||
proc evalStmt*(c: PCtx, n: PNode) =
|
||||
let n = transformExpr(c.graph, c.module, n)
|
||||
let n = transformExpr(c.graph, c.idgen, c.module, n)
|
||||
let start = genStmt(c, n)
|
||||
# execute new instructions; this redundant opcEof check saves us lots
|
||||
# of allocations in 'execute':
|
||||
|
|
@ -2111,7 +2111,7 @@ proc evalStmt*(c: PCtx, n: PNode) =
|
|||
discard execute(c, start)
|
||||
|
||||
proc evalExpr*(c: PCtx, n: PNode): PNode =
|
||||
let n = transformExpr(c.graph, c.module, n)
|
||||
let n = transformExpr(c.graph, c.idgen, c.module, n)
|
||||
let start = genExpr(c, n)
|
||||
assert c.code[start].opcode != opcEof
|
||||
result = execute(c, start)
|
||||
|
|
@ -2122,20 +2122,20 @@ proc getGlobalValue*(c: PCtx; s: PSym): PNode =
|
|||
|
||||
include vmops
|
||||
|
||||
proc setupGlobalCtx*(module: PSym; graph: ModuleGraph) =
|
||||
proc setupGlobalCtx*(module: PSym; graph: ModuleGraph; idgen: IdGenerator) =
|
||||
if graph.vm.isNil:
|
||||
graph.vm = newCtx(module, graph.cache, graph)
|
||||
graph.vm = newCtx(module, graph.cache, graph, idgen)
|
||||
registerAdditionalOps(PCtx graph.vm)
|
||||
else:
|
||||
refresh(PCtx graph.vm, module)
|
||||
refresh(PCtx graph.vm, module, idgen)
|
||||
|
||||
proc myOpen(graph: ModuleGraph; module: PSym): PPassContext {.nosinks.} =
|
||||
proc myOpen(graph: ModuleGraph; module: PSym; idgen: IdGenerator): PPassContext {.nosinks.} =
|
||||
#var c = newEvalContext(module, emRepl)
|
||||
#c.features = {allowCast, allowInfiniteLoops}
|
||||
#pushStackFrame(c, newStackFrame())
|
||||
|
||||
# XXX produce a new 'globals' environment here:
|
||||
setupGlobalCtx(module, graph)
|
||||
setupGlobalCtx(module, graph, idgen)
|
||||
result = PCtx graph.vm
|
||||
|
||||
proc myProcess(c: PPassContext, n: PNode): PNode =
|
||||
|
|
@ -2149,16 +2149,16 @@ proc myProcess(c: PPassContext, n: PNode): PNode =
|
|||
c.oldErrorCount = c.config.errorCounter
|
||||
|
||||
proc myClose(graph: ModuleGraph; c: PPassContext, n: PNode): PNode =
|
||||
myProcess(c, n)
|
||||
result = myProcess(c, n)
|
||||
|
||||
const evalPass* = makePass(myOpen, myProcess, myClose)
|
||||
|
||||
proc evalConstExprAux(module: PSym;
|
||||
proc evalConstExprAux(module: PSym; idgen: IdGenerator;
|
||||
g: ModuleGraph; prc: PSym, n: PNode,
|
||||
mode: TEvalMode): PNode =
|
||||
if g.config.errorCounter > 0: return n
|
||||
let n = transformExpr(g, module, n)
|
||||
setupGlobalCtx(module, g)
|
||||
let n = transformExpr(g, idgen, module, n)
|
||||
setupGlobalCtx(module, g, idgen)
|
||||
var c = PCtx g.vm
|
||||
let oldMode = c.mode
|
||||
c.mode = mode
|
||||
|
|
@ -2173,17 +2173,17 @@ proc evalConstExprAux(module: PSym;
|
|||
if result.info.col < 0: result.info = n.info
|
||||
c.mode = oldMode
|
||||
|
||||
proc evalConstExpr*(module: PSym; g: ModuleGraph; e: PNode): PNode =
|
||||
result = evalConstExprAux(module, g, nil, e, emConst)
|
||||
proc evalConstExpr*(module: PSym; idgen: IdGenerator; g: ModuleGraph; e: PNode): PNode =
|
||||
result = evalConstExprAux(module, idgen, g, nil, e, emConst)
|
||||
|
||||
proc evalStaticExpr*(module: PSym; g: ModuleGraph; e: PNode, prc: PSym): PNode =
|
||||
result = evalConstExprAux(module, g, prc, e, emStaticExpr)
|
||||
proc evalStaticExpr*(module: PSym; idgen: IdGenerator; g: ModuleGraph; e: PNode, prc: PSym): PNode =
|
||||
result = evalConstExprAux(module, idgen, g, prc, e, emStaticExpr)
|
||||
|
||||
proc evalStaticStmt*(module: PSym; g: ModuleGraph; e: PNode, prc: PSym) =
|
||||
discard evalConstExprAux(module, g, prc, e, emStaticStmt)
|
||||
proc evalStaticStmt*(module: PSym; idgen: IdGenerator; g: ModuleGraph; e: PNode, prc: PSym) =
|
||||
discard evalConstExprAux(module, idgen, g, prc, e, emStaticStmt)
|
||||
|
||||
proc setupCompileTimeVar*(module: PSym; g: ModuleGraph; n: PNode) =
|
||||
discard evalConstExprAux(module, g, nil, n, emStaticStmt)
|
||||
proc setupCompileTimeVar*(module: PSym; idgen: IdGenerator; g: ModuleGraph; n: PNode) =
|
||||
discard evalConstExprAux(module, idgen, g, nil, n, emStaticStmt)
|
||||
|
||||
proc prepareVMValue(arg: PNode): PNode =
|
||||
## strip nkExprColonExpr from tuple values recurively. That is how
|
||||
|
|
@ -2227,14 +2227,14 @@ iterator genericParamsInMacroCall*(macroSym: PSym, call: PNode): (PSym, PNode) =
|
|||
# to prevent endless recursion in macro instantiation
|
||||
const evalMacroLimit = 1000
|
||||
|
||||
proc errorNode(owner: PSym, n: PNode): PNode =
|
||||
proc errorNode(idgen: IdGenerator; owner: PSym, n: PNode): PNode =
|
||||
result = newNodeI(nkEmpty, n.info)
|
||||
result.typ = newType(tyError, owner)
|
||||
result.typ = newType(tyError, nextId idgen, owner)
|
||||
result.typ.flags.incl tfCheckedForDestructor
|
||||
|
||||
proc evalMacroCall*(module: PSym; g: ModuleGraph; templInstCounter: ref int;
|
||||
proc evalMacroCall*(module: PSym; idgen: IdGenerator; g: ModuleGraph; templInstCounter: ref int;
|
||||
n, nOrig: PNode, sym: PSym): PNode =
|
||||
if g.config.errorCounter > 0: return errorNode(module, n)
|
||||
if g.config.errorCounter > 0: return errorNode(idgen, module, n)
|
||||
|
||||
# XXX globalError() is ugly here, but I don't know a better solution for now
|
||||
inc(g.config.evalMacroCounter)
|
||||
|
|
@ -2247,7 +2247,7 @@ proc evalMacroCall*(module: PSym; g: ModuleGraph; templInstCounter: ref int;
|
|||
globalError(g.config, n.info, "in call '$#' got $#, but expected $# argument(s)" % [
|
||||
n.renderTree, $(n.safeLen-1), $(sym.typ.len-1)])
|
||||
|
||||
setupGlobalCtx(module, g)
|
||||
setupGlobalCtx(module, g, idgen)
|
||||
var c = PCtx g.vm
|
||||
let oldMode = c.mode
|
||||
c.mode = emStaticStmt
|
||||
|
|
|
|||
|
|
@ -282,17 +282,18 @@ type
|
|||
|
||||
PEvalContext* = PCtx
|
||||
|
||||
proc newCtx*(module: PSym; cache: IdentCache; g: ModuleGraph): PCtx =
|
||||
proc newCtx*(module: PSym; cache: IdentCache; g: ModuleGraph; idgen: IdGenerator): PCtx =
|
||||
PCtx(code: @[], debug: @[],
|
||||
globals: newNode(nkStmtListExpr), constants: newNode(nkStmtList), types: @[],
|
||||
prc: PProc(blocks: @[]), module: module, loopIterations: g.config.maxLoopIterationsVM,
|
||||
comesFromHeuristic: unknownLineInfo, callbacks: @[], errorFlag: "",
|
||||
cache: cache, config: g.config, graph: g)
|
||||
cache: cache, config: g.config, graph: g, idgen: idgen)
|
||||
|
||||
proc refresh*(c: PCtx, module: PSym) =
|
||||
proc refresh*(c: PCtx, module: PSym; idgen: IdGenerator) =
|
||||
c.module = module
|
||||
c.prc = PProc(blocks: @[])
|
||||
c.loopIterations = c.config.maxLoopIterationsVM
|
||||
c.idgen = idgen
|
||||
|
||||
proc registerCallback*(c: PCtx; name: string; callback: VmCallback): int {.discardable.} =
|
||||
result = c.callbacks.len
|
||||
|
|
|
|||
|
|
@ -24,8 +24,9 @@ proc opSlurp*(file: string, info: TLineInfo, module: PSym; conf: ConfigRef): str
|
|||
localError(conf, info, "cannot open file: " & file)
|
||||
result = ""
|
||||
|
||||
proc atomicTypeX(cache: IdentCache; name: string; m: TMagic; t: PType; info: TLineInfo): PNode =
|
||||
let sym = newSym(skType, getIdent(cache, name), t.owner, info)
|
||||
proc atomicTypeX(cache: IdentCache; name: string; m: TMagic; t: PType; info: TLineInfo;
|
||||
idgen: IdGenerator): PNode =
|
||||
let sym = newSym(skType, getIdent(cache, name), nextId(idgen), t.owner, info)
|
||||
sym.magic = m
|
||||
sym.typ = t
|
||||
result = newSymNode(sym)
|
||||
|
|
@ -35,44 +36,46 @@ proc atomicTypeX(s: PSym; info: TLineInfo): PNode =
|
|||
result = newSymNode(s)
|
||||
result.info = info
|
||||
|
||||
proc mapTypeToAstX(cache: IdentCache; t: PType; info: TLineInfo;
|
||||
proc mapTypeToAstX(cache: IdentCache; t: PType; info: TLineInfo; idgen: IdGenerator;
|
||||
inst=false; allowRecursionX=false): PNode
|
||||
|
||||
proc mapTypeToBracketX(cache: IdentCache; name: string; m: TMagic; t: PType; info: TLineInfo;
|
||||
idgen: IdGenerator;
|
||||
inst=false): PNode =
|
||||
result = newNodeIT(nkBracketExpr, if t.n.isNil: info else: t.n.info, t)
|
||||
result.add atomicTypeX(cache, name, m, t, info)
|
||||
result.add atomicTypeX(cache, name, m, t, info, idgen)
|
||||
for i in 0..<t.len:
|
||||
if t[i] == nil:
|
||||
let void = atomicTypeX(cache, "void", mVoid, t, info)
|
||||
void.typ = newType(tyVoid, t.owner)
|
||||
let void = atomicTypeX(cache, "void", mVoid, t, info, idgen)
|
||||
void.typ = newType(tyVoid, nextId(idgen), t.owner)
|
||||
result.add void
|
||||
else:
|
||||
result.add mapTypeToAstX(cache, t[i], info, inst)
|
||||
result.add mapTypeToAstX(cache, t[i], info, idgen, inst)
|
||||
|
||||
proc objectNode(cache: IdentCache; n: PNode): PNode =
|
||||
proc objectNode(cache: IdentCache; n: PNode; idgen: IdGenerator): PNode =
|
||||
if n.kind == nkSym:
|
||||
result = newNodeI(nkIdentDefs, n.info)
|
||||
result.add n # name
|
||||
result.add mapTypeToAstX(cache, n.sym.typ, n.info, true, false) # type
|
||||
result.add mapTypeToAstX(cache, n.sym.typ, n.info, idgen, true, false) # type
|
||||
result.add newNodeI(nkEmpty, n.info) # no assigned value
|
||||
else:
|
||||
result = copyNode(n)
|
||||
for i in 0..<n.safeLen:
|
||||
result.add objectNode(cache, n[i])
|
||||
result.add objectNode(cache, n[i], idgen)
|
||||
|
||||
proc mapTypeToAstX(cache: IdentCache; t: PType; info: TLineInfo;
|
||||
idgen: IdGenerator;
|
||||
inst=false; allowRecursionX=false): PNode =
|
||||
var allowRecursion = allowRecursionX
|
||||
template atomicType(name, m): untyped = atomicTypeX(cache, name, m, t, info)
|
||||
template atomicType(name, m): untyped = atomicTypeX(cache, name, m, t, info, idgen)
|
||||
template atomicType(s): untyped = atomicTypeX(s, info)
|
||||
template mapTypeToAst(t,info): untyped = mapTypeToAstX(cache, t, info, inst)
|
||||
template mapTypeToAstR(t,info): untyped = mapTypeToAstX(cache, t, info, inst, true)
|
||||
template mapTypeToAst(t,info): untyped = mapTypeToAstX(cache, t, info, idgen, inst)
|
||||
template mapTypeToAstR(t,info): untyped = mapTypeToAstX(cache, t, info, idgen, inst, true)
|
||||
template mapTypeToAst(t,i,info): untyped =
|
||||
if i<t.len and t[i]!=nil: mapTypeToAstX(cache, t[i], info, inst)
|
||||
if i<t.len and t[i]!=nil: mapTypeToAstX(cache, t[i], info, idgen, inst)
|
||||
else: newNodeI(nkEmpty, info)
|
||||
template mapTypeToBracket(name, m, t, info): untyped =
|
||||
mapTypeToBracketX(cache, name, m, t, info, inst)
|
||||
mapTypeToBracketX(cache, name, m, t, info, idgen, inst)
|
||||
template newNodeX(kind): untyped =
|
||||
newNodeIT(kind, if t.n.isNil: info else: t.n.info, t)
|
||||
template newIdentDefs(n,t): untyped =
|
||||
|
|
@ -134,14 +137,14 @@ proc mapTypeToAstX(cache: IdentCache; t: PType; info: TLineInfo;
|
|||
for i in 1..<t.len-1:
|
||||
result.add mapTypeToAst(t[i], info)
|
||||
else:
|
||||
result = mapTypeToAstX(cache, t.lastSon, info, inst, allowRecursion)
|
||||
result = mapTypeToAstX(cache, t.lastSon, info, idgen, inst, allowRecursion)
|
||||
of tyGenericBody:
|
||||
if inst:
|
||||
result = mapTypeToAstR(t.lastSon, info)
|
||||
else:
|
||||
result = mapTypeToAst(t.lastSon, info)
|
||||
of tyAlias:
|
||||
result = mapTypeToAstX(cache, t.lastSon, info, inst, allowRecursion)
|
||||
result = mapTypeToAstX(cache, t.lastSon, info, idgen, inst, allowRecursion)
|
||||
of tyOrdinal:
|
||||
result = mapTypeToAst(t.lastSon, info)
|
||||
of tyDistinct:
|
||||
|
|
@ -169,7 +172,7 @@ proc mapTypeToAstX(cache: IdentCache; t: PType; info: TLineInfo;
|
|||
nn.add mapTypeToAst(t[0], info)
|
||||
result.add nn
|
||||
if t.n.len > 0:
|
||||
result.add objectNode(cache, t.n)
|
||||
result.add objectNode(cache, t.n, idgen)
|
||||
else:
|
||||
result.add newNodeI(nkEmpty, info)
|
||||
else:
|
||||
|
|
@ -298,15 +301,15 @@ proc mapTypeToAstX(cache: IdentCache; t: PType; info: TLineInfo;
|
|||
of tyOwned: result = mapTypeToBracket("owned", mBuiltinType, t, info)
|
||||
of tyOptDeprecated: doAssert false
|
||||
|
||||
proc opMapTypeToAst*(cache: IdentCache; t: PType; info: TLineInfo): PNode =
|
||||
result = mapTypeToAstX(cache, t, info, inst=false, allowRecursionX=true)
|
||||
proc opMapTypeToAst*(cache: IdentCache; t: PType; info: TLineInfo; idgen: IdGenerator): PNode =
|
||||
result = mapTypeToAstX(cache, t, info, idgen, inst=false, allowRecursionX=true)
|
||||
|
||||
# the "Inst" version includes generic parameters in the resulting type tree
|
||||
# and also tries to look like the corresponding Nim type declaration
|
||||
proc opMapTypeInstToAst*(cache: IdentCache; t: PType; info: TLineInfo): PNode =
|
||||
result = mapTypeToAstX(cache, t, info, inst=true, allowRecursionX=false)
|
||||
proc opMapTypeInstToAst*(cache: IdentCache; t: PType; info: TLineInfo; idgen: IdGenerator): PNode =
|
||||
result = mapTypeToAstX(cache, t, info, idgen, inst=true, allowRecursionX=false)
|
||||
|
||||
# the "Impl" version includes generic parameters in the resulting type tree
|
||||
# and also tries to look like the corresponding Nim type implementation
|
||||
proc opMapTypeImplToAst*(cache: IdentCache; t: PType; info: TLineInfo): PNode =
|
||||
result = mapTypeToAstX(cache, t, info, inst=true, allowRecursionX=true)
|
||||
proc opMapTypeImplToAst*(cache: IdentCache; t: PType; info: TLineInfo; idgen: IdGenerator): PNode =
|
||||
result = mapTypeToAstX(cache, t, info, idgen, inst=true, allowRecursionX=true)
|
||||
|
|
|
|||
|
|
@ -1118,7 +1118,7 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) =
|
|||
c.freeTemp(d)
|
||||
of mSwap:
|
||||
unused(c, n, dest)
|
||||
c.gen(lowerSwap(c.graph, n, if c.prc == nil: c.module else: c.prc.sym))
|
||||
c.gen(lowerSwap(c.graph, n, c.idgen, if c.prc == nil: c.module else: c.prc.sym))
|
||||
of mIsNil: genUnaryABC(c, n, dest, opcIsNil)
|
||||
of mParseBiggestFloat:
|
||||
if dest < 0: dest = c.getTemp(n.typ)
|
||||
|
|
@ -1819,7 +1819,7 @@ proc genVarSection(c: PCtx; n: PNode) =
|
|||
if a[i].kind == nkSym:
|
||||
if not a[i].sym.isGlobal: setSlot(c, a[i].sym)
|
||||
checkCanEval(c, a[i])
|
||||
c.gen(lowerTupleUnpacking(c.graph, a, c.getOwner))
|
||||
c.gen(lowerTupleUnpacking(c.graph, a, c.idgen, c.getOwner))
|
||||
elif a[0].kind == nkSym:
|
||||
let s = a[0].sym
|
||||
checkCanEval(c, a[0])
|
||||
|
|
@ -2235,7 +2235,7 @@ proc genProc(c: PCtx; s: PSym): int =
|
|||
s.ast[miscPos] = x
|
||||
# thanks to the jmp we can add top level statements easily and also nest
|
||||
# procs easily:
|
||||
let body = transformBody(c.graph, s, cache = not isCompileTimeProc(s))
|
||||
let body = transformBody(c.graph, c.idgen, s, cache = not isCompileTimeProc(s))
|
||||
let procStart = c.xjmp(body, opcJmp, 0)
|
||||
var p = PProc(blocks: @[], sym: s)
|
||||
let oldPrc = c.prc
|
||||
|
|
|
|||
|
|
@ -136,7 +136,8 @@ proc storeAny*(s: var string; t: PType; a: PNode; conf: ConfigRef) =
|
|||
proc loadAny(p: var JsonParser, t: PType,
|
||||
tab: var Table[BiggestInt, PNode];
|
||||
cache: IdentCache;
|
||||
conf: ConfigRef): PNode =
|
||||
conf: ConfigRef;
|
||||
idgen: IdGenerator): PNode =
|
||||
case t.kind
|
||||
of tyNone: assert false
|
||||
of tyBool:
|
||||
|
|
@ -170,7 +171,7 @@ proc loadAny(p: var JsonParser, t: PType,
|
|||
next(p)
|
||||
result = newNode(nkBracket)
|
||||
while p.kind != jsonArrayEnd and p.kind != jsonEof:
|
||||
result.add loadAny(p, t.elemType, tab, cache, conf)
|
||||
result.add loadAny(p, t.elemType, tab, cache, conf, idgen)
|
||||
if p.kind == jsonArrayEnd: next(p)
|
||||
else: raiseParseErr(p, "']' end of array expected")
|
||||
of tySequence:
|
||||
|
|
@ -182,7 +183,7 @@ proc loadAny(p: var JsonParser, t: PType,
|
|||
next(p)
|
||||
result = newNode(nkBracket)
|
||||
while p.kind != jsonArrayEnd and p.kind != jsonEof:
|
||||
result.add loadAny(p, t.elemType, tab, cache, conf)
|
||||
result.add loadAny(p, t.elemType, tab, cache, conf, idgen)
|
||||
if p.kind == jsonArrayEnd: next(p)
|
||||
else: raiseParseErr(p, "")
|
||||
else:
|
||||
|
|
@ -198,7 +199,7 @@ proc loadAny(p: var JsonParser, t: PType,
|
|||
next(p)
|
||||
if i >= t.len:
|
||||
raiseParseErr(p, "too many fields to tuple type " & typeToString(t))
|
||||
result.add loadAny(p, t[i], tab, cache, conf)
|
||||
result.add loadAny(p, t[i], tab, cache, conf, idgen)
|
||||
inc i
|
||||
if p.kind == jsonObjectEnd: next(p)
|
||||
else: raiseParseErr(p, "'}' end of object expected")
|
||||
|
|
@ -219,8 +220,8 @@ proc loadAny(p: var JsonParser, t: PType,
|
|||
if pos >= result.len:
|
||||
setLen(result.sons, pos + 1)
|
||||
let fieldNode = newNode(nkExprColonExpr)
|
||||
fieldNode.add newSymNode(newSym(skField, ident, nil, unknownLineInfo))
|
||||
fieldNode.add loadAny(p, field.typ, tab, cache, conf)
|
||||
fieldNode.add newSymNode(newSym(skField, ident, nextId(idgen), nil, unknownLineInfo))
|
||||
fieldNode.add loadAny(p, field.typ, tab, cache, conf, idgen)
|
||||
result[pos] = fieldNode
|
||||
if p.kind == jsonObjectEnd: next(p)
|
||||
else: raiseParseErr(p, "'}' end of object expected")
|
||||
|
|
@ -229,7 +230,7 @@ proc loadAny(p: var JsonParser, t: PType,
|
|||
next(p)
|
||||
result = newNode(nkCurly)
|
||||
while p.kind != jsonArrayEnd and p.kind != jsonEof:
|
||||
result.add loadAny(p, t.lastSon, tab, cache, conf)
|
||||
result.add loadAny(p, t.lastSon, tab, cache, conf, idgen)
|
||||
next(p)
|
||||
if p.kind == jsonArrayEnd: next(p)
|
||||
else: raiseParseErr(p, "']' end of array expected")
|
||||
|
|
@ -248,7 +249,7 @@ proc loadAny(p: var JsonParser, t: PType,
|
|||
if p.kind == jsonInt:
|
||||
let idx = p.getInt
|
||||
next(p)
|
||||
result = loadAny(p, t.lastSon, tab, cache, conf)
|
||||
result = loadAny(p, t.lastSon, tab, cache, conf, idgen)
|
||||
tab[idx] = result
|
||||
else: raiseParseErr(p, "index for ref type expected")
|
||||
if p.kind == jsonArrayEnd: next(p)
|
||||
|
|
@ -276,14 +277,14 @@ proc loadAny(p: var JsonParser, t: PType,
|
|||
return
|
||||
raiseParseErr(p, "float expected")
|
||||
of tyRange, tyGenericInst, tyAlias, tySink:
|
||||
result = loadAny(p, t.lastSon, tab, cache, conf)
|
||||
result = loadAny(p, t.lastSon, tab, cache, conf, idgen)
|
||||
else:
|
||||
internalError conf, "cannot marshal at compile-time " & t.typeToString
|
||||
|
||||
proc loadAny*(s: string; t: PType; cache: IdentCache; conf: ConfigRef): PNode =
|
||||
proc loadAny*(s: string; t: PType; cache: IdentCache; conf: ConfigRef; idgen: IdGenerator): PNode =
|
||||
var tab = initTable[BiggestInt, PNode]()
|
||||
var p: JsonParser
|
||||
open(p, newStringStream(s), "unknown file")
|
||||
next(p)
|
||||
result = loadAny(p, t, tab, cache, conf)
|
||||
result = loadAny(p, t, tab, cache, conf, idgen)
|
||||
close(p)
|
||||
|
|
|
|||
|
|
@ -268,7 +268,7 @@ proc registerAdditionalOps*(c: PCtx) =
|
|||
fn.typ.n[0][effectIndex] != nil:
|
||||
var list = newNodeI(nkBracket, fn.info)
|
||||
for e in fn.typ.n[0][effectIndex]:
|
||||
list.add opMapTypeInstToAst(c.cache, e.typ.skipTypes({tyRef}), e.info)
|
||||
list.add opMapTypeInstToAst(c.cache, e.typ.skipTypes({tyRef}), e.info, c.idgen)
|
||||
setResult(a, list)
|
||||
|
||||
registerCallback c, "stdlib.effecttraits.getRaisesListImpl", proc (a: VmArgs) =
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ iterator mitems*(a: var cstring): var char {.inline.} =
|
|||
yield a[i]
|
||||
inc(i)
|
||||
|
||||
iterator items*(E: typedesc[enum]): E =
|
||||
iterator items*[T: enum](E: typedesc[T]): T =
|
||||
## Iterates over the values of the enum ``E``.
|
||||
for v in low(E) .. high(E):
|
||||
yield v
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue