diff options
author | Mike Pall <mike> | 2010-11-18 00:23:24 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2010-11-18 00:23:24 +0100 |
commit | ba602c9578e01b1d692beddf7e974fa70b6eecf2 (patch) | |
tree | 3ec1beecf5205801d9c1048aca92c97b5bafe859 /src/lib_base.c | |
parent | 3754a8fe7a820bcfc5e2633d15c648a194dd4144 (diff) | |
download | luajit-ba602c9578e01b1d692beddf7e974fa70b6eecf2.tar.gz luajit-ba602c9578e01b1d692beddf7e974fa70b6eecf2.tar.bz2 luajit-ba602c9578e01b1d692beddf7e974fa70b6eecf2.zip |
Add support for __pairs and __ipairs metamethods (from Lua 5.2).
Diffstat (limited to 'src/lib_base.c')
-rw-r--r-- | src/lib_base.c | 34 |
1 files changed, 30 insertions, 4 deletions
diff --git a/src/lib_base.c b/src/lib_base.c index 908099d4..aa55faba 100644 --- a/src/lib_base.c +++ b/src/lib_base.c | |||
@@ -246,17 +246,43 @@ LJ_STATIC_ASSERT((int)FF_next == FF_next_N); | |||
246 | LJLIB_ASM(next) | 246 | LJLIB_ASM(next) |
247 | { | 247 | { |
248 | lj_lib_checktab(L, 1); | 248 | lj_lib_checktab(L, 1); |
249 | lj_lib_checknum(L, 2); /* For ipairs_aux. */ | ||
250 | return FFH_UNREACHABLE; | 249 | return FFH_UNREACHABLE; |
251 | } | 250 | } |
252 | 251 | ||
252 | static int ffh_pairs(lua_State *L, MMS mm) | ||
253 | { | ||
254 | TValue *o = lj_lib_checkany(L, 1); | ||
255 | cTValue *mo = lj_meta_lookup(L, o, mm); | ||
256 | if (!tvisnil(mo)) { | ||
257 | L->top = o+1; /* Only keep one argument. */ | ||
258 | copyTV(L, L->base-1, mo); /* Replace callable. */ | ||
259 | return FFH_TAILCALL; | ||
260 | } else { | ||
261 | if (!tvistab(o)) lj_err_argt(L, 1, LUA_TTABLE); | ||
262 | setfuncV(L, o-1, funcV(lj_lib_upvalue(L, 1))); | ||
263 | if (mm == MM_pairs) setnilV(o+1); else setintV(o+1, 0); | ||
264 | return FFH_RES(3); | ||
265 | } | ||
266 | } | ||
267 | |||
253 | LJLIB_PUSH(lastcl) | 268 | LJLIB_PUSH(lastcl) |
254 | LJLIB_ASM_(pairs) | 269 | LJLIB_ASM(pairs) |
270 | { | ||
271 | return ffh_pairs(L, MM_pairs); | ||
272 | } | ||
255 | 273 | ||
256 | LJLIB_NOREGUV LJLIB_ASM_(ipairs_aux) LJLIB_REC(.) | 274 | LJLIB_NOREGUV LJLIB_ASM(ipairs_aux) LJLIB_REC(.) |
275 | { | ||
276 | lj_lib_checktab(L, 1); | ||
277 | lj_lib_checknum(L, 2); | ||
278 | return FFH_UNREACHABLE; | ||
279 | } | ||
257 | 280 | ||
258 | LJLIB_PUSH(lastcl) | 281 | LJLIB_PUSH(lastcl) |
259 | LJLIB_ASM_(ipairs) LJLIB_REC(.) | 282 | LJLIB_ASM(ipairs) LJLIB_REC(.) |
283 | { | ||
284 | return ffh_pairs(L, MM_ipairs); | ||
285 | } | ||
260 | 286 | ||
261 | /* -- Base library: throw and catch errors -------------------------------- */ | 287 | /* -- Base library: throw and catch errors -------------------------------- */ |
262 | 288 | ||