mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 15:14:08 +00:00
FFI: Handle __pairs/__ipairs metamethods for cdata objects.
This commit is contained in:
parent
90ec1f90d0
commit
0648fd47cb
@ -525,7 +525,16 @@ Returns a string representation of the value of 64 bit integers
|
|||||||
complex numbers (<tt><b>"</b>re±im<b>i"</b></tt>). Otherwise
|
complex numbers (<tt><b>"</b>re±im<b>i"</b></tt>). Otherwise
|
||||||
returns a string representation of the C type of a ctype object
|
returns a string representation of the C type of a ctype object
|
||||||
(<tt><b>"ctype<</b>type<b>>"</b></tt>) or a cdata object
|
(<tt><b>"ctype<</b>type<b>>"</b></tt>) or a cdata object
|
||||||
(<tt><b>"cdata<</b>type<b>>: </b>address"</tt>).
|
(<tt><b>"cdata<</b>type<b>>: </b>address"</tt>), unless you
|
||||||
|
override it with a <tt>__tostring</tt> metamethod (see
|
||||||
|
<a href="#ffi_metatype"><tt>ffi.metatype()</tt></a>).
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h3 id="pairs"><tt>iter, obj, start = pairs(cdata)<br>
|
||||||
|
iter, obj, start = ipairs(cdata)<br></tt></h3>
|
||||||
|
<p>
|
||||||
|
Calls the <tt>__pairs</tt> or <tt>__ipairs</tt> metamethod of the
|
||||||
|
corresponding ctype.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h2 id="literals">Extensions to the Lua Parser</h2>
|
<h2 id="literals">Extensions to the Lua Parser</h2>
|
||||||
|
@ -278,12 +278,16 @@ LJLIB_ASM(next)
|
|||||||
return FFH_UNREACHABLE;
|
return FFH_UNREACHABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LUAJIT_ENABLE_LUA52COMPAT
|
#if defined(LUAJIT_ENABLE_LUA52COMPAT) || LJ_HASFFI
|
||||||
static int ffh_pairs(lua_State *L, MMS mm)
|
static int ffh_pairs(lua_State *L, MMS mm)
|
||||||
{
|
{
|
||||||
TValue *o = lj_lib_checkany(L, 1);
|
TValue *o = lj_lib_checkany(L, 1);
|
||||||
cTValue *mo = lj_meta_lookup(L, o, mm);
|
cTValue *mo = lj_meta_lookup(L, o, mm);
|
||||||
if (!tvisnil(mo)) {
|
if (
|
||||||
|
#if !defined(LUAJIT_ENABLE_LUA52COMPAT)
|
||||||
|
tviscdata(o) &&
|
||||||
|
#endif
|
||||||
|
!tvisnil(mo)) {
|
||||||
L->top = o+1; /* Only keep one argument. */
|
L->top = o+1; /* Only keep one argument. */
|
||||||
copyTV(L, L->base-1, mo); /* Replace callable. */
|
copyTV(L, L->base-1, mo); /* Replace callable. */
|
||||||
return FFH_TAILCALL;
|
return FFH_TAILCALL;
|
||||||
|
@ -323,6 +323,30 @@ checkgc:
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ffi_pairs(lua_State *L, MMS mm)
|
||||||
|
{
|
||||||
|
CTState *cts = ctype_cts(L);
|
||||||
|
CTypeID id = ffi_checkcdata(L, 1)->ctypeid;
|
||||||
|
CType *ct = ctype_raw(cts, id);
|
||||||
|
cTValue *tv;
|
||||||
|
if (ctype_isptr(ct->info)) id = ctype_cid(ct->info);
|
||||||
|
tv = lj_ctype_meta(cts, id, mm);
|
||||||
|
if (!tv)
|
||||||
|
lj_err_callerv(L, LJ_ERR_FFI_BADMM, strdata(lj_ctype_repr(L, id, NULL)),
|
||||||
|
strdata(mmname_str(G(L), mm)));
|
||||||
|
return lj_meta_tailcall(L, tv);
|
||||||
|
}
|
||||||
|
|
||||||
|
LJLIB_CF(ffi_meta___pairs)
|
||||||
|
{
|
||||||
|
return ffi_pairs(L, MM_pairs);
|
||||||
|
}
|
||||||
|
|
||||||
|
LJLIB_CF(ffi_meta___ipairs)
|
||||||
|
{
|
||||||
|
return ffi_pairs(L, MM_ipairs);
|
||||||
|
}
|
||||||
|
|
||||||
LJLIB_PUSH("ffi") LJLIB_SET(__metatable)
|
LJLIB_PUSH("ffi") LJLIB_SET(__metatable)
|
||||||
|
|
||||||
#include "lj_libdef.h"
|
#include "lj_libdef.h"
|
||||||
|
@ -162,6 +162,7 @@ ERRDEF(FFI_NUMARG, "wrong number of arguments for function call")
|
|||||||
ERRDEF(FFI_BADMEMBER, LUA_QS " has no member named " LUA_QS)
|
ERRDEF(FFI_BADMEMBER, LUA_QS " has no member named " LUA_QS)
|
||||||
ERRDEF(FFI_BADIDX, LUA_QS " cannot be indexed")
|
ERRDEF(FFI_BADIDX, LUA_QS " cannot be indexed")
|
||||||
ERRDEF(FFI_BADIDXW, LUA_QS " cannot be indexed with " LUA_QS)
|
ERRDEF(FFI_BADIDXW, LUA_QS " cannot be indexed with " LUA_QS)
|
||||||
|
ERRDEF(FFI_BADMM, LUA_QS " has no " LUA_QS " metamethod")
|
||||||
ERRDEF(FFI_WRCONST, "attempt to write to constant location")
|
ERRDEF(FFI_WRCONST, "attempt to write to constant location")
|
||||||
ERRDEF(FFI_NODECL, "missing declaration for symbol " LUA_QS)
|
ERRDEF(FFI_NODECL, "missing declaration for symbol " LUA_QS)
|
||||||
ERRDEF(FFI_BADCBACK, "bad callback")
|
ERRDEF(FFI_BADCBACK, "bad callback")
|
||||||
|
10
src/lj_obj.h
10
src/lj_obj.h
@ -447,10 +447,12 @@ enum {
|
|||||||
#define MMDEF_FFI(_)
|
#define MMDEF_FFI(_)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef LUAJIT_ENABLE_LUA52COMPAT
|
#if defined(LUAJIT_ENABLE_LUA52COMPAT) || LJ_HASFFI
|
||||||
#define MMDEF_52(_) _(pairs) _(ipairs)
|
#define MMDEF_PAIRS(_) _(pairs) _(ipairs)
|
||||||
#else
|
#else
|
||||||
#define MMDEF_52(_)
|
#define MMDEF_PAIRS(_)
|
||||||
|
#define MM_pairs 255
|
||||||
|
#define MM_ipairs 255
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MMDEF(_) \
|
#define MMDEF(_) \
|
||||||
@ -460,7 +462,7 @@ enum {
|
|||||||
/* The following must be in ORDER ARITH. */ \
|
/* The following must be in ORDER ARITH. */ \
|
||||||
_(add) _(sub) _(mul) _(div) _(mod) _(pow) _(unm) \
|
_(add) _(sub) _(mul) _(div) _(mod) _(pow) _(unm) \
|
||||||
/* The following are used in the standard libraries. */ \
|
/* The following are used in the standard libraries. */ \
|
||||||
_(metatable) _(tostring) MMDEF_FFI(_) MMDEF_52(_)
|
_(metatable) _(tostring) MMDEF_FFI(_) MMDEF_PAIRS(_)
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
#define MMENUM(name) MM_##name,
|
#define MMENUM(name) MM_##name,
|
||||||
|
Loading…
Reference in New Issue
Block a user