aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Makefile.dep2
-rw-r--r--src/lj_ccall.c34
2 files changed, 24 insertions, 12 deletions
diff --git a/src/Makefile.dep b/src/Makefile.dep
index 9b790fb8..9982f7b0 100644
--- a/src/Makefile.dep
+++ b/src/Makefile.dep
@@ -56,7 +56,7 @@ lj_asm.o: lj_asm.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
56lj_bc.o: lj_bc.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_bc.h \ 56lj_bc.o: lj_bc.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_bc.h \
57 lj_bcdef.h 57 lj_bcdef.h
58lj_ccall.o: lj_ccall.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ 58lj_ccall.o: lj_ccall.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
59 lj_err.h lj_errmsg.h lj_str.h lj_ctype.h lj_gc.h lj_cconv.h lj_cdata.h \ 59 lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_ctype.h lj_cconv.h lj_cdata.h \
60 lj_ccall.h 60 lj_ccall.h
61lj_cconv.o: lj_cconv.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ 61lj_cconv.o: lj_cconv.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
62 lj_err.h lj_errmsg.h lj_tab.h lj_ctype.h lj_gc.h lj_cdata.h lj_cconv.h 62 lj_err.h lj_errmsg.h lj_tab.h lj_ctype.h lj_gc.h lj_cdata.h lj_cconv.h
diff --git a/src/lj_ccall.c b/src/lj_ccall.c
index 5e91d962..688dfc89 100644
--- a/src/lj_ccall.c
+++ b/src/lj_ccall.c
@@ -7,6 +7,7 @@
7 7
8#if LJ_HASFFI 8#if LJ_HASFFI
9 9
10#include "lj_gc.h"
10#include "lj_err.h" 11#include "lj_err.h"
11#include "lj_str.h" 12#include "lj_str.h"
12#include "lj_ctype.h" 13#include "lj_ctype.h"
@@ -105,9 +106,10 @@ static CTypeID ccall_ctid_vararg(CTState *cts, cTValue *o)
105} 106}
106 107
107/* Setup arguments for C call. */ 108/* Setup arguments for C call. */
108static void ccall_set_args(lua_State *L, CTState *cts, CType *ct, 109static int ccall_set_args(lua_State *L, CTState *cts, CType *ct,
109 CCallState *cc) 110 CCallState *cc)
110{ 111{
112 int gcsteps = 0;
111 TValue *o, *top = L->top; 113 TValue *o, *top = L->top;
112 CTypeID fid; 114 CTypeID fid;
113 CType *ctr; 115 CType *ctr;
@@ -257,6 +259,7 @@ static void ccall_set_args(lua_State *L, CTState *cts, CType *ct,
257 259
258 done: 260 done:
259 if (rp) { /* Pass by reference. */ 261 if (rp) { /* Pass by reference. */
262 gcsteps++;
260 *(void **)dp = rp; 263 *(void **)dp = rp;
261 dp = rp; 264 dp = rp;
262 } 265 }
@@ -279,24 +282,30 @@ static void ccall_set_args(lua_State *L, CTState *cts, CType *ct,
279 cc->spadj = (CCALL_SPS_FREE + CCALL_SPS_EXTRA)*CTSIZE_PTR; 282 cc->spadj = (CCALL_SPS_FREE + CCALL_SPS_EXTRA)*CTSIZE_PTR;
280 if (nsp > CCALL_SPS_FREE) 283 if (nsp > CCALL_SPS_FREE)
281 cc->spadj += (((nsp-CCALL_SPS_FREE)*CTSIZE_PTR + 15u) & ~15u); 284 cc->spadj += (((nsp-CCALL_SPS_FREE)*CTSIZE_PTR + 15u) & ~15u);
285 return gcsteps;
282} 286}
283 287
284/* Get results from C call. */ 288/* Get results from C call. */
285static int ccall_get_results(lua_State *L, CTState *cts, CType *ct, 289static int ccall_get_results(lua_State *L, CTState *cts, CType *ct,
286 CCallState *cc) 290 CCallState *cc, int *ret)
287{ 291{
288 CType *ctr = ctype_rawchild(cts, ct); 292 CType *ctr = ctype_rawchild(cts, ct);
289 void *sp = &cc->gpr[0]; 293 void *sp = &cc->gpr[0];
290 if (ctype_isvoid(ctr->info)) 294 if (ctype_isvoid(ctr->info)) {
291 return 0; /* Zero results. */ 295 *ret = 0; /* Zero results. */
296 return 0; /* No additional GC step. */
297 }
298 *ret = 1; /* One result. */
292 if (ctype_isstruct(ctr->info)) { 299 if (ctype_isstruct(ctr->info)) {
300 /* Return cdata object which is already on top of stack. */
293 if (!CCALL_STRUCT_RETREF && !cc->retref) { 301 if (!CCALL_STRUCT_RETREF && !cc->retref) {
294 void *dp = cdataptr(cdataV(L->top-1)); /* Use preallocated object. */ 302 void *dp = cdataptr(cdataV(L->top-1)); /* Use preallocated object. */
295 memcpy(dp, sp, ctr->size); /* Copy struct return value from GPRs. */ 303 memcpy(dp, sp, ctr->size); /* Copy struct return value from GPRs. */
296 } 304 }
297 return 1; /* Return cdata object which is already on top of stack. */ 305 return 1; /* One GC step. */
298 } 306 }
299 if (ctype_iscomplex(ctr->info)) { 307 if (ctype_iscomplex(ctr->info)) {
308 /* Return cdata object which is already on top of stack. */
300#if !CCALL_COMPLEX_RETREF || !CCALL_COMPLEXF_RETREF 309#if !CCALL_COMPLEX_RETREF || !CCALL_COMPLEXF_RETREF
301 void *dp = cdataptr(cdataV(L->top-1)); /* Use preallocated object. */ 310 void *dp = cdataptr(cdataV(L->top-1)); /* Use preallocated object. */
302#if CCALL_COMPLEX_RETREF && !CCALL_COMPLEXF_RETREF 311#if CCALL_COMPLEX_RETREF && !CCALL_COMPLEXF_RETREF
@@ -315,7 +324,7 @@ static int ccall_get_results(lua_State *L, CTState *cts, CType *ct,
315 memcpy(dp, sp, ctr->size); /* Copy complex from GPRs. */ 324 memcpy(dp, sp, ctr->size); /* Copy complex from GPRs. */
316#endif 325#endif
317#endif 326#endif
318 return 1; /* Return cdata object which is already on top of stack. */ 327 return 1; /* One GC step. */
319 } 328 }
320#if CCALL_NUM_FPR 329#if CCALL_NUM_FPR
321 if (ctype_isfp(ctr->info) || ctype_isvector(ctr->info)) 330 if (ctype_isfp(ctr->info) || ctype_isvector(ctr->info))
@@ -323,8 +332,7 @@ static int ccall_get_results(lua_State *L, CTState *cts, CType *ct,
323#endif 332#endif
324 /* No reference types end up here, so there's no need for the CTypeID. */ 333 /* No reference types end up here, so there's no need for the CTypeID. */
325 lua_assert(!(ctype_isrefarray(ctr->info) || ctype_isstruct(ctr->info))); 334 lua_assert(!(ctype_isrefarray(ctr->info) || ctype_isstruct(ctr->info)));
326 lj_cconv_tv_ct(cts, ctr, 0, L->top-1, (uint8_t *)sp); 335 return lj_cconv_tv_ct(cts, ctr, 0, L->top-1, (uint8_t *)sp);
327 return 1; /* One result. */
328} 336}
329 337
330/* Call C function. */ 338/* Call C function. */
@@ -338,10 +346,14 @@ int lj_ccall_func(lua_State *L, GCcdata *cd)
338 ct = ctype_rawchild(cts, ct); 346 ct = ctype_rawchild(cts, ct);
339 if (ctype_isfunc(ct->info)) { 347 if (ctype_isfunc(ct->info)) {
340 CCallState cc; 348 CCallState cc;
349 int gcsteps, ret;
341 cc.func = (void (*)(void))cdata_getptr(p, sz); 350 cc.func = (void (*)(void))cdata_getptr(p, sz);
342 ccall_set_args(L, cts, ct, &cc); 351 gcsteps = ccall_set_args(L, cts, ct, &cc);
343 lj_vm_ffi_call(&cc); 352 lj_vm_ffi_call(&cc);
344 return ccall_get_results(L, cts, ct, &cc); 353 gcsteps += ccall_get_results(L, cts, ct, &cc, &ret);
354 while (gcsteps-- > 0)
355 lj_gc_check(L);
356 return ret;
345 } 357 }
346 return -1; /* Not a function. */ 358 return -1; /* Not a function. */
347} 359}