diff options
author | Mike Pall <mike> | 2012-09-03 21:10:10 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2012-09-03 21:11:08 +0200 |
commit | 0648fd47cb5560cf1a44a211a75997863e8470dd (patch) | |
tree | 794077cf10c0f9dcb05c406904342880025311e3 /src | |
parent | 90ec1f90d0c31ab9398e971665c1e33d3158f9c0 (diff) | |
download | luajit-0648fd47cb5560cf1a44a211a75997863e8470dd.tar.gz luajit-0648fd47cb5560cf1a44a211a75997863e8470dd.tar.bz2 luajit-0648fd47cb5560cf1a44a211a75997863e8470dd.zip |
FFI: Handle __pairs/__ipairs metamethods for cdata objects.
Diffstat (limited to 'src')
-rw-r--r-- | src/lib_base.c | 8 | ||||
-rw-r--r-- | src/lib_ffi.c | 24 | ||||
-rw-r--r-- | src/lj_errmsg.h | 1 | ||||
-rw-r--r-- | src/lj_obj.h | 10 |
4 files changed, 37 insertions, 6 deletions
diff --git a/src/lib_base.c b/src/lib_base.c index 9702c5b4..824fc0e7 100644 --- a/src/lib_base.c +++ b/src/lib_base.c | |||
@@ -278,12 +278,16 @@ LJLIB_ASM(next) | |||
278 | return FFH_UNREACHABLE; | 278 | return FFH_UNREACHABLE; |
279 | } | 279 | } |
280 | 280 | ||
281 | #ifdef LUAJIT_ENABLE_LUA52COMPAT | 281 | #if defined(LUAJIT_ENABLE_LUA52COMPAT) || LJ_HASFFI |
282 | static int ffh_pairs(lua_State *L, MMS mm) | 282 | static int ffh_pairs(lua_State *L, MMS mm) |
283 | { | 283 | { |
284 | TValue *o = lj_lib_checkany(L, 1); | 284 | TValue *o = lj_lib_checkany(L, 1); |
285 | cTValue *mo = lj_meta_lookup(L, o, mm); | 285 | cTValue *mo = lj_meta_lookup(L, o, mm); |
286 | if (!tvisnil(mo)) { | 286 | if ( |
287 | #if !defined(LUAJIT_ENABLE_LUA52COMPAT) | ||
288 | tviscdata(o) && | ||
289 | #endif | ||
290 | !tvisnil(mo)) { | ||
287 | L->top = o+1; /* Only keep one argument. */ | 291 | L->top = o+1; /* Only keep one argument. */ |
288 | copyTV(L, L->base-1, mo); /* Replace callable. */ | 292 | copyTV(L, L->base-1, mo); /* Replace callable. */ |
289 | return FFH_TAILCALL; | 293 | return FFH_TAILCALL; |
diff --git a/src/lib_ffi.c b/src/lib_ffi.c index 24a6625c..69bebefc 100644 --- a/src/lib_ffi.c +++ b/src/lib_ffi.c | |||
@@ -323,6 +323,30 @@ checkgc: | |||
323 | return 1; | 323 | return 1; |
324 | } | 324 | } |
325 | 325 | ||
326 | static int ffi_pairs(lua_State *L, MMS mm) | ||
327 | { | ||
328 | CTState *cts = ctype_cts(L); | ||
329 | CTypeID id = ffi_checkcdata(L, 1)->ctypeid; | ||
330 | CType *ct = ctype_raw(cts, id); | ||
331 | cTValue *tv; | ||
332 | if (ctype_isptr(ct->info)) id = ctype_cid(ct->info); | ||
333 | tv = lj_ctype_meta(cts, id, mm); | ||
334 | if (!tv) | ||
335 | lj_err_callerv(L, LJ_ERR_FFI_BADMM, strdata(lj_ctype_repr(L, id, NULL)), | ||
336 | strdata(mmname_str(G(L), mm))); | ||
337 | return lj_meta_tailcall(L, tv); | ||
338 | } | ||
339 | |||
340 | LJLIB_CF(ffi_meta___pairs) | ||
341 | { | ||
342 | return ffi_pairs(L, MM_pairs); | ||
343 | } | ||
344 | |||
345 | LJLIB_CF(ffi_meta___ipairs) | ||
346 | { | ||
347 | return ffi_pairs(L, MM_ipairs); | ||
348 | } | ||
349 | |||
326 | LJLIB_PUSH("ffi") LJLIB_SET(__metatable) | 350 | LJLIB_PUSH("ffi") LJLIB_SET(__metatable) |
327 | 351 | ||
328 | #include "lj_libdef.h" | 352 | #include "lj_libdef.h" |
diff --git a/src/lj_errmsg.h b/src/lj_errmsg.h index 5b10dea8..dd3eefa8 100644 --- a/src/lj_errmsg.h +++ b/src/lj_errmsg.h | |||
@@ -162,6 +162,7 @@ ERRDEF(FFI_NUMARG, "wrong number of arguments for function call") | |||
162 | ERRDEF(FFI_BADMEMBER, LUA_QS " has no member named " LUA_QS) | 162 | ERRDEF(FFI_BADMEMBER, LUA_QS " has no member named " LUA_QS) |
163 | ERRDEF(FFI_BADIDX, LUA_QS " cannot be indexed") | 163 | ERRDEF(FFI_BADIDX, LUA_QS " cannot be indexed") |
164 | ERRDEF(FFI_BADIDXW, LUA_QS " cannot be indexed with " LUA_QS) | 164 | ERRDEF(FFI_BADIDXW, LUA_QS " cannot be indexed with " LUA_QS) |
165 | ERRDEF(FFI_BADMM, LUA_QS " has no " LUA_QS " metamethod") | ||
165 | ERRDEF(FFI_WRCONST, "attempt to write to constant location") | 166 | ERRDEF(FFI_WRCONST, "attempt to write to constant location") |
166 | ERRDEF(FFI_NODECL, "missing declaration for symbol " LUA_QS) | 167 | ERRDEF(FFI_NODECL, "missing declaration for symbol " LUA_QS) |
167 | ERRDEF(FFI_BADCBACK, "bad callback") | 168 | ERRDEF(FFI_BADCBACK, "bad callback") |
diff --git a/src/lj_obj.h b/src/lj_obj.h index 7890e54b..67fb5ed9 100644 --- a/src/lj_obj.h +++ b/src/lj_obj.h | |||
@@ -447,10 +447,12 @@ enum { | |||
447 | #define MMDEF_FFI(_) | 447 | #define MMDEF_FFI(_) |
448 | #endif | 448 | #endif |
449 | 449 | ||
450 | #ifdef LUAJIT_ENABLE_LUA52COMPAT | 450 | #if defined(LUAJIT_ENABLE_LUA52COMPAT) || LJ_HASFFI |
451 | #define MMDEF_52(_) _(pairs) _(ipairs) | 451 | #define MMDEF_PAIRS(_) _(pairs) _(ipairs) |
452 | #else | 452 | #else |
453 | #define MMDEF_52(_) | 453 | #define MMDEF_PAIRS(_) |
454 | #define MM_pairs 255 | ||
455 | #define MM_ipairs 255 | ||
454 | #endif | 456 | #endif |
455 | 457 | ||
456 | #define MMDEF(_) \ | 458 | #define MMDEF(_) \ |
@@ -460,7 +462,7 @@ enum { | |||
460 | /* The following must be in ORDER ARITH. */ \ | 462 | /* The following must be in ORDER ARITH. */ \ |
461 | _(add) _(sub) _(mul) _(div) _(mod) _(pow) _(unm) \ | 463 | _(add) _(sub) _(mul) _(div) _(mod) _(pow) _(unm) \ |
462 | /* The following are used in the standard libraries. */ \ | 464 | /* The following are used in the standard libraries. */ \ |
463 | _(metatable) _(tostring) MMDEF_FFI(_) MMDEF_52(_) | 465 | _(metatable) _(tostring) MMDEF_FFI(_) MMDEF_PAIRS(_) |
464 | 466 | ||
465 | typedef enum { | 467 | typedef enum { |
466 | #define MMENUM(name) MM_##name, | 468 | #define MMENUM(name) MM_##name, |