diff options
Diffstat (limited to 'byterun/callback.c')
-rw-r--r-- | byterun/callback.c | 32 |
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; } |