aboutsummaryrefslogtreecommitdiff
path: root/lvm.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2007-09-10 14:59:32 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2007-09-10 14:59:32 -0300
commitfe0838cd1c75e309f9d136d69f9d77e997181d80 (patch)
tree88acac0e70fe74cb686d87ffb471e906c04b9cfd /lvm.c
parent8acaa2ce07ff19a99a8f6d97627df37fd15cc669 (diff)
downloadlua-fe0838cd1c75e309f9d136d69f9d77e997181d80.tar.gz
lua-fe0838cd1c75e309f9d136d69f9d77e997181d80.tar.bz2
lua-fe0838cd1c75e309f9d136d69f9d77e997181d80.zip
tables and strings respect __len metamethod
Diffstat (limited to 'lvm.c')
-rw-r--r--lvm.c47
1 files changed, 29 insertions, 18 deletions
diff --git a/lvm.c b/lvm.c
index 054327a7..6e227053 100644
--- a/lvm.c
+++ b/lvm.c
@@ -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
313static 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
313static void Arith (lua_State *L, StkId ra, const TValue *rb, 340static 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: {