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, |
