(cherry picked from commit d472022a77)
This commit is contained in:
Andreas Rumpf
2025-08-27 12:23:04 +02:00
committed by narimiran
parent 1735e585f2
commit fef0b5a351
4 changed files with 31 additions and 17 deletions

View File

@@ -815,6 +815,7 @@ type
# nodes are compared by structure!
counter*: int
data*: TNodePairSeq
ignoreTypes*: bool
TObjectSeq* = seq[RootRef]
TObjectSet* = object
@@ -1637,8 +1638,8 @@ proc initObjectSet*(): TObjectSet =
result = TObjectSet(counter: 0)
newSeq(result.data, StartSize)
proc initNodeTable*(): TNodeTable =
result = TNodeTable(counter: 0)
proc initNodeTable*(ignoreTypes=false): TNodeTable =
result = TNodeTable(counter: 0, ignoreTypes: ignoreTypes)
newSeq(result.data, StartSize)
proc skipTypes*(t: PType, kinds: TTypeKinds; maxIters: int): PType =

View File

@@ -42,32 +42,37 @@ proc hashTree*(n: PNode): Hash =
#echo "hashTree ", result
#echo n
proc treesEquivalent(a, b: PNode): bool =
proc treesEquivalent(a, b: PNode; ignoreTypes: bool): bool =
if a == b:
result = true
elif (a != nil) and (b != nil) and (a.kind == b.kind):
case a.kind
of nkEmpty, nkNilLit, nkType: result = true
of nkEmpty: result = true
of nkSym: result = a.sym.id == b.sym.id
of nkIdent: result = a.ident.id == b.ident.id
of nkCharLit..nkUInt64Lit: result = a.intVal == b.intVal
of nkFloatLit..nkFloat64Lit: result = a.floatVal == b.floatVal
of nkFloatLit..nkFloat64Lit:
result = cast[uint64](a.floatVal) == cast[uint64](b.floatVal)
#result = a.floatVal == b.floatVal
of nkStrLit..nkTripleStrLit: result = a.strVal == b.strVal
of nkType, nkNilLit:
result = a.typ == b.typ
else:
if a.len == b.len:
for i in 0..<a.len:
if not treesEquivalent(a[i], b[i]): return
if not treesEquivalent(a[i], b[i], ignoreTypes): return
result = true
else:
result = false
if result: result = sameTypeOrNil(a.typ, b.typ)
if result and not ignoreTypes:
result = sameTypeOrNil(a.typ, b.typ)
else:
result = false
proc nodeTableRawGet(t: TNodeTable, k: Hash, key: PNode): int =
var h: Hash = k and high(t.data)
while t.data[h].key != nil:
if (t.data[h].h == k) and treesEquivalent(t.data[h].key, key):
if (t.data[h].h == k) and treesEquivalent(t.data[h].key, key, t.ignoreTypes):
return h
h = nextTry(h, high(t.data))
result = -1

View File

@@ -249,6 +249,7 @@ type
# to not slow down interpretation
globals*: PNode #
constants*: PNode # constant data
contstantTab*: TNodeTable
types*: seq[PType] # some instructions reference types (e.g. 'except')
currentExceptionA*, currentExceptionB*: PNode
exceptionInstr*: int # index of instruction that raised the exception
@@ -298,7 +299,8 @@ proc newCtx*(module: PSym; cache: IdentCache; g: ModuleGraph; idgen: IdGenerator
prc: PProc(blocks: @[]), module: module, loopIterations: g.config.maxLoopIterationsVM,
callDepth: g.config.maxCallDepthVM,
comesFromHeuristic: unknownLineInfo, callbacks: @[], callbackIndex: initTable[string, int](), errorFlag: "",
cache: cache, config: g.config, graph: g, idgen: idgen)
cache: cache, config: g.config, graph: g, idgen: idgen,
contstantTab: initNodeTable(true))
proc refresh*(c: PCtx, module: PSym; idgen: IdGenerator) =
c.module = module

View File

@@ -33,7 +33,8 @@ when defined(nimPreviewSlimSystem):
import
ast, types, msgs, renderer, vmdef, trees,
magicsys, options, lowerings, lineinfos, transf, astmsgs
magicsys, options, lowerings, lineinfos, transf, astmsgs,
treetab
from modulegraphs import getBody
@@ -478,10 +479,16 @@ proc sameConstant*(a, b: PNode): bool =
result = true
proc genLiteral(c: PCtx; n: PNode): int =
# types do not matter here:
for i in 0..<c.constants.len:
if sameConstant(c.constants[i], n): return i
result = rawGenLiteral(c, n)
result = nodeTableTestOrSet(c.contstantTab, n, c.constants.len)
if result == c.constants.len:
let lit = rawGenLiteral(c, n)
assert lit == result
when false:
# types do not matter here:
for i in 0..<c.constants.len:
if sameConstant(c.constants[i], n): return i
result = rawGenLiteral(c, n)
proc unused(c: PCtx; n: PNode; x: TDest) {.inline.} =
if x >= 0:
@@ -1549,8 +1556,7 @@ template cannotEval(c: PCtx; n: PNode) =
if c.config.cmd == cmdCheck and c.config.m.errorOutputs != {}:
# nim check command with no error outputs doesn't need to cascade here,
# includes `tryConstExpr` case which should not continue generating code
localError(c.config, n.info, "cannot evaluate at compile time: " &
n.renderTree)
localError(c.config, n.info, "cannot evaluate at compile time: " & n.renderTree)
c.cannotEval = true
return
globalError(c.config, n.info, "cannot evaluate at compile time: " &
@@ -1888,7 +1894,7 @@ proc genCheckedObjAccess(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags) =
c.freeTemp(objR)
proc genArrAccess(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags) =
if n[0].typ == nil:
if n[0].typ == nil:
globalError(c.config, n.info, "cannot access array with nil type")
return