summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--lib/system.nim32
1 files changed, 31 insertions, 1 deletions
diff --git a/lib/system.nim b/lib/system.nim
index 633f637ca..56fa91ee2 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -2246,19 +2246,49 @@ when notJSnotNims:
 
   proc rawProc*[T: proc {.closure.} | iterator {.closure.}](x: T): pointer {.noSideEffect, inline.} =
     ## Retrieves the raw proc pointer of the closure `x`. This is
-    ## useful for interfacing closures with C/C++, hash compuations, etc.
+    ## useful for interfacing closures with C/C++, hash computations, etc.
+    ## If `rawEnv(x)` returns `nil`, the proc which the result points to
+    ## takes as many parameters as `x`, but with `{.nimcall.}` as its calling
+    ## convention instead of `{.closure.}`, otherwise it takes one more parameter
+    ## which is a `pointer`, and it still has `{.nimcall.}` as its calling convention.
+    ## To invoke the resulted proc, what this returns has to be casted into a `proc`,
+    ## not a `ptr proc`, and, in a case where `rawEnv(x)` returns non-`nil`,
+    ## the last and additional argument has to be the result of `rawEnv(x)`.
+    ## This is not available for the JS target.
     #[
     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
     ]#
+    runnableExamples:
+      proc makeClosure(x: int): (proc(y: int): int) =
+        var n = x
+        result = (
+          proc(y: int): int =
+            n += y
+            return n
+        )
+
+      var
+        c1 = makeClosure(10)
+        e = c1.rawEnv()
+        p = c1.rawProc()
+
+      if e.isNil():
+        let c2 = cast[proc(y: int): int {.nimcall.}](p)
+        echo c2(2)
+      else:
+        let c3 = cast[proc(y: int; env: pointer): int {.nimcall.}](p)
+        echo c3(3, e)
+
     {.emit: """
     `result` = (void*)`x`.ClP_0;
     """.}
 
   proc rawEnv*[T: proc {.closure.} | iterator {.closure.}](x: T): pointer {.noSideEffect, inline.} =
     ## Retrieves the raw environment pointer of the closure `x`. See also `rawProc`.
+    ## This is not available for the JS target.
     {.emit: """
     `result` = `x`.ClE_0;
     """.}
tter Araq <rumpf_a@web.de> 2013-12-27 23:10:36 +0100 case consistency part 4' href='/ahoang/Nim/commit/lib/system/widestrs.nim?h=devel&id=92b8fac94a7243cde785d985db3fd86b6025b079'>92b8fac94 ^
2ca90a20a ^
92b8fac94 ^
























































baf89e3d6 ^
92b8fac94 ^






2ca90a20a ^
92b8fac94 ^



2ca90a20a ^
92b8fac94 ^
2ca90a20a ^
92b8fac94 ^
2ca90a20a ^
92b8fac94 ^



64b048520 ^
92b8fac94 ^



7c757599f ^
92b8fac94 ^



c103eddc7 ^
92b8fac94 ^
c103eddc7 ^
92b8fac94 ^
c103eddc7 ^
43bddf62d ^
7c757599f ^









43bddf62d ^
c103eddc7 ^
92b8fac94 ^
c103eddc7 ^
493dbc893 ^

c103eddc7 ^
493dbc893 ^


7c757599f ^
493dbc893 ^



7c757599f ^




43bddf62d ^
92b8fac94 ^

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155