aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2012-09-03 21:10:10 +0200
committerMike Pall <mike>2012-09-03 21:11:08 +0200
commit0648fd47cb5560cf1a44a211a75997863e8470dd (patch)
tree794077cf10c0f9dcb05c406904342880025311e3 /src
parent90ec1f90d0c31ab9398e971665c1e33d3158f9c0 (diff)
downloadluajit-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.c8
-rw-r--r--src/lib_ffi.c24
-rw-r--r--src/lj_errmsg.h1
-rw-r--r--src/lj_obj.h10
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
282static int ffh_pairs(lua_State *L, MMS mm) 282static 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
326static 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
340LJLIB_CF(ffi_meta___pairs)
341{
342 return ffi_pairs(L, MM_pairs);
343}
344
345LJLIB_CF(ffi_meta___ipairs)
346{
347 return ffi_pairs(L, MM_ipairs);
348}
349
326LJLIB_PUSH("ffi") LJLIB_SET(__metatable) 350LJLIB_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")
162ERRDEF(FFI_BADMEMBER, LUA_QS " has no member named " LUA_QS) 162ERRDEF(FFI_BADMEMBER, LUA_QS " has no member named " LUA_QS)
163ERRDEF(FFI_BADIDX, LUA_QS " cannot be indexed") 163ERRDEF(FFI_BADIDX, LUA_QS " cannot be indexed")
164ERRDEF(FFI_BADIDXW, LUA_QS " cannot be indexed with " LUA_QS) 164ERRDEF(FFI_BADIDXW, LUA_QS " cannot be indexed with " LUA_QS)
165ERRDEF(FFI_BADMM, LUA_QS " has no " LUA_QS " metamethod")
165ERRDEF(FFI_WRCONST, "attempt to write to constant location") 166ERRDEF(FFI_WRCONST, "attempt to write to constant location")
166ERRDEF(FFI_NODECL, "missing declaration for symbol " LUA_QS) 167ERRDEF(FFI_NODECL, "missing declaration for symbol " LUA_QS)
167ERRDEF(FFI_BADCBACK, "bad callback") 168ERRDEF(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
465typedef enum { 467typedef enum {
466#define MMENUM(name) MM_##name, 468#define MMENUM(name) MM_##name,