diff options
-rw-r--r-- | ltm.c | 6 | ||||
-rw-r--r-- | ltm.h | 4 | ||||
-rw-r--r-- | lvm.c | 47 |
3 files changed, 34 insertions, 23 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltm.c,v 2.7 2005/12/22 16:19:56 roberto Exp roberto $ | 2 | ** $Id: ltm.c,v 2.8 2006/01/10 12:50:00 roberto Exp roberto $ |
3 | ** Tag methods | 3 | ** Tag methods |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -30,9 +30,9 @@ const char *const luaT_typenames[] = { | |||
30 | void luaT_init (lua_State *L) { | 30 | void luaT_init (lua_State *L) { |
31 | static const char *const luaT_eventname[] = { /* ORDER TM */ | 31 | static const char *const luaT_eventname[] = { /* ORDER TM */ |
32 | "__index", "__newindex", | 32 | "__index", "__newindex", |
33 | "__gc", "__mode", "__eq", | 33 | "__gc", "__mode", "__len", "__eq", |
34 | "__add", "__sub", "__mul", "__div", "__mod", | 34 | "__add", "__sub", "__mul", "__div", "__mod", |
35 | "__pow", "__unm", "__len", "__lt", "__le", | 35 | "__pow", "__unm", "__lt", "__le", |
36 | "__concat", "__call" | 36 | "__concat", "__call" |
37 | }; | 37 | }; |
38 | int i; | 38 | int i; |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltm.h,v 2.5 2005/05/20 15:53:42 roberto Exp roberto $ | 2 | ** $Id: ltm.h,v 2.6 2005/06/06 13:30:25 roberto Exp roberto $ |
3 | ** Tag methods | 3 | ** Tag methods |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -20,6 +20,7 @@ typedef enum { | |||
20 | TM_NEWINDEX, | 20 | TM_NEWINDEX, |
21 | TM_GC, | 21 | TM_GC, |
22 | TM_MODE, | 22 | TM_MODE, |
23 | TM_LEN, | ||
23 | TM_EQ, /* last tag method with `fast' access */ | 24 | TM_EQ, /* last tag method with `fast' access */ |
24 | TM_ADD, | 25 | TM_ADD, |
25 | TM_SUB, | 26 | TM_SUB, |
@@ -28,7 +29,6 @@ typedef enum { | |||
28 | TM_MOD, | 29 | TM_MOD, |
29 | TM_POW, | 30 | TM_POW, |
30 | TM_UNM, | 31 | TM_UNM, |
31 | TM_LEN, | ||
32 | TM_LT, | 32 | TM_LT, |
33 | TM_LE, | 33 | TM_LE, |
34 | TM_CONCAT, | 34 | TM_CONCAT, |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 2.71 2007/03/26 15:56:23 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 2.72 2007/06/19 19:48:15 roberto Exp roberto $ |
3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -310,6 +310,33 @@ void luaV_concat (lua_State *L, int total, int last) { | |||
310 | } | 310 | } |
311 | 311 | ||
312 | 312 | ||
313 | static void objlen (lua_State *L, StkId ra, const TValue *rb) { | ||
314 | const TValue *tm; | ||
315 | switch (ttype(rb)) { | ||
316 | case LUA_TTABLE: { | ||
317 | Table *h = hvalue(rb); | ||
318 | tm = fasttm(L, h->metatable, TM_LEN); | ||
319 | if (tm) break; /* metamethod? break switch to call it */ | ||
320 | setnvalue(ra, cast_num(luaH_getn(h))); /* else primitive len */ | ||
321 | return; | ||
322 | } | ||
323 | case LUA_TSTRING: { | ||
324 | tm = fasttm(L, G(L)->mt[LUA_TSTRING], TM_LEN); | ||
325 | if (tm) break; /* metamethod? break switch to call it */ | ||
326 | setnvalue(ra, cast_num(tsvalue(rb)->len)); | ||
327 | return; | ||
328 | } | ||
329 | default: { /* try metamethod */ | ||
330 | tm = luaT_gettmbyobj(L, rb, TM_LEN); | ||
331 | if (ttisnil(tm)) /* no metamethod? */ | ||
332 | luaG_typeerror(L, rb, "get length of"); | ||
333 | break; | ||
334 | } | ||
335 | } | ||
336 | callTMres(L, ra, tm, rb, luaO_nilobject); | ||
337 | } | ||
338 | |||
339 | |||
313 | static void Arith (lua_State *L, StkId ra, const TValue *rb, | 340 | static void Arith (lua_State *L, StkId ra, const TValue *rb, |
314 | const TValue *rc, TMS op) { | 341 | const TValue *rc, TMS op) { |
315 | TValue tempb, tempc; | 342 | TValue tempb, tempc; |
@@ -509,23 +536,7 @@ void luaV_execute (lua_State *L, int nexeccalls) { | |||
509 | continue; | 536 | continue; |
510 | } | 537 | } |
511 | case OP_LEN: { | 538 | case OP_LEN: { |
512 | const TValue *rb = RB(i); | 539 | Protect(objlen(L, ra, RB(i))); |
513 | switch (ttype(rb)) { | ||
514 | case LUA_TTABLE: { | ||
515 | setnvalue(ra, cast_num(luaH_getn(hvalue(rb)))); | ||
516 | break; | ||
517 | } | ||
518 | case LUA_TSTRING: { | ||
519 | setnvalue(ra, cast_num(tsvalue(rb)->len)); | ||
520 | break; | ||
521 | } | ||
522 | default: { /* try metamethod */ | ||
523 | Protect( | ||
524 | if (!call_binTM(L, rb, rb, ra, TM_LEN)) | ||
525 | luaG_typeerror(L, rb, "get length of"); | ||
526 | ) | ||
527 | } | ||
528 | } | ||
529 | continue; | 540 | continue; |
530 | } | 541 | } |
531 | case OP_CONCAT: { | 542 | case OP_CONCAT: { |