aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/ext_ffi_semantics.html16
-rw-r--r--src/lj_ccallback.c10
2 files changed, 23 insertions, 3 deletions
diff --git a/doc/ext_ffi_semantics.html b/doc/ext_ffi_semantics.html
index f8da1e60..ab02f2b8 100644
--- a/doc/ext_ffi_semantics.html
+++ b/doc/ext_ffi_semantics.html
@@ -934,6 +934,22 @@ advisable in general. Do this only if you know the C function, that
934called the callback, copes with the forced stack unwinding and doesn't 934called the callback, copes with the forced stack unwinding and doesn't
935leak resources. 935leak resources.
936</p> 936</p>
937<p>
938One thing that's not allowed, is to let an FFI call into a C&nbsp;function
939get JIT-compiled, which in turn calls a callback, calling into Lua again.
940Usually this attempt is caught by the interpreter first and the
941C&nbsp;function is blacklisted for compilation.
942</p>
943<p>
944However, this heuristic may fail under specific circumstances: e.g. a
945message polling function might not run Lua callbacks right away and the call
946gets JIT-compiled. If it later happens to call back into Lua, you'll get a
947VM PANIC with the message <tt>"bad callback"</tt>. Then you'll need to
948manually turn off JIT-compilation with
949<a href="ext_jit.html#jit_onoff_func"><tt>jit.off()</tt></a> for the
950surrounding Lua function that invokes such a message polling function (or
951similar).
952</p>
937 953
938<h3 id="callback_resources">Callback resource handling</h3> 954<h3 id="callback_resources">Callback resource handling</h3>
939<p> 955<p>
diff --git a/src/lj_ccallback.c b/src/lj_ccallback.c
index 430643ee..e1d03fcf 100644
--- a/src/lj_ccallback.c
+++ b/src/lj_ccallback.c
@@ -527,10 +527,14 @@ static void callback_conv_result(CTState *cts, lua_State *L, TValue *o)
527lua_State * LJ_FASTCALL lj_ccallback_enter(CTState *cts, void *cf) 527lua_State * LJ_FASTCALL lj_ccallback_enter(CTState *cts, void *cf)
528{ 528{
529 lua_State *L = cts->L; 529 lua_State *L = cts->L;
530 global_State *g = cts->g;
530 lua_assert(L != NULL); 531 lua_assert(L != NULL);
531 if (gcref(cts->g->jit_L)) 532 if (gcref(g->jit_L)) {
532 lj_err_caller(gco2th(gcref(cts->g->jit_L)), LJ_ERR_FFI_BADCBACK); 533 setstrV(L, L->top++, lj_err_str(L, LJ_ERR_FFI_BADCBACK));
533 lj_trace_abort(cts->g); /* Never record across callback. */ 534 if (g->panic) g->panic(L);
535 exit(EXIT_FAILURE);
536 }
537 lj_trace_abort(g); /* Never record across callback. */
534 /* Setup C frame. */ 538 /* Setup C frame. */
535 cframe_prev(cf) = L->cframe; 539 cframe_prev(cf) = L->cframe;
536 setcframe_L(cf, L); 540 setcframe_L(cf, L);