diff options
-rw-r--r-- | doc/ext_ffi_api.html | 11 | ||||
-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 |
5 files changed, 47 insertions, 7 deletions
diff --git a/doc/ext_ffi_api.html b/doc/ext_ffi_api.html index 16066612..503c6e4a 100644 --- a/doc/ext_ffi_api.html +++ b/doc/ext_ffi_api.html | |||
@@ -525,7 +525,16 @@ Returns a string representation of the value of 64 bit integers | |||
525 | complex numbers (<tt><b>"</b>re±im<b>i"</b></tt>). Otherwise | 525 | complex numbers (<tt><b>"</b>re±im<b>i"</b></tt>). Otherwise |
526 | returns a string representation of the C type of a ctype object | 526 | returns a string representation of the C type of a ctype object |
527 | (<tt><b>"ctype<</b>type<b>>"</b></tt>) or a cdata object | 527 | (<tt><b>"ctype<</b>type<b>>"</b></tt>) or a cdata object |
528 | (<tt><b>"cdata<</b>type<b>>: </b>address"</tt>). | 528 | (<tt><b>"cdata<</b>type<b>>: </b>address"</tt>), unless you |
529 | override it with a <tt>__tostring</tt> metamethod (see | ||
530 | <a href="#ffi_metatype"><tt>ffi.metatype()</tt></a>). | ||
531 | </p> | ||
532 | |||
533 | <h3 id="pairs"><tt>iter, obj, start = pairs(cdata)<br> | ||
534 | iter, obj, start = ipairs(cdata)<br></tt></h3> | ||
535 | <p> | ||
536 | Calls the <tt>__pairs</tt> or <tt>__ipairs</tt> metamethod of the | ||
537 | corresponding ctype. | ||
529 | </p> | 538 | </p> |
530 | 539 | ||
531 | <h2 id="literals">Extensions to the Lua Parser</h2> | 540 | <h2 id="literals">Extensions to the Lua Parser</h2> |
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, |