IC: next steps (#16705)
* code cleanups * refactorings for IC * more refactorings for IC * IC: attach the 'nil' type to its module * IC: refactorings and improvements * IC: progress * IC: more serialization fixes * IC: embarrassing omission * code cleanups
This commit is contained in:
parent
ef9027c290
commit
1fd4c666dc
14 changed files with 289 additions and 277 deletions
|
|
@ -223,6 +223,7 @@ type
|
||||||
nkTupleConstr # a tuple constructor
|
nkTupleConstr # a tuple constructor
|
||||||
nkModuleRef # for .rod file support: A (moduleId, itemId) pair
|
nkModuleRef # for .rod file support: A (moduleId, itemId) pair
|
||||||
nkReplayAction # for .rod file support: A replay action
|
nkReplayAction # for .rod file support: A replay action
|
||||||
|
nkNilRodNode # for .rod file support: a 'nil' PNode
|
||||||
|
|
||||||
TNodeKinds* = set[TNodeKind]
|
TNodeKinds* = set[TNodeKind]
|
||||||
|
|
||||||
|
|
@ -923,7 +924,7 @@ type
|
||||||
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*: ItemId # 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.
|
# is required by the --incremental:on mode.
|
||||||
|
|
||||||
TPair* = object
|
TPair* = object
|
||||||
key*, val*: RootRef
|
key*, val*: RootRef
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@
|
||||||
## use this representation directly in all the transformations,
|
## use this representation directly in all the transformations,
|
||||||
## it is superior.
|
## it is superior.
|
||||||
|
|
||||||
import std / [hashes, tables, strtabs, md5]
|
import std / [hashes, tables, strtabs]
|
||||||
import bitabs
|
import bitabs
|
||||||
import ".." / [ast, options]
|
import ".." / [ast, options]
|
||||||
|
|
||||||
|
|
@ -27,8 +27,6 @@ type
|
||||||
module*: LitId # 0 if it's this module
|
module*: LitId # 0 if it's this module
|
||||||
item*: int32 # same as the in-memory representation
|
item*: int32 # same as the in-memory representation
|
||||||
|
|
||||||
TypeId* = PackedItemId
|
|
||||||
|
|
||||||
const
|
const
|
||||||
nilItemId* = PackedItemId(module: LitId(0), item: -1.int32)
|
nilItemId* = PackedItemId(module: LitId(0), item: -1.int32)
|
||||||
|
|
||||||
|
|
@ -51,7 +49,7 @@ type
|
||||||
PackedSym* = object
|
PackedSym* = object
|
||||||
kind*: TSymKind
|
kind*: TSymKind
|
||||||
name*: LitId
|
name*: LitId
|
||||||
typ*: TypeId
|
typ*: PackedItemId
|
||||||
flags*: TSymFlags
|
flags*: TSymFlags
|
||||||
magic*: TMagic
|
magic*: TMagic
|
||||||
info*: PackedLineInfo
|
info*: PackedLineInfo
|
||||||
|
|
@ -74,7 +72,7 @@ type
|
||||||
callConv*: TCallingConvention
|
callConv*: TCallingConvention
|
||||||
#nodekind*: TNodeKind
|
#nodekind*: TNodeKind
|
||||||
flags*: TTypeFlags
|
flags*: TTypeFlags
|
||||||
types*: seq[TypeId]
|
types*: seq[PackedItemId]
|
||||||
n*: NodeId
|
n*: NodeId
|
||||||
methods*: seq[(int, PackedItemId)]
|
methods*: seq[(int, PackedItemId)]
|
||||||
#nodeflags*: TNodeFlags
|
#nodeflags*: TNodeFlags
|
||||||
|
|
@ -86,7 +84,7 @@ type
|
||||||
paddingAtEnd*: int16
|
paddingAtEnd*: int16
|
||||||
lockLevel*: TLockLevel # lock level as required for deadlock checking
|
lockLevel*: TLockLevel # lock level as required for deadlock checking
|
||||||
# not serialized: loc*: TLoc because it is backend-specific
|
# not serialized: loc*: TLoc because it is backend-specific
|
||||||
typeInst*: TypeId
|
typeInst*: PackedItemId
|
||||||
nonUniqueId*: int32
|
nonUniqueId*: int32
|
||||||
|
|
||||||
PackedNode* = object # 20 bytes
|
PackedNode* = object # 20 bytes
|
||||||
|
|
@ -96,17 +94,9 @@ type
|
||||||
# for kind in {nkStrLit, nkIdent, nkNumberLit}: LitId
|
# for kind in {nkStrLit, nkIdent, nkNumberLit}: LitId
|
||||||
# for kind in nkInt32Lit: direct value
|
# for kind in nkInt32Lit: direct value
|
||||||
# for non-atom kinds: the number of nodes (for easy skipping)
|
# for non-atom kinds: the number of nodes (for easy skipping)
|
||||||
typeId*: TypeId
|
typeId*: PackedItemId
|
||||||
info*: PackedLineInfo
|
info*: PackedLineInfo
|
||||||
|
|
||||||
ModulePhase* = enum
|
|
||||||
preLookup, lookedUpTopLevelStmts
|
|
||||||
|
|
||||||
GenericKey* = object
|
|
||||||
module*: int32
|
|
||||||
name*: string
|
|
||||||
types*: seq[MD5Digest] # is this a joke?
|
|
||||||
|
|
||||||
PackedTree* = object ## usually represents a full Nim module
|
PackedTree* = object ## usually represents a full Nim module
|
||||||
nodes*: seq[PackedNode]
|
nodes*: seq[PackedNode]
|
||||||
#sh*: Shared
|
#sh*: Shared
|
||||||
|
|
@ -121,18 +111,11 @@ type
|
||||||
floats*: BiTable[BiggestFloat]
|
floats*: BiTable[BiggestFloat]
|
||||||
#config*: ConfigRef
|
#config*: ConfigRef
|
||||||
|
|
||||||
proc hash*(key: GenericKey): Hash =
|
|
||||||
var h: Hash = 0
|
|
||||||
h = h !& hash(key.module)
|
|
||||||
h = h !& hash(key.name)
|
|
||||||
h = h !& hash(key.types)
|
|
||||||
result = !$h
|
|
||||||
|
|
||||||
proc `==`*(a, b: SymId): bool {.borrow.}
|
proc `==`*(a, b: SymId): bool {.borrow.}
|
||||||
proc hash*(a: SymId): Hash {.borrow.}
|
proc hash*(a: SymId): Hash {.borrow.}
|
||||||
|
|
||||||
proc `==`*(a, b: NodePos): bool {.borrow.}
|
proc `==`*(a, b: NodePos): bool {.borrow.}
|
||||||
#proc `==`*(a, b: TypeId): bool {.borrow.}
|
#proc `==`*(a, b: PackedItemId): bool {.borrow.}
|
||||||
proc `==`*(a, b: NodeId): bool {.borrow.}
|
proc `==`*(a, b: NodeId): bool {.borrow.}
|
||||||
|
|
||||||
proc newTreeFrom*(old: PackedTree): PackedTree =
|
proc newTreeFrom*(old: PackedTree): PackedTree =
|
||||||
|
|
@ -197,7 +180,7 @@ when false:
|
||||||
result = PatchPos tree.nodes.len
|
result = PatchPos tree.nodes.len
|
||||||
tree.nodes.add PackedNode(kind: kind, operand: 0, info: info)
|
tree.nodes.add PackedNode(kind: kind, operand: 0, info: info)
|
||||||
|
|
||||||
proc prepare*(tree: var PackedTree; kind: TNodeKind; flags: TNodeFlags; typeId: TypeId; info: PackedLineInfo): PatchPos =
|
proc prepare*(tree: var PackedTree; kind: TNodeKind; flags: TNodeFlags; typeId: PackedItemId; info: PackedLineInfo): PatchPos =
|
||||||
result = PatchPos tree.nodes.len
|
result = PatchPos tree.nodes.len
|
||||||
tree.nodes.add PackedNode(kind: kind, flags: flags, operand: 0, info: info,
|
tree.nodes.add PackedNode(kind: kind, flags: flags, operand: 0, info: info,
|
||||||
typeId: typeId)
|
typeId: typeId)
|
||||||
|
|
|
||||||
|
|
@ -174,16 +174,16 @@ proc addCompilerProc*(c: var PackedEncoder; m: var PackedModule; s: PSym) =
|
||||||
m.compilerProcs.add((nameId, s.itemId.item))
|
m.compilerProcs.add((nameId, s.itemId.item))
|
||||||
|
|
||||||
proc toPackedNode*(n: PNode; ir: var PackedTree; c: var PackedEncoder; m: var PackedModule)
|
proc toPackedNode*(n: PNode; ir: var PackedTree; c: var PackedEncoder; m: var PackedModule)
|
||||||
proc toPackedSym*(s: PSym; c: var PackedEncoder; m: var PackedModule): PackedItemId
|
proc storeSym*(s: PSym; c: var PackedEncoder; m: var PackedModule): PackedItemId
|
||||||
proc toPackedType(t: PType; c: var PackedEncoder; m: var PackedModule): PackedItemId
|
proc storeType(t: PType; c: var PackedEncoder; m: var PackedModule): PackedItemId
|
||||||
|
|
||||||
proc flush(c: var PackedEncoder; m: var PackedModule) =
|
proc flush(c: var PackedEncoder; m: var PackedModule) =
|
||||||
## serialize any pending types or symbols from the context
|
## serialize any pending types or symbols from the context
|
||||||
while true:
|
while true:
|
||||||
if c.pendingTypes.len > 0:
|
if c.pendingTypes.len > 0:
|
||||||
discard toPackedType(c.pendingTypes.pop, c, m)
|
discard storeType(c.pendingTypes.pop, c, m)
|
||||||
elif c.pendingSyms.len > 0:
|
elif c.pendingSyms.len > 0:
|
||||||
discard toPackedSym(c.pendingSyms.pop, c, m)
|
discard storeSym(c.pendingSyms.pop, c, m)
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
|
@ -210,16 +210,6 @@ proc safeItemId(s: PSym; c: var PackedEncoder; m: var PackedModule): PackedItemI
|
||||||
result = PackedItemId(module: toLitId(s.itemId.module.FileIndex, c, m),
|
result = PackedItemId(module: toLitId(s.itemId.module.FileIndex, c, m),
|
||||||
item: s.itemId.item)
|
item: s.itemId.item)
|
||||||
|
|
||||||
proc addModuleRef(n: PNode; ir: var PackedTree; c: var PackedEncoder; m: var PackedModule) =
|
|
||||||
## add a remote symbol reference to the tree
|
|
||||||
let info = n.info.toPackedInfo(c, m)
|
|
||||||
ir.nodes.add PackedNode(kind: nkModuleRef, operand: 3.int32, # spans 3 nodes in total
|
|
||||||
typeId: toPackedType(n.typ, c, m), info: info)
|
|
||||||
ir.nodes.add PackedNode(kind: nkInt32Lit, info: info,
|
|
||||||
operand: toLitId(n.sym.itemId.module.FileIndex, c, m).int32)
|
|
||||||
ir.nodes.add PackedNode(kind: nkInt32Lit, info: info,
|
|
||||||
operand: n.sym.itemId.item)
|
|
||||||
|
|
||||||
proc addMissing(c: var PackedEncoder; p: PSym) =
|
proc addMissing(c: var PackedEncoder; p: PSym) =
|
||||||
## consider queuing a symbol for later addition to the packed tree
|
## consider queuing a symbol for later addition to the packed tree
|
||||||
if p != nil and p.itemId.module == c.thisModule:
|
if p != nil and p.itemId.module == c.thisModule:
|
||||||
|
|
@ -241,7 +231,36 @@ template storeNode(dest, src, field) =
|
||||||
nodeId = emptyNodeId
|
nodeId = emptyNodeId
|
||||||
dest.field = nodeId
|
dest.field = nodeId
|
||||||
|
|
||||||
proc toPackedType(t: PType; c: var PackedEncoder; m: var PackedModule): PackedItemId =
|
proc storeTypeLater(t: PType; c: var PackedEncoder; m: var PackedModule): PackedItemId =
|
||||||
|
# We store multiple different trees in m.bodies. For this to work out, we
|
||||||
|
# cannot immediately store types/syms. We enqueue them instead to ensure
|
||||||
|
# we only write one tree into m.bodies after the other.
|
||||||
|
if t.isNil: return nilItemId
|
||||||
|
|
||||||
|
if t.uniqueId.module != c.thisModule:
|
||||||
|
# XXX Assert here that it already was serialized in the foreign module!
|
||||||
|
# it is a foreign type:
|
||||||
|
assert t.uniqueId.module >= 0
|
||||||
|
assert t.uniqueId.item > 0
|
||||||
|
return PackedItemId(module: toLitId(t.uniqueId.module.FileIndex, c, m), item: t.uniqueId.item)
|
||||||
|
assert t.itemId.module >= 0
|
||||||
|
assert t.uniqueId.item > 0
|
||||||
|
result = PackedItemId(module: toLitId(t.itemId.module.FileIndex, c, m), item: t.uniqueId.item)
|
||||||
|
addMissing(c, t)
|
||||||
|
|
||||||
|
proc storeSymLater(s: PSym; c: var PackedEncoder; m: var PackedModule): PackedItemId =
|
||||||
|
if s.isNil: return nilItemId
|
||||||
|
assert s.itemId.module >= 0
|
||||||
|
if s.itemId.module != c.thisModule:
|
||||||
|
# XXX Assert here that it already was serialized in the foreign module!
|
||||||
|
# it is a foreign symbol:
|
||||||
|
assert s.itemId.module >= 0
|
||||||
|
return PackedItemId(module: toLitId(s.itemId.module.FileIndex, c, m), item: s.itemId.item)
|
||||||
|
assert s.itemId.module >= 0
|
||||||
|
result = PackedItemId(module: toLitId(s.itemId.module.FileIndex, c, m), item: s.itemId.item)
|
||||||
|
addMissing(c, s)
|
||||||
|
|
||||||
|
proc storeType(t: PType; c: var PackedEncoder; m: var PackedModule): PackedItemId =
|
||||||
## serialize a ptype
|
## serialize a ptype
|
||||||
if t.isNil: return nilItemId
|
if t.isNil: return nilItemId
|
||||||
|
|
||||||
|
|
@ -249,6 +268,7 @@ proc toPackedType(t: PType; c: var PackedEncoder; m: var PackedModule): PackedIt
|
||||||
# XXX Assert here that it already was serialized in the foreign module!
|
# XXX Assert here that it already was serialized in the foreign module!
|
||||||
# it is a foreign type:
|
# it is a foreign type:
|
||||||
assert t.uniqueId.module >= 0
|
assert t.uniqueId.module >= 0
|
||||||
|
assert t.uniqueId.item > 0
|
||||||
return PackedItemId(module: toLitId(t.uniqueId.module.FileIndex, c, m), item: t.uniqueId.item)
|
return PackedItemId(module: toLitId(t.uniqueId.module.FileIndex, c, m), item: t.uniqueId.item)
|
||||||
|
|
||||||
if not c.typeMarker.containsOrIncl(t.uniqueId.item):
|
if not c.typeMarker.containsOrIncl(t.uniqueId.item):
|
||||||
|
|
@ -264,9 +284,9 @@ proc toPackedType(t: PType; c: var PackedEncoder; m: var PackedModule): PackedIt
|
||||||
c.addMissing s
|
c.addMissing s
|
||||||
p.attachedOps[op] = s.safeItemId(c, m)
|
p.attachedOps[op] = s.safeItemId(c, m)
|
||||||
|
|
||||||
p.typeInst = t.typeInst.toPackedType(c, m)
|
p.typeInst = t.typeInst.storeType(c, m)
|
||||||
for kid in items t.sons:
|
for kid in items t.sons:
|
||||||
p.types.add kid.toPackedType(c, m)
|
p.types.add kid.storeType(c, m)
|
||||||
for i, s in items t.methods:
|
for i, s in items t.methods:
|
||||||
c.addMissing s
|
c.addMissing s
|
||||||
p.methods.add (i, s.safeItemId(c, m))
|
p.methods.add (i, s.safeItemId(c, m))
|
||||||
|
|
@ -279,6 +299,7 @@ proc toPackedType(t: PType; c: var PackedEncoder; m: var PackedModule): PackedIt
|
||||||
m.sh.types[t.uniqueId.item] = p
|
m.sh.types[t.uniqueId.item] = p
|
||||||
|
|
||||||
assert t.itemId.module >= 0
|
assert t.itemId.module >= 0
|
||||||
|
assert t.uniqueId.item > 0
|
||||||
result = PackedItemId(module: toLitId(t.itemId.module.FileIndex, c, m), item: t.uniqueId.item)
|
result = PackedItemId(module: toLitId(t.itemId.module.FileIndex, c, m), item: t.uniqueId.item)
|
||||||
|
|
||||||
proc toPackedLib(l: PLib; c: var PackedEncoder; m: var PackedModule): PackedLib =
|
proc toPackedLib(l: PLib; c: var PackedEncoder; m: var PackedModule): PackedLib =
|
||||||
|
|
@ -290,7 +311,7 @@ proc toPackedLib(l: PLib; c: var PackedEncoder; m: var PackedModule): PackedLib
|
||||||
result.name = toLitId($l.name, m)
|
result.name = toLitId($l.name, m)
|
||||||
storeNode(result, l, path)
|
storeNode(result, l, path)
|
||||||
|
|
||||||
proc toPackedSym*(s: PSym; c: var PackedEncoder; m: var PackedModule): PackedItemId =
|
proc storeSym*(s: PSym; c: var PackedEncoder; m: var PackedModule): PackedItemId =
|
||||||
## serialize a psym
|
## serialize a psym
|
||||||
if s.isNil: return nilItemId
|
if s.isNil: return nilItemId
|
||||||
|
|
||||||
|
|
@ -321,7 +342,7 @@ proc toPackedSym*(s: PSym; c: var PackedEncoder; m: var PackedModule): PackedIte
|
||||||
|
|
||||||
p.externalName = toLitId(if s.loc.r.isNil: "" else: $s.loc.r, m)
|
p.externalName = toLitId(if s.loc.r.isNil: "" else: $s.loc.r, m)
|
||||||
c.addMissing s.typ
|
c.addMissing s.typ
|
||||||
p.typ = s.typ.toPackedType(c, m)
|
p.typ = s.typ.storeType(c, m)
|
||||||
c.addMissing s.owner
|
c.addMissing s.owner
|
||||||
p.owner = s.owner.safeItemId(c, m)
|
p.owner = s.owner.safeItemId(c, m)
|
||||||
p.annex = toPackedLib(s.annex, c, m)
|
p.annex = toPackedLib(s.annex, c, m)
|
||||||
|
|
@ -334,70 +355,77 @@ proc toPackedSym*(s: PSym; c: var PackedEncoder; m: var PackedModule): PackedIte
|
||||||
assert s.itemId.module >= 0
|
assert s.itemId.module >= 0
|
||||||
result = PackedItemId(module: toLitId(s.itemId.module.FileIndex, c, m), item: s.itemId.item)
|
result = PackedItemId(module: toLitId(s.itemId.module.FileIndex, c, m), item: s.itemId.item)
|
||||||
|
|
||||||
proc toSymNode(n: PNode; ir: var PackedTree; c: var PackedEncoder; m: var PackedModule) =
|
proc addModuleRef(n: PNode; ir: var PackedTree; c: var PackedEncoder; m: var PackedModule) =
|
||||||
## store a local or remote psym reference in the tree
|
## add a remote symbol reference to the tree
|
||||||
assert n.kind == nkSym
|
let info = n.info.toPackedInfo(c, m)
|
||||||
template s: PSym = n.sym
|
ir.nodes.add PackedNode(kind: nkModuleRef, operand: 3.int32, # spans 3 nodes in total
|
||||||
let id = s.toPackedSym(c, m).item
|
typeId: storeTypeLater(n.typ, c, m), info: info)
|
||||||
if s.itemId.module == c.thisModule:
|
ir.nodes.add PackedNode(kind: nkInt32Lit, info: info,
|
||||||
# it is a symbol that belongs to the module we're currently
|
operand: toLitId(n.sym.itemId.module.FileIndex, c, m).int32)
|
||||||
# packing:
|
ir.nodes.add PackedNode(kind: nkInt32Lit, info: info,
|
||||||
ir.addSym(id, toPackedInfo(n.info, c, m))
|
operand: n.sym.itemId.item)
|
||||||
else:
|
|
||||||
# store it as an external module reference:
|
|
||||||
addModuleRef(n, ir, c, m)
|
|
||||||
|
|
||||||
proc toPackedNode*(n: PNode; ir: var PackedTree; c: var PackedEncoder; m: var PackedModule) =
|
proc toPackedNode*(n: PNode; ir: var PackedTree; c: var PackedEncoder; m: var PackedModule) =
|
||||||
## serialize a node into the tree
|
## serialize a node into the tree
|
||||||
if n.isNil: return
|
if n == nil:
|
||||||
|
ir.nodes.add PackedNode(kind: nkNilRodNode, flags: {}, operand: 1)
|
||||||
|
return
|
||||||
let info = toPackedInfo(n.info, c, m)
|
let info = toPackedInfo(n.info, c, m)
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkNone, nkEmpty, nkNilLit, nkType:
|
of nkNone, nkEmpty, nkNilLit, nkType:
|
||||||
ir.nodes.add PackedNode(kind: n.kind, flags: n.flags, operand: 0,
|
ir.nodes.add PackedNode(kind: n.kind, flags: n.flags, operand: 0,
|
||||||
typeId: toPackedType(n.typ, c, m), info: info)
|
typeId: storeTypeLater(n.typ, c, m), info: info)
|
||||||
of nkIdent:
|
of nkIdent:
|
||||||
ir.nodes.add PackedNode(kind: n.kind, flags: n.flags,
|
ir.nodes.add PackedNode(kind: n.kind, flags: n.flags,
|
||||||
operand: int32 getOrIncl(m.sh.strings, n.ident.s),
|
operand: int32 getOrIncl(m.sh.strings, n.ident.s),
|
||||||
typeId: toPackedType(n.typ, c, m), info: info)
|
typeId: storeTypeLater(n.typ, c, m), info: info)
|
||||||
of nkSym:
|
of nkSym:
|
||||||
toSymNode(n, ir, c, m)
|
if n.sym.itemId.module == c.thisModule:
|
||||||
|
# it is a symbol that belongs to the module we're currently
|
||||||
|
# packing:
|
||||||
|
let id = n.sym.storeSymLater(c, m).item
|
||||||
|
ir.nodes.add PackedNode(kind: nkSym, flags: n.flags, operand: id,
|
||||||
|
typeId: storeTypeLater(n.typ, c, m), info: info)
|
||||||
|
else:
|
||||||
|
# store it as an external module reference:
|
||||||
|
addModuleRef(n, ir, c, m)
|
||||||
of directIntLit:
|
of directIntLit:
|
||||||
ir.nodes.add PackedNode(kind: n.kind, flags: n.flags,
|
ir.nodes.add PackedNode(kind: n.kind, flags: n.flags,
|
||||||
operand: int32(n.intVal),
|
operand: int32(n.intVal),
|
||||||
typeId: toPackedType(n.typ, c, m), info: info)
|
typeId: storeTypeLater(n.typ, c, m), info: info)
|
||||||
of externIntLit:
|
of externIntLit:
|
||||||
ir.nodes.add PackedNode(kind: n.kind, flags: n.flags,
|
ir.nodes.add PackedNode(kind: n.kind, flags: n.flags,
|
||||||
operand: int32 getOrIncl(m.sh.integers, n.intVal),
|
operand: int32 getOrIncl(m.sh.integers, n.intVal),
|
||||||
typeId: toPackedType(n.typ, c, m), info: info)
|
typeId: storeTypeLater(n.typ, c, m), info: info)
|
||||||
of nkStrLit..nkTripleStrLit:
|
of nkStrLit..nkTripleStrLit:
|
||||||
ir.nodes.add PackedNode(kind: n.kind, flags: n.flags,
|
ir.nodes.add PackedNode(kind: n.kind, flags: n.flags,
|
||||||
operand: int32 getOrIncl(m.sh.strings, n.strVal),
|
operand: int32 getOrIncl(m.sh.strings, n.strVal),
|
||||||
typeId: toPackedType(n.typ, c, m), info: info)
|
typeId: storeTypeLater(n.typ, c, m), info: info)
|
||||||
of nkFloatLit..nkFloat128Lit:
|
of nkFloatLit..nkFloat128Lit:
|
||||||
ir.nodes.add PackedNode(kind: n.kind, flags: n.flags,
|
ir.nodes.add PackedNode(kind: n.kind, flags: n.flags,
|
||||||
operand: int32 getOrIncl(m.sh.floats, n.floatVal),
|
operand: int32 getOrIncl(m.sh.floats, n.floatVal),
|
||||||
typeId: toPackedType(n.typ, c, m), info: info)
|
typeId: storeTypeLater(n.typ, c, m), info: info)
|
||||||
else:
|
else:
|
||||||
let patchPos = ir.prepare(n.kind, n.flags,
|
let patchPos = ir.prepare(n.kind, n.flags,
|
||||||
toPackedType(n.typ, c, m), info)
|
storeTypeLater(n.typ, c, m), info)
|
||||||
for i in 0..<n.len:
|
for i in 0..<n.len:
|
||||||
toPackedNode(n[i], ir, c, m)
|
toPackedNode(n[i], ir, c, m)
|
||||||
ir.patch patchPos
|
ir.patch patchPos
|
||||||
|
|
||||||
when false:
|
|
||||||
ir.flush c # flush any pending types and symbols
|
|
||||||
|
|
||||||
proc addPragmaComputation*(c: var PackedEncoder; m: var PackedModule; n: PNode) =
|
proc addPragmaComputation*(c: var PackedEncoder; m: var PackedModule; n: PNode) =
|
||||||
toPackedNode(n, m.toReplay, c, m)
|
toPackedNode(n, m.toReplay, c, m)
|
||||||
|
|
||||||
proc toPackedNodeIgnoreProcDefs*(n: PNode, encoder: var PackedEncoder; m: var PackedModule) =
|
proc toPackedNodeIgnoreProcDefs(n: PNode, encoder: var PackedEncoder; m: var PackedModule) =
|
||||||
case n.kind
|
case n.kind
|
||||||
of routineDefs:
|
of routineDefs:
|
||||||
# we serialize n[namePos].sym instead
|
# we serialize n[namePos].sym instead
|
||||||
if n[namePos].kind == nkSym:
|
if n[namePos].kind == nkSym:
|
||||||
discard toPackedSym(n[namePos].sym, encoder, m)
|
discard storeSym(n[namePos].sym, encoder, m)
|
||||||
else:
|
else:
|
||||||
toPackedNode(n, m.topLevel, encoder, m)
|
toPackedNode(n, m.topLevel, encoder, m)
|
||||||
|
of nkStmtList, nkStmtListExpr:
|
||||||
|
for it in n:
|
||||||
|
toPackedNodeIgnoreProcDefs(it, encoder, m)
|
||||||
else:
|
else:
|
||||||
toPackedNode(n, m.topLevel, encoder, m)
|
toPackedNode(n, m.topLevel, encoder, m)
|
||||||
|
|
||||||
|
|
@ -549,7 +577,7 @@ type
|
||||||
type
|
type
|
||||||
ModuleStatus* = enum
|
ModuleStatus* = enum
|
||||||
undefined,
|
undefined,
|
||||||
storing,
|
storing, # state is strictly for stress-testing purposes
|
||||||
loading,
|
loading,
|
||||||
loaded,
|
loaded,
|
||||||
outdated
|
outdated
|
||||||
|
|
@ -586,6 +614,10 @@ proc translateLineInfo(c: var PackedDecoder; g: var PackedModuleGraph; thisModul
|
||||||
proc loadNodes(c: var PackedDecoder; g: var PackedModuleGraph; thisModule: int;
|
proc loadNodes(c: var PackedDecoder; g: var PackedModuleGraph; thisModule: int;
|
||||||
tree: PackedTree; n: NodePos): PNode =
|
tree: PackedTree; n: NodePos): PNode =
|
||||||
let k = n.kind
|
let k = n.kind
|
||||||
|
if k == nkNilRodNode:
|
||||||
|
return nil
|
||||||
|
when false:
|
||||||
|
echo "loading node ", c.config $ translateLineInfo(c, g, thisModule, n.info)
|
||||||
result = newNodeIT(k, translateLineInfo(c, g, thisModule, n.info),
|
result = newNodeIT(k, translateLineInfo(c, g, thisModule, n.info),
|
||||||
loadType(c, g, thisModule, n.typ))
|
loadType(c, g, thisModule, n.typ))
|
||||||
result.flags = n.flags
|
result.flags = n.flags
|
||||||
|
|
@ -613,7 +645,7 @@ proc loadNodes(c: var PackedDecoder; g: var PackedModuleGraph; thisModule: int;
|
||||||
result.sym = loadSym(c, g, thisModule, PackedItemId(module: n1.litId, item: tree.nodes[n2.int].operand))
|
result.sym = loadSym(c, g, thisModule, PackedItemId(module: n1.litId, item: tree.nodes[n2.int].operand))
|
||||||
else:
|
else:
|
||||||
for n0 in sonsReadonly(tree, n):
|
for n0 in sonsReadonly(tree, n):
|
||||||
result.add loadNodes(c, g, thisModule, tree, n0)
|
result.addAllowNil loadNodes(c, g, thisModule, tree, n0)
|
||||||
|
|
||||||
proc loadProcHeader(c: var PackedDecoder; g: var PackedModuleGraph; thisModule: int;
|
proc loadProcHeader(c: var PackedDecoder; g: var PackedModuleGraph; thisModule: int;
|
||||||
tree: PackedTree; n: NodePos): PNode =
|
tree: PackedTree; n: NodePos): PNode =
|
||||||
|
|
@ -705,13 +737,11 @@ proc loadSym(c: var PackedDecoder; g: var PackedModuleGraph; thisModule: int; s:
|
||||||
setLen g[si].syms, g[si].fromDisk.sh.syms.len
|
setLen g[si].syms, g[si].fromDisk.sh.syms.len
|
||||||
|
|
||||||
if g[si].syms[s.item] == nil:
|
if g[si].syms[s.item] == nil:
|
||||||
let packed = addr(g[si].fromDisk.sh.syms[s.item])
|
if g[si].fromDisk.sh.syms[s.item].kind != skModule:
|
||||||
|
result = symHeaderFromPacked(c, g, g[si].fromDisk.sh.syms[s.item], si, s.item)
|
||||||
if packed.kind != skModule:
|
|
||||||
result = symHeaderFromPacked(c, g, packed[], si, s.item)
|
|
||||||
# store it here early on, so that recursions work properly:
|
# store it here early on, so that recursions work properly:
|
||||||
g[si].syms[s.item] = result
|
g[si].syms[s.item] = result
|
||||||
symBodyFromPacked(c, g, packed[], si, s.item, result)
|
symBodyFromPacked(c, g, g[si].fromDisk.sh.syms[s.item], si, s.item, result)
|
||||||
else:
|
else:
|
||||||
result = g[si].module
|
result = g[si].module
|
||||||
assert result != nil
|
assert result != nil
|
||||||
|
|
@ -724,7 +754,8 @@ proc typeHeaderFromPacked(c: var PackedDecoder; g: var PackedModuleGraph;
|
||||||
result = PType(itemId: ItemId(module: si, item: t.nonUniqueId), kind: t.kind,
|
result = PType(itemId: ItemId(module: si, item: t.nonUniqueId), kind: t.kind,
|
||||||
flags: t.flags, size: t.size, align: t.align,
|
flags: t.flags, size: t.size, align: t.align,
|
||||||
paddingAtEnd: t.paddingAtEnd, lockLevel: t.lockLevel,
|
paddingAtEnd: t.paddingAtEnd, lockLevel: t.lockLevel,
|
||||||
uniqueId: ItemId(module: si, item: item))
|
uniqueId: ItemId(module: si, item: item),
|
||||||
|
callConv: t.callConv)
|
||||||
|
|
||||||
proc typeBodyFromPacked(c: var PackedDecoder; g: var PackedModuleGraph;
|
proc typeBodyFromPacked(c: var PackedDecoder; g: var PackedModuleGraph;
|
||||||
t: PackedType; si, item: int32; result: PType) =
|
t: PackedType; si, item: int32; result: PType) =
|
||||||
|
|
@ -745,18 +776,20 @@ proc loadType(c: var PackedDecoder; g: var PackedModuleGraph; thisModule: int; t
|
||||||
else:
|
else:
|
||||||
let si = moduleIndex(c, g, thisModule, t)
|
let si = moduleIndex(c, g, thisModule, t)
|
||||||
assert g[si].status in {loaded, storing}
|
assert g[si].status in {loaded, storing}
|
||||||
|
assert t.item > 0
|
||||||
|
|
||||||
if not g[si].typesInit:
|
if not g[si].typesInit:
|
||||||
g[si].typesInit = true
|
g[si].typesInit = true
|
||||||
setLen g[si].types, g[si].fromDisk.sh.types.len
|
setLen g[si].types, g[si].fromDisk.sh.types.len
|
||||||
|
|
||||||
if g[si].types[t.item] == nil:
|
if g[si].types[t.item] == nil:
|
||||||
let packed = addr(g[si].fromDisk.sh.types[t.item])
|
result = typeHeaderFromPacked(c, g, g[si].fromDisk.sh.types[t.item], si, t.item)
|
||||||
result = typeHeaderFromPacked(c, g, packed[], si, t.item)
|
|
||||||
# store it here early on, so that recursions work properly:
|
# store it here early on, so that recursions work properly:
|
||||||
g[si].types[t.item] = result
|
g[si].types[t.item] = result
|
||||||
typeBodyFromPacked(c, g, packed[], si, t.item, result)
|
typeBodyFromPacked(c, g, g[si].fromDisk.sh.types[t.item], si, t.item, result)
|
||||||
else:
|
else:
|
||||||
result = g[si].types[t.item]
|
result = g[si].types[t.item]
|
||||||
|
assert result.itemId.item > 0
|
||||||
|
|
||||||
proc setupLookupTables(g: var PackedModuleGraph; conf: ConfigRef; cache: IdentCache;
|
proc setupLookupTables(g: var PackedModuleGraph; conf: ConfigRef; cache: IdentCache;
|
||||||
fileIdx: FileIndex; m: var LoadedModule) =
|
fileIdx: FileIndex; m: var LoadedModule) =
|
||||||
|
|
@ -794,6 +827,7 @@ proc loadToReplayNodes(g: var PackedModuleGraph; conf: ConfigRef; cache: IdentCa
|
||||||
|
|
||||||
proc needsRecompile(g: var PackedModuleGraph; conf: ConfigRef; cache: IdentCache;
|
proc needsRecompile(g: var PackedModuleGraph; conf: ConfigRef; cache: IdentCache;
|
||||||
fileIdx: FileIndex): bool =
|
fileIdx: FileIndex): bool =
|
||||||
|
# Does the file belong to the fileIdx need to be recompiled?
|
||||||
let m = int(fileIdx)
|
let m = int(fileIdx)
|
||||||
if m >= g.len:
|
if m >= g.len:
|
||||||
g.setLen(m+1)
|
g.setLen(m+1)
|
||||||
|
|
@ -822,6 +856,7 @@ proc needsRecompile(g: var PackedModuleGraph; conf: ConfigRef; cache: IdentCache
|
||||||
g[m].status = outdated
|
g[m].status = outdated
|
||||||
result = true
|
result = true
|
||||||
of loading, loaded:
|
of loading, loaded:
|
||||||
|
# For loading: Assume no recompile is required.
|
||||||
result = false
|
result = false
|
||||||
of outdated, storing:
|
of outdated, storing:
|
||||||
result = true
|
result = true
|
||||||
|
|
@ -857,6 +892,19 @@ proc loadProcBody*(config: ConfigRef, cache: IdentCache;
|
||||||
assert pos != emptyNodeId
|
assert pos != emptyNodeId
|
||||||
result = loadProcBody(decoder, g, mId, g[mId].fromDisk.bodies, NodePos pos)
|
result = loadProcBody(decoder, g, mId, g[mId].fromDisk.bodies, NodePos pos)
|
||||||
|
|
||||||
|
proc checkForHoles(m: PackedModule; config: ConfigRef; moduleId: int) =
|
||||||
|
var bugs = 0
|
||||||
|
for i in 1 .. high(m.sh.syms):
|
||||||
|
if m.sh.syms[i].kind == skUnknown:
|
||||||
|
echo "EMPTY ID ", i, " module ", moduleId, " ", toFullPath(config, FileIndex(moduleId))
|
||||||
|
inc bugs
|
||||||
|
assert bugs == 0
|
||||||
|
when false:
|
||||||
|
var nones = 0
|
||||||
|
for i in 1 .. high(m.sh.types):
|
||||||
|
inc nones, m.sh.types[i].kind == tyNone
|
||||||
|
assert nones < 1
|
||||||
|
|
||||||
proc simulateLoadedModule*(g: var PackedModuleGraph; conf: ConfigRef; cache: IdentCache;
|
proc simulateLoadedModule*(g: var PackedModuleGraph; conf: ConfigRef; cache: IdentCache;
|
||||||
moduleSym: PSym; m: PackedModule) =
|
moduleSym: PSym; m: PackedModule) =
|
||||||
# For now only used for heavy debugging. In the future we could use this to reduce the
|
# For now only used for heavy debugging. In the future we could use this to reduce the
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,6 @@ export createMagic
|
||||||
|
|
||||||
proc nilOrSysInt*(g: ModuleGraph): PType = g.sysTypes[tyInt]
|
proc nilOrSysInt*(g: ModuleGraph): PType = g.sysTypes[tyInt]
|
||||||
|
|
||||||
proc registerSysType*(g: ModuleGraph; t: PType) =
|
|
||||||
if g.sysTypes[t.kind] == nil: g.sysTypes[t.kind] = t
|
|
||||||
|
|
||||||
proc newSysType(g: ModuleGraph; kind: TTypeKind, size: int): PType =
|
proc newSysType(g: ModuleGraph; kind: TTypeKind, size: int): PType =
|
||||||
result = newType(kind, nextTypeId(g.idgen), g.systemModule)
|
result = newType(kind, nextTypeId(g.idgen), g.systemModule)
|
||||||
result.size = size
|
result.size = size
|
||||||
|
|
@ -88,24 +85,6 @@ proc resetSysTypes*(g: ModuleGraph) =
|
||||||
for i in low(g.sysTypes)..high(g.sysTypes):
|
for i in low(g.sysTypes)..high(g.sysTypes):
|
||||||
g.sysTypes[i] = nil
|
g.sysTypes[i] = nil
|
||||||
|
|
||||||
for i in low(g.intTypeCache)..high(g.intTypeCache):
|
|
||||||
g.intTypeCache[i] = nil
|
|
||||||
|
|
||||||
proc getIntLitType*(g: ModuleGraph; literal: PNode): PType =
|
|
||||||
# we cache some common integer literal types for performance:
|
|
||||||
let value = literal.intVal
|
|
||||||
if value >= low(g.intTypeCache) and value <= high(g.intTypeCache):
|
|
||||||
result = g.intTypeCache[value.int]
|
|
||||||
if result == nil:
|
|
||||||
let ti = getSysType(g, literal.info, tyInt)
|
|
||||||
result = copyType(ti, nextTypeId(g.idgen), ti.owner)
|
|
||||||
result.n = literal
|
|
||||||
g.intTypeCache[value.int] = result
|
|
||||||
else:
|
|
||||||
let ti = getSysType(g, literal.info, tyInt)
|
|
||||||
result = copyType(ti, nextTypeId(g.idgen), ti.owner)
|
|
||||||
result.n = literal
|
|
||||||
|
|
||||||
proc getFloatLitType*(g: ModuleGraph; literal: PNode): PType =
|
proc getFloatLitType*(g: ModuleGraph; literal: PNode): PType =
|
||||||
# for now we do not cache these:
|
# for now we do not cache these:
|
||||||
result = newSysType(g, tyFloat, size=8)
|
result = newSysType(g, tyFloat, size=8)
|
||||||
|
|
@ -125,35 +104,6 @@ proc addSonSkipIntLit*(father, son: PType; id: IdGenerator) =
|
||||||
father.sons.add(s)
|
father.sons.add(s)
|
||||||
propagateToOwner(father, s)
|
propagateToOwner(father, s)
|
||||||
|
|
||||||
proc setIntLitType*(g: ModuleGraph; result: PNode) =
|
|
||||||
let i = result.intVal
|
|
||||||
case g.config.target.intSize
|
|
||||||
of 8: result.typ = getIntLitType(g, result)
|
|
||||||
of 4:
|
|
||||||
if i >= low(int32) and i <= high(int32):
|
|
||||||
result.typ = getIntLitType(g, result)
|
|
||||||
else:
|
|
||||||
result.typ = getSysType(g, result.info, tyInt64)
|
|
||||||
of 2:
|
|
||||||
if i >= low(int16) and i <= high(int16):
|
|
||||||
result.typ = getIntLitType(g, result)
|
|
||||||
elif i >= low(int32) and i <= high(int32):
|
|
||||||
result.typ = getSysType(g, result.info, tyInt32)
|
|
||||||
else:
|
|
||||||
result.typ = getSysType(g, result.info, tyInt64)
|
|
||||||
of 1:
|
|
||||||
# 8 bit CPUs are insane ...
|
|
||||||
if i >= low(int8) and i <= high(int8):
|
|
||||||
result.typ = getIntLitType(g, result)
|
|
||||||
elif i >= low(int16) and i <= high(int16):
|
|
||||||
result.typ = getSysType(g, result.info, tyInt16)
|
|
||||||
elif i >= low(int32) and i <= high(int32):
|
|
||||||
result.typ = getSysType(g, result.info, tyInt32)
|
|
||||||
else:
|
|
||||||
result.typ = getSysType(g, result.info, tyInt64)
|
|
||||||
else:
|
|
||||||
internalError(g.config, result.info, "invalid int size")
|
|
||||||
|
|
||||||
proc getCompilerProc*(g: ModuleGraph; name: string): PSym =
|
proc getCompilerProc*(g: ModuleGraph; name: string): PSym =
|
||||||
let ident = getIdent(g.cache, name)
|
let ident = getIdent(g.cache, name)
|
||||||
result = strTableGet(g.compilerprocs, ident)
|
result = strTableGet(g.compilerprocs, ident)
|
||||||
|
|
|
||||||
|
|
@ -55,16 +55,14 @@ type
|
||||||
compilerprocs*: TStrTable
|
compilerprocs*: TStrTable
|
||||||
exposed*: TStrTable
|
exposed*: TStrTable
|
||||||
packageTypes*: TStrTable
|
packageTypes*: TStrTable
|
||||||
intTypeCache*: array[-5..64, PType]
|
|
||||||
opContains*, opNot*: PSym
|
|
||||||
emptyNode*: PNode
|
emptyNode*: PNode
|
||||||
canonTypes*: Table[SigHash, PType]
|
canonTypes*: Table[SigHash, PType]
|
||||||
symBodyHashes*: Table[int, SigHash] # symId to digest mapping
|
symBodyHashes*: Table[int, SigHash] # symId to digest mapping
|
||||||
importModuleCallback*: proc (graph: ModuleGraph; m: PSym, fileIdx: FileIndex): PSym {.nimcall.}
|
importModuleCallback*: proc (graph: ModuleGraph; m: PSym, fileIdx: FileIndex): PSym {.nimcall.}
|
||||||
includeFileCallback*: proc (graph: ModuleGraph; m: PSym, fileIdx: FileIndex): PNode {.nimcall.}
|
includeFileCallback*: proc (graph: ModuleGraph; m: PSym, fileIdx: FileIndex): PNode {.nimcall.}
|
||||||
cacheSeqs*: Table[string, PNode] # state that is shared to support the 'macrocache' API
|
cacheSeqs*: Table[string, PNode] # state that is shared to support the 'macrocache' API; IC: implemented
|
||||||
cacheCounters*: Table[string, BiggestInt]
|
cacheCounters*: Table[string, BiggestInt] # IC: implemented
|
||||||
cacheTables*: Table[string, BTree[string, PNode]]
|
cacheTables*: Table[string, BTree[string, PNode]] # IC: implemented
|
||||||
passes*: seq[TPass]
|
passes*: seq[TPass]
|
||||||
onDefinition*: proc (graph: ModuleGraph; s: PSym; info: TLineInfo) {.nimcall.}
|
onDefinition*: proc (graph: ModuleGraph; s: PSym; info: TLineInfo) {.nimcall.}
|
||||||
onDefinitionResolveForward*: proc (graph: ModuleGraph; s: PSym; info: TLineInfo) {.nimcall.}
|
onDefinitionResolveForward*: proc (graph: ModuleGraph; s: PSym; info: TLineInfo) {.nimcall.}
|
||||||
|
|
@ -245,6 +243,8 @@ proc registerModule*(g: ModuleGraph; m: PSym) =
|
||||||
|
|
||||||
proc newModuleGraph*(cache: IdentCache; config: ConfigRef): ModuleGraph =
|
proc newModuleGraph*(cache: IdentCache; config: ConfigRef): ModuleGraph =
|
||||||
result = ModuleGraph()
|
result = ModuleGraph()
|
||||||
|
# A module ID of -1 means that the symbol is not attached to a module at all,
|
||||||
|
# but to the module graph:
|
||||||
result.idgen = IdGenerator(module: -1'i32, symId: 0'i32, typeId: 0'i32)
|
result.idgen = IdGenerator(module: -1'i32, symId: 0'i32, typeId: 0'i32)
|
||||||
initStrTable(result.packageSyms)
|
initStrTable(result.packageSyms)
|
||||||
result.deps = initIntSet()
|
result.deps = initIntSet()
|
||||||
|
|
@ -259,8 +259,6 @@ proc newModuleGraph*(cache: IdentCache; config: ConfigRef): ModuleGraph =
|
||||||
initStrTable(result.compilerprocs)
|
initStrTable(result.compilerprocs)
|
||||||
initStrTable(result.exposed)
|
initStrTable(result.exposed)
|
||||||
initStrTable(result.packageTypes)
|
initStrTable(result.packageTypes)
|
||||||
result.opNot = createMagic(result, "not", mNot)
|
|
||||||
result.opContains = createMagic(result, "contains", mInSet)
|
|
||||||
result.emptyNode = newNode(nkEmpty)
|
result.emptyNode = newNode(nkEmpty)
|
||||||
result.cacheSeqs = initTable[string, PNode]()
|
result.cacheSeqs = initTable[string, PNode]()
|
||||||
result.cacheCounters = initTable[string, BiggestInt]()
|
result.cacheCounters = initTable[string, BiggestInt]()
|
||||||
|
|
|
||||||
|
|
@ -505,6 +505,8 @@ proc addCodeForGenerics(c: PContext, n: PNode) =
|
||||||
proc myOpen(graph: ModuleGraph; module: PSym; idgen: IdGenerator): 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
|
c.idgen = idgen
|
||||||
|
c.enforceVoidContext = newType(tyTyped, nextTypeId(idgen), nil)
|
||||||
|
|
||||||
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
|
||||||
|
|
|
||||||
|
|
@ -93,6 +93,9 @@ type
|
||||||
imports*: seq[ImportedModule] # scope for all imported symbols
|
imports*: seq[ImportedModule] # scope for all imported symbols
|
||||||
topLevelScope*: PScope # scope for all top-level symbols
|
topLevelScope*: PScope # scope for all top-level symbols
|
||||||
p*: PProcCon # procedure context
|
p*: PProcCon # procedure context
|
||||||
|
intTypeCache*: array[-5..32, PType] # cache some common integer types
|
||||||
|
# to avoid type allocations
|
||||||
|
nilTypeCache*: PType
|
||||||
matchedConcept*: ptr TMatchedConcept # the current concept being matched
|
matchedConcept*: ptr TMatchedConcept # the current concept being matched
|
||||||
friendModules*: seq[PSym] # friend modules; may access private data;
|
friendModules*: seq[PSym] # friend modules; may access private data;
|
||||||
# this is used so that generic instantiations
|
# this is used so that generic instantiations
|
||||||
|
|
@ -149,17 +152,56 @@ type
|
||||||
isAmbiguous*: bool # little hack
|
isAmbiguous*: bool # little hack
|
||||||
features*: set[Feature]
|
features*: set[Feature]
|
||||||
inTypeContext*: int
|
inTypeContext*: int
|
||||||
typesWithOps*: seq[(PType, PType)] #\
|
|
||||||
# We need to instantiate the type bound ops lazily after
|
|
||||||
# the generic type has been constructed completely. See
|
|
||||||
# tests/destructor/topttree.nim for an example that
|
|
||||||
# would otherwise fail.
|
|
||||||
unusedImports*: seq[(PSym, TLineInfo)]
|
unusedImports*: seq[(PSym, TLineInfo)]
|
||||||
exportIndirections*: HashSet[(int, int)]
|
exportIndirections*: HashSet[(int, int)]
|
||||||
lastTLineInfo*: TLineInfo
|
lastTLineInfo*: TLineInfo
|
||||||
|
|
||||||
template config*(c: PContext): ConfigRef = c.graph.config
|
template config*(c: PContext): ConfigRef = c.graph.config
|
||||||
|
|
||||||
|
proc getIntLitType*(c: PContext; literal: PNode): PType =
|
||||||
|
# we cache some common integer literal types for performance:
|
||||||
|
let value = literal.intVal
|
||||||
|
if value >= low(c.intTypeCache) and value <= high(c.intTypeCache):
|
||||||
|
result = c.intTypeCache[value.int]
|
||||||
|
if result == nil:
|
||||||
|
let ti = getSysType(c.graph, literal.info, tyInt)
|
||||||
|
result = copyType(ti, nextTypeId(c.idgen), ti.owner)
|
||||||
|
result.n = literal
|
||||||
|
c.intTypeCache[value.int] = result
|
||||||
|
else:
|
||||||
|
let ti = getSysType(c.graph, literal.info, tyInt)
|
||||||
|
result = copyType(ti, nextTypeId(c.idgen), ti.owner)
|
||||||
|
result.n = literal
|
||||||
|
|
||||||
|
proc setIntLitType*(c: PContext; result: PNode) =
|
||||||
|
let i = result.intVal
|
||||||
|
case c.config.target.intSize
|
||||||
|
of 8: result.typ = getIntLitType(c, result)
|
||||||
|
of 4:
|
||||||
|
if i >= low(int32) and i <= high(int32):
|
||||||
|
result.typ = getIntLitType(c, result)
|
||||||
|
else:
|
||||||
|
result.typ = getSysType(c.graph, result.info, tyInt64)
|
||||||
|
of 2:
|
||||||
|
if i >= low(int16) and i <= high(int16):
|
||||||
|
result.typ = getIntLitType(c, result)
|
||||||
|
elif i >= low(int32) and i <= high(int32):
|
||||||
|
result.typ = getSysType(c.graph, result.info, tyInt32)
|
||||||
|
else:
|
||||||
|
result.typ = getSysType(c.graph, result.info, tyInt64)
|
||||||
|
of 1:
|
||||||
|
# 8 bit CPUs are insane ...
|
||||||
|
if i >= low(int8) and i <= high(int8):
|
||||||
|
result.typ = getIntLitType(c, result)
|
||||||
|
elif i >= low(int16) and i <= high(int16):
|
||||||
|
result.typ = getSysType(c.graph, result.info, tyInt16)
|
||||||
|
elif i >= low(int32) and i <= high(int32):
|
||||||
|
result.typ = getSysType(c.graph, result.info, tyInt32)
|
||||||
|
else:
|
||||||
|
result.typ = getSysType(c.graph, result.info, tyInt64)
|
||||||
|
else:
|
||||||
|
internalError(c.config, result.info, "invalid int size")
|
||||||
|
|
||||||
proc makeInstPair*(s: PSym, inst: PInstantiation): TInstantiationPair =
|
proc makeInstPair*(s: PSym, inst: PInstantiation): TInstantiationPair =
|
||||||
result.genericSym = s
|
result.genericSym = s
|
||||||
result.inst = inst
|
result.inst = inst
|
||||||
|
|
@ -250,7 +292,6 @@ proc popOptionEntry*(c: PContext) =
|
||||||
|
|
||||||
proc newContext*(graph: ModuleGraph; module: PSym): PContext =
|
proc newContext*(graph: ModuleGraph; module: PSym): PContext =
|
||||||
new(result)
|
new(result)
|
||||||
result.enforceVoidContext = PType(kind: tyTyped)
|
|
||||||
result.optionStack = @[newOptionEntry(graph.config)]
|
result.optionStack = @[newOptionEntry(graph.config)]
|
||||||
result.libs = @[]
|
result.libs = @[]
|
||||||
result.module = module
|
result.module = module
|
||||||
|
|
@ -265,7 +306,6 @@ proc newContext*(graph: ModuleGraph; module: PSym): PContext =
|
||||||
result.cache = graph.cache
|
result.cache = graph.cache
|
||||||
result.graph = graph
|
result.graph = graph
|
||||||
initStrTable(result.signatures)
|
initStrTable(result.signatures)
|
||||||
result.typesWithOps = @[]
|
|
||||||
result.features = graph.config.features
|
result.features = graph.config.features
|
||||||
if graph.config.symbolFiles != disabledSf:
|
if graph.config.symbolFiles != disabledSf:
|
||||||
let id = module.position
|
let id = module.position
|
||||||
|
|
|
||||||
|
|
@ -1072,7 +1072,7 @@ proc lookupInRecordAndBuildCheck(c: PContext, n, r: PNode, field: PIdent,
|
||||||
s = newNodeIT(nkCurly, n.info, setType)
|
s = newNodeIT(nkCurly, n.info, setType)
|
||||||
for j in 0..<it.len - 1: s.add copyTree(it[j])
|
for j in 0..<it.len - 1: s.add copyTree(it[j])
|
||||||
var inExpr = newNodeIT(nkCall, n.info, getSysType(c.graph, n.info, tyBool))
|
var inExpr = newNodeIT(nkCall, n.info, getSysType(c.graph, n.info, tyBool))
|
||||||
inExpr.add newSymNode(c.graph.opContains, n.info)
|
inExpr.add newSymNode(getSysMagic(c.graph, n.info, "contains", mInSet), n.info)
|
||||||
inExpr.add s
|
inExpr.add s
|
||||||
inExpr.add copyTree(r[0])
|
inExpr.add copyTree(r[0])
|
||||||
check.add inExpr
|
check.add inExpr
|
||||||
|
|
@ -1085,11 +1085,11 @@ proc lookupInRecordAndBuildCheck(c: PContext, n, r: PNode, field: PIdent,
|
||||||
check = newNodeI(nkCheckedFieldExpr, n.info)
|
check = newNodeI(nkCheckedFieldExpr, n.info)
|
||||||
check.add c.graph.emptyNode # make space for access node
|
check.add c.graph.emptyNode # make space for access node
|
||||||
var inExpr = newNodeIT(nkCall, n.info, getSysType(c.graph, n.info, tyBool))
|
var inExpr = newNodeIT(nkCall, n.info, getSysType(c.graph, n.info, tyBool))
|
||||||
inExpr.add newSymNode(c.graph.opContains, n.info)
|
inExpr.add newSymNode(getSysMagic(c.graph, n.info, "contains", mInSet), n.info)
|
||||||
inExpr.add s
|
inExpr.add s
|
||||||
inExpr.add copyTree(r[0])
|
inExpr.add copyTree(r[0])
|
||||||
var notExpr = newNodeIT(nkCall, n.info, getSysType(c.graph, n.info, tyBool))
|
var notExpr = newNodeIT(nkCall, n.info, getSysType(c.graph, n.info, tyBool))
|
||||||
notExpr.add newSymNode(c.graph.opNot, n.info)
|
notExpr.add newSymNode(getSysMagic(c.graph, n.info, "not", mNot), n.info)
|
||||||
notExpr.add inExpr
|
notExpr.add inExpr
|
||||||
check.add notExpr
|
check.add notExpr
|
||||||
return
|
return
|
||||||
|
|
@ -2641,6 +2641,14 @@ proc hoistParamsUsedInDefault(c: PContext, call, letSection, defExpr: var PNode)
|
||||||
for i in 0..<defExpr.safeLen:
|
for i in 0..<defExpr.safeLen:
|
||||||
hoistParamsUsedInDefault(c, call, letSection, defExpr[i])
|
hoistParamsUsedInDefault(c, call, letSection, defExpr[i])
|
||||||
|
|
||||||
|
proc getNilType(c: PContext): PType =
|
||||||
|
result = c.nilTypeCache
|
||||||
|
if result == nil:
|
||||||
|
result = newTypeS(tyNil, c)
|
||||||
|
result.size = c.config.target.ptrSize
|
||||||
|
result.align = c.config.target.ptrSize.int16
|
||||||
|
c.nilTypeCache = result
|
||||||
|
|
||||||
proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
when defined(nimCompilerStackraceHints):
|
when defined(nimCompilerStackraceHints):
|
||||||
setFrameMsg c.config$n.info & " " & $n.kind
|
setFrameMsg c.config$n.info & " " & $n.kind
|
||||||
|
|
@ -2676,9 +2684,9 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
|
||||||
of nkEmpty, nkNone, nkCommentStmt, nkType:
|
of nkEmpty, nkNone, nkCommentStmt, nkType:
|
||||||
discard
|
discard
|
||||||
of nkNilLit:
|
of nkNilLit:
|
||||||
if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyNil)
|
if result.typ == nil: result.typ = getNilType(c)
|
||||||
of nkIntLit:
|
of nkIntLit:
|
||||||
if result.typ == nil: setIntLitType(c.graph, result)
|
if result.typ == nil: setIntLitType(c, result)
|
||||||
of nkInt8Lit:
|
of nkInt8Lit:
|
||||||
if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyInt8)
|
if result.typ == nil: result.typ = getSysType(c.graph, n.info, tyInt8)
|
||||||
of nkInt16Lit:
|
of nkInt16Lit:
|
||||||
|
|
|
||||||
|
|
@ -22,13 +22,19 @@ proc errorType*(g: ModuleGraph): PType =
|
||||||
result = newType(tyError, nextTypeId(g.idgen), g.owners[^1])
|
result = newType(tyError, nextTypeId(g.idgen), g.owners[^1])
|
||||||
result.flags.incl tfCheckedForDestructor
|
result.flags.incl tfCheckedForDestructor
|
||||||
|
|
||||||
proc newIntNodeT*(intVal: Int128, n: PNode; g: ModuleGraph): PNode =
|
proc getIntLitTypeG(g: ModuleGraph; literal: PNode; idgen: IdGenerator): PType =
|
||||||
|
# we cache some common integer literal types for performance:
|
||||||
|
let ti = getSysType(g, literal.info, tyInt)
|
||||||
|
result = copyType(ti, nextTypeId(idgen), ti.owner)
|
||||||
|
result.n = literal
|
||||||
|
|
||||||
|
proc newIntNodeT*(intVal: Int128, n: PNode; idgen: IdGenerator; g: ModuleGraph): PNode =
|
||||||
result = newIntTypeNode(intVal, n.typ)
|
result = newIntTypeNode(intVal, n.typ)
|
||||||
# See bug #6989. 'pred' et al only produce an int literal type if the
|
# See bug #6989. 'pred' et al only produce an int literal type if the
|
||||||
# original type was 'int', not a distinct int etc.
|
# original type was 'int', not a distinct int etc.
|
||||||
if n.typ.kind == tyInt:
|
if n.typ.kind == tyInt:
|
||||||
# access cache for the int lit type
|
# access cache for the int lit type
|
||||||
result.typ = getIntLitType(g, result)
|
result.typ = getIntLitTypeG(g, result, idgen)
|
||||||
result.info = n.info
|
result.info = n.info
|
||||||
|
|
||||||
proc newFloatNodeT*(floatVal: BiggestFloat, n: PNode; g: ModuleGraph): PNode =
|
proc newFloatNodeT*(floatVal: BiggestFloat, n: PNode; g: ModuleGraph): PNode =
|
||||||
|
|
@ -47,33 +53,33 @@ proc newStrNodeT*(strVal: string, n: PNode; g: ModuleGraph): PNode =
|
||||||
proc getConstExpr*(m: PSym, n: PNode; idgen: IdGenerator; 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; idgen: IdGenerator; g: ModuleGraph): PNode
|
||||||
|
|
||||||
proc checkInRange(conf: ConfigRef; n: PNode, res: Int128): bool =
|
proc checkInRange(conf: ConfigRef; n: PNode, res: Int128): bool =
|
||||||
res in firstOrd(conf, n.typ)..lastOrd(conf, n.typ)
|
res in firstOrd(conf, n.typ)..lastOrd(conf, n.typ)
|
||||||
|
|
||||||
proc foldAdd(a, b: Int128, n: PNode; g: ModuleGraph): PNode =
|
proc foldAdd(a, b: Int128, n: PNode; idgen: IdGenerator; g: ModuleGraph): PNode =
|
||||||
let res = a + b
|
let res = a + b
|
||||||
if checkInRange(g.config, n, res):
|
if checkInRange(g.config, n, res):
|
||||||
result = newIntNodeT(res, n, g)
|
result = newIntNodeT(res, n, idgen, g)
|
||||||
|
|
||||||
proc foldSub(a, b: Int128, n: PNode; g: ModuleGraph): PNode =
|
proc foldSub(a, b: Int128, n: PNode; idgen: IdGenerator; g: ModuleGraph): PNode =
|
||||||
let res = a - b
|
let res = a - b
|
||||||
if checkInRange(g.config, n, res):
|
if checkInRange(g.config, n, res):
|
||||||
result = newIntNodeT(res, n, g)
|
result = newIntNodeT(res, n, idgen, g)
|
||||||
|
|
||||||
proc foldUnarySub(a: Int128, n: PNode, g: ModuleGraph): PNode =
|
proc foldUnarySub(a: Int128, n: PNode; idgen: IdGenerator, g: ModuleGraph): PNode =
|
||||||
if a != firstOrd(g.config, n.typ):
|
if a != firstOrd(g.config, n.typ):
|
||||||
result = newIntNodeT(-a, n, g)
|
result = newIntNodeT(-a, n, idgen, g)
|
||||||
|
|
||||||
proc foldAbs(a: Int128, n: PNode; g: ModuleGraph): PNode =
|
proc foldAbs(a: Int128, n: PNode; idgen: IdGenerator; g: ModuleGraph): PNode =
|
||||||
if a != firstOrd(g.config, n.typ):
|
if a != firstOrd(g.config, n.typ):
|
||||||
result = newIntNodeT(abs(a), n, g)
|
result = newIntNodeT(abs(a), n, idgen, g)
|
||||||
|
|
||||||
proc foldMul(a, b: Int128, n: PNode; g: ModuleGraph): PNode =
|
proc foldMul(a, b: Int128, n: PNode; idgen: IdGenerator; g: ModuleGraph): PNode =
|
||||||
let res = a * b
|
let res = a * b
|
||||||
if checkInRange(g.config, n, res):
|
if checkInRange(g.config, n, res):
|
||||||
return newIntNodeT(res, n, g)
|
return newIntNodeT(res, n, idgen, g)
|
||||||
|
|
||||||
proc ordinalValToString*(a: PNode; g: ModuleGraph): string =
|
proc ordinalValToString*(a: PNode; g: ModuleGraph): string =
|
||||||
# because $ has the param ordinal[T], `a` is not necessarily an enum, but an
|
# because $ has the param ordinal[T], `a` is not necessarily an enum, but an
|
||||||
|
|
@ -115,68 +121,68 @@ 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 evalOp(m: TMagic, n, a, b, c: PNode; g: ModuleGraph): PNode =
|
proc evalOp(m: TMagic, n, a, b, c: PNode; idgen: IdGenerator; g: ModuleGraph): PNode =
|
||||||
# b and c may be nil
|
# b and c may be nil
|
||||||
result = nil
|
result = nil
|
||||||
case m
|
case m
|
||||||
of mOrd: result = newIntNodeT(getOrdValue(a), n, g)
|
of mOrd: result = newIntNodeT(getOrdValue(a), n, idgen, g)
|
||||||
of mChr: result = newIntNodeT(getInt(a), n, g)
|
of mChr: result = newIntNodeT(getInt(a), n, idgen, g)
|
||||||
of mUnaryMinusI, mUnaryMinusI64: result = foldUnarySub(getInt(a), n, g)
|
of mUnaryMinusI, mUnaryMinusI64: result = foldUnarySub(getInt(a), n, idgen, g)
|
||||||
of mUnaryMinusF64: result = newFloatNodeT(-getFloat(a), n, g)
|
of mUnaryMinusF64: result = newFloatNodeT(-getFloat(a), n, g)
|
||||||
of mNot: result = newIntNodeT(One - getInt(a), n, g)
|
of mNot: result = newIntNodeT(One - getInt(a), n, idgen, g)
|
||||||
of mCard: result = newIntNodeT(toInt128(nimsets.cardSet(g.config, a)), n, g)
|
of mCard: result = newIntNodeT(toInt128(nimsets.cardSet(g.config, a)), n, idgen, g)
|
||||||
of mBitnotI:
|
of mBitnotI:
|
||||||
if n.typ.isUnsigned:
|
if n.typ.isUnsigned:
|
||||||
result = newIntNodeT(bitnot(getInt(a)).maskBytes(int(n.typ.size)), n, g)
|
result = newIntNodeT(bitnot(getInt(a)).maskBytes(int(n.typ.size)), n, idgen, g)
|
||||||
else:
|
else:
|
||||||
result = newIntNodeT(bitnot(getInt(a)), n, g)
|
result = newIntNodeT(bitnot(getInt(a)), n, idgen, g)
|
||||||
of mLengthArray: result = newIntNodeT(lengthOrd(g.config, a.typ), n, g)
|
of mLengthArray: result = newIntNodeT(lengthOrd(g.config, a.typ), n, idgen, g)
|
||||||
of mLengthSeq, mLengthOpenArray, mLengthStr:
|
of mLengthSeq, mLengthOpenArray, mLengthStr:
|
||||||
if a.kind == nkNilLit:
|
if a.kind == nkNilLit:
|
||||||
result = newIntNodeT(Zero, n, g)
|
result = newIntNodeT(Zero, n, idgen, g)
|
||||||
elif a.kind in {nkStrLit..nkTripleStrLit}:
|
elif a.kind in {nkStrLit..nkTripleStrLit}:
|
||||||
if a.typ.kind == tyString:
|
if a.typ.kind == tyString:
|
||||||
result = newIntNodeT(toInt128(a.strVal.len), n, g)
|
result = newIntNodeT(toInt128(a.strVal.len), n, idgen, g)
|
||||||
elif a.typ.kind == tyCString:
|
elif a.typ.kind == tyCString:
|
||||||
result = newIntNodeT(toInt128(nimCStrLen(a.strVal)), n, g)
|
result = newIntNodeT(toInt128(nimCStrLen(a.strVal)), n, idgen, g)
|
||||||
else:
|
else:
|
||||||
result = newIntNodeT(toInt128(a.len), n, g)
|
result = newIntNodeT(toInt128(a.len), n, idgen, g)
|
||||||
of mUnaryPlusI, mUnaryPlusF64: result = a # throw `+` away
|
of mUnaryPlusI, mUnaryPlusF64: result = a # throw `+` away
|
||||||
# XXX: Hides overflow/underflow
|
# XXX: Hides overflow/underflow
|
||||||
of mAbsI: result = foldAbs(getInt(a), n, g)
|
of mAbsI: result = foldAbs(getInt(a), n, idgen, g)
|
||||||
of mSucc: result = foldAdd(getOrdValue(a), getInt(b), n, g)
|
of mSucc: result = foldAdd(getOrdValue(a), getInt(b), n, idgen, g)
|
||||||
of mPred: result = foldSub(getOrdValue(a), getInt(b), n, g)
|
of mPred: result = foldSub(getOrdValue(a), getInt(b), n, idgen, g)
|
||||||
of mAddI: result = foldAdd(getInt(a), getInt(b), n, g)
|
of mAddI: result = foldAdd(getInt(a), getInt(b), n, idgen, g)
|
||||||
of mSubI: result = foldSub(getInt(a), getInt(b), n, g)
|
of mSubI: result = foldSub(getInt(a), getInt(b), n, idgen, g)
|
||||||
of mMulI: result = foldMul(getInt(a), getInt(b), n, g)
|
of mMulI: result = foldMul(getInt(a), getInt(b), n, idgen, g)
|
||||||
of mMinI:
|
of mMinI:
|
||||||
let argA = getInt(a)
|
let argA = getInt(a)
|
||||||
let argB = getInt(b)
|
let argB = getInt(b)
|
||||||
result = newIntNodeT(if argA < argB: argA else: argB, n, g)
|
result = newIntNodeT(if argA < argB: argA else: argB, n, idgen, g)
|
||||||
of mMaxI:
|
of mMaxI:
|
||||||
let argA = getInt(a)
|
let argA = getInt(a)
|
||||||
let argB = getInt(b)
|
let argB = getInt(b)
|
||||||
result = newIntNodeT(if argA > argB: argA else: argB, n, g)
|
result = newIntNodeT(if argA > argB: argA else: argB, n, idgen, g)
|
||||||
of mShlI:
|
of mShlI:
|
||||||
case skipTypes(n.typ, abstractRange).kind
|
case skipTypes(n.typ, abstractRange).kind
|
||||||
of tyInt8: result = newIntNodeT(toInt128(toInt8(getInt(a)) shl toInt64(getInt(b))), n, g)
|
of tyInt8: result = newIntNodeT(toInt128(toInt8(getInt(a)) shl toInt64(getInt(b))), n, idgen, g)
|
||||||
of tyInt16: result = newIntNodeT(toInt128(toInt16(getInt(a)) shl toInt64(getInt(b))), n, g)
|
of tyInt16: result = newIntNodeT(toInt128(toInt16(getInt(a)) shl toInt64(getInt(b))), n, idgen, g)
|
||||||
of tyInt32: result = newIntNodeT(toInt128(toInt32(getInt(a)) shl toInt64(getInt(b))), n, g)
|
of tyInt32: result = newIntNodeT(toInt128(toInt32(getInt(a)) shl toInt64(getInt(b))), n, idgen, g)
|
||||||
of tyInt64: result = newIntNodeT(toInt128(toInt64(getInt(a)) shl toInt64(getInt(b))), n, g)
|
of tyInt64: result = newIntNodeT(toInt128(toInt64(getInt(a)) shl toInt64(getInt(b))), n, idgen, g)
|
||||||
of tyInt:
|
of tyInt:
|
||||||
if g.config.target.intSize == 4:
|
if g.config.target.intSize == 4:
|
||||||
result = newIntNodeT(toInt128(toInt32(getInt(a)) shl toInt64(getInt(b))), n, g)
|
result = newIntNodeT(toInt128(toInt32(getInt(a)) shl toInt64(getInt(b))), n, idgen, g)
|
||||||
else:
|
else:
|
||||||
result = newIntNodeT(toInt128(toInt64(getInt(a)) shl toInt64(getInt(b))), n, g)
|
result = newIntNodeT(toInt128(toInt64(getInt(a)) shl toInt64(getInt(b))), n, idgen, g)
|
||||||
of tyUInt8: result = newIntNodeT(toInt128(toUInt8(getInt(a)) shl toInt64(getInt(b))), n, g)
|
of tyUInt8: result = newIntNodeT(toInt128(toUInt8(getInt(a)) shl toInt64(getInt(b))), n, idgen, g)
|
||||||
of tyUInt16: result = newIntNodeT(toInt128(toUInt16(getInt(a)) shl toInt64(getInt(b))), n, g)
|
of tyUInt16: result = newIntNodeT(toInt128(toUInt16(getInt(a)) shl toInt64(getInt(b))), n, idgen, g)
|
||||||
of tyUInt32: result = newIntNodeT(toInt128(toUInt32(getInt(a)) shl toInt64(getInt(b))), n, g)
|
of tyUInt32: result = newIntNodeT(toInt128(toUInt32(getInt(a)) shl toInt64(getInt(b))), n, idgen, g)
|
||||||
of tyUInt64: result = newIntNodeT(toInt128(toUInt64(getInt(a)) shl toInt64(getInt(b))), n, g)
|
of tyUInt64: result = newIntNodeT(toInt128(toUInt64(getInt(a)) shl toInt64(getInt(b))), n, idgen, g)
|
||||||
of tyUInt:
|
of tyUInt:
|
||||||
if g.config.target.intSize == 4:
|
if g.config.target.intSize == 4:
|
||||||
result = newIntNodeT(toInt128(toUInt32(getInt(a)) shl toInt64(getInt(b))), n, g)
|
result = newIntNodeT(toInt128(toUInt32(getInt(a)) shl toInt64(getInt(b))), n, idgen, g)
|
||||||
else:
|
else:
|
||||||
result = newIntNodeT(toInt128(toUInt64(getInt(a)) shl toInt64(getInt(b))), n, g)
|
result = newIntNodeT(toInt128(toUInt64(getInt(a)) shl toInt64(getInt(b))), n, idgen, g)
|
||||||
else: internalError(g.config, n.info, "constant folding for shl")
|
else: internalError(g.config, n.info, "constant folding for shl")
|
||||||
of mShrI:
|
of mShrI:
|
||||||
var a = cast[uint64](getInt(a))
|
var a = cast[uint64](getInt(a))
|
||||||
|
|
@ -197,75 +203,75 @@ proc evalOp(m: TMagic, n, a, b, c: PNode; g: ModuleGraph): PNode =
|
||||||
# unsigned and 64 bit integers don't need masking
|
# unsigned and 64 bit integers don't need masking
|
||||||
discard
|
discard
|
||||||
let c = cast[BiggestInt](a shr b)
|
let c = cast[BiggestInt](a shr b)
|
||||||
result = newIntNodeT(toInt128(c), n, g)
|
result = newIntNodeT(toInt128(c), n, idgen, g)
|
||||||
of mAshrI:
|
of mAshrI:
|
||||||
case skipTypes(n.typ, abstractRange).kind
|
case skipTypes(n.typ, abstractRange).kind
|
||||||
of tyInt8: result = newIntNodeT(toInt128(ashr(toInt8(getInt(a)), toInt8(getInt(b)))), n, g)
|
of tyInt8: result = newIntNodeT(toInt128(ashr(toInt8(getInt(a)), toInt8(getInt(b)))), n, idgen, g)
|
||||||
of tyInt16: result = newIntNodeT(toInt128(ashr(toInt16(getInt(a)), toInt16(getInt(b)))), n, g)
|
of tyInt16: result = newIntNodeT(toInt128(ashr(toInt16(getInt(a)), toInt16(getInt(b)))), n, idgen, g)
|
||||||
of tyInt32: result = newIntNodeT(toInt128(ashr(toInt32(getInt(a)), toInt32(getInt(b)))), n, g)
|
of tyInt32: result = newIntNodeT(toInt128(ashr(toInt32(getInt(a)), toInt32(getInt(b)))), n, idgen, g)
|
||||||
of tyInt64, tyInt:
|
of tyInt64, tyInt:
|
||||||
result = newIntNodeT(toInt128(ashr(toInt64(getInt(a)), toInt64(getInt(b)))), n, g)
|
result = newIntNodeT(toInt128(ashr(toInt64(getInt(a)), toInt64(getInt(b)))), n, idgen, g)
|
||||||
else: internalError(g.config, n.info, "constant folding for ashr")
|
else: internalError(g.config, n.info, "constant folding for ashr")
|
||||||
of mDivI:
|
of mDivI:
|
||||||
let argA = getInt(a)
|
let argA = getInt(a)
|
||||||
let argB = getInt(b)
|
let argB = getInt(b)
|
||||||
if argB != Zero and (argA != firstOrd(g.config, n.typ) or argB != NegOne):
|
if argB != Zero and (argA != firstOrd(g.config, n.typ) or argB != NegOne):
|
||||||
result = newIntNodeT(argA div argB, n, g)
|
result = newIntNodeT(argA div argB, n, idgen, g)
|
||||||
of mModI:
|
of mModI:
|
||||||
let argA = getInt(a)
|
let argA = getInt(a)
|
||||||
let argB = getInt(b)
|
let argB = getInt(b)
|
||||||
if argB != Zero and (argA != firstOrd(g.config, n.typ) or argB != NegOne):
|
if argB != Zero and (argA != firstOrd(g.config, n.typ) or argB != NegOne):
|
||||||
result = newIntNodeT(argA mod argB, n, g)
|
result = newIntNodeT(argA mod argB, n, idgen, g)
|
||||||
of mAddF64: result = newFloatNodeT(getFloat(a) + getFloat(b), n, g)
|
of mAddF64: result = newFloatNodeT(getFloat(a) + getFloat(b), n, g)
|
||||||
of mSubF64: result = newFloatNodeT(getFloat(a) - getFloat(b), n, g)
|
of mSubF64: result = newFloatNodeT(getFloat(a) - getFloat(b), n, g)
|
||||||
of mMulF64: result = newFloatNodeT(getFloat(a) * getFloat(b), n, g)
|
of mMulF64: result = newFloatNodeT(getFloat(a) * getFloat(b), n, g)
|
||||||
of mDivF64:
|
of mDivF64:
|
||||||
result = newFloatNodeT(getFloat(a) / getFloat(b), n, g)
|
result = newFloatNodeT(getFloat(a) / getFloat(b), n, g)
|
||||||
of mIsNil: result = newIntNodeT(toInt128(ord(a.kind == nkNilLit)), n, g)
|
of mIsNil: result = newIntNodeT(toInt128(ord(a.kind == nkNilLit)), n, idgen, g)
|
||||||
of mLtI, mLtB, mLtEnum, mLtCh:
|
of mLtI, mLtB, mLtEnum, mLtCh:
|
||||||
result = newIntNodeT(toInt128(ord(getOrdValue(a) < getOrdValue(b))), n, g)
|
result = newIntNodeT(toInt128(ord(getOrdValue(a) < getOrdValue(b))), n, idgen, g)
|
||||||
of mLeI, mLeB, mLeEnum, mLeCh:
|
of mLeI, mLeB, mLeEnum, mLeCh:
|
||||||
result = newIntNodeT(toInt128(ord(getOrdValue(a) <= getOrdValue(b))), n, g)
|
result = newIntNodeT(toInt128(ord(getOrdValue(a) <= getOrdValue(b))), n, idgen, g)
|
||||||
of mEqI, mEqB, mEqEnum, mEqCh:
|
of mEqI, mEqB, mEqEnum, mEqCh:
|
||||||
result = newIntNodeT(toInt128(ord(getOrdValue(a) == getOrdValue(b))), n, g)
|
result = newIntNodeT(toInt128(ord(getOrdValue(a) == getOrdValue(b))), n, idgen, g)
|
||||||
of mLtF64: result = newIntNodeT(toInt128(ord(getFloat(a) < getFloat(b))), n, g)
|
of mLtF64: result = newIntNodeT(toInt128(ord(getFloat(a) < getFloat(b))), n, idgen, g)
|
||||||
of mLeF64: result = newIntNodeT(toInt128(ord(getFloat(a) <= getFloat(b))), n, g)
|
of mLeF64: result = newIntNodeT(toInt128(ord(getFloat(a) <= getFloat(b))), n, idgen, g)
|
||||||
of mEqF64: result = newIntNodeT(toInt128(ord(getFloat(a) == getFloat(b))), n, g)
|
of mEqF64: result = newIntNodeT(toInt128(ord(getFloat(a) == getFloat(b))), n, idgen, g)
|
||||||
of mLtStr: result = newIntNodeT(toInt128(ord(getStr(a) < getStr(b))), n, g)
|
of mLtStr: result = newIntNodeT(toInt128(ord(getStr(a) < getStr(b))), n, idgen, g)
|
||||||
of mLeStr: result = newIntNodeT(toInt128(ord(getStr(a) <= getStr(b))), n, g)
|
of mLeStr: result = newIntNodeT(toInt128(ord(getStr(a) <= getStr(b))), n, idgen, g)
|
||||||
of mEqStr: result = newIntNodeT(toInt128(ord(getStr(a) == getStr(b))), n, g)
|
of mEqStr: result = newIntNodeT(toInt128(ord(getStr(a) == getStr(b))), n, idgen, g)
|
||||||
of mLtU:
|
of mLtU:
|
||||||
result = newIntNodeT(toInt128(ord(`<%`(toInt64(getOrdValue(a)), toInt64(getOrdValue(b))))), n, g)
|
result = newIntNodeT(toInt128(ord(`<%`(toInt64(getOrdValue(a)), toInt64(getOrdValue(b))))), n, idgen, g)
|
||||||
of mLeU:
|
of mLeU:
|
||||||
result = newIntNodeT(toInt128(ord(`<=%`(toInt64(getOrdValue(a)), toInt64(getOrdValue(b))))), n, g)
|
result = newIntNodeT(toInt128(ord(`<=%`(toInt64(getOrdValue(a)), toInt64(getOrdValue(b))))), n, idgen, g)
|
||||||
of mBitandI, mAnd: result = newIntNodeT(bitand(a.getInt, b.getInt), n, g)
|
of mBitandI, mAnd: result = newIntNodeT(bitand(a.getInt, b.getInt), n, idgen, g)
|
||||||
of mBitorI, mOr: result = newIntNodeT(bitor(getInt(a), getInt(b)), n, g)
|
of mBitorI, mOr: result = newIntNodeT(bitor(getInt(a), getInt(b)), n, idgen, g)
|
||||||
of mBitxorI, mXor: result = newIntNodeT(bitxor(getInt(a), getInt(b)), n, g)
|
of mBitxorI, mXor: result = newIntNodeT(bitxor(getInt(a), getInt(b)), n, idgen, g)
|
||||||
of mAddU:
|
of mAddU:
|
||||||
let val = maskBytes(getInt(a) + getInt(b), int(n.typ.size))
|
let val = maskBytes(getInt(a) + getInt(b), int(n.typ.size))
|
||||||
result = newIntNodeT(val, n, g)
|
result = newIntNodeT(val, n, idgen, g)
|
||||||
of mSubU:
|
of mSubU:
|
||||||
let val = maskBytes(getInt(a) - getInt(b), int(n.typ.size))
|
let val = maskBytes(getInt(a) - getInt(b), int(n.typ.size))
|
||||||
result = newIntNodeT(val, n, g)
|
result = newIntNodeT(val, n, idgen, g)
|
||||||
# echo "subU: ", val, " n: ", n, " result: ", val
|
# echo "subU: ", val, " n: ", n, " result: ", val
|
||||||
of mMulU:
|
of mMulU:
|
||||||
let val = maskBytes(getInt(a) * getInt(b), int(n.typ.size))
|
let val = maskBytes(getInt(a) * getInt(b), int(n.typ.size))
|
||||||
result = newIntNodeT(val, n, g)
|
result = newIntNodeT(val, n, idgen, g)
|
||||||
of mModU:
|
of mModU:
|
||||||
let argA = maskBytes(getInt(a), int(a.typ.size))
|
let argA = maskBytes(getInt(a), int(a.typ.size))
|
||||||
let argB = maskBytes(getInt(b), int(a.typ.size))
|
let argB = maskBytes(getInt(b), int(a.typ.size))
|
||||||
if argB != Zero:
|
if argB != Zero:
|
||||||
result = newIntNodeT(argA mod argB, n, g)
|
result = newIntNodeT(argA mod argB, n, idgen, g)
|
||||||
of mDivU:
|
of mDivU:
|
||||||
let argA = maskBytes(getInt(a), int(a.typ.size))
|
let argA = maskBytes(getInt(a), int(a.typ.size))
|
||||||
let argB = maskBytes(getInt(b), int(a.typ.size))
|
let argB = maskBytes(getInt(b), int(a.typ.size))
|
||||||
if argB != Zero:
|
if argB != Zero:
|
||||||
result = newIntNodeT(argA div argB, n, g)
|
result = newIntNodeT(argA div argB, n, idgen, g)
|
||||||
of mLeSet: result = newIntNodeT(toInt128(ord(containsSets(g.config, a, b))), n, g)
|
of mLeSet: result = newIntNodeT(toInt128(ord(containsSets(g.config, a, b))), n, idgen, g)
|
||||||
of mEqSet: result = newIntNodeT(toInt128(ord(equalSets(g.config, a, b))), n, g)
|
of mEqSet: result = newIntNodeT(toInt128(ord(equalSets(g.config, a, b))), n, idgen, g)
|
||||||
of mLtSet:
|
of mLtSet:
|
||||||
result = newIntNodeT(toInt128(ord(
|
result = newIntNodeT(toInt128(ord(
|
||||||
containsSets(g.config, a, b) and not equalSets(g.config, a, b))), n, g)
|
containsSets(g.config, a, b) and not equalSets(g.config, a, b))), n, idgen, g)
|
||||||
of mMulSet:
|
of mMulSet:
|
||||||
result = nimsets.intersectSets(g.config, a, b)
|
result = nimsets.intersectSets(g.config, a, b)
|
||||||
result.info = n.info
|
result.info = n.info
|
||||||
|
|
@ -276,7 +282,7 @@ proc evalOp(m: TMagic, n, a, b, c: PNode; g: ModuleGraph): PNode =
|
||||||
result = nimsets.diffSets(g.config, a, b)
|
result = nimsets.diffSets(g.config, a, b)
|
||||||
result.info = n.info
|
result.info = n.info
|
||||||
of mConStrStr: result = newStrNodeT(getStrOrChar(a) & getStrOrChar(b), n, g)
|
of mConStrStr: result = newStrNodeT(getStrOrChar(a) & getStrOrChar(b), n, g)
|
||||||
of mInSet: result = newIntNodeT(toInt128(ord(inSet(a, b))), n, g)
|
of mInSet: result = newIntNodeT(toInt128(ord(inSet(a, b))), n, idgen, g)
|
||||||
of mRepr:
|
of mRepr:
|
||||||
# BUGFIX: we cannot eval mRepr here for reasons that I forgot.
|
# BUGFIX: we cannot eval mRepr here for reasons that I forgot.
|
||||||
discard
|
discard
|
||||||
|
|
@ -299,13 +305,13 @@ proc evalOp(m: TMagic, n, a, b, c: PNode; g: ModuleGraph): PNode =
|
||||||
result = copyTree(a)
|
result = copyTree(a)
|
||||||
result.typ = n.typ
|
result.typ = n.typ
|
||||||
of mCompileOption:
|
of mCompileOption:
|
||||||
result = newIntNodeT(toInt128(ord(commands.testCompileOption(g.config, a.getStr, n.info))), n, g)
|
result = newIntNodeT(toInt128(ord(commands.testCompileOption(g.config, a.getStr, n.info))), n, idgen, g)
|
||||||
of mCompileOptionArg:
|
of mCompileOptionArg:
|
||||||
result = newIntNodeT(toInt128(ord(
|
result = newIntNodeT(toInt128(ord(
|
||||||
testCompileOptionArg(g.config, getStr(a), getStr(b), n.info))), n, g)
|
testCompileOptionArg(g.config, getStr(a), getStr(b), n.info))), n, idgen, g)
|
||||||
of mEqProc:
|
of mEqProc:
|
||||||
result = newIntNodeT(toInt128(ord(
|
result = newIntNodeT(toInt128(ord(
|
||||||
exprStructuralEquivalent(a, b, strictSymEquality=true))), n, g)
|
exprStructuralEquivalent(a, b, strictSymEquality=true))), n, idgen, g)
|
||||||
else: discard
|
else: discard
|
||||||
|
|
||||||
proc getConstIfExpr(c: PSym, n: PNode; idgen: IdGenerator; g: ModuleGraph): PNode =
|
proc getConstIfExpr(c: PSym, n: PNode; idgen: IdGenerator; g: ModuleGraph): PNode =
|
||||||
|
|
@ -351,7 +357,7 @@ proc magicCall(m: PSym, n: PNode; idgen: IdGenerator; g: ModuleGraph): PNode =
|
||||||
if n.len > 3:
|
if n.len > 3:
|
||||||
c = getConstExpr(m, n[3], idgen, 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, idgen, g)
|
||||||
|
|
||||||
proc getAppType(n: PNode; g: ModuleGraph): PNode =
|
proc getAppType(n: PNode; g: ModuleGraph): PNode =
|
||||||
if g.config.globalOptions.contains(optGenDynLib):
|
if g.config.globalOptions.contains(optGenDynLib):
|
||||||
|
|
@ -368,7 +374,7 @@ proc rangeCheck(n: PNode, value: Int128; g: ModuleGraph) =
|
||||||
localError(g.config, n.info, "cannot convert " & $value &
|
localError(g.config, n.info, "cannot convert " & $value &
|
||||||
" to " & typeToString(n.typ))
|
" to " & typeToString(n.typ))
|
||||||
|
|
||||||
proc foldConv(n, a: PNode; g: ModuleGraph; check = false): PNode =
|
proc foldConv(n, a: PNode; idgen: IdGenerator; g: ModuleGraph; check = false): PNode =
|
||||||
let dstTyp = skipTypes(n.typ, abstractRange - {tyTypeDesc})
|
let dstTyp = skipTypes(n.typ, abstractRange - {tyTypeDesc})
|
||||||
let srcTyp = skipTypes(a.typ, abstractRange - {tyTypeDesc})
|
let srcTyp = skipTypes(a.typ, abstractRange - {tyTypeDesc})
|
||||||
|
|
||||||
|
|
@ -382,9 +388,9 @@ proc foldConv(n, a: PNode; g: ModuleGraph; check = false): PNode =
|
||||||
of tyBool:
|
of tyBool:
|
||||||
case srcTyp.kind
|
case srcTyp.kind
|
||||||
of tyFloat..tyFloat64:
|
of tyFloat..tyFloat64:
|
||||||
result = newIntNodeT(toInt128(getFloat(a) != 0.0), n, g)
|
result = newIntNodeT(toInt128(getFloat(a) != 0.0), n, idgen, g)
|
||||||
of tyChar, tyUInt..tyUInt64, tyInt..tyInt64:
|
of tyChar, tyUInt..tyUInt64, tyInt..tyInt64:
|
||||||
result = newIntNodeT(toInt128(a.getOrdValue != 0), n, g)
|
result = newIntNodeT(toInt128(a.getOrdValue != 0), n, idgen, g)
|
||||||
of tyBool, tyEnum: # xxx shouldn't we disallow `tyEnum`?
|
of tyBool, tyEnum: # xxx shouldn't we disallow `tyEnum`?
|
||||||
result = a
|
result = a
|
||||||
result.typ = n.typ
|
result.typ = n.typ
|
||||||
|
|
@ -392,11 +398,11 @@ proc foldConv(n, a: PNode; g: ModuleGraph; check = false): PNode =
|
||||||
of tyInt..tyInt64, tyUInt..tyUInt64:
|
of tyInt..tyInt64, tyUInt..tyUInt64:
|
||||||
case srcTyp.kind
|
case srcTyp.kind
|
||||||
of tyFloat..tyFloat64:
|
of tyFloat..tyFloat64:
|
||||||
result = newIntNodeT(toInt128(getFloat(a)), n, g)
|
result = newIntNodeT(toInt128(getFloat(a)), n, idgen, g)
|
||||||
of tyChar, tyUInt..tyUInt64, tyInt..tyInt64:
|
of tyChar, tyUInt..tyUInt64, tyInt..tyInt64:
|
||||||
var val = a.getOrdValue
|
var val = a.getOrdValue
|
||||||
if check: rangeCheck(n, val, g)
|
if check: rangeCheck(n, val, g)
|
||||||
result = newIntNodeT(val, n, g)
|
result = newIntNodeT(val, n, idgen, g)
|
||||||
if dstTyp.kind in {tyUInt..tyUInt64}:
|
if dstTyp.kind in {tyUInt..tyUInt64}:
|
||||||
result.transitionIntKind(nkUIntLit)
|
result.transitionIntKind(nkUIntLit)
|
||||||
else:
|
else:
|
||||||
|
|
@ -493,13 +499,13 @@ proc getConstExpr(m: PSym, n: PNode; idgen: IdGenerator; g: ModuleGraph): PNode
|
||||||
var s = n.sym
|
var s = n.sym
|
||||||
case s.kind
|
case s.kind
|
||||||
of skEnumField:
|
of skEnumField:
|
||||||
result = newIntNodeT(toInt128(s.position), n, g)
|
result = newIntNodeT(toInt128(s.position), n, idgen, g)
|
||||||
of skConst:
|
of skConst:
|
||||||
case s.magic
|
case s.magic
|
||||||
of mIsMainModule: result = newIntNodeT(toInt128(ord(sfMainModule in m.flags)), n, g)
|
of mIsMainModule: result = newIntNodeT(toInt128(ord(sfMainModule in m.flags)), n, idgen, g)
|
||||||
of mCompileDate: result = newStrNodeT(getDateStr(), n, g)
|
of mCompileDate: result = newStrNodeT(getDateStr(), n, g)
|
||||||
of mCompileTime: result = newStrNodeT(getClockStr(), n, g)
|
of mCompileTime: result = newStrNodeT(getClockStr(), n, g)
|
||||||
of mCpuEndian: result = newIntNodeT(toInt128(ord(CPU[g.config.target.targetCPU].endian)), n, g)
|
of mCpuEndian: result = newIntNodeT(toInt128(ord(CPU[g.config.target.targetCPU].endian)), n, idgen, g)
|
||||||
of mHostOS: result = newStrNodeT(toLowerAscii(platform.OS[g.config.target.targetOS].name), n, g)
|
of mHostOS: result = newStrNodeT(toLowerAscii(platform.OS[g.config.target.targetOS].name), n, g)
|
||||||
of mHostCPU: result = newStrNodeT(platform.CPU[g.config.target.targetCPU].name.toLowerAscii, n, g)
|
of mHostCPU: result = newStrNodeT(platform.CPU[g.config.target.targetCPU].name.toLowerAscii, n, g)
|
||||||
of mBuildOS: result = newStrNodeT(toLowerAscii(platform.OS[g.config.target.hostOS].name), n, g)
|
of mBuildOS: result = newStrNodeT(toLowerAscii(platform.OS[g.config.target.hostOS].name), n, g)
|
||||||
|
|
@ -508,7 +514,7 @@ proc getConstExpr(m: PSym, n: PNode; idgen: IdGenerator; g: ModuleGraph): PNode
|
||||||
of mIntDefine:
|
of mIntDefine:
|
||||||
if isDefined(g.config, s.name.s):
|
if isDefined(g.config, s.name.s):
|
||||||
try:
|
try:
|
||||||
result = newIntNodeT(toInt128(g.config.symbols[s.name.s].parseInt), n, g)
|
result = newIntNodeT(toInt128(g.config.symbols[s.name.s].parseInt), n, idgen, g)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
localError(g.config, s.info,
|
localError(g.config, s.info,
|
||||||
"{.intdefine.} const was set to an invalid integer: '" &
|
"{.intdefine.} const was set to an invalid integer: '" &
|
||||||
|
|
@ -523,7 +529,7 @@ proc getConstExpr(m: PSym, n: PNode; idgen: IdGenerator; g: ModuleGraph): PNode
|
||||||
of mBoolDefine:
|
of mBoolDefine:
|
||||||
if isDefined(g.config, s.name.s):
|
if isDefined(g.config, s.name.s):
|
||||||
try:
|
try:
|
||||||
result = newIntNodeT(toInt128(g.config.symbols[s.name.s].parseBool.int), n, g)
|
result = newIntNodeT(toInt128(g.config.symbols[s.name.s].parseBool.int), n, idgen, g)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
localError(g.config, s.info,
|
localError(g.config, s.info,
|
||||||
"{.booldefine.} const was set to an invalid bool: '" &
|
"{.booldefine.} const was set to an invalid bool: '" &
|
||||||
|
|
@ -569,30 +575,30 @@ proc getConstExpr(m: PSym, n: PNode; idgen: IdGenerator; g: ModuleGraph): PNode
|
||||||
if skipTypes(n[1].typ, abstractVarRange).kind in tyFloat..tyFloat64:
|
if skipTypes(n[1].typ, abstractVarRange).kind in tyFloat..tyFloat64:
|
||||||
result = newFloatNodeT(firstFloat(n[1].typ), n, g)
|
result = newFloatNodeT(firstFloat(n[1].typ), n, g)
|
||||||
else:
|
else:
|
||||||
result = newIntNodeT(firstOrd(g.config, n[1].typ), n, g)
|
result = newIntNodeT(firstOrd(g.config, n[1].typ), n, idgen, g)
|
||||||
of mHigh:
|
of mHigh:
|
||||||
if skipTypes(n[1].typ, abstractVar+{tyUserTypeClassInst}).kind notin
|
if skipTypes(n[1].typ, abstractVar+{tyUserTypeClassInst}).kind notin
|
||||||
{tySequence, tyString, tyCString, tyOpenArray, tyVarargs}:
|
{tySequence, tyString, tyCString, tyOpenArray, tyVarargs}:
|
||||||
if skipTypes(n[1].typ, abstractVarRange).kind in tyFloat..tyFloat64:
|
if skipTypes(n[1].typ, abstractVarRange).kind in tyFloat..tyFloat64:
|
||||||
result = newFloatNodeT(lastFloat(n[1].typ), n, g)
|
result = newFloatNodeT(lastFloat(n[1].typ), n, g)
|
||||||
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, idgen, g)
|
||||||
else:
|
else:
|
||||||
var a = getArrayConstr(m, n[1], idgen, 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, idgen, g)
|
||||||
of mLengthOpenArray:
|
of mLengthOpenArray:
|
||||||
var a = getArrayConstr(m, n[1], idgen, 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, idgen, g)
|
||||||
else:
|
else:
|
||||||
result = magicCall(m, n, idgen, 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.
|
||||||
result = newIntNodeT(lengthOrd(g.config, n[1].typ), n, g)
|
result = newIntNodeT(lengthOrd(g.config, n[1].typ), n, idgen, g)
|
||||||
of mSizeOf:
|
of mSizeOf:
|
||||||
result = foldSizeOf(g.config, n, nil)
|
result = foldSizeOf(g.config, n, nil)
|
||||||
of mAlignOf:
|
of mAlignOf:
|
||||||
|
|
@ -675,7 +681,7 @@ proc getConstExpr(m: PSym, n: PNode; idgen: IdGenerator; g: ModuleGraph): PNode
|
||||||
of nkHiddenStdConv, nkHiddenSubConv, nkConv:
|
of nkHiddenStdConv, nkHiddenSubConv, nkConv:
|
||||||
var a = getConstExpr(m, n[1], idgen, 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, idgen, g, check=true)
|
||||||
of nkDerefExpr, nkHiddenDeref:
|
of nkDerefExpr, nkHiddenDeref:
|
||||||
let a = getConstExpr(m, n[0], idgen, g)
|
let a = getConstExpr(m, n[0], idgen, g)
|
||||||
if a != nil and a.kind == nkNilLit:
|
if a != nil and a.kind == nkNilLit:
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@ proc semAsgnOpr(c: PContext; n: PNode): PNode =
|
||||||
|
|
||||||
proc semIsPartOf(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
proc semIsPartOf(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
var r = isPartOf(n[1], n[2])
|
var r = isPartOf(n[1], n[2])
|
||||||
result = newIntNodeT(toInt128(ord(r)), n, c.graph)
|
result = newIntNodeT(toInt128(ord(r)), n, c.idgen, c.graph)
|
||||||
|
|
||||||
proc expectIntLit(c: PContext, n: PNode): int =
|
proc expectIntLit(c: PContext, n: PNode): int =
|
||||||
let x = c.semConstExpr(c, n)
|
let x = c.semConstExpr(c, n)
|
||||||
|
|
@ -179,15 +179,15 @@ proc evalTypeTrait(c: PContext; traitCall: PNode, operand: PType, context: PSym)
|
||||||
let t = operand.skipTypes({tyVar, tyLent, tyGenericInst, tyAlias, tySink, tyInferred})
|
let t = operand.skipTypes({tyVar, tyLent, tyGenericInst, tyAlias, tySink, tyInferred})
|
||||||
let complexObj = containsGarbageCollectedRef(t) or
|
let complexObj = containsGarbageCollectedRef(t) or
|
||||||
hasDestructor(t)
|
hasDestructor(t)
|
||||||
result = newIntNodeT(toInt128(ord(not complexObj)), traitCall, c.graph)
|
result = newIntNodeT(toInt128(ord(not complexObj)), traitCall, c.idgen, c.graph)
|
||||||
of "isNamedTuple":
|
of "isNamedTuple":
|
||||||
var operand = operand.skipTypes({tyGenericInst})
|
var operand = operand.skipTypes({tyGenericInst})
|
||||||
let cond = operand.kind == tyTuple and operand.n != nil
|
let cond = operand.kind == tyTuple and operand.n != nil
|
||||||
result = newIntNodeT(toInt128(ord(cond)), traitCall, c.graph)
|
result = newIntNodeT(toInt128(ord(cond)), traitCall, c.idgen, c.graph)
|
||||||
of "tupleLen":
|
of "tupleLen":
|
||||||
var operand = operand.skipTypes({tyGenericInst})
|
var operand = operand.skipTypes({tyGenericInst})
|
||||||
assert operand.kind == tyTuple, $operand.kind
|
assert operand.kind == tyTuple, $operand.kind
|
||||||
result = newIntNodeT(toInt128(operand.len), traitCall, c.graph)
|
result = newIntNodeT(toInt128(operand.len), traitCall, c.idgen, c.graph)
|
||||||
of "distinctBase":
|
of "distinctBase":
|
||||||
var arg = operand.skipTypes({tyGenericInst})
|
var arg = operand.skipTypes({tyGenericInst})
|
||||||
if arg.kind == tyDistinct:
|
if arg.kind == tyDistinct:
|
||||||
|
|
|
||||||
|
|
@ -537,8 +537,6 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode =
|
||||||
typFlags.incl taConcept
|
typFlags.incl taConcept
|
||||||
typeAllowedCheck(c, a.info, typ, symkind, typFlags)
|
typeAllowedCheck(c, a.info, typ, symkind, typFlags)
|
||||||
|
|
||||||
when false: liftTypeBoundOps(c, typ, a.info)
|
|
||||||
instAllTypeBoundOp(c, a.info)
|
|
||||||
var tup = skipTypes(typ, {tyGenericInst, tyAlias, tySink})
|
var tup = skipTypes(typ, {tyGenericInst, tyAlias, tySink})
|
||||||
if a.kind == nkVarTuple:
|
if a.kind == nkVarTuple:
|
||||||
if tup.kind != tyTuple:
|
if tup.kind != tyTuple:
|
||||||
|
|
|
||||||
|
|
@ -1967,10 +1967,6 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType =
|
||||||
result = newOrPrevType(tyError, prev, c)
|
result = newOrPrevType(tyError, prev, c)
|
||||||
n.typ = result
|
n.typ = result
|
||||||
dec c.inTypeContext
|
dec c.inTypeContext
|
||||||
if false: # c.inTypeContext == 0:
|
|
||||||
#if $n == "var seq[StackTraceEntry]":
|
|
||||||
# echo "begin ", n
|
|
||||||
instAllTypeBoundOp(c, n.info)
|
|
||||||
|
|
||||||
proc setMagicType(conf: ConfigRef; m: PSym, kind: TTypeKind, size: int) =
|
proc setMagicType(conf: ConfigRef; m: PSym, kind: TTypeKind, size: int) =
|
||||||
# source : https://en.wikipedia.org/wiki/Data_structure_alignment#x86
|
# source : https://en.wikipedia.org/wiki/Data_structure_alignment#x86
|
||||||
|
|
|
||||||
|
|
@ -432,7 +432,6 @@ proc handleGenericInvocation(cl: var TReplTypeVars, t: PType): PType =
|
||||||
# adding myseq for myseq[system.int]
|
# adding myseq for myseq[system.int]
|
||||||
# sigmatch: Formal myseq[=destroy.T] real myseq[system.int]
|
# sigmatch: Formal myseq[=destroy.T] real myseq[system.int]
|
||||||
#echo "DESTROY: adding ", typeToString(newbody), " for ", typeToString(result, preferDesc)
|
#echo "DESTROY: adding ", typeToString(newbody), " for ", typeToString(result, preferDesc)
|
||||||
#cl.c.typesWithOps.add((newbody, result))
|
|
||||||
let mm = skipTypes(bbody, abstractPtrs)
|
let mm = skipTypes(bbody, abstractPtrs)
|
||||||
if tfFromGeneric notin mm.flags:
|
if tfFromGeneric notin mm.flags:
|
||||||
# bug #5479, prevent endless recursions here:
|
# bug #5479, prevent endless recursions here:
|
||||||
|
|
@ -642,23 +641,6 @@ proc replaceTypeVarsTAux(cl: var TReplTypeVars, t: PType): PType =
|
||||||
result.size = -1
|
result.size = -1
|
||||||
result.n = replaceObjBranches(cl, result.n)
|
result.n = replaceObjBranches(cl, result.n)
|
||||||
|
|
||||||
template typeBound(c, newty, oldty, field, info) =
|
|
||||||
let opr = newty.attachedOps[field]
|
|
||||||
if opr != nil and sfFromGeneric notin opr.flags:
|
|
||||||
# '=' needs to be instantiated for generics when the type is constructed:
|
|
||||||
#echo "DESTROY: instantiating ", astToStr(field), " for ", typeToString(oldty)
|
|
||||||
newty.attachedOps[field] = c.instTypeBoundOp(c, opr, oldty, info, attachedAsgn, 1)
|
|
||||||
|
|
||||||
proc instAllTypeBoundOp*(c: PContext, info: TLineInfo) =
|
|
||||||
var i = 0
|
|
||||||
while i < c.typesWithOps.len:
|
|
||||||
let (newty, oldty) = c.typesWithOps[i]
|
|
||||||
typeBound(c, newty, oldty, attachedDestructor, info)
|
|
||||||
typeBound(c, newty, oldty, attachedSink, info)
|
|
||||||
typeBound(c, newty, oldty, attachedAsgn, info)
|
|
||||||
inc i
|
|
||||||
setLen(c.typesWithOps, 0)
|
|
||||||
|
|
||||||
proc initTypeVars*(p: PContext, typeMap: LayeredIdTable, info: TLineInfo;
|
proc initTypeVars*(p: PContext, typeMap: LayeredIdTable, info: TLineInfo;
|
||||||
owner: PSym): TReplTypeVars =
|
owner: PSym): TReplTypeVars =
|
||||||
initIdTable(result.symMap)
|
initIdTable(result.symMap)
|
||||||
|
|
|
||||||
|
|
@ -791,7 +791,7 @@ proc transformCall(c: PTransf, n: PNode): PNode =
|
||||||
while (j < n.len):
|
while (j < n.len):
|
||||||
let b = transform(c, n[j])
|
let b = transform(c, n[j])
|
||||||
if not isConstExpr(b): break
|
if not isConstExpr(b): break
|
||||||
a = evalOp(op.magic, n, a, b, nil, c.graph)
|
a = evalOp(op.magic, n, a, b, nil, c.idgen, c.graph)
|
||||||
inc(j)
|
inc(j)
|
||||||
result.add(a)
|
result.add(a)
|
||||||
if result.len == 2: result = result[1]
|
if result.len == 2: result = result[1]
|
||||||
|
|
@ -869,7 +869,7 @@ proc commonOptimizations*(g: ModuleGraph; idgen: IdGenerator; c: PSym, n: PNode)
|
||||||
while j < args.len:
|
while j < args.len:
|
||||||
let b = args[j]
|
let b = args[j]
|
||||||
if not isConstExpr(b): break
|
if not isConstExpr(b): break
|
||||||
a = evalOp(op.magic, result, a, b, nil, g)
|
a = evalOp(op.magic, result, a, b, nil, idgen, g)
|
||||||
inc(j)
|
inc(j)
|
||||||
result.add(a)
|
result.add(a)
|
||||||
if result.len == 2: result = result[1]
|
if result.len == 2: result = result[1]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue