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