diff options
| author | Mike Pall <mike> | 2011-11-14 12:01:48 +0100 |
|---|---|---|
| committer | Mike Pall <mike> | 2011-11-14 12:01:48 +0100 |
| commit | ae79ff4e53392f80c4e64a043800c6838ab535a0 (patch) | |
| tree | 1f917b84dbc2c88cf1adeae654a83323608a8300 | |
| parent | 4d59752217148d81f01034161672b289c3d5ba22 (diff) | |
| download | luajit-ae79ff4e53392f80c4e64a043800c6838ab535a0.tar.gz luajit-ae79ff4e53392f80c4e64a043800c6838ab535a0.tar.bz2 luajit-ae79ff4e53392f80c4e64a043800c6838ab535a0.zip | |
FFI: Resolve __call metamethod for pointers, too.
| -rw-r--r-- | src/lib_ffi.c | 5 | ||||
| -rw-r--r-- | src/lj_crecord.c | 19 |
2 files changed, 22 insertions, 2 deletions
diff --git a/src/lib_ffi.c b/src/lib_ffi.c index 82942e44..af500118 100644 --- a/src/lib_ffi.c +++ b/src/lib_ffi.c | |||
| @@ -207,7 +207,10 @@ LJLIB_CF(ffi_meta___concat) LJLIB_REC(cdata_arith MM_concat) | |||
| 207 | static int ffi_call_meta(lua_State *L, CTypeID id) | 207 | static int ffi_call_meta(lua_State *L, CTypeID id) |
| 208 | { | 208 | { |
| 209 | CTState *cts = ctype_cts(L); | 209 | CTState *cts = ctype_cts(L); |
| 210 | cTValue *tv = lj_ctype_meta(cts, id, MM_call); | 210 | CType *ct = ctype_raw(cts, id); |
| 211 | cTValue *tv; | ||
| 212 | if (ctype_isptr(ct->info)) id = ctype_cid(ct->info); | ||
| 213 | tv = lj_ctype_meta(cts, id, MM_call); | ||
| 211 | if (!tv) | 214 | if (!tv) |
| 212 | lj_err_callerv(L, LJ_ERR_FFI_BADCALL, strdata(lj_ctype_repr(L, id, NULL))); | 215 | lj_err_callerv(L, LJ_ERR_FFI_BADCALL, strdata(lj_ctype_repr(L, id, NULL))); |
| 213 | return lj_meta_tailcall(L, tv); | 216 | return lj_meta_tailcall(L, tv); |
diff --git a/src/lj_crecord.c b/src/lj_crecord.c index 3dd6f495..2c63e8a6 100644 --- a/src/lj_crecord.c +++ b/src/lj_crecord.c | |||
| @@ -890,13 +890,30 @@ static int crec_call(jit_State *J, RecordFFData *rd, GCcdata *cd) | |||
| 890 | return 0; | 890 | return 0; |
| 891 | } | 891 | } |
| 892 | 892 | ||
| 893 | /* Record ctype call metamethod. */ | ||
| 894 | static void crec_call_meta(jit_State *J, RecordFFData *rd, CTypeID id) | ||
| 895 | { | ||
| 896 | CTState *cts = ctype_ctsG(J2G(J)); | ||
| 897 | CType *ct = ctype_raw(cts, id); | ||
| 898 | cTValue *tv; | ||
| 899 | if (ctype_isptr(ct->info)) id = ctype_cid(ct->info); | ||
| 900 | tv = lj_ctype_meta(cts, id, MM_call); | ||
| 901 | if (tv && tvisfunc(tv)) { | ||
| 902 | J->base[-1] = lj_ir_kfunc(J, funcV(tv)) | TREF_FRAME; | ||
| 903 | rd->nres = -1; /* Pending tailcall. */ | ||
| 904 | } else { | ||
| 905 | /* NYI: non-function metamethods. */ | ||
| 906 | lj_trace_err(J, LJ_TRERR_BADTYPE); | ||
| 907 | } | ||
| 908 | } | ||
| 909 | |||
| 893 | void LJ_FASTCALL recff_cdata_call(jit_State *J, RecordFFData *rd) | 910 | void LJ_FASTCALL recff_cdata_call(jit_State *J, RecordFFData *rd) |
| 894 | { | 911 | { |
| 895 | GCcdata *cd = argv2cdata(J, J->base[0], &rd->argv[0]); | 912 | GCcdata *cd = argv2cdata(J, J->base[0], &rd->argv[0]); |
| 896 | if (cd->typeid == CTID_CTYPEID) | 913 | if (cd->typeid == CTID_CTYPEID) |
| 897 | crec_alloc(J, rd, crec_constructor(J, cd, J->base[0])); | 914 | crec_alloc(J, rd, crec_constructor(J, cd, J->base[0])); |
| 898 | else if (!crec_call(J, rd, cd)) | 915 | else if (!crec_call(J, rd, cd)) |
| 899 | lj_trace_err(J, LJ_TRERR_BADTYPE); | 916 | crec_call_meta(J, rd, cd->typeid); |
| 900 | } | 917 | } |
| 901 | 918 | ||
| 902 | static TRef crec_arith_int64(jit_State *J, TRef *sp, CType **s, MMS mm) | 919 | static TRef crec_arith_int64(jit_State *J, TRef *sp, CType **s, MMS mm) |
