diff --git a/compiler/vm.nim b/compiler/vm.nim index 37d5a609eb00b..c07ce296d488d 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -428,6 +428,7 @@ proc opConv(c: PCtx; dest: var TFullReg, src: TFullReg, desttyp, srctyp: PType): else: internalError(c.config, "cannot convert to string " & desttyp.typeToString) else: + let kind = skipTypes(desttyp, abstractVarRange).kind case skipTypes(desttyp, abstractVarRange).kind of tyInt..tyInt64: dest.ensureKind(rkInt) @@ -599,18 +600,22 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = of opcCastPtrToInt: # RENAME opcCastPtrOrRefToInt decodeBImm(rkInt) + var val = 0 case imm of 1: # PtrLikeKinds case regs[rb].kind of rkNode: - regs[ra].intVal = cast[int](regs[rb].node.intVal) - of rkNodeAddr: - regs[ra].intVal = cast[int](regs[rb].nodeAddr) + let node = regs[rb].node + if nfIsRef in node.flags: val = cast[int](node) + elif node.kind == nkIntLit: val = cast[int](node.intVal) + else: assert false, $node.kind + of rkNodeAddr: val = cast[int](regs[rb].nodeAddr) else: stackTrace(c, tos, pc, "opcCastPtrToInt: got " & $regs[rb].kind) of 2: # tyRef - regs[ra].intVal = cast[int](regs[rb].node) + val = cast[int](regs[rb].node) else: assert false, $imm + regs[ra].intVal = val of opcCastIntToPtr: let rb = instr.regB let typ = regs[ra].node.typ diff --git a/compiler/vmops.nim b/compiler/vmops.nim index ef36419a70f6e..473527be759f8 100644 --- a/compiler/vmops.nim +++ b/compiler/vmops.nim @@ -19,6 +19,7 @@ from sighashes import symBodyDigest from times import cpuTime from hashes import hash +from system/dollars import toHexImpl from osproc import nil import vmconv @@ -199,6 +200,9 @@ proc registerAdditionalOps*(c: PCtx) = registerCallback c, "stdlib.os.getCurrentCompilerExe", proc (a: VmArgs) {.nimcall.} = setResult(a, getAppFilename()) + registerCallback c, "stdlib.dollars.toHexImpl", proc (a: VmArgs) {.nimcall.} = + setResult(a, a.getInt(0).int.toHexImpl) + registerCallback c, "stdlib.macros.symBodyHash", proc (a: VmArgs) {.nimcall.} = let n = getNode(a, 0) if n.kind != nkSym: diff --git a/lib/pure/hashes.nim b/lib/pure/hashes.nim index f7b4e907b08a3..3e29e8275ef8b 100644 --- a/lib/pure/hashes.nim +++ b/lib/pure/hashes.nim @@ -149,21 +149,12 @@ proc hashData*(data: pointer, size: int): Hash = result = !$h when defined(js): - var objectID = 0 + from dollars import getNimJsObjectID proc hash*(x: pointer): Hash {.inline.} = ## Efficient hashing of pointers. when defined(js): - asm """ - if (typeof `x` == "object") { - if ("_NimID" in `x`) - `result` = `x`["_NimID"]; - else { - `result` = ++`objectID`; - `x`["_NimID"] = `result`; - } - } - """ + result = getNimJsObjectID(x) else: result = cast[Hash](cast[uint](x) shr 3) # skip the alignment diff --git a/lib/system.nim b/lib/system.nim index 221a538b131ca..e430ff4fbd5c6 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -2051,7 +2051,7 @@ template unlikely*(val: bool): bool = import system/dollars -export dollars +export dollars except toHexImpl, getNimJsObjectID const NimMajor* {.intdefine.}: int = 1 diff --git a/lib/system/dollars.nim b/lib/system/dollars.nim index 8e10dae4b7dc7..9332dab9ce9da 100644 --- a/lib/system/dollars.nim +++ b/lib/system/dollars.nim @@ -65,6 +65,37 @@ else: return true return false +proc c_sprintf(buf, frmt: cstring): cint {.importc: "sprintf", header: "", varargs, noSideEffect.} + +proc toHexImpl*(x: int): string {.inline.} = + var buf {.noinit.}: array[int.sizeof*2+3, char] # 3 for 0x+\0 + let num = c_sprintf(buf.addr, "%p", cast[int](x)) + result = newString(num) + for i in 0..