Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

$ works for ref|ptr|pointer for all targets (c,cpp,js,vm) + other bugfixes #14043

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
7 changes: 5 additions & 2 deletions tests/concepts/tconcepts_issues.nim
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ type
v: T
converter toObj1[T](t: T): Obj1[T] =
return Obj1[T](v: t)

proc echo2(a: varargs[string, mytostr]) = echo a[0]

block t976:
type
int1 = distinct int
Expand Down Expand Up @@ -117,12 +120,12 @@ block t976:
PrintAble = concept x
$x is string

proc `$`[T](nt: Obj1[T]): string =
proc mytostr[T](nt: Obj1[T]): string =
when T is PrintAble: result = "Printable"
else: result = "Non Printable"

echo Obj2()

echo2 Obj2()


block t1128:
Expand Down
6 changes: 2 additions & 4 deletions tests/destructor/tdestructor3.nim
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@ destroy
123
destroy Foo: 123
destroy Foo: 5
(x1: (val: ...))
destroy
---------------
app begin
(val: ...)
destroy
app end
'''
Expand Down Expand Up @@ -96,7 +94,7 @@ proc newObj2(x:int, y: float): MyObject2 =

proc test =
let obj2 = newObj2(1, 1.0)
echo obj2
doAssert obj2.x1.val != nil

test()

Expand All @@ -119,7 +117,7 @@ proc createTop(): ptr TopObject =

proc test2() =
let x = createTop()
echo $x.internal
doAssert x.internal.val != nil
deleteTop(x)

echo "---------------"
Expand Down
2 changes: 1 addition & 1 deletion tests/generics/tgeneric0.nim
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ discard """
0
float32
float32
(name: "Resource 1", readers: ..., writers: ...)
(name: "Resource 1", readers: @[], writers: @[])
'''
"""

Expand Down
2 changes: 1 addition & 1 deletion tests/js/trefbyvar.nim
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,4 @@ proc initTypeA1(a: int; b: string; c: pointer = nil): TypeA1 =
result.c_impl = c

let x = initTypeA1(1, "a")
doAssert($x == "(a_impl: 1, b_impl: \"a\", c_impl: ...)")
doAssert($x == "(a_impl: 1, b_impl: \"a\", c_impl: nil)")
6 changes: 1 addition & 5 deletions tests/statictypes/tstackmatrix.nim
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
discard """
output: "(M: 3, N: 3, fp: ...)"
"""

# bug #6843

type
Expand All @@ -26,4 +22,4 @@ var
[7'f64, 8, 9]
]
m = stackMatrix(data)
echo m
doAssert m.M == 3 and m.N == 3 and m.fp != nil
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"
4 changes: 2 additions & 2 deletions tests/types/tissues_types.nim
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ true
ptr Foo
(member: "hello world")
(member: 123.456)
(member: "hello world", x: ...)
(member: 123.456, x: ...)
(member: "hello world", x: nil)
(member: 123.456, x: nil)
0
false
'''
Expand Down