diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index db9dedcee2..c5b3aef0aa 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -11,7 +11,7 @@ # ------------------------- Name Mangling -------------------------------- -import debuginfo, sighashes +import sighashes proc isKeyword(w: PIdent): bool = # Nim and C++ share some keywords @@ -29,26 +29,29 @@ proc mangleField(name: PIdent): string = # Mangling makes everything lowercase, # but some identifiers are C keywords -proc hashOwner(s: PSym): SigHash = - var m = s - while m.kind != skModule: m = m.owner - let p = m.owner - assert p.kind == skPackage - result = gDebugInfo.register(p.name.s, m.name.s) +when false: + proc hashOwner(s: PSym): SigHash = + var m = s + while m.kind != skModule: m = m.owner + let p = m.owner + assert p.kind == skPackage + result = gDebugInfo.register(p.name.s, m.name.s) -proc idOrSig(m: BModule; s: PSym): BiggestInt = +proc idOrSig(m: BModule; s: PSym): Rope = if s.kind in routineKinds and s.typ != nil and sfExported in s.flags and s.typ.callConv != ccInline: # signatures for exported routines are reliable enough to # produce a unique name and this means produced C++ is more stable wrt # Nim changes: - let h = hashType(s.typ, {considerParamNames}) - if m.hashConflicts.containsOrIncl(cast[int](h)): - result = s.id - else: - result = BiggestInt(h) + when false: + let h = hashType(s.typ, {considerParamNames}) + if m.hashConflicts.containsOrIncl(cast[int](h)): + result = s.id + else: + result = BiggestInt(h) + result = rope($hashProc(s)) else: - result = s.id + result = rope s.id proc mangleName(m: BModule; s: PSym): Rope = result = s.loc.r @@ -100,9 +103,9 @@ proc mangleName(m: BModule; s: PSym): Rope = result.add "0" else: add(result, ~"_") - add(result, rope(m.idOrSig(s))) - add(result, ~"_") - add(result, rope(hashOwner(s).BiggestInt)) + add(result, m.idOrSig(s)) + #add(result, ~"_") + #add(result, rope(hashOwner(s).BiggestInt)) s.loc.r = result proc typeName(typ: PType): Rope = @@ -114,7 +117,7 @@ proc getTypeName(m: BModule; typ: PType): Rope = result = typ.sym.loc.r else: if typ.loc.r == nil: - when true: + when false: # doesn't work yet and would require bigger rewritings let h = hashType(typ, {considerParamNames})# and 0x0fff_ffffu32 let sig = @@ -125,8 +128,8 @@ proc getTypeName(m: BModule; typ: PType): Rope = else: let sig = BiggestInt typ.id typ.loc.r = typ.typeName & sig.rope #& ("_" & m.module.name.s) - if typ.kind != tySet: - typ.loc.r.add "_" & m.module.name.s + #if typ.kind != tySet: + # typ.loc.r.add "_" & m.module.name.s result = typ.loc.r if result == nil: internalError("getTypeName: " & $typ.kind) @@ -625,15 +628,16 @@ proc getTypeDescAux(m: BModule, typ: PType, check: var IntSet): Rope = of 4: addf(m.s[cfsTypes], "typedef NI32 $1;$n", [result]) of 8: addf(m.s[cfsTypes], "typedef NI64 $1;$n", [result]) else: internalError(t.sym.info, "getTypeDescAux: enum") - let owner = hashOwner(t.sym) - if not gDebugInfo.hasEnum(t.sym.name.s, t.sym.info.line, owner): - var vals: seq[(string, int)] = @[] - for i in countup(0, t.n.len - 1): - assert(t.n.sons[i].kind == nkSym) - let field = t.n.sons[i].sym - vals.add((field.name.s, field.position.int)) - gDebugInfo.registerEnum(EnumDesc(size: size, owner: owner, id: t.sym.id, - name: t.sym.name.s, values: vals)) + when false: + let owner = hashOwner(t.sym) + if not gDebugInfo.hasEnum(t.sym.name.s, t.sym.info.line, owner): + var vals: seq[(string, int)] = @[] + for i in countup(0, t.n.len - 1): + assert(t.n.sons[i].kind == nkSym) + let field = t.n.sons[i].sym + vals.add((field.name.s, field.position.int)) + gDebugInfo.registerEnum(EnumDesc(size: size, owner: owner, id: t.sym.id, + name: t.sym.name.s, values: vals)) of tyProc: result = getTypeName(m, t) idTablePut(m.typeCache, t, result) diff --git a/compiler/debuginfo.nim b/compiler/debuginfo.nim index 32e95d1eb9..7729a6a515 100644 --- a/compiler/debuginfo.nim +++ b/compiler/debuginfo.nim @@ -7,9 +7,9 @@ # distribution, for details about the copyright. # -## The compiler can generate debuginfo to help debuggers in translating back from C/C++/JS code -## to Nim. The data structure has been designed to produce something useful with Nim's marshal -## module. +## The compiler can generate debuginfo to help debuggers in translating back +## from C/C++/JS code to Nim. The data structure has been designed to produce +## something useful with Nim's marshal module. import sighashes diff --git a/compiler/extccomp.nim b/compiler/extccomp.nim index 6f8b0b197e..4eb68a7719 100644 --- a/compiler/extccomp.nim +++ b/compiler/extccomp.nim @@ -16,7 +16,7 @@ import lists, ropes, os, strutils, osproc, platform, condsyms, options, msgs, securehash, streams -from debuginfo import writeDebugInfo +#from debuginfo import writeDebugInfo type TSystemCC* = enum @@ -734,8 +734,8 @@ proc callCCompiler*(projectfile: string) = if not noAbsolutePaths(): if not exefile.isAbsolute(): exefile = joinPath(splitFile(projectfile).dir, exefile) - if optCDebug in gGlobalOptions: - writeDebugInfo(exefile.changeFileExt("ndb")) + #if optCDebug in gGlobalOptions: + # writeDebugInfo(exefile.changeFileExt("ndb")) exefile = quoteShell(exefile) let linkOptions = getLinkOptions() & " " & getConfigVar(cCompiler, ".options.linker") diff --git a/compiler/sighashes.nim b/compiler/sighashes.nim index 9653b0e520..706da3d68b 100644 --- a/compiler/sighashes.nim +++ b/compiler/sighashes.nim @@ -9,19 +9,63 @@ ## Computes hash values for routine (proc, method etc) signatures. -import ast +import ast, md5 +export md5.`==` -type - SigHash* = uint32 ## a hash good enough for a filename or a proc signature +when false: + type + SigHash* = uint32 ## a hash good enough for a filename or a proc signature -proc sdbmHash(hash: SigHash, c: char): SigHash {.inline.} = - return SigHash(c) + (hash shl 6) + (hash shl 16) - hash + proc sdbmHash(hash: SigHash, c: char): SigHash {.inline.} = + return SigHash(c) + (hash shl 6) + (hash shl 16) - hash -template `&=`*(x: var SigHash, c: char) = x = sdbmHash(x, c) -template `&=`*(x: var SigHash, s: string) = - for c in s: x = sdbmHash(x, c) + template `&=`*(x: var SigHash, c: char) = x = sdbmHash(x, c) + template `&=`*(x: var SigHash, s: string) = + for c in s: x = sdbmHash(x, c) -proc hashSym(c: var SigHash, s: PSym) = +else: + type + SigHash* = Md5Digest + + const + cb64 = [ + "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", + "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", + "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", + "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", + "0", "1", "2", "3", "4", "5", "6", "7", "8", "9a", + "9b", "9c"] + + proc toBase64a(s: cstring, len: int): string = + ## encodes `s` into base64 representation. + result = newStringOfCap(((len + 2) div 3) * 4) + var i = 0 + while i < len - 2: + let a = ord(s[i]) + let b = ord(s[i+1]) + let c = ord(s[i+2]) + result.add cb64[a shr 2] + result.add cb64[((a and 3) shl 4) or ((b and 0xF0) shr 4)] + result.add cb64[((b and 0x0F) shl 2) or ((c and 0xC0) shr 6)] + result.add cb64[c and 0x3F] + inc(i, 3) + if i < len-1: + let a = ord(s[i]) + let b = ord(s[i+1]) + result.add cb64[a shr 2] + result.add cb64[((a and 3) shl 4) or ((b and 0xF0) shr 4)] + result.add cb64[((b and 0x0F) shl 2)] + elif i < len: + let a = ord(s[i]) + result.add cb64[a shr 2] + result.add cb64[(a and 3) shl 4] + + proc `$`*(u: SigHash): string = + toBase64a(cast[cstring](unsafeAddr u), sizeof(u)) + proc `&=`(c: var MD5Context, s: string) = md5Update(c, s, s.len) + proc `&=`(c: var MD5Context, ch: char) = md5Update(c, unsafeAddr ch, 1) + +proc hashSym(c: var MD5Context, s: PSym) = if sfAnon in s.flags or s.kind == skGenericParam: c &= ":anon" else: @@ -31,9 +75,9 @@ proc hashSym(c: var SigHash, s: PSym) = c &= "." it = it.owner -proc hashTree(c: var SigHash, n: PNode) = +proc hashTree(c: var MD5Context, n: PNode) = template lowlevel(v) = - for i in 0..