24
24
#include "caml/memory.h"
25
25
#include "caml/mlvalues.h"
26
26
27
+ static value raise_if_exception (value res )
28
+ {
29
+ if (Is_exception_result (res )) {
30
+ if (Caml_state -> raising_async_exn ) {
31
+ Caml_state -> raising_async_exn = 0 ;
32
+ caml_raise_async (Extract_exception (res ));
33
+ } else {
34
+ caml_raise (Extract_exception (res ));
35
+ }
36
+ }
37
+ return res ;
38
+ }
39
+
27
40
#ifndef NATIVE_CODE
28
41
29
42
/* Bytecode callbacks */
@@ -51,7 +64,9 @@ static void init_callback_code(void)
51
64
callback_code_inited = 1 ;
52
65
}
53
66
54
- CAMLexport value caml_callbackN_exn (value closure , int narg , value args [])
67
+ /* Functions that return all exceptions, including asynchronous ones */
68
+
69
+ static value caml_callbackN_exn0 (value closure , int narg , value args [])
55
70
{
56
71
int i ;
57
72
value res ;
@@ -72,29 +87,75 @@ CAMLexport value caml_callbackN_exn(value closure, int narg, value args[])
72
87
return res ;
73
88
}
74
89
90
+ CAMLexport value caml_callbackN_exn (value closure , int narg , value args [])
91
+ {
92
+ value res = caml_callbackN_exn0 (closure , narg , args );
93
+ Caml_state -> raising_async_exn = 0 ;
94
+ return res ;
95
+ }
96
+
75
97
CAMLexport value caml_callback_exn (value closure , value arg1 )
76
98
{
77
- value arg [1 ];
99
+ value res , arg [1 ];
78
100
arg [0 ] = arg1 ;
79
- return caml_callbackN_exn (closure , 1 , arg );
101
+ res = caml_callbackN_exn0 (closure , 1 , arg );
102
+ Caml_state -> raising_async_exn = 0 ;
103
+ return res ;
80
104
}
81
105
82
106
CAMLexport value caml_callback2_exn (value closure , value arg1 , value arg2 )
83
107
{
84
- value arg [2 ];
108
+ value res , arg [2 ];
85
109
arg [0 ] = arg1 ;
86
110
arg [1 ] = arg2 ;
87
- return caml_callbackN_exn (closure , 2 , arg );
111
+ res = caml_callbackN_exn0 (closure , 2 , arg );
112
+ Caml_state -> raising_async_exn = 0 ;
113
+ return res ;
88
114
}
89
115
90
116
CAMLexport value caml_callback3_exn (value closure ,
91
- value arg1 , value arg2 , value arg3 )
117
+ value arg1 , value arg2 , value arg3 )
118
+ {
119
+ value res , arg [3 ];
120
+ arg [0 ] = arg1 ;
121
+ arg [1 ] = arg2 ;
122
+ arg [2 ] = arg3 ;
123
+ res = caml_callbackN_exn0 (closure , 3 , arg );
124
+ Caml_state -> raising_async_exn = 0 ;
125
+ return res ;
126
+ }
127
+
128
+ /* Functions that propagate all exceptions, with any asynchronous exceptions
129
+ also being propagated asynchronously. */
130
+
131
+ CAMLexport value caml_callbackN (value closure , int narg , value args [])
132
+ {
133
+ return raise_if_exception (caml_callbackN_exn0 (closure , narg , args ));
134
+ }
135
+
136
+ CAMLexport value caml_callback (value closure , value arg1 )
137
+ {
138
+ value arg [1 ];
139
+ arg [0 ] = arg1 ;
140
+ return caml_callbackN (closure , 1 , arg );
141
+ }
142
+
143
+ CAMLexport value caml_callback2 (value closure , value arg1 , value arg2 )
144
+ {
145
+ value arg [2 ];
146
+ arg [0 ] = arg1 ;
147
+ arg [1 ] = arg2 ;
148
+ return caml_callbackN (closure , 2 , arg );
149
+ }
150
+
151
+ CAMLexport value caml_callback3 (value closure ,
152
+ value arg1 , value arg2 , value arg3 )
92
153
{
93
154
value arg [3 ];
94
155
arg [0 ] = arg1 ;
95
156
arg [1 ] = arg2 ;
96
157
arg [2 ] = arg3 ;
97
- return caml_callbackN_exn (closure , 3 , arg );
158
+ return caml_callbackN (closure , 3 , arg );
98
159
}
99
160
100
161
#else
@@ -106,26 +167,24 @@ typedef value (callback_stub)(caml_domain_state* state, value closure,
106
167
107
168
callback_stub caml_callback_asm , caml_callback2_asm , caml_callback3_asm ;
108
169
109
- CAMLexport value caml_callback_exn (value closure , value arg )
170
+ static value callback (value closure , value arg )
110
171
{
111
172
return caml_callback_asm (Caml_state , closure , & arg );
112
173
}
113
174
114
- CAMLexport value caml_callback2_exn (value closure , value arg1 , value arg2 )
175
+ static value callback2 (value closure , value arg1 , value arg2 )
115
176
{
116
177
value args [] = {arg1 , arg2 };
117
178
return caml_callback2_asm (Caml_state , closure , args );
118
179
}
119
180
120
- CAMLexport value caml_callback3_exn (value closure ,
121
- value arg1 , value arg2 , value arg3 )
181
+ static value callback3 (value closure , value arg1 , value arg2 , value arg3 )
122
182
{
123
183
value args [] = {arg1 , arg2 , arg3 };
124
184
return caml_callback3_asm (Caml_state , closure , args );
125
185
}
126
186
127
-
128
- CAMLexport value caml_callbackN_exn (value closure , int narg , value args [])
187
+ static value callbackN (value closure , int narg , value args [])
129
188
{
130
189
CAMLparam1 (closure );
131
190
CAMLxparamN (args , narg );
@@ -137,17 +196,17 @@ CAMLexport value caml_callbackN_exn(value closure, int narg, value args[])
137
196
/* Pass as many arguments as possible */
138
197
switch (narg - i ) {
139
198
case 1 :
140
- res = caml_callback_exn (res , args [i ]);
199
+ res = callback (res , args [i ]);
141
200
if (Is_exception_result (res )) CAMLreturn (res );
142
201
i += 1 ;
143
202
break ;
144
203
case 2 :
145
- res = caml_callback2_exn (res , args [i ], args [i + 1 ]);
204
+ res = callback2 (res , args [i ], args [i + 1 ]);
146
205
if (Is_exception_result (res )) CAMLreturn (res );
147
206
i += 2 ;
148
207
break ;
149
208
default :
150
- res = caml_callback3_exn (res , args [i ], args [i + 1 ], args [i + 2 ]);
209
+ res = callback3 (res , args [i ], args [i + 1 ], args [i + 2 ]);
151
210
if (Is_exception_result (res )) CAMLreturn (res );
152
211
i += 3 ;
153
212
break ;
@@ -156,31 +215,76 @@ CAMLexport value caml_callbackN_exn(value closure, int narg, value args[])
156
215
CAMLreturn (res );
157
216
}
158
217
159
- #endif
218
+ /* Functions that return all exceptions, including asynchronous ones */
219
+
220
+ CAMLexport value caml_callback_exn (value closure , value arg )
221
+ {
222
+ value res = callback (closure , arg );
223
+ Caml_state -> raising_async_exn = 0 ;
224
+ return res ;
225
+ }
226
+
227
+ CAMLexport value caml_callback2_exn (value closure , value arg1 , value arg2 )
228
+ {
229
+ value res = callback2 (closure , arg1 , arg2 );
230
+ Caml_state -> raising_async_exn = 0 ;
231
+ return res ;
232
+ }
160
233
161
- /* Exception-propagating variants of the above */
234
+ CAMLexport value caml_callback3_exn (value closure , value arg1 , value arg2 ,
235
+ value arg3 )
236
+ {
237
+ value res = callback3 (closure , arg1 , arg2 , arg3 );
238
+ Caml_state -> raising_async_exn = 0 ;
239
+ return res ;
240
+ }
241
+
242
+ CAMLexport value caml_callbackN_exn (value closure , int narg , value args [])
243
+ {
244
+ value res = callbackN (closure , narg , args );
245
+ Caml_state -> raising_async_exn = 0 ;
246
+ return res ;
247
+ }
248
+
249
+ /* Functions that propagate all exceptions, with any asynchronous exceptions
250
+ also being propagated asynchronously. */
162
251
163
252
CAMLexport value caml_callback (value closure , value arg )
164
253
{
165
- return caml_raise_if_exception ( caml_callback_exn (closure , arg ));
254
+ return raise_if_exception ( callback (closure , arg ));
166
255
}
167
256
168
257
CAMLexport value caml_callback2 (value closure , value arg1 , value arg2 )
169
258
{
170
- return caml_raise_if_exception ( caml_callback2_exn (closure , arg1 , arg2 ));
259
+ return raise_if_exception ( callback2 (closure , arg1 , arg2 ));
171
260
}
172
261
173
262
CAMLexport value caml_callback3 (value closure , value arg1 , value arg2 ,
174
263
value arg3 )
175
264
{
176
- return caml_raise_if_exception ( caml_callback3_exn (closure , arg1 , arg2 , arg3 ));
265
+ return raise_if_exception ( callback3 (closure , arg1 , arg2 , arg3 ));
177
266
}
178
267
179
268
CAMLexport value caml_callbackN (value closure , int narg , value args [])
180
269
{
181
- return caml_raise_if_exception ( caml_callbackN_exn (closure , narg , args ));
270
+ return raise_if_exception ( callbackN (closure , narg , args ));
182
271
}
183
272
273
+ #endif
274
+
275
+ CAMLprim value caml_with_async_exns (value body_callback )
276
+ {
277
+ value res ;
278
+ res = caml_callback_exn (body_callback , Val_unit );
279
+
280
+ /* raised as a normal exn, even if it was asynchronous */
281
+ if (Is_exception_result (res ))
282
+ caml_raise (Extract_exception (res ));
283
+
284
+ return res ;
285
+ }
286
+
287
+
184
288
/* Naming of OCaml values */
185
289
186
290
struct named_value {
0 commit comments