aboutsummaryrefslogtreecommitdiff
path: root/src/lib_ffi.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lib_ffi.c41
1 files changed, 22 insertions, 19 deletions
diff --git a/src/lib_ffi.c b/src/lib_ffi.c
index f4097041..e7d31fe7 100644
--- a/src/lib_ffi.c
+++ b/src/lib_ffi.c
@@ -206,31 +206,34 @@ LJLIB_CF(ffi_meta___concat) LJLIB_REC(cdata_arith MM_concat)
206 return ffi_arith(L); 206 return ffi_arith(L);
207} 207}
208 208
209/* Handle ctype __call metamethod. */
210static int ffi_call_meta(lua_State *L, CTypeID id)
211{
212 CTState *cts = ctype_cts(L);
213 CType *ct = ctype_raw(cts, id);
214 cTValue *tv;
215 if (ctype_isptr(ct->info)) id = ctype_cid(ct->info);
216 tv = lj_ctype_meta(cts, id, MM_call);
217 if (!tv)
218 lj_err_callerv(L, LJ_ERR_FFI_BADCALL, strdata(lj_ctype_repr(L, id, NULL)));
219 return lj_meta_tailcall(L, tv);
220}
221
222/* Forward declaration. */ 209/* Forward declaration. */
223static int lj_cf_ffi_new(lua_State *L); 210static int lj_cf_ffi_new(lua_State *L);
224 211
225LJLIB_CF(ffi_meta___call) LJLIB_REC(cdata_call) 212LJLIB_CF(ffi_meta___call) LJLIB_REC(cdata_call)
226{ 213{
214 CTState *cts = ctype_cts(L);
227 GCcdata *cd = ffi_checkcdata(L, 1); 215 GCcdata *cd = ffi_checkcdata(L, 1);
228 int ret; 216 CTypeID id = cd->typeid;
229 if (cd->typeid == CTID_CTYPEID) 217 CType *ct;
230 return lj_cf_ffi_new(L); 218 cTValue *tv;
231 if ((ret = lj_ccall_func(L, cd)) < 0) 219 MMS mm = MM_call;
232 return ffi_call_meta(L, cd->typeid); 220 if (cd->typeid == CTID_CTYPEID) {
233 return ret; 221 id = *(CTypeID *)cdataptr(cd);
222 mm = MM_new;
223 } else {
224 int ret = lj_ccall_func(L, cd);
225 if (ret >= 0)
226 return ret;
227 }
228 /* Handle ctype __call/__new metamethod. */
229 ct = ctype_raw(cts, id);
230 if (ctype_isptr(ct->info)) id = ctype_cid(ct->info);
231 tv = lj_ctype_meta(cts, id, mm);
232 if (tv)
233 return lj_meta_tailcall(L, tv);
234 else if (mm == MM_call)
235 lj_err_callerv(L, LJ_ERR_FFI_BADCALL, strdata(lj_ctype_repr(L, id, NULL)));
236 return lj_cf_ffi_new(L);
234} 237}
235 238
236LJLIB_CF(ffi_meta___add) LJLIB_REC(cdata_arith MM_add) 239LJLIB_CF(ffi_meta___add) LJLIB_REC(cdata_arith MM_add)