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: { |
