fix #17911 rawProc for cpp (#17912)

This commit is contained in:
Timothee Cour 2021-05-01 02:12:13 -07:00 • committed by GitHub
commit ee6d56141c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 93 additions and 14 deletions

View file

@ -524,15 +524,21 @@ proc hash*[T: tuple | object | proc](x: T): Hash {.inline.} =
proc hash(a: Obj2): Hash = hash((a.x))
assert hash(Obj2[float](x: 520, y: "Nim")) == hash(Obj2[float](x: 520, y: "Nim2"))
runnableExamples:
# proc and closure examples
# proc
proc fn1() = discard
var a = 0
proc fn2() = a.inc
assert hash(fn1) != hash(fn2)
const fn1b = fn1
assert hash(fn1b) == hash(fn1)
let fn2b = fn2
assert hash(fn2b) == hash(fn2)
# closure
proc outer =
var a = 0
proc fn2() = a.inc
assert fn2 is "closure"
let fn2b = fn2
assert hash(fn2b) == hash(fn2)
assert hash(fn2) != hash(fn1)
outer()
when T is "closure":
result = hash((rawProc(x), rawEnv(x)))
elif T is (proc):

View file

@ -2414,17 +2414,22 @@ when notJSnotNims:
proc rawProc*[T: proc](x: T): pointer {.noSideEffect, inline.} =
## Retrieves the raw proc pointer of the closure `x`. This is
## useful for interfacing closures with C.
## useful for interfacing closures with C/C++, hash compuations, etc.
when T is "closure":
#[
The conversion from function pointer to `void*` is a tricky topic, but this
should work at least for c++ >= c++11, e.g. for `dlsym` support.
refs: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57869,
https://stackoverflow.com/questions/14125474/casts-between-pointer-to-function-and-pointer-to-object-in-c-and-c
]#
{.emit: """
`result` = `x`.ClP_0;
`result` = (void*)`x`.ClP_0;
""".}
else:
{.error: "Only closure function and iterator are allowed!".}
proc rawEnv*[T: proc](x: T): pointer {.noSideEffect, inline.} =
## Retrieves the raw environment pointer of the closure `x`. This is
## useful for interfacing closures with C.
## Retrieves the raw environment pointer of the closure `x`. See also `rawProc`.
when T is "closure":
{.emit: """
`result` = `x`.ClE_0;