diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/pure/hashes.nim | 18 | ||||
-rw-r--r-- | lib/system.nim | 13 |
2 files changed, 21 insertions, 10 deletions
diff --git a/lib/pure/hashes.nim b/lib/pure/hashes.nim index 2dab498d7..f61fbdf2b 100644 --- a/lib/pure/hashes.nim +++ b/lib/pure/hashes.nim @@ -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): diff --git a/lib/system.nim b/lib/system.nim index e9c036b8a..aecda4a70 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -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; |