diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-12-10 20:10:30 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-12-10 20:10:30 -0200 |
commit | a4c35a3269f0581da212b3c4abd04989f88425ce (patch) | |
tree | e46d6548e1ccbae3cfd4af102eedd881d0454e55 | |
parent | 9cd36059ad6f3f6750b8cff54c305ae347c6caca (diff) | |
download | lua-a4c35a3269f0581da212b3c4abd04989f88425ce.tar.gz lua-a4c35a3269f0581da212b3c4abd04989f88425ce.tar.bz2 lua-a4c35a3269f0581da212b3c4abd04989f88425ce.zip |
it doesn't pay to optimize absence when it is an error
-rw-r--r-- | ldo.c | 2 | ||||
-rw-r--r-- | ltm.c | 11 | ||||
-rw-r--r-- | lvm.c | 39 |
3 files changed, 33 insertions, 19 deletions
@@ -143,7 +143,7 @@ void luaD_call (lua_State *L, StkId func) { | |||
143 | if (ttype(func) != LUA_TFUNCTION) { | 143 | if (ttype(func) != LUA_TFUNCTION) { |
144 | /* `func' is not a function; check the `function' tag method */ | 144 | /* `func' is not a function; check the `function' tag method */ |
145 | const TObject *tm = luaT_gettmbyobj(L, func, TM_CALL); | 145 | const TObject *tm = luaT_gettmbyobj(L, func, TM_CALL); |
146 | if (tm == NULL || ttype(tm) != LUA_TFUNCTION) | 146 | if (ttype(tm) != LUA_TFUNCTION) |
147 | luaG_typeerror(L, func, "call"); | 147 | luaG_typeerror(L, func, "call"); |
148 | luaD_openstack(L, func); | 148 | luaD_openstack(L, func); |
149 | setobj(func, tm); /* tag method is the new function to be called */ | 149 | setobj(func, tm); /* tag method is the new function to be called */ |
@@ -39,6 +39,10 @@ void luaT_init (lua_State *L) { | |||
39 | } | 39 | } |
40 | 40 | ||
41 | 41 | ||
42 | /* | ||
43 | ** function to be used with macro "fasttm": optimized for absence of | ||
44 | ** tag methods | ||
45 | */ | ||
42 | const TObject *luaT_gettm (Table *events, TMS event, TString *ename) { | 46 | const TObject *luaT_gettm (Table *events, TMS event, TString *ename) { |
43 | const TObject *tm = luaH_getstr(events, ename); | 47 | const TObject *tm = luaH_getstr(events, ename); |
44 | if (ttype(tm) == LUA_TNIL) { /* no tag method? */ | 48 | if (ttype(tm) == LUA_TNIL) { /* no tag method? */ |
@@ -50,13 +54,14 @@ const TObject *luaT_gettm (Table *events, TMS event, TString *ename) { | |||
50 | 54 | ||
51 | 55 | ||
52 | const TObject *luaT_gettmbyobj (lua_State *L, const TObject *o, TMS event) { | 56 | const TObject *luaT_gettmbyobj (lua_State *L, const TObject *o, TMS event) { |
57 | TString *ename = G(L)->tmname[event]; | ||
53 | switch (ttype(o)) { | 58 | switch (ttype(o)) { |
54 | case LUA_TTABLE: | 59 | case LUA_TTABLE: |
55 | return fasttm(L, hvalue(o)->eventtable, event); | 60 | return luaH_getstr(hvalue(o)->eventtable, ename); |
56 | case LUA_TUSERDATA: | 61 | case LUA_TUSERDATA: |
57 | return fasttm(L, uvalue(o)->uv.eventtable, event); | 62 | return luaH_getstr(uvalue(o)->uv.eventtable, ename); |
58 | default: | 63 | default: |
59 | return NULL; | 64 | return &luaO_nilobject; |
60 | } | 65 | } |
61 | } | 66 | } |
62 | 67 | ||
@@ -113,7 +113,7 @@ static void callTM (lua_State *L, const TObject *f, | |||
113 | 113 | ||
114 | /* | 114 | /* |
115 | ** Function to index a table. | 115 | ** Function to index a table. |
116 | ** Receives the table at `t' and the key at the `key'. | 116 | ** Receives the table at `t' and the key at `key'. |
117 | ** leaves the result at `res'. | 117 | ** leaves the result at `res'. |
118 | */ | 118 | */ |
119 | void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res) { | 119 | void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res) { |
@@ -132,13 +132,11 @@ void luaV_gettable (lua_State *L, StkId t, TObject *key, StkId res) { | |||
132 | } | 132 | } |
133 | /* else will call the tag method */ | 133 | /* else will call the tag method */ |
134 | } else { /* not a table; try a `gettable' tag method */ | 134 | } else { /* not a table; try a `gettable' tag method */ |
135 | if (ttype(t) != LUA_TUSERDATA || | 135 | if (ttype(tm = luaT_gettmbyobj(L, t, TM_GETTABLE)) == LUA_TNIL) { |
136 | (tm = fasttm(L, uvalue(t)->uv.eventtable, TM_GETTABLE)) == NULL) { | ||
137 | luaG_typeerror(L, t, "index"); | 136 | luaG_typeerror(L, t, "index"); |
138 | return; /* to avoid warnings */ | 137 | return; /* to avoid warnings */ |
139 | } | 138 | } |
140 | } | 139 | } |
141 | lua_assert(tm != NULL); | ||
142 | if (ttype(tm) == LUA_TFUNCTION) | 140 | if (ttype(tm) == LUA_TFUNCTION) |
143 | callTM(L, tm, t, key, NULL, res); | 141 | callTM(L, tm, t, key, NULL, res); |
144 | else { | 142 | else { |
@@ -163,13 +161,11 @@ void luaV_settable (lua_State *L, StkId t, TObject *key, StkId val) { | |||
163 | } | 161 | } |
164 | /* else will call the tag method */ | 162 | /* else will call the tag method */ |
165 | } else { /* not a table; try a `settable' tag method */ | 163 | } else { /* not a table; try a `settable' tag method */ |
166 | if (ttype(t) != LUA_TUSERDATA || | 164 | if (ttype(tm = luaT_gettmbyobj(L, t, TM_SETTABLE)) == LUA_TNIL) { |
167 | (tm = fasttm(L, uvalue(t)->uv.eventtable, TM_SETTABLE)) == NULL) { | ||
168 | luaG_typeerror(L, t, "index"); | 165 | luaG_typeerror(L, t, "index"); |
169 | return; /* to avoid warnings */ | 166 | return; /* to avoid warnings */ |
170 | } | 167 | } |
171 | } | 168 | } |
172 | lua_assert(tm != NULL); | ||
173 | if (ttype(tm) == LUA_TFUNCTION) | 169 | if (ttype(tm) == LUA_TFUNCTION) |
174 | callTM(L, tm, t, key, val, NULL); | 170 | callTM(L, tm, t, key, val, NULL); |
175 | else { | 171 | else { |
@@ -182,15 +178,10 @@ void luaV_settable (lua_State *L, StkId t, TObject *key, StkId val) { | |||
182 | static int call_binTM (lua_State *L, const TObject *p1, const TObject *p2, | 178 | static int call_binTM (lua_State *L, const TObject *p1, const TObject *p2, |
183 | TObject *res, TMS event) { | 179 | TObject *res, TMS event) { |
184 | const TObject *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */ | 180 | const TObject *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */ |
185 | if (tm == NULL) { | 181 | if (ttype(tm) == LUA_TNIL) |
186 | tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ | 182 | tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ |
187 | if (tm == NULL) { | ||
188 | tm = fasttm(L, hvalue(gt(L)), event); | ||
189 | if (tm == NULL) return 0; /* no tag method */ | ||
190 | } | ||
191 | } | ||
192 | if (ttype(tm) != LUA_TFUNCTION) return 0; | 183 | if (ttype(tm) != LUA_TFUNCTION) return 0; |
193 | callTM(L, tm, p1, p2, NULL, res); | 184 | callTM(L, tm, p1, p2, NULL, res); |
194 | return 1; | 185 | return 1; |
195 | } | 186 | } |
196 | 187 | ||
@@ -297,6 +288,24 @@ static void adjust_varargs (lua_State *L, StkId base, int nfixargs) { | |||
297 | } | 288 | } |
298 | 289 | ||
299 | 290 | ||
291 | static void powOp (lua_State *L, StkId ra, StkId rb, StkId rc) { | ||
292 | const TObject *b = rb; | ||
293 | const TObject *c = rc; | ||
294 | TObject tempb, tempc; | ||
295 | if ((b = luaV_tonumber(b, &tempb)) != NULL && | ||
296 | (c = luaV_tonumber(c, &tempc)) != NULL) { | ||
297 | TObject o, f; | ||
298 | setsvalue(&o, luaS_newliteral(L, "pow")); | ||
299 | luaV_gettable(L, gt(L), &o, &f); | ||
300 | if (ttype(&f) != LUA_TFUNCTION) | ||
301 | luaD_error(L, "`pow' (for `^' operator) is not a function"); | ||
302 | callTM(L, &f, b, c, NULL, ra); | ||
303 | } | ||
304 | else | ||
305 | call_arith(L, rb, rc, ra, TM_POW); | ||
306 | } | ||
307 | |||
308 | |||
300 | 309 | ||
301 | /* | 310 | /* |
302 | ** some macros for common tasks in `luaV_execute' | 311 | ** some macros for common tasks in `luaV_execute' |
@@ -425,7 +434,7 @@ StkId luaV_execute (lua_State *L, const LClosure *cl, StkId base) { | |||
425 | break; | 434 | break; |
426 | } | 435 | } |
427 | case OP_POW: { | 436 | case OP_POW: { |
428 | call_arith(L, RB(i), RKC(i), ra, TM_POW); | 437 | powOp(L, ra, RB(i), RKC(i)); |
429 | break; | 438 | break; |
430 | } | 439 | } |
431 | case OP_UNM: { | 440 | case OP_UNM: { |