diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-07-05 15:27:39 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2002-07-05 15:27:39 -0300 |
commit | f8279f6cd8bf22245be30649df5a2d19d868e114 (patch) | |
tree | 46172bc8ff351275f5e1232f8eb8e842fc3b8c9e | |
parent | 1fe280df725810594ef9b70af663dec3ea22b2de (diff) | |
download | lua-f8279f6cd8bf22245be30649df5a2d19d868e114.tar.gz lua-f8279f6cd8bf22245be30649df5a2d19d868e114.tar.bz2 lua-f8279f6cd8bf22245be30649df5a2d19d868e114.zip |
optimizations for gettable (temporary)
-rw-r--r-- | lvm.c | 98 | ||||
-rw-r--r-- | lvm.h | 5 |
2 files changed, 69 insertions, 34 deletions
@@ -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 | ||
38 | static void luaV_checkGC (lua_State *L, StkId top) { | 38 | static 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 | ||
111 | static 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 | |||
122 | static 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 | */ |
116 | const TObject *luaV_gettable (lua_State *L, const TObject *t, TObject *key) { | 140 | const 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; |
@@ -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); | |||
26 | int luaV_equalval (lua_State *L, const TObject *t1, const TObject *t2); | 26 | int luaV_equalval (lua_State *L, const TObject *t1, const TObject *t2); |
27 | const TObject *luaV_tonumber (const TObject *obj, TObject *n); | 27 | const TObject *luaV_tonumber (const TObject *obj, TObject *n); |
28 | int luaV_tostring (lua_State *L, TObject *obj); | 28 | int luaV_tostring (lua_State *L, TObject *obj); |
29 | const TObject *luaV_gettable (lua_State *L, const TObject *t, TObject *key); | 29 | const TObject *luaV_gettable (lua_State *L, const TObject *t, TObject *key, |
30 | int loop); | ||
30 | void luaV_settable (lua_State *L, const TObject *t, TObject *key, StkId val); | 31 | void luaV_settable (lua_State *L, const TObject *t, TObject *key, StkId val); |
31 | StkId luaV_execute (lua_State *L); | 32 | StkId luaV_execute (lua_State *L); |
32 | void luaV_concat (lua_State *L, int total, int last); | 33 | void luaV_concat (lua_State *L, int total, int last); |