aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-07-05 15:27:39 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2002-07-05 15:27:39 -0300
commitf8279f6cd8bf22245be30649df5a2d19d868e114 (patch)
tree46172bc8ff351275f5e1232f8eb8e842fc3b8c9e
parent1fe280df725810594ef9b70af663dec3ea22b2de (diff)
downloadlua-f8279f6cd8bf22245be30649df5a2d19d868e114.tar.gz
lua-f8279f6cd8bf22245be30649df5a2d19d868e114.tar.bz2
lua-f8279f6cd8bf22245be30649df5a2d19d868e114.zip
optimizations for gettable (temporary)
-rw-r--r--lvm.c98
-rw-r--r--lvm.h5
2 files changed, 69 insertions, 34 deletions
diff --git a/lvm.c b/lvm.c
index d61953fe..0e643f7f 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 1.242 2002/06/24 14:11:14 roberto Exp roberto $ 2** $Id: lvm.c,v 1.243 2002/06/24 15:07:21 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*/
@@ -32,7 +32,7 @@
32 32
33 33
34/* limit for table tag-method chains (to avoid loops) */ 34/* limit for table tag-method chains (to avoid loops) */
35#define MAXTAGLOOP 10000 35#define MAXTAGLOOP 100
36 36
37 37
38static void luaV_checkGC (lua_State *L, StkId top) { 38static void luaV_checkGC (lua_State *L, StkId top) {
@@ -108,34 +108,46 @@ static void callTM (lua_State *L, const TObject *f,
108} 108}
109 109
110 110
111static const TObject *luaV_index (lua_State *L, const TObject *t,
112 TObject *key, int loop) {
113 const TObject *tm = fasttm(L, hvalue(t)->metatable, TM_INDEX);
114 if (tm == NULL) return &luaO_nilobject; /* no TM */
115 if (ttype(tm) == LUA_TFUNCTION) {
116 callTMres(L, tm, t, key);
117 return L->top;
118 }
119 else return luaV_gettable(L, tm, key, loop);
120}
121
122static const TObject *luaV_getnotable (lua_State *L, const TObject *t,
123 TObject *key, int loop) {
124 const TObject *tm = luaT_gettmbyobj(L, t, TM_GETTABLE);
125 if (ttype(tm) == LUA_TNIL)
126 luaG_typeerror(L, t, "index");
127 if (ttype(tm) == LUA_TFUNCTION) {
128 callTMres(L, tm, t, key);
129 return L->top;
130 }
131 else return luaV_gettable(L, tm, key, loop);
132}
133
134
111/* 135/*
112** Function to index a table. 136** Function to index a table.
113** Receives the table at `t' and the key at `key'. 137** Receives the table at `t' and the key at `key'.
114** leaves the result at `res'. 138** leaves the result at `res'.
115*/ 139*/
116const TObject *luaV_gettable (lua_State *L, const TObject *t, TObject *key) { 140const TObject *luaV_gettable (lua_State *L, const TObject *t, TObject *key,
117 const TObject *tm; 141 int loop) {
118 int loop = 0; 142 if (loop > MAXTAGLOOP)
119 do { 143 luaG_runerror(L, "loop in gettable");
120 if (ttype(t) == LUA_TTABLE) { /* `t' is a table? */ 144 if (ttype(t) == LUA_TTABLE) { /* `t' is a table? */
121 Table *h = hvalue(t); 145 Table *h = hvalue(t);
122 const TObject *v = luaH_get(h, key); /* do a primitive get */ 146 const TObject *v = luaH_get(h, key); /* do a primitive get */
123 if (ttype(v) != LUA_TNIL || /* result is no nil? */ 147 if (ttype(v) != LUA_TNIL) return v;
124 (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */ 148 else return luaV_index(L, t, key, loop+1);
125 return v; 149 }
126 } 150 else return luaV_getnotable(L, t, key, loop+1);
127 /* else will try the tag method */
128 }
129 else if (ttype(tm = luaT_gettmbyobj(L, t, TM_GETTABLE)) == LUA_TNIL)
130 luaG_typeerror(L, t, "index");
131 if (ttype(tm) == LUA_TFUNCTION) {
132 callTMres(L, tm, t, key);
133 return L->top;
134 }
135 t = tm; /* else repeat access with `tm' */
136 } while (++loop <= MAXTAGLOOP);
137 luaG_runerror(L, "loop in gettable");
138 return NULL; /* to avoid warnings */
139} 151}
140 152
141 153
@@ -392,12 +404,26 @@ StkId luaV_execute (lua_State *L) {
392 break; 404 break;
393 } 405 }
394 case OP_GETGLOBAL: { 406 case OP_GETGLOBAL: {
395 lua_assert(ttype(KBx(i)) == LUA_TSTRING && ttype(&cl->g) == LUA_TTABLE); 407 StkId rb = KBx(i);
396 setobj(RA(i), luaV_gettable(L, &cl->g, KBx(i))); 408 const TObject *v;
409 lua_assert(ttype(rb) == LUA_TSTRING && ttype(&cl->g) == LUA_TTABLE);
410 v = luaH_getstr(hvalue(&cl->g), tsvalue(rb));
411 if (ttype(v) != LUA_TNIL) { setobj(ra, v); }
412 else
413 setobj(RA(i), luaV_index(L, &cl->g, rb, 0));
397 break; 414 break;
398 } 415 }
399 case OP_GETTABLE: { 416 case OP_GETTABLE: {
400 setobj(RA(i), luaV_gettable(L, RB(i), RKC(i))); 417 StkId rb = RB(i);
418 TObject *rc = RKC(i);
419 if (ttype(rb) == LUA_TTABLE) {
420 const TObject *v = luaH_get(hvalue(rb), rc);
421 if (ttype(v) != LUA_TNIL) { setobj(ra, v); }
422 else
423 setobj(RA(i), luaV_index(L, rb, rc, 0));
424 }
425 else
426 setobj(RA(i), luaV_getnotable(L, rb, rc, 0));
401 break; 427 break;
402 } 428 }
403 case OP_SETGLOBAL: { 429 case OP_SETGLOBAL: {
@@ -423,8 +449,17 @@ StkId luaV_execute (lua_State *L) {
423 } 449 }
424 case OP_SELF: { 450 case OP_SELF: {
425 StkId rb = RB(i); 451 StkId rb = RB(i);
452 TObject *rc = RKC(i);
453 runtime_check(L, ttype(rc) == LUA_TSTRING);
426 setobj(ra+1, rb); 454 setobj(ra+1, rb);
427 setobj(RA(i), luaV_gettable(L, rb, RKC(i))); 455 if (ttype(rb) == LUA_TTABLE) {
456 const TObject *v = luaH_getstr(hvalue(rb), tsvalue(rc));
457 if (ttype(v) != LUA_TNIL) { setobj(ra, v); }
458 else
459 setobj(RA(i), luaV_index(L, rb, rc, 0));
460 }
461 else
462 setobj(RA(i), luaV_getnotable(L, rb, rc, 0));
428 break; 463 break;
429 } 464 }
430 case OP_ADD: { 465 case OP_ADD: {
@@ -620,11 +655,10 @@ StkId luaV_execute (lua_State *L) {
620 else dojump(pc, GETARG_sBx(*pc) + 1); /* else jump back */ 655 else dojump(pc, GETARG_sBx(*pc) + 1); /* else jump back */
621 break; 656 break;
622 } 657 }
623 case OP_TFORPREP: { 658 case OP_TFORPREP: { /* for compatibility only */
624 if (ttype(ra) == LUA_TTABLE) { 659 if (ttype(ra) == LUA_TTABLE) {
625 setobj(ra+1, ra); 660 setobj(ra+1, ra);
626 setsvalue(ra, luaS_new(L, "next")); 661 setobj(ra, luaH_getstr(hvalue(gt(L)), luaS_new(L, "next")));
627 setobj(RA(i), luaV_gettable(L, gt(L), ra));
628 } 662 }
629 dojump(pc, GETARG_sBx(i)); 663 dojump(pc, GETARG_sBx(i));
630 break; 664 break;
diff --git a/lvm.h b/lvm.h
index 170e8c9c..6b462e09 100644
--- a/lvm.h
+++ b/lvm.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.h,v 1.42 2002/06/13 13:39:55 roberto Exp roberto $ 2** $Id: lvm.h,v 1.43 2002/06/24 13:08:45 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*/
@@ -26,7 +26,8 @@ int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r);
26int luaV_equalval (lua_State *L, const TObject *t1, const TObject *t2); 26int luaV_equalval (lua_State *L, const TObject *t1, const TObject *t2);
27const TObject *luaV_tonumber (const TObject *obj, TObject *n); 27const TObject *luaV_tonumber (const TObject *obj, TObject *n);
28int luaV_tostring (lua_State *L, TObject *obj); 28int luaV_tostring (lua_State *L, TObject *obj);
29const TObject *luaV_gettable (lua_State *L, const TObject *t, TObject *key); 29const TObject *luaV_gettable (lua_State *L, const TObject *t, TObject *key,
30 int loop);
30void luaV_settable (lua_State *L, const TObject *t, TObject *key, StkId val); 31void luaV_settable (lua_State *L, const TObject *t, TObject *key, StkId val);
31StkId luaV_execute (lua_State *L); 32StkId luaV_execute (lua_State *L);
32void luaV_concat (lua_State *L, int total, int last); 33void luaV_concat (lua_State *L, int total, int last);