summaryrefslogtreecommitdiff
path: root/byterun/callback.c
diff options
context:
space:
mode:
Diffstat (limited to 'byterun/callback.c')
-rw-r--r--byterun/callback.c32
1 files changed, 31 insertions, 1 deletions
diff --git a/byterun/callback.c b/byterun/callback.c
index f16c4728c9..a960df5448 100644
--- a/byterun/callback.c
+++ b/byterun/callback.c
@@ -32,7 +32,10 @@
CAMLexport int caml_callback_depth = 0;
+#ifndef LOCAL_CALLBACK_BYTECODE
static opcode_t callback_code[] = { ACC, 0, APPLY, 0, POP, 1, STOP };
+#endif
+
#ifdef THREADED_CODE
@@ -57,17 +60,44 @@ CAMLexport value caml_callbackN_exn(value closure, int narg, value args[])
int i;
value res;
+ /* some alternate bytecode implementations (e.g. a JIT translator)
+ might require that the bytecode is kept in a local variable on
+ the C stack */
+#ifdef LOCAL_CALLBACK_BYTECODE
+ opcode_t local_callback_code[7];
+#endif
+
Assert(narg + 4 <= 256);
- Init_callback();
+
caml_extern_sp -= narg + 4;
for (i = 0; i < narg; i++) caml_extern_sp[i] = args[i]; /* arguments */
+#ifndef LOCAL_CALLBACK_BYTECODE
caml_extern_sp[narg] = (value) (callback_code + 4); /* return address */
caml_extern_sp[narg + 1] = Val_unit; /* environment */
caml_extern_sp[narg + 2] = Val_long(0); /* extra args */
caml_extern_sp[narg + 3] = closure;
+ Init_callback();
callback_code[1] = narg + 3;
callback_code[3] = narg;
res = caml_interprete(callback_code, sizeof(callback_code));
+#else /*have LOCAL_CALLBACK_BYTECODE*/
+ caml_extern_sp[narg] = (value) (local_callback_code + 4); /* return address */
+ caml_extern_sp[narg + 1] = Val_unit; /* environment */
+ caml_extern_sp[narg + 2] = Val_long(0); /* extra args */
+ caml_extern_sp[narg + 3] = closure;
+ local_callback_code[0] = ACC;
+ local_callback_code[1] = narg + 3;
+ local_callback_code[2] = APPLY;
+ local_callback_code[3] = narg;
+ local_callback_code[4] = POP;
+ local_callback_code[5] = 1;
+ local_callback_code[6] = STOP;
+#ifdef THREADED_CODE
+ caml_thread_code(local_callback_code, sizeof(local_callback_code));
+#endif /*THREADED_CODE*/
+ res = caml_interprete(local_callback_code, sizeof(local_callback_code));
+ caml_release_bytecode(local_callback_code, sizeof(local_callback_code));
+#endif /*LOCAL_CALLBACK_BYTECODE*/
if (Is_exception_result(res)) caml_extern_sp += narg + 4; /* PR#1228 */
return res;
}