Skip to content

Commit

Permalink
$ works for ref|ptr|pointer for all targets (c,cpp,js,vm)
Browse files Browse the repository at this point in the history
  • Loading branch information
timotheecour committed Apr 21, 2020
1 parent 42a6424 commit 5869d17
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 23 deletions.
12 changes: 8 additions & 4 deletions compiler/vm.nim
Original file line number Diff line number Diff line change
Expand Up @@ -599,18 +599,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
Expand Down
4 changes: 4 additions & 0 deletions compiler/vmops.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand Down
13 changes: 2 additions & 11 deletions lib/pure/hashes.nim
Original file line number Diff line number Diff line change
Expand Up @@ -149,21 +149,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

Expand Down
2 changes: 1 addition & 1 deletion lib/system.nim
Original file line number Diff line number Diff line change
Expand Up @@ -2051,7 +2051,7 @@ template unlikely*(val: bool): bool =


import system/dollars
export dollars
export dollars except toHexImpl, getNimJsObjectID

const
NimMajor* {.intdefine.}: int = 1
Expand Down
30 changes: 30 additions & 0 deletions lib/system/dollars.nim
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,36 @@ else:
return true
return false

proc c_sprintf(buf, frmt: cstring): cint {.importc: "sprintf", header: "<stdio.h>", 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..<num: result[i] = buf[i] # or memcpy

when defined(js):
var objectID = 0
proc getNimJsObjectID*(x: pointer): int =
asm """
if (typeof `x` == "object") {
if ("_NimID" in `x`)
`result` = `x`["_NimID"];
else {
`result` = ++`objectID`;
`x`["_NimID"] = `result`;
}
}
"""

proc `$`*(x: ref|ptr|pointer): string =
if x == nil: "nil"
else:
template fun(): untyped = toHexImpl(cast[int](x))
when defined(js):
when nimvm: fun()
else: "@" & $getNimJsObjectID(cast[pointer](x))
else: fun()

proc `$`*[T: tuple|object](x: T): string =
## Generic ``$`` operator for tuples that is lifted from the components
Expand Down
44 changes: 37 additions & 7 deletions tests/system/tostring.nim
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
discard """
output: "DONE: tostring.nim"
targets: "c cpp js"
"""
# xxx move this to tests/system/tdollars.nim

doAssert "@[23, 45]" == $(@[23, 45])
doAssert "[32, 45]" == $([32, 45])
Expand Down Expand Up @@ -46,12 +48,13 @@ const
# ensure same result when on VM or when at program execution
doAssert dataStr == $data

import strutils
from strutils import contains
# array test

let arr = ['H','e','l','l','o',' ','W','o','r','l','d','!','\0']
doAssert $arr == "['H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '!', '\\x00']"
doAssert $cstring(unsafeAddr arr) == "Hello World!"
when not defined js: # bug
doAssert $cstring(unsafeAddr arr) == "Hello World!"

proc takes(c: cstring) =
doAssert c == cstring""
Expand Down Expand Up @@ -82,10 +85,11 @@ proc stringCompare() =
b.add "bee"
doAssert b == "bee"
b.add g
doAssert b == "bee"
c.add 123.456
when not defined js: # bug
doAssert b == "bee"
c.addFloat 123.456
doAssert c == "123.456"
d.add 123456
d.addInt 123456
doAssert d == "123456"

doAssert e == ""
Expand All @@ -94,7 +98,8 @@ proc stringCompare() =
doAssert "" == ""

g.setLen(10)
doAssert g == "\0\0\0\0\0\0\0\0\0\0"
when not defined(js): # bug
doAssert g == "\0\0\0\0\0\0\0\0\0\0"
doAssert "" != "\0\0\0\0\0\0\0\0\0\0"

var nilstring: string
Expand All @@ -103,7 +108,8 @@ proc stringCompare() =

stringCompare()
var nilstring: string
bar(nilstring)
when not defined(js): # bug
bar(nilstring)

static:
stringCompare()
Expand All @@ -116,5 +122,29 @@ block:
s.addQuoted a2
doAssert s == "\"fo\\\"o2\""

block: # ptr-like types
type
TFoo = object
x1: int
x2: pointer
x3: seq[Foo]
x4: ptr TFoo
Foo = ref TFoo

template fun() =
doAssert $Foo.default == "nil"
var z = 0
var a = Foo(x1: 1, x2: z.addr)
let sa = $a
a.x3 = @[nil, a, Foo()]
a.x4 = a[].addr
doAssert $a.x4 == sa
doAssert $a.x3[0] == "nil"
doAssert $a.x3[1] == sa
doAssert $a.x3[2] != sa
doAssert sa in $a[]

fun()
static: fun()

echo "DONE: tostring.nim"

0 comments on commit 5869d17

Please sign in to comment.