* fixes #20139; hash types based on its path relative its project * add a test case * fixes procs * better implementation and test case --------- Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
This commit is contained in:
parent
50baf21eac
commit
38d299dfc0
13 changed files with 143 additions and 74 deletions
|
|
@ -1704,7 +1704,7 @@ proc genNewFinalize(p: BProc, e: PNode) =
|
||||||
|
|
||||||
proc genOfHelper(p: BProc; dest: PType; a: Rope; info: TLineInfo; result: var Rope) =
|
proc genOfHelper(p: BProc; dest: PType; a: Rope; info: TLineInfo; result: var Rope) =
|
||||||
if optTinyRtti in p.config.globalOptions:
|
if optTinyRtti in p.config.globalOptions:
|
||||||
let token = $genDisplayElem(MD5Digest(hashType(dest)))
|
let token = $genDisplayElem(MD5Digest(hashType(dest, p.config)))
|
||||||
appcg(p.module, result, "#isObjDisplayCheck($#.m_type, $#, $#)", [a, getObjDepth(dest), token])
|
appcg(p.module, result, "#isObjDisplayCheck($#.m_type, $#, $#)", [a, getObjDepth(dest), token])
|
||||||
else:
|
else:
|
||||||
# unfortunately 'genTypeInfoV1' sets tfObjHasKids as a side effect, so we
|
# unfortunately 'genTypeInfoV1' sets tfObjHasKids as a side effect, so we
|
||||||
|
|
@ -2779,7 +2779,7 @@ proc upConv(p: BProc, n: PNode, d: var TLoc) =
|
||||||
rdMType(p, a, nilCheck, r)
|
rdMType(p, a, nilCheck, r)
|
||||||
if optTinyRtti in p.config.globalOptions:
|
if optTinyRtti in p.config.globalOptions:
|
||||||
let checkFor = $getObjDepth(dest)
|
let checkFor = $getObjDepth(dest)
|
||||||
let token = $genDisplayElem(MD5Digest(hashType(dest)))
|
let token = $genDisplayElem(MD5Digest(hashType(dest, p.config)))
|
||||||
if nilCheck != "":
|
if nilCheck != "":
|
||||||
linefmt(p, cpsStmts, "if ($1 && !#isObjDisplayCheck($2, $3, $4)){ #raiseObjectConversionError(); ",
|
linefmt(p, cpsStmts, "if ($1 && !#isObjDisplayCheck($2, $3, $4)){ #raiseObjectConversionError(); ",
|
||||||
[nilCheck, r, checkFor, token])
|
[nilCheck, r, checkFor, token])
|
||||||
|
|
|
||||||
|
|
@ -1081,7 +1081,7 @@ proc genTryCpp(p: BProc, t: PNode, d: var TLoc) =
|
||||||
let memberName = if p.module.compileToCpp: "m_type" else: "Sup.m_type"
|
let memberName = if p.module.compileToCpp: "m_type" else: "Sup.m_type"
|
||||||
if optTinyRtti in p.config.globalOptions:
|
if optTinyRtti in p.config.globalOptions:
|
||||||
let checkFor = $getObjDepth(typeNode.typ)
|
let checkFor = $getObjDepth(typeNode.typ)
|
||||||
appcg(p.module, orExpr, "#isObjDisplayCheck(#nimBorrowCurrentException()->$1, $2, $3)", [memberName, checkFor, $genDisplayElem(MD5Digest(hashType(typeNode.typ)))])
|
appcg(p.module, orExpr, "#isObjDisplayCheck(#nimBorrowCurrentException()->$1, $2, $3)", [memberName, checkFor, $genDisplayElem(MD5Digest(hashType(typeNode.typ, p.config)))])
|
||||||
else:
|
else:
|
||||||
let checkFor = genTypeInfoV1(p.module, typeNode.typ, typeNode.info)
|
let checkFor = genTypeInfoV1(p.module, typeNode.typ, typeNode.info)
|
||||||
appcg(p.module, orExpr, "#isObj(#nimBorrowCurrentException()->$1, $2)", [memberName, checkFor])
|
appcg(p.module, orExpr, "#isObj(#nimBorrowCurrentException()->$1, $2)", [memberName, checkFor])
|
||||||
|
|
@ -1300,7 +1300,7 @@ proc genTryGoto(p: BProc; t: PNode; d: var TLoc) =
|
||||||
let memberName = if p.module.compileToCpp: "m_type" else: "Sup.m_type"
|
let memberName = if p.module.compileToCpp: "m_type" else: "Sup.m_type"
|
||||||
if optTinyRtti in p.config.globalOptions:
|
if optTinyRtti in p.config.globalOptions:
|
||||||
let checkFor = $getObjDepth(t[i][j].typ)
|
let checkFor = $getObjDepth(t[i][j].typ)
|
||||||
appcg(p.module, orExpr, "#isObjDisplayCheck(#nimBorrowCurrentException()->$1, $2, $3)", [memberName, checkFor, $genDisplayElem(MD5Digest(hashType(t[i][j].typ)))])
|
appcg(p.module, orExpr, "#isObjDisplayCheck(#nimBorrowCurrentException()->$1, $2, $3)", [memberName, checkFor, $genDisplayElem(MD5Digest(hashType(t[i][j].typ, p.config)))])
|
||||||
else:
|
else:
|
||||||
let checkFor = genTypeInfoV1(p.module, t[i][j].typ, t[i][j].info)
|
let checkFor = genTypeInfoV1(p.module, t[i][j].typ, t[i][j].info)
|
||||||
appcg(p.module, orExpr, "#isObj(#nimBorrowCurrentException()->$1, $2)", [memberName, checkFor])
|
appcg(p.module, orExpr, "#isObj(#nimBorrowCurrentException()->$1, $2)", [memberName, checkFor])
|
||||||
|
|
@ -1445,7 +1445,7 @@ proc genTrySetjmp(p: BProc, t: PNode, d: var TLoc) =
|
||||||
let memberName = if p.module.compileToCpp: "m_type" else: "Sup.m_type"
|
let memberName = if p.module.compileToCpp: "m_type" else: "Sup.m_type"
|
||||||
if optTinyRtti in p.config.globalOptions:
|
if optTinyRtti in p.config.globalOptions:
|
||||||
let checkFor = $getObjDepth(t[i][j].typ)
|
let checkFor = $getObjDepth(t[i][j].typ)
|
||||||
appcg(p.module, orExpr, "#isObjDisplayCheck(#nimBorrowCurrentException()->$1, $2, $3)", [memberName, checkFor, $genDisplayElem(MD5Digest(hashType(t[i][j].typ)))])
|
appcg(p.module, orExpr, "#isObjDisplayCheck(#nimBorrowCurrentException()->$1, $2, $3)", [memberName, checkFor, $genDisplayElem(MD5Digest(hashType(t[i][j].typ, p.config)))])
|
||||||
else:
|
else:
|
||||||
let checkFor = genTypeInfoV1(p.module, t[i][j].typ, t[i][j].info)
|
let checkFor = genTypeInfoV1(p.module, t[i][j].typ, t[i][j].info)
|
||||||
appcg(p.module, orExpr, "#isObj(#nimBorrowCurrentException()->$1, $2)", [memberName, checkFor])
|
appcg(p.module, orExpr, "#isObj(#nimBorrowCurrentException()->$1, $2)", [memberName, checkFor])
|
||||||
|
|
|
||||||
|
|
@ -43,14 +43,14 @@ proc fillBackendName(m: BModule; s: PSym) =
|
||||||
result.add rope s.itemId.item
|
result.add rope s.itemId.item
|
||||||
if m.hcrOn:
|
if m.hcrOn:
|
||||||
result.add "_"
|
result.add "_"
|
||||||
result.add(idOrSig(s, m.module.name.s.mangle, m.sigConflicts))
|
result.add(idOrSig(s, m.module.name.s.mangle, m.sigConflicts, m.config))
|
||||||
s.loc.r = result
|
s.loc.r = result
|
||||||
writeMangledName(m.ndi, s, m.config)
|
writeMangledName(m.ndi, s, m.config)
|
||||||
|
|
||||||
proc fillParamName(m: BModule; s: PSym) =
|
proc fillParamName(m: BModule; s: PSym) =
|
||||||
if s.loc.r == "":
|
if s.loc.r == "":
|
||||||
var res = s.name.s.mangle
|
var res = s.name.s.mangle
|
||||||
res.add idOrSig(s, res, m.sigConflicts)
|
res.add idOrSig(s, res, m.sigConflicts, m.config)
|
||||||
# Take into account if HCR is on because of the following scenario:
|
# Take into account if HCR is on because of the following scenario:
|
||||||
# if a module gets imported and it has some more importc symbols in it,
|
# if a module gets imported and it has some more importc symbols in it,
|
||||||
# some param names might receive the "_0" suffix to distinguish from what
|
# some param names might receive the "_0" suffix to distinguish from what
|
||||||
|
|
@ -302,7 +302,7 @@ proc getSimpleTypeDesc(m: BModule, typ: PType): Rope =
|
||||||
else: result = ""
|
else: result = ""
|
||||||
|
|
||||||
if result != "" and typ.isImportedType():
|
if result != "" and typ.isImportedType():
|
||||||
let sig = hashType typ
|
let sig = hashType(typ, m.config)
|
||||||
if cacheGetType(m.typeCache, sig) == "":
|
if cacheGetType(m.typeCache, sig) == "":
|
||||||
m.typeCache[sig] = result
|
m.typeCache[sig] = result
|
||||||
|
|
||||||
|
|
@ -362,10 +362,10 @@ proc getTypeDescWeak(m: BModule; t: PType; check: var IntSet; kind: TSymKind): R
|
||||||
if isImportedCppType(etB) and t.kind == tyGenericInst:
|
if isImportedCppType(etB) and t.kind == tyGenericInst:
|
||||||
result = getTypeDescAux(m, t, check, kind)
|
result = getTypeDescAux(m, t, check, kind)
|
||||||
else:
|
else:
|
||||||
result = getTypeForward(m, t, hashType(t))
|
result = getTypeForward(m, t, hashType(t, m.config))
|
||||||
pushType(m, t)
|
pushType(m, t)
|
||||||
of tySequence:
|
of tySequence:
|
||||||
let sig = hashType(t)
|
let sig = hashType(t, m.config)
|
||||||
if optSeqDestructors in m.config.globalOptions:
|
if optSeqDestructors in m.config.globalOptions:
|
||||||
if skipTypes(etB[0], typedescInst).kind == tyEmpty:
|
if skipTypes(etB[0], typedescInst).kind == tyEmpty:
|
||||||
internalError(m.config, "cannot map the empty seq type to a C type")
|
internalError(m.config, "cannot map the empty seq type to a C type")
|
||||||
|
|
@ -398,7 +398,7 @@ proc getSeqPayloadType(m: BModule; t: PType): Rope =
|
||||||
#result = getTypeForward(m, t, hashType(t)) & "_Content"
|
#result = getTypeForward(m, t, hashType(t)) & "_Content"
|
||||||
|
|
||||||
proc seqV2ContentType(m: BModule; t: PType; check: var IntSet) =
|
proc seqV2ContentType(m: BModule; t: PType; check: var IntSet) =
|
||||||
let sig = hashType(t)
|
let sig = hashType(t, m.config)
|
||||||
let result = cacheGetType(m.typeCache, sig)
|
let result = cacheGetType(m.typeCache, sig)
|
||||||
if result == "":
|
if result == "":
|
||||||
discard getTypeDescAux(m, t, check, skVar)
|
discard getTypeDescAux(m, t, check, skVar)
|
||||||
|
|
@ -664,7 +664,7 @@ proc resolveStarsInCppType(typ: PType, idx, stars: int): PType =
|
||||||
else: result.elemType
|
else: result.elemType
|
||||||
|
|
||||||
proc getOpenArrayDesc(m: BModule, t: PType, check: var IntSet; kind: TSymKind): Rope =
|
proc getOpenArrayDesc(m: BModule, t: PType, check: var IntSet; kind: TSymKind): Rope =
|
||||||
let sig = hashType(t)
|
let sig = hashType(t, m.config)
|
||||||
if kind == skParam:
|
if kind == skParam:
|
||||||
result = getTypeDescWeak(m, t[0], check, kind) & "*"
|
result = getTypeDescWeak(m, t[0], check, kind) & "*"
|
||||||
else:
|
else:
|
||||||
|
|
@ -688,7 +688,7 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet; kind: TSymKin
|
||||||
# C type generation into an analysis and a code generation phase somehow.
|
# C type generation into an analysis and a code generation phase somehow.
|
||||||
if t.sym != nil: useHeader(m, t.sym)
|
if t.sym != nil: useHeader(m, t.sym)
|
||||||
if t != origTyp and origTyp.sym != nil: useHeader(m, origTyp.sym)
|
if t != origTyp and origTyp.sym != nil: useHeader(m, origTyp.sym)
|
||||||
let sig = hashType(origTyp)
|
let sig = hashType(origTyp, m.config)
|
||||||
|
|
||||||
defer: # defer is the simplest in this case
|
defer: # defer is the simplest in this case
|
||||||
if isImportedType(t) and not m.typeABICache.containsOrIncl(sig):
|
if isImportedType(t) and not m.typeABICache.containsOrIncl(sig):
|
||||||
|
|
@ -717,7 +717,7 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet; kind: TSymKin
|
||||||
result = getTypeDescAux(m, et, check, kind) & star
|
result = getTypeDescAux(m, et, check, kind) & star
|
||||||
else:
|
else:
|
||||||
# no restriction! We have a forward declaration for structs
|
# no restriction! We have a forward declaration for structs
|
||||||
let name = getTypeForward(m, et, hashType et)
|
let name = getTypeForward(m, et, hashType(et, m.config))
|
||||||
result = name & star
|
result = name & star
|
||||||
m.typeCache[sig] = result
|
m.typeCache[sig] = result
|
||||||
of tySequence:
|
of tySequence:
|
||||||
|
|
@ -726,7 +726,7 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet; kind: TSymKin
|
||||||
m.typeCache[sig] = result
|
m.typeCache[sig] = result
|
||||||
else:
|
else:
|
||||||
# no restriction! We have a forward declaration for structs
|
# no restriction! We have a forward declaration for structs
|
||||||
let name = getTypeForward(m, et, hashType et)
|
let name = getTypeForward(m, et, hashType(et, m.config))
|
||||||
result = name & seqStar(m) & star
|
result = name & seqStar(m) & star
|
||||||
m.typeCache[sig] = result
|
m.typeCache[sig] = result
|
||||||
pushType(m, et)
|
pushType(m, et)
|
||||||
|
|
@ -893,7 +893,7 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet; kind: TSymKin
|
||||||
# Don't use the imported name as it may be scoped: 'Foo::SomeKind'
|
# Don't use the imported name as it may be scoped: 'Foo::SomeKind'
|
||||||
result = rope("tySet_")
|
result = rope("tySet_")
|
||||||
t.lastSon.typeName(result)
|
t.lastSon.typeName(result)
|
||||||
result.add $t.lastSon.hashType
|
result.add $t.lastSon.hashType(m.config)
|
||||||
m.typeCache[sig] = result
|
m.typeCache[sig] = result
|
||||||
if not isImportedType(t):
|
if not isImportedType(t):
|
||||||
let s = int(getSize(m.config, t))
|
let s = int(getSize(m.config, t))
|
||||||
|
|
@ -1066,7 +1066,7 @@ proc discriminatorTableName(m: BModule, objtype: PType, d: PSym): Rope =
|
||||||
objtype = objtype[0].skipTypes(abstractPtrs)
|
objtype = objtype[0].skipTypes(abstractPtrs)
|
||||||
if objtype.sym == nil:
|
if objtype.sym == nil:
|
||||||
internalError(m.config, d.info, "anonymous obj with discriminator")
|
internalError(m.config, d.info, "anonymous obj with discriminator")
|
||||||
result = "NimDT_$1_$2" % [rope($hashType(objtype)), rope(d.name.s.mangle)]
|
result = "NimDT_$1_$2" % [rope($hashType(objtype, m.config)), rope(d.name.s.mangle)]
|
||||||
|
|
||||||
proc rope(arg: Int128): Rope = rope($arg)
|
proc rope(arg: Int128): Rope = rope($arg)
|
||||||
|
|
||||||
|
|
@ -1285,7 +1285,7 @@ proc genTypeInfo2Name(m: BModule; t: PType): Rope =
|
||||||
result.add m.name.s & "."
|
result.add m.name.s & "."
|
||||||
result.add it.sym.name.s
|
result.add it.sym.name.s
|
||||||
else:
|
else:
|
||||||
result = $hashType(it)
|
result = $hashType(it, m.config)
|
||||||
result = makeCString(result)
|
result = makeCString(result)
|
||||||
|
|
||||||
proc isTrivialProc(g: ModuleGraph; s: PSym): bool {.inline.} = getBody(g, s).len == 0
|
proc isTrivialProc(g: ModuleGraph; s: PSym): bool {.inline.} = getBody(g, s).len == 0
|
||||||
|
|
@ -1329,14 +1329,14 @@ proc genDisplayElem(d: MD5Digest): uint32 =
|
||||||
result += uint32(d[i])
|
result += uint32(d[i])
|
||||||
result = result shl 8
|
result = result shl 8
|
||||||
|
|
||||||
proc genDisplay(t: PType, depth: int): Rope =
|
proc genDisplay(m: BModule, t: PType, depth: int): Rope =
|
||||||
result = Rope"{"
|
result = Rope"{"
|
||||||
var x = t
|
var x = t
|
||||||
var seqs = newSeq[string](depth+1)
|
var seqs = newSeq[string](depth+1)
|
||||||
var i = 0
|
var i = 0
|
||||||
while x != nil:
|
while x != nil:
|
||||||
x = skipTypes(x, skipPtrs)
|
x = skipTypes(x, skipPtrs)
|
||||||
seqs[i] = $genDisplayElem(MD5Digest(hashType(x)))
|
seqs[i] = $genDisplayElem(MD5Digest(hashType(x, m.config)))
|
||||||
x = x[0]
|
x = x[0]
|
||||||
inc i
|
inc i
|
||||||
|
|
||||||
|
|
@ -1376,7 +1376,7 @@ proc genTypeInfoV2OldImpl(m: BModule; t, origType: PType, name: Rope; info: TLin
|
||||||
[name, getTypeDesc(m, t), rope(objDepth), rope(flags)])
|
[name, getTypeDesc(m, t), rope(objDepth), rope(flags)])
|
||||||
|
|
||||||
if objDepth >= 0:
|
if objDepth >= 0:
|
||||||
let objDisplay = genDisplay(t, objDepth)
|
let objDisplay = genDisplay(m, t, objDepth)
|
||||||
let objDisplayStore = getTempName(m)
|
let objDisplayStore = getTempName(m)
|
||||||
m.s[cfsVars].addf("static $1 $2[$3] = $4;$n", [getTypeDesc(m, getSysType(m.g.graph, unknownLineInfo, tyUInt32), skVar), objDisplayStore, rope(objDepth+1), objDisplay])
|
m.s[cfsVars].addf("static $1 $2[$3] = $4;$n", [getTypeDesc(m, getSysType(m.g.graph, unknownLineInfo, tyUInt32), skVar), objDisplayStore, rope(objDepth+1), objDisplay])
|
||||||
addf(typeEntry, "$1.display = $2;$n", [name, rope(objDisplayStore)])
|
addf(typeEntry, "$1.display = $2;$n", [name, rope(objDisplayStore)])
|
||||||
|
|
@ -1408,7 +1408,7 @@ proc genTypeInfoV2Impl(m: BModule; t, origType: PType, name: Rope; info: TLineIn
|
||||||
[getTypeDesc(m, t), rope(objDepth)])
|
[getTypeDesc(m, t), rope(objDepth)])
|
||||||
|
|
||||||
if objDepth >= 0:
|
if objDepth >= 0:
|
||||||
let objDisplay = genDisplay(t, objDepth)
|
let objDisplay = genDisplay(m, t, objDepth)
|
||||||
let objDisplayStore = getTempName(m)
|
let objDisplayStore = getTempName(m)
|
||||||
m.s[cfsVars].addf("static NIM_CONST $1 $2[$3] = $4;$n", [getTypeDesc(m, getSysType(m.g.graph, unknownLineInfo, tyUInt32), skVar), objDisplayStore, rope(objDepth+1), objDisplay])
|
m.s[cfsVars].addf("static NIM_CONST $1 $2[$3] = $4;$n", [getTypeDesc(m, getSysType(m.g.graph, unknownLineInfo, tyUInt32), skVar), objDisplayStore, rope(objDepth+1), objDisplay])
|
||||||
addf(typeEntry, ", .display = $1", [rope(objDisplayStore)])
|
addf(typeEntry, ", .display = $1", [rope(objDisplayStore)])
|
||||||
|
|
@ -1435,7 +1435,7 @@ proc genTypeInfoV2(m: BModule, t: PType; info: TLineInfo): Rope =
|
||||||
|
|
||||||
let prefixTI = if m.hcrOn: "(" else: "(&"
|
let prefixTI = if m.hcrOn: "(" else: "(&"
|
||||||
|
|
||||||
let sig = hashType(origType)
|
let sig = hashType(origType, m.config)
|
||||||
result = m.typeInfoMarkerV2.getOrDefault(sig)
|
result = m.typeInfoMarkerV2.getOrDefault(sig)
|
||||||
if result != "":
|
if result != "":
|
||||||
return prefixTI.rope & result & ")".rope
|
return prefixTI.rope & result & ")".rope
|
||||||
|
|
@ -1509,7 +1509,7 @@ proc genTypeInfoV1(m: BModule, t: PType; info: TLineInfo): Rope =
|
||||||
|
|
||||||
let prefixTI = if m.hcrOn: "(" else: "(&"
|
let prefixTI = if m.hcrOn: "(" else: "(&"
|
||||||
|
|
||||||
let sig = hashType(origType)
|
let sig = hashType(origType, m.config)
|
||||||
result = m.typeInfoMarker.getOrDefault(sig)
|
result = m.typeInfoMarker.getOrDefault(sig)
|
||||||
if result != "":
|
if result != "":
|
||||||
return prefixTI.rope & result & ")".rope
|
return prefixTI.rope & result & ")".rope
|
||||||
|
|
|
||||||
|
|
@ -1630,7 +1630,7 @@ proc registerModuleToMain(g: BModuleList; m: BModule) =
|
||||||
hcrModuleMeta.addf("\t\"\"};$n", [])
|
hcrModuleMeta.addf("\t\"\"};$n", [])
|
||||||
hcrModuleMeta.addf("$nN_LIB_EXPORT N_NIMCALL(void**, HcrGetImportedModules)() { return (void**)hcr_module_list; }$n", [])
|
hcrModuleMeta.addf("$nN_LIB_EXPORT N_NIMCALL(void**, HcrGetImportedModules)() { return (void**)hcr_module_list; }$n", [])
|
||||||
hcrModuleMeta.addf("$nN_LIB_EXPORT N_NIMCALL(char*, HcrGetSigHash)() { return \"$1\"; }$n$n",
|
hcrModuleMeta.addf("$nN_LIB_EXPORT N_NIMCALL(char*, HcrGetSigHash)() { return \"$1\"; }$n$n",
|
||||||
[($sigHash(m.module)).rope])
|
[($sigHash(m.module, m.config)).rope])
|
||||||
if sfMainModule in m.module.flags:
|
if sfMainModule in m.module.flags:
|
||||||
g.mainModProcs.add(hcrModuleMeta)
|
g.mainModProcs.add(hcrModuleMeta)
|
||||||
g.mainModProcs.addf("static void* hcr_handle;$N", [])
|
g.mainModProcs.addf("static void* hcr_handle;$N", [])
|
||||||
|
|
|
||||||
|
|
@ -217,7 +217,7 @@ proc genOp(c: var Con; t: PType; kind: TTypeAttachedOp; dest, ri: PNode): PNode
|
||||||
var op = getAttachedOp(c.graph, t, kind)
|
var op = getAttachedOp(c.graph, t, kind)
|
||||||
if op == nil or op.ast.isGenericRoutine:
|
if op == nil or op.ast.isGenericRoutine:
|
||||||
# give up and find the canonical type instead:
|
# give up and find the canonical type instead:
|
||||||
let h = sighashes.hashType(t, {CoType, CoConsiderOwned, CoDistinct})
|
let h = sighashes.hashType(t, c.graph.config, {CoType, CoConsiderOwned, CoDistinct})
|
||||||
let canon = c.graph.canonTypes.getOrDefault(h)
|
let canon = c.graph.canonTypes.getOrDefault(h)
|
||||||
if canon != nil:
|
if canon != nil:
|
||||||
op = getAttachedOp(c.graph, canon, kind)
|
op = getAttachedOp(c.graph, canon, kind)
|
||||||
|
|
|
||||||
|
|
@ -262,7 +262,7 @@ proc mangleName(m: BModule, s: PSym): Rope =
|
||||||
if m.config.hcrOn:
|
if m.config.hcrOn:
|
||||||
# When hot reloading is enabled, we must ensure that the names
|
# When hot reloading is enabled, we must ensure that the names
|
||||||
# of functions and types will be preserved across rebuilds:
|
# of functions and types will be preserved across rebuilds:
|
||||||
result.add(idOrSig(s, m.module.name.s, m.sigConflicts))
|
result.add(idOrSig(s, m.module.name.s, m.sigConflicts, m.config))
|
||||||
else:
|
else:
|
||||||
result.add("_")
|
result.add("_")
|
||||||
result.add(rope(s.id))
|
result.add(rope(s.id))
|
||||||
|
|
@ -2813,7 +2813,7 @@ proc genModule(p: PProc, n: PNode) =
|
||||||
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" &
|
||||||
idOrSig(moduleSym, moduleSym.name.s, p.module.sigConflicts)
|
idOrSig(moduleSym, moduleSym.name.s, p.module.sigConflicts, p.config)
|
||||||
lineF(p, "var $1;$n", [moduleLoadedVar])
|
lineF(p, "var $1;$n", [moduleLoadedVar])
|
||||||
var inGuardedBlock = false
|
var inGuardedBlock = false
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -553,7 +553,7 @@ proc useSeqOrStrOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||||
# operation here:
|
# operation here:
|
||||||
var t = t
|
var t = t
|
||||||
if t.assignment == nil or t.destructor == nil:
|
if t.assignment == nil or t.destructor == nil:
|
||||||
let h = sighashes.hashType(t, {CoType, CoConsiderOwned, CoDistinct})
|
let h = sighashes.hashType(t,c.g.config, {CoType, CoConsiderOwned, CoDistinct})
|
||||||
let canon = c.g.canonTypes.getOrDefault(h)
|
let canon = c.g.canonTypes.getOrDefault(h)
|
||||||
if canon != nil: t = canon
|
if canon != nil: t = canon
|
||||||
|
|
||||||
|
|
@ -1113,7 +1113,7 @@ proc createTypeBoundOps(g: ModuleGraph; c: PContext; orig: PType; info: TLineInf
|
||||||
let skipped = orig.skipTypes({tyGenericInst, tyAlias, tySink})
|
let skipped = orig.skipTypes({tyGenericInst, tyAlias, tySink})
|
||||||
if isEmptyContainer(skipped) or skipped.kind == tyStatic: return
|
if isEmptyContainer(skipped) or skipped.kind == tyStatic: return
|
||||||
|
|
||||||
let h = sighashes.hashType(skipped, {CoType, CoConsiderOwned, CoDistinct})
|
let h = sighashes.hashType(skipped, g.config, {CoType, CoConsiderOwned, CoDistinct})
|
||||||
var canon = g.canonTypes.getOrDefault(h)
|
var canon = g.canonTypes.getOrDefault(h)
|
||||||
if canon == nil:
|
if canon == nil:
|
||||||
g.canonTypes[h] = skipped
|
g.canonTypes[h] = skipped
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
## Path handling utilities for Nim. Strictly typed code in order
|
## Path handling utilities for Nim. Strictly typed code in order
|
||||||
## to avoid the never ending time sink in getting path handling right.
|
## to avoid the never ending time sink in getting path handling right.
|
||||||
|
|
||||||
import os, pathnorm
|
import os, pathnorm, strutils
|
||||||
|
|
||||||
when defined(nimPreviewSlimSystem):
|
when defined(nimPreviewSlimSystem):
|
||||||
import std/[syncio, assertions]
|
import std/[syncio, assertions]
|
||||||
|
|
@ -102,3 +102,52 @@ when true:
|
||||||
proc addFileExt*(x: RelativeFile; ext: string): RelativeFile {.borrow.}
|
proc addFileExt*(x: RelativeFile; ext: string): RelativeFile {.borrow.}
|
||||||
|
|
||||||
proc writeFile*(x: AbsoluteFile; content: string) {.borrow.}
|
proc writeFile*(x: AbsoluteFile; content: string) {.borrow.}
|
||||||
|
|
||||||
|
proc skipHomeDir(x: string): int =
|
||||||
|
when defined(windows):
|
||||||
|
if x.continuesWith("Users/", len("C:/")):
|
||||||
|
result = 3
|
||||||
|
else:
|
||||||
|
result = 0
|
||||||
|
else:
|
||||||
|
if x.startsWith("/home/") or x.startsWith("/Users/"):
|
||||||
|
result = 3
|
||||||
|
elif x.startsWith("/mnt/") and x.continuesWith("/Users/", len("/mnt/c")):
|
||||||
|
result = 5
|
||||||
|
else:
|
||||||
|
result = 0
|
||||||
|
|
||||||
|
proc relevantPart(s: string; afterSlashX: int): string =
|
||||||
|
result = newStringOfCap(s.len - 8)
|
||||||
|
var slashes = afterSlashX
|
||||||
|
for i in 0..<s.len:
|
||||||
|
if slashes == 0:
|
||||||
|
result.add s[i]
|
||||||
|
elif s[i] == '/':
|
||||||
|
dec slashes
|
||||||
|
|
||||||
|
template canonSlashes(x: string): string =
|
||||||
|
when defined(windows):
|
||||||
|
x.replace('\\', '/')
|
||||||
|
else:
|
||||||
|
x
|
||||||
|
|
||||||
|
proc customPathImpl(x: string): string =
|
||||||
|
# Idea: Encode a "protocol" via "//protocol/path" which is not ambiguous
|
||||||
|
# as path canonicalization would have removed the double slashes.
|
||||||
|
# /mnt/X/Users/Y
|
||||||
|
# X:\\Users\Y
|
||||||
|
# /home/Y
|
||||||
|
# -->
|
||||||
|
# //user/
|
||||||
|
if not isAbsolute(x):
|
||||||
|
result = customPathImpl(canonSlashes(getCurrentDir() / x))
|
||||||
|
else:
|
||||||
|
let slashes = skipHomeDir(x)
|
||||||
|
if slashes > 0:
|
||||||
|
result = "//user/" & relevantPart(x, slashes)
|
||||||
|
else:
|
||||||
|
result = x
|
||||||
|
|
||||||
|
proc customPath*(x: string): string =
|
||||||
|
customPathImpl canonSlashes x
|
||||||
|
|
|
||||||
|
|
@ -9,10 +9,12 @@
|
||||||
|
|
||||||
## Computes hash values for routine (proc, method etc) signatures.
|
## Computes hash values for routine (proc, method etc) signatures.
|
||||||
|
|
||||||
import ast, tables, ropes, md5, modulegraphs
|
import ast, tables, ropes, md5, modulegraphs, options, msgs, packages, pathutils
|
||||||
from hashes import Hash
|
from hashes import Hash
|
||||||
import types
|
import types
|
||||||
|
|
||||||
|
import std/os
|
||||||
|
|
||||||
when defined(nimPreviewSlimSystem):
|
when defined(nimPreviewSlimSystem):
|
||||||
import std/assertions
|
import std/assertions
|
||||||
|
|
||||||
|
|
@ -42,8 +44,7 @@ type
|
||||||
CoDistinct
|
CoDistinct
|
||||||
CoHashTypeInsideNode
|
CoHashTypeInsideNode
|
||||||
|
|
||||||
proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag])
|
proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]; conf: ConfigRef)
|
||||||
|
|
||||||
proc hashSym(c: var MD5Context, s: PSym) =
|
proc hashSym(c: var MD5Context, s: PSym) =
|
||||||
if sfAnon in s.flags or s.kind == skGenericParam:
|
if sfAnon in s.flags or s.kind == skGenericParam:
|
||||||
c &= ":anon"
|
c &= ":anon"
|
||||||
|
|
@ -54,20 +55,21 @@ proc hashSym(c: var MD5Context, s: PSym) =
|
||||||
c &= "."
|
c &= "."
|
||||||
it = it.owner
|
it = it.owner
|
||||||
|
|
||||||
proc hashTypeSym(c: var MD5Context, s: PSym) =
|
proc hashTypeSym(c: var MD5Context, s: PSym; conf: ConfigRef) =
|
||||||
if sfAnon in s.flags or s.kind == skGenericParam:
|
if sfAnon in s.flags or s.kind == skGenericParam:
|
||||||
c &= ":anon"
|
c &= ":anon"
|
||||||
else:
|
else:
|
||||||
var it = s
|
var it = s
|
||||||
|
c &= customPath(conf.toFullPath(s.info))
|
||||||
while it != nil:
|
while it != nil:
|
||||||
if sfFromGeneric in it.flags and it.kind in routineKinds and
|
if sfFromGeneric in it.flags and it.kind in routineKinds and
|
||||||
it.typ != nil:
|
it.typ != nil:
|
||||||
hashType c, it.typ, {CoProc}
|
hashType c, it.typ, {CoProc}, conf
|
||||||
c &= it.name.s
|
c &= it.name.s
|
||||||
c &= "."
|
c &= "."
|
||||||
it = it.owner
|
it = it.owner
|
||||||
|
|
||||||
proc hashTree(c: var MD5Context, n: PNode; flags: set[ConsiderFlag]) =
|
proc hashTree(c: var MD5Context, n: PNode; flags: set[ConsiderFlag]; conf: ConfigRef) =
|
||||||
if n == nil:
|
if n == nil:
|
||||||
c &= "\255"
|
c &= "\255"
|
||||||
return
|
return
|
||||||
|
|
@ -82,7 +84,7 @@ proc hashTree(c: var MD5Context, n: PNode; flags: set[ConsiderFlag]) =
|
||||||
of nkSym:
|
of nkSym:
|
||||||
hashSym(c, n.sym)
|
hashSym(c, n.sym)
|
||||||
if CoHashTypeInsideNode in flags and n.sym.typ != nil:
|
if CoHashTypeInsideNode in flags and n.sym.typ != nil:
|
||||||
hashType(c, n.sym.typ, flags)
|
hashType(c, n.sym.typ, flags, conf)
|
||||||
of nkCharLit..nkUInt64Lit:
|
of nkCharLit..nkUInt64Lit:
|
||||||
let v = n.intVal
|
let v = n.intVal
|
||||||
lowlevel v
|
lowlevel v
|
||||||
|
|
@ -92,9 +94,9 @@ proc hashTree(c: var MD5Context, n: PNode; flags: set[ConsiderFlag]) =
|
||||||
of nkStrLit..nkTripleStrLit:
|
of nkStrLit..nkTripleStrLit:
|
||||||
c &= n.strVal
|
c &= n.strVal
|
||||||
else:
|
else:
|
||||||
for i in 0..<n.len: hashTree(c, n[i], flags)
|
for i in 0..<n.len: hashTree(c, n[i], flags, conf)
|
||||||
|
|
||||||
proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
|
proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]; conf: ConfigRef) =
|
||||||
if t == nil:
|
if t == nil:
|
||||||
c &= "\254"
|
c &= "\254"
|
||||||
return
|
return
|
||||||
|
|
@ -102,14 +104,14 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
|
||||||
case t.kind
|
case t.kind
|
||||||
of tyGenericInvocation:
|
of tyGenericInvocation:
|
||||||
for i in 0..<t.len:
|
for i in 0..<t.len:
|
||||||
c.hashType t[i], flags
|
c.hashType t[i], flags, conf
|
||||||
of tyDistinct:
|
of tyDistinct:
|
||||||
if CoDistinct in flags:
|
if CoDistinct in flags:
|
||||||
if t.sym != nil: c.hashSym(t.sym)
|
if t.sym != nil: c.hashSym(t.sym)
|
||||||
if t.sym == nil or tfFromGeneric in t.flags:
|
if t.sym == nil or tfFromGeneric in t.flags:
|
||||||
c.hashType t.lastSon, flags
|
c.hashType t.lastSon, flags, conf
|
||||||
elif CoType in flags or t.sym == nil:
|
elif CoType in flags or t.sym == nil:
|
||||||
c.hashType t.lastSon, flags
|
c.hashType t.lastSon, flags, conf
|
||||||
else:
|
else:
|
||||||
c.hashSym(t.sym)
|
c.hashSym(t.sym)
|
||||||
of tyGenericInst:
|
of tyGenericInst:
|
||||||
|
|
@ -119,15 +121,15 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
|
||||||
# value for each instantiation, so we hash the generic parameters here:
|
# value for each instantiation, so we hash the generic parameters here:
|
||||||
let normalizedType = t.skipGenericAlias
|
let normalizedType = t.skipGenericAlias
|
||||||
for i in 0..<normalizedType.len - 1:
|
for i in 0..<normalizedType.len - 1:
|
||||||
c.hashType t[i], flags
|
c.hashType t[i], flags, conf
|
||||||
else:
|
else:
|
||||||
c.hashType t.lastSon, flags
|
c.hashType t.lastSon, flags, conf
|
||||||
of tyAlias, tySink, tyUserTypeClasses, tyInferred:
|
of tyAlias, tySink, tyUserTypeClasses, tyInferred:
|
||||||
c.hashType t.lastSon, flags
|
c.hashType t.lastSon, flags, conf
|
||||||
of tyOwned:
|
of tyOwned:
|
||||||
if CoConsiderOwned in flags:
|
if CoConsiderOwned in flags:
|
||||||
c &= char(t.kind)
|
c &= char(t.kind)
|
||||||
c.hashType t.lastSon, flags
|
c.hashType t.lastSon, flags, conf
|
||||||
of tyBool, tyChar, tyInt..tyUInt64:
|
of tyBool, tyChar, tyInt..tyUInt64:
|
||||||
# no canonicalization for integral types, so that e.g. ``pid_t`` is
|
# no canonicalization for integral types, so that e.g. ``pid_t`` is
|
||||||
# produced instead of ``NI``:
|
# produced instead of ``NI``:
|
||||||
|
|
@ -141,7 +143,7 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
|
||||||
t.typeInst = nil
|
t.typeInst = nil
|
||||||
assert inst.kind == tyGenericInst
|
assert inst.kind == tyGenericInst
|
||||||
for i in 0..<inst.len - 1:
|
for i in 0..<inst.len - 1:
|
||||||
c.hashType inst[i], flags
|
c.hashType inst[i], flags, conf
|
||||||
t.typeInst = inst
|
t.typeInst = inst
|
||||||
return
|
return
|
||||||
c &= char(t.kind)
|
c &= char(t.kind)
|
||||||
|
|
@ -153,7 +155,7 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
|
||||||
# The user has set a specific name for this type
|
# The user has set a specific name for this type
|
||||||
c &= t.sym.loc.r
|
c &= t.sym.loc.r
|
||||||
elif CoOwnerSig in flags:
|
elif CoOwnerSig in flags:
|
||||||
c.hashTypeSym(t.sym)
|
c.hashTypeSym(t.sym, conf)
|
||||||
else:
|
else:
|
||||||
c.hashSym(t.sym)
|
c.hashSym(t.sym)
|
||||||
|
|
||||||
|
|
@ -172,7 +174,7 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
|
||||||
# xxx instead, use a hash table to indicate we've already visited a type, which
|
# xxx instead, use a hash table to indicate we've already visited a type, which
|
||||||
# would also be more efficient.
|
# would also be more efficient.
|
||||||
symWithFlags.flags.excl {sfAnon, sfGenSym}
|
symWithFlags.flags.excl {sfAnon, sfGenSym}
|
||||||
hashTree(c, t.n, flags + {CoHashTypeInsideNode})
|
hashTree(c, t.n, flags + {CoHashTypeInsideNode}, conf)
|
||||||
symWithFlags.flags = oldFlags
|
symWithFlags.flags = oldFlags
|
||||||
else:
|
else:
|
||||||
# The object has no fields: we _must_ add something here in order to
|
# The object has no fields: we _must_ add something here in order to
|
||||||
|
|
@ -182,15 +184,15 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
|
||||||
else:
|
else:
|
||||||
c &= t.id
|
c &= t.id
|
||||||
if t.len > 0 and t[0] != nil:
|
if t.len > 0 and t[0] != nil:
|
||||||
hashType c, t[0], flags
|
hashType c, t[0], flags, conf
|
||||||
of tyRef, tyPtr, tyGenericBody, tyVar:
|
of tyRef, tyPtr, tyGenericBody, tyVar:
|
||||||
c &= char(t.kind)
|
c &= char(t.kind)
|
||||||
if t.sons.len > 0:
|
if t.sons.len > 0:
|
||||||
c.hashType t.lastSon, flags
|
c.hashType t.lastSon, flags, conf
|
||||||
if tfVarIsPtr in t.flags: c &= ".varisptr"
|
if tfVarIsPtr in t.flags: c &= ".varisptr"
|
||||||
of tyFromExpr:
|
of tyFromExpr:
|
||||||
c &= char(t.kind)
|
c &= char(t.kind)
|
||||||
c.hashTree(t.n, {})
|
c.hashTree(t.n, {}, conf)
|
||||||
of tyTuple:
|
of tyTuple:
|
||||||
c &= char(t.kind)
|
c &= char(t.kind)
|
||||||
if t.n != nil and CoType notin flags:
|
if t.n != nil and CoType notin flags:
|
||||||
|
|
@ -199,19 +201,19 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
|
||||||
assert(t.n[i].kind == nkSym)
|
assert(t.n[i].kind == nkSym)
|
||||||
c &= t.n[i].sym.name.s
|
c &= t.n[i].sym.name.s
|
||||||
c &= ':'
|
c &= ':'
|
||||||
c.hashType(t[i], flags+{CoIgnoreRange})
|
c.hashType(t[i], flags+{CoIgnoreRange}, conf)
|
||||||
c &= ','
|
c &= ','
|
||||||
else:
|
else:
|
||||||
for i in 0..<t.len: c.hashType t[i], flags+{CoIgnoreRange}
|
for i in 0..<t.len: c.hashType t[i], flags+{CoIgnoreRange}, conf
|
||||||
of tyRange:
|
of tyRange:
|
||||||
if CoIgnoreRange notin flags:
|
if CoIgnoreRange notin flags:
|
||||||
c &= char(t.kind)
|
c &= char(t.kind)
|
||||||
c.hashTree(t.n, {})
|
c.hashTree(t.n, {}, conf)
|
||||||
c.hashType(t[0], flags)
|
c.hashType(t[0], flags, conf)
|
||||||
of tyStatic:
|
of tyStatic:
|
||||||
c &= char(t.kind)
|
c &= char(t.kind)
|
||||||
c.hashTree(t.n, {})
|
c.hashTree(t.n, {}, conf)
|
||||||
c.hashType(t[0], flags)
|
c.hashType(t[0], flags, conf)
|
||||||
of tyProc:
|
of tyProc:
|
||||||
c &= char(t.kind)
|
c &= char(t.kind)
|
||||||
c &= (if tfIterator in t.flags: "iterator " else: "proc ")
|
c &= (if tfIterator in t.flags: "iterator " else: "proc ")
|
||||||
|
|
@ -221,11 +223,11 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
|
||||||
let param = params[i].sym
|
let param = params[i].sym
|
||||||
c &= param.name.s
|
c &= param.name.s
|
||||||
c &= ':'
|
c &= ':'
|
||||||
c.hashType(param.typ, flags)
|
c.hashType(param.typ, flags, conf)
|
||||||
c &= ','
|
c &= ','
|
||||||
c.hashType(t[0], flags)
|
c.hashType(t[0], flags, conf)
|
||||||
else:
|
else:
|
||||||
for i in 0..<t.len: c.hashType(t[i], flags)
|
for i in 0..<t.len: c.hashType(t[i], flags, conf)
|
||||||
c &= char(t.callConv)
|
c &= char(t.callConv)
|
||||||
# purity of functions doesn't have to affect the mangling (which is in fact
|
# purity of functions doesn't have to affect the mangling (which is in fact
|
||||||
# problematic for HCR - someone could have cached a pointer to another
|
# problematic for HCR - someone could have cached a pointer to another
|
||||||
|
|
@ -237,10 +239,10 @@ proc hashType(c: var MD5Context, t: PType; flags: set[ConsiderFlag]) =
|
||||||
if tfVarargs in t.flags: c &= ".varargs"
|
if tfVarargs in t.flags: c &= ".varargs"
|
||||||
of tyArray:
|
of tyArray:
|
||||||
c &= char(t.kind)
|
c &= char(t.kind)
|
||||||
for i in 0..<t.len: c.hashType(t[i], flags-{CoIgnoreRange})
|
for i in 0..<t.len: c.hashType(t[i], flags-{CoIgnoreRange}, conf)
|
||||||
else:
|
else:
|
||||||
c &= char(t.kind)
|
c &= char(t.kind)
|
||||||
for i in 0..<t.len: c.hashType(t[i], flags)
|
for i in 0..<t.len: c.hashType(t[i], flags, conf)
|
||||||
if tfNotNil in t.flags and CoType notin flags: c &= "not nil"
|
if tfNotNil in t.flags and CoType notin flags: c &= "not nil"
|
||||||
|
|
||||||
when defined(debugSigHashes):
|
when defined(debugSigHashes):
|
||||||
|
|
@ -257,19 +259,19 @@ when defined(debugSigHashes):
|
||||||
# select hash, type from sighashes where hash in
|
# select hash, type from sighashes where hash in
|
||||||
# (select hash from sighashes group by hash having count(*) > 1) order by hash;
|
# (select hash from sighashes group by hash having count(*) > 1) order by hash;
|
||||||
|
|
||||||
proc hashType*(t: PType; flags: set[ConsiderFlag] = {CoType}): SigHash =
|
proc hashType*(t: PType; conf: ConfigRef; flags: set[ConsiderFlag] = {CoType}): SigHash =
|
||||||
var c: MD5Context
|
var c: MD5Context
|
||||||
md5Init c
|
md5Init c
|
||||||
hashType c, t, flags+{CoOwnerSig}
|
hashType c, t, flags+{CoOwnerSig}, conf
|
||||||
md5Final c, result.MD5Digest
|
md5Final c, result.MD5Digest
|
||||||
when defined(debugSigHashes):
|
when defined(debugSigHashes):
|
||||||
db.exec(sql"INSERT OR IGNORE INTO sighashes(type, hash) VALUES (?, ?)",
|
db.exec(sql"INSERT OR IGNORE INTO sighashes(type, hash) VALUES (?, ?)",
|
||||||
typeToString(t), $result)
|
typeToString(t), $result)
|
||||||
|
|
||||||
proc hashProc*(s: PSym): SigHash =
|
proc hashProc*(s: PSym; conf: ConfigRef): SigHash =
|
||||||
var c: MD5Context
|
var c: MD5Context
|
||||||
md5Init c
|
md5Init c
|
||||||
hashType c, s.typ, {CoProc}
|
hashType c, s.typ, {CoProc}, conf
|
||||||
|
|
||||||
var m = s
|
var m = s
|
||||||
while m.kind != skModule: m = m.owner
|
while m.kind != skModule: m = m.owner
|
||||||
|
|
@ -315,9 +317,9 @@ proc hashOwner*(s: PSym): SigHash =
|
||||||
|
|
||||||
md5Final c, result.MD5Digest
|
md5Final c, result.MD5Digest
|
||||||
|
|
||||||
proc sigHash*(s: PSym): SigHash =
|
proc sigHash*(s: PSym; conf: ConfigRef): SigHash =
|
||||||
if s.kind in routineKinds and s.typ != nil:
|
if s.kind in routineKinds and s.typ != nil:
|
||||||
result = hashProc(s)
|
result = hashProc(s, conf)
|
||||||
else:
|
else:
|
||||||
result = hashNonProc(s)
|
result = hashNonProc(s)
|
||||||
|
|
||||||
|
|
@ -378,7 +380,7 @@ proc symBodyDigest*(graph: ModuleGraph, sym: PSym): SigHash =
|
||||||
|
|
||||||
var c: MD5Context
|
var c: MD5Context
|
||||||
md5Init(c)
|
md5Init(c)
|
||||||
c.hashType(sym.typ, {CoProc})
|
c.hashType(sym.typ, {CoProc}, graph.config)
|
||||||
c &= char(sym.kind)
|
c &= char(sym.kind)
|
||||||
c.md5Final(result.MD5Digest)
|
c.md5Final(result.MD5Digest)
|
||||||
graph.symBodyHashes[sym.id] = result # protect from recursion in the body
|
graph.symBodyHashes[sym.id] = result # protect from recursion in the body
|
||||||
|
|
@ -391,12 +393,12 @@ proc symBodyDigest*(graph: ModuleGraph, sym: PSym): SigHash =
|
||||||
graph.symBodyHashes[sym.id] = result
|
graph.symBodyHashes[sym.id] = result
|
||||||
|
|
||||||
proc idOrSig*(s: PSym, currentModule: string,
|
proc idOrSig*(s: PSym, currentModule: string,
|
||||||
sigCollisions: var CountTable[SigHash]): Rope =
|
sigCollisions: var CountTable[SigHash]; conf: ConfigRef): Rope =
|
||||||
if s.kind in routineKinds and s.typ != nil:
|
if s.kind in routineKinds and s.typ != nil:
|
||||||
# signatures for exported routines are reliable enough to
|
# signatures for exported routines are reliable enough to
|
||||||
# produce a unique name and this means produced C++ is more stable regarding
|
# produce a unique name and this means produced C++ is more stable regarding
|
||||||
# Nim changes:
|
# Nim changes:
|
||||||
let sig = hashProc(s)
|
let sig = hashProc(s, conf)
|
||||||
result = rope($sig)
|
result = rope($sig)
|
||||||
#let m = if s.typ.callConv != ccInline: findPendingModule(m, s) else: m
|
#let m = if s.typ.callConv != ccInline: findPendingModule(m, s) else: m
|
||||||
let counter = sigCollisions.getOrDefault(sig)
|
let counter = sigCollisions.getOrDefault(sig)
|
||||||
|
|
|
||||||
|
|
@ -1855,7 +1855,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||||
if regs[rb].node.kind != nkSym:
|
if regs[rb].node.kind != nkSym:
|
||||||
stackTrace(c, tos, pc, "node is not a symbol")
|
stackTrace(c, tos, pc, "node is not a symbol")
|
||||||
else:
|
else:
|
||||||
regs[ra].node.strVal = $sigHash(regs[rb].node.sym)
|
regs[ra].node.strVal = $sigHash(regs[rb].node.sym, c.config)
|
||||||
of opcSlurp:
|
of opcSlurp:
|
||||||
decodeB(rkNode)
|
decodeB(rkNode)
|
||||||
createStr regs[ra]
|
createStr regs[ra]
|
||||||
|
|
|
||||||
4
tests/ccgbugs/m1/defs.nim
Normal file
4
tests/ccgbugs/m1/defs.nim
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
type MyObj* = object
|
||||||
|
field1*: int
|
||||||
|
s*: string
|
||||||
|
ch*: char
|
||||||
4
tests/ccgbugs/m2/defs.nim
Normal file
4
tests/ccgbugs/m2/defs.nim
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
type MyObj* = object
|
||||||
|
s*: string
|
||||||
|
field1*: int
|
||||||
|
ch*: char
|
||||||
10
tests/ccgbugs/t20139.nim
Normal file
10
tests/ccgbugs/t20139.nim
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
discard """
|
||||||
|
joinable: false
|
||||||
|
"""
|
||||||
|
|
||||||
|
# bug #20139
|
||||||
|
import m1/defs as md1
|
||||||
|
import m2/defs as md2
|
||||||
|
|
||||||
|
doAssert $(md1.MyObj(field1: 1)) == """(field1: 1, s: "", ch: '\x00')"""
|
||||||
|
doAssert $(md2.MyObj(field1: 1)) == """(s: "", field1: 1, ch: '\x00')"""
|
||||||
Loading…
Add table
Add a link
Reference in a new issue