diff --git a/compiler/vm.nim b/compiler/vm.nim index c15f9e2681de7..4ac152117284b 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -602,18 +602,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 27d1ef479964f..0895fe06cfcaa 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 @@ -200,6 +201,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 1024ce26f5cf7..8a44573237e26 100644 --- a/lib/pure/hashes.nim +++ b/lib/pure/hashes.nim @@ -152,21 +152,12 @@ proc hashData*(data: pointer, size: int): Hash = result = !$h when defined(js): - var objectID = 0 + from system/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 85be43cbac43b..4c0730c4b15cf 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -2078,7 +2078,7 @@ const ## Odd for devel, even for releases. import system/dollars -export dollars +export dollars except toHexImpl, getNimJsObjectID const NimVersion*: string = $NimMajor & "." & $NimMinor & "." & $NimPatch diff --git a/lib/system/dollars.nim b/lib/system/dollars.nim index b2f0186b31ddb..4535938fd7be9 100644 --- a/lib/system/dollars.nim +++ b/lib/system/dollars.nim @@ -82,6 +82,36 @@ 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..