diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-10-05 10:00:17 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-10-05 10:00:17 -0300 |
commit | 046a3d6173792b7d4d4d26a4e063e2fe383c10a7 (patch) | |
tree | efe5a4544585084ab6e8d301847cc8568a1cc955 /lvm.c | |
parent | 001f2bdd0e2f8803889c1b5164b57a51e44aef5b (diff) | |
download | lua-046a3d6173792b7d4d4d26a4e063e2fe383c10a7.tar.gz lua-046a3d6173792b7d4d4d26a4e063e2fe383c10a7.tar.bz2 lua-046a3d6173792b7d4d4d26a4e063e2fe383c10a7.zip |
tag methods are always functions, so don't need to store a whole object
Diffstat (limited to 'lvm.c')
-rw-r--r-- | lvm.c | 77 |
1 files changed, 40 insertions, 37 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 1.142 2000/10/04 12:16:08 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 1.143 2000/10/05 12:14:08 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 | */ |
@@ -116,27 +116,27 @@ void luaV_Lclosure (lua_State *L, Proto *l, int nelems) { | |||
116 | ** Receives the table at `t' and the key at top. | 116 | ** Receives the table at `t' and the key at top. |
117 | */ | 117 | */ |
118 | const TObject *luaV_gettable (lua_State *L, StkId t) { | 118 | const TObject *luaV_gettable (lua_State *L, StkId t) { |
119 | const TObject *im; | 119 | Closure *tm; |
120 | int tg; | 120 | int tg; |
121 | if (ttype(t) == LUA_TTABLE && /* `t' is a table? */ | 121 | if (ttype(t) == LUA_TTABLE && /* `t' is a table? */ |
122 | ((tg = hvalue(t)->htag) == LUA_TTABLE || /* with default tag? */ | 122 | ((tg = hvalue(t)->htag) == LUA_TTABLE || /* with default tag? */ |
123 | ttype(luaT_getim(L, tg, IM_GETTABLE)) == LUA_TNIL)) { /* or no TM? */ | 123 | luaT_gettm(L, tg, TM_GETTABLE) == NULL)) { /* or no TM? */ |
124 | /* do a primitive get */ | 124 | /* do a primitive get */ |
125 | const TObject *h = luaH_get(L, hvalue(t), L->top-1); | 125 | const TObject *h = luaH_get(L, hvalue(t), L->top-1); |
126 | /* result is no nil or there is no `index' tag method? */ | 126 | /* result is no nil or there is no `index' tag method? */ |
127 | if (ttype(h) != LUA_TNIL || | 127 | if (ttype(h) != LUA_TNIL || ((tm=luaT_gettm(L, tg, TM_INDEX)) == NULL)) |
128 | (ttype(im=luaT_getim(L, tg, IM_INDEX)) == LUA_TNIL)) | ||
129 | return h; /* return result */ | 128 | return h; /* return result */ |
130 | /* else call `index' tag method */ | 129 | /* else call `index' tag method */ |
131 | } | 130 | } |
132 | else { /* try a `gettable' tag method */ | 131 | else { /* try a `gettable' tag method */ |
133 | im = luaT_getimbyObj(L, t, IM_GETTABLE); | 132 | tm = luaT_gettmbyObj(L, t, TM_GETTABLE); |
134 | } | 133 | } |
135 | if (ttype(im) != LUA_TNIL) { /* is there a tag method? */ | 134 | if (tm != NULL) { /* is there a tag method? */ |
136 | luaD_checkstack(L, 2); | 135 | luaD_checkstack(L, 2); |
137 | *(L->top+1) = *(L->top-1); /* key */ | 136 | *(L->top+1) = *(L->top-1); /* key */ |
138 | *L->top = *t; /* table */ | 137 | *L->top = *t; /* table */ |
139 | *(L->top-1) = *im; /* tag method */ | 138 | clvalue(L->top-1) = tm; /* tag method */ |
139 | ttype(L->top-1) = LUA_TFUNCTION; | ||
140 | L->top += 2; | 140 | L->top += 2; |
141 | luaD_call(L, L->top - 3, 1); | 141 | luaD_call(L, L->top - 3, 1); |
142 | return L->top - 1; /* call result */ | 142 | return L->top - 1; /* call result */ |
@@ -155,16 +155,17 @@ void luaV_settable (lua_State *L, StkId t, StkId key) { | |||
155 | int tg; | 155 | int tg; |
156 | if (ttype(t) == LUA_TTABLE && /* `t' is a table? */ | 156 | if (ttype(t) == LUA_TTABLE && /* `t' is a table? */ |
157 | ((tg = hvalue(t)->htag) == LUA_TTABLE || /* with default tag? */ | 157 | ((tg = hvalue(t)->htag) == LUA_TTABLE || /* with default tag? */ |
158 | ttype(luaT_getim(L, tg, IM_SETTABLE)) == LUA_TNIL)) /* or no TM? */ | 158 | luaT_gettm(L, tg, TM_SETTABLE) == NULL)) /* or no TM? */ |
159 | *luaH_set(L, hvalue(t), key) = *(L->top-1); /* do a primitive set */ | 159 | *luaH_set(L, hvalue(t), key) = *(L->top-1); /* do a primitive set */ |
160 | else { /* try a `settable' tag method */ | 160 | else { /* try a `settable' tag method */ |
161 | const TObject *im = luaT_getimbyObj(L, t, IM_SETTABLE); | 161 | Closure *tm = luaT_gettmbyObj(L, t, TM_SETTABLE); |
162 | if (ttype(im) != LUA_TNIL) { | 162 | if (tm != NULL) { |
163 | luaD_checkstack(L, 3); | 163 | luaD_checkstack(L, 3); |
164 | *(L->top+2) = *(L->top-1); | 164 | *(L->top+2) = *(L->top-1); |
165 | *(L->top+1) = *key; | 165 | *(L->top+1) = *key; |
166 | *(L->top) = *t; | 166 | *(L->top) = *t; |
167 | *(L->top-1) = *im; | 167 | clvalue(L->top-1) = tm; |
168 | ttype(L->top-1) = LUA_TFUNCTION; | ||
168 | L->top += 3; | 169 | L->top += 3; |
169 | luaD_call(L, L->top - 4, 0); /* call `settable' tag method */ | 170 | luaD_call(L, L->top - 4, 0); /* call `settable' tag method */ |
170 | } | 171 | } |
@@ -176,14 +177,15 @@ void luaV_settable (lua_State *L, StkId t, StkId key) { | |||
176 | 177 | ||
177 | const TObject *luaV_getglobal (lua_State *L, TString *s) { | 178 | const TObject *luaV_getglobal (lua_State *L, TString *s) { |
178 | const TObject *value = luaH_getstr(L->gt, s); | 179 | const TObject *value = luaH_getstr(L->gt, s); |
179 | const TObject *im = luaT_getimbyObj(L, value, IM_GETGLOBAL); | 180 | Closure *tm = luaT_gettmbyObj(L, value, TM_GETGLOBAL); |
180 | if (ttype(im) == LUA_TNIL) /* is there a tag method? */ | 181 | if (tm == NULL) /* is there a tag method? */ |
181 | return value; /* default behavior */ | 182 | return value; /* default behavior */ |
182 | else { /* tag method */ | 183 | else { /* tag method */ |
183 | luaD_checkstack(L, 3); | 184 | luaD_checkstack(L, 3); |
184 | *L->top = *im; | 185 | clvalue(L->top) = tm; |
185 | ttype(L->top+1) = LUA_TSTRING; | 186 | ttype(L->top) = LUA_TFUNCTION; |
186 | tsvalue(L->top+1) = s; /* global name */ | 187 | tsvalue(L->top+1) = s; /* global name */ |
188 | ttype(L->top+1) = LUA_TSTRING; | ||
187 | *(L->top+2) = *value; | 189 | *(L->top+2) = *value; |
188 | L->top += 3; | 190 | L->top += 3; |
189 | luaD_call(L, L->top - 3, 1); | 191 | luaD_call(L, L->top - 3, 1); |
@@ -194,8 +196,8 @@ const TObject *luaV_getglobal (lua_State *L, TString *s) { | |||
194 | 196 | ||
195 | void luaV_setglobal (lua_State *L, TString *s) { | 197 | void luaV_setglobal (lua_State *L, TString *s) { |
196 | const TObject *oldvalue = luaH_getstr(L->gt, s); | 198 | const TObject *oldvalue = luaH_getstr(L->gt, s); |
197 | const TObject *im = luaT_getimbyObj(L, oldvalue, IM_SETGLOBAL); | 199 | Closure *tm = luaT_gettmbyObj(L, oldvalue, TM_SETGLOBAL); |
198 | if (ttype(im) == LUA_TNIL) { /* is there a tag method? */ | 200 | if (tm == NULL) { /* is there a tag method? */ |
199 | if (oldvalue != &luaO_nilobject) { | 201 | if (oldvalue != &luaO_nilobject) { |
200 | /* cast to remove `const' is OK, because `oldvalue' != luaO_nilobject */ | 202 | /* cast to remove `const' is OK, because `oldvalue' != luaO_nilobject */ |
201 | *(TObject *)oldvalue = *(L->top - 1); | 203 | *(TObject *)oldvalue = *(L->top - 1); |
@@ -213,32 +215,33 @@ void luaV_setglobal (lua_State *L, TString *s) { | |||
213 | *(L->top+1) = *oldvalue; | 215 | *(L->top+1) = *oldvalue; |
214 | ttype(L->top) = LUA_TSTRING; | 216 | ttype(L->top) = LUA_TSTRING; |
215 | tsvalue(L->top) = s; | 217 | tsvalue(L->top) = s; |
216 | *(L->top-1) = *im; | 218 | clvalue(L->top-1) = tm; |
219 | ttype(L->top-1) = LUA_TFUNCTION; | ||
217 | L->top += 3; | 220 | L->top += 3; |
218 | luaD_call(L, L->top - 4, 0); | 221 | luaD_call(L, L->top - 4, 0); |
219 | } | 222 | } |
220 | } | 223 | } |
221 | 224 | ||
222 | 225 | ||
223 | static int call_binTM (lua_State *L, StkId top, IMS event) { | 226 | static int call_binTM (lua_State *L, StkId top, TMS event) { |
224 | /* try first operand */ | 227 | /* try first operand */ |
225 | const TObject *im = luaT_getimbyObj(L, top-2, event); | 228 | Closure *tm = luaT_gettmbyObj(L, top-2, event); |
226 | L->top = top; | 229 | L->top = top; |
227 | if (ttype(im) == LUA_TNIL) { | 230 | if (tm == NULL) { |
228 | im = luaT_getimbyObj(L, top-1, event); /* try second operand */ | 231 | tm = luaT_gettmbyObj(L, top-1, event); /* try second operand */ |
229 | if (ttype(im) == LUA_TNIL) { | 232 | if (tm == NULL) { |
230 | im = luaT_getim(L, 0, event); /* try a `global' method */ | 233 | tm = luaT_gettm(L, 0, event); /* try a `global' method */ |
231 | if (ttype(im) == LUA_TNIL) | 234 | if (tm == NULL) |
232 | return 0; /* error */ | 235 | return 0; /* error */ |
233 | } | 236 | } |
234 | } | 237 | } |
235 | lua_pushstring(L, luaT_eventname[event]); | 238 | lua_pushstring(L, luaT_eventname[event]); |
236 | luaD_callTM(L, im, 3, 1); | 239 | luaD_callTM(L, tm, 3, 1); |
237 | return 1; | 240 | return 1; |
238 | } | 241 | } |
239 | 242 | ||
240 | 243 | ||
241 | static void call_arith (lua_State *L, StkId top, IMS event) { | 244 | static void call_arith (lua_State *L, StkId top, TMS event) { |
242 | if (!call_binTM(L, top, event)) | 245 | if (!call_binTM(L, top, event)) |
243 | luaG_binerror(L, top-2, LUA_TNUMBER, "perform arithmetic on"); | 246 | luaG_binerror(L, top-2, LUA_TNUMBER, "perform arithmetic on"); |
244 | } | 247 | } |
@@ -275,7 +278,7 @@ int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r, StkId top) | |||
275 | luaD_checkstack(L, 2); | 278 | luaD_checkstack(L, 2); |
276 | *top++ = *l; | 279 | *top++ = *l; |
277 | *top++ = *r; | 280 | *top++ = *r; |
278 | if (!call_binTM(L, top, IM_LT)) | 281 | if (!call_binTM(L, top, TM_LT)) |
279 | luaG_ordererror(L, top-2); | 282 | luaG_ordererror(L, top-2); |
280 | L->top--; | 283 | L->top--; |
281 | return (ttype(L->top) != LUA_TNIL); | 284 | return (ttype(L->top) != LUA_TNIL); |
@@ -287,7 +290,7 @@ void luaV_strconc (lua_State *L, int total, StkId top) { | |||
287 | do { | 290 | do { |
288 | int n = 2; /* number of elements handled in this pass (at least 2) */ | 291 | int n = 2; /* number of elements handled in this pass (at least 2) */ |
289 | if (tostring(L, top-2) || tostring(L, top-1)) { | 292 | if (tostring(L, top-2) || tostring(L, top-1)) { |
290 | if (!call_binTM(L, top, IM_CONCAT)) | 293 | if (!call_binTM(L, top, TM_CONCAT)) |
291 | luaG_binerror(L, top-2, LUA_TSTRING, "concat"); | 294 | luaG_binerror(L, top-2, LUA_TSTRING, "concat"); |
292 | } | 295 | } |
293 | else if (tsvalue(top-1)->u.s.len > 0) { /* if len=0, do nothing */ | 296 | else if (tsvalue(top-1)->u.s.len > 0) { /* if len=0, do nothing */ |
@@ -517,7 +520,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
517 | } | 520 | } |
518 | case OP_ADD: { | 521 | case OP_ADD: { |
519 | if (tonumber(top-2) || tonumber(top-1)) | 522 | if (tonumber(top-2) || tonumber(top-1)) |
520 | call_arith(L, top, IM_ADD); | 523 | call_arith(L, top, TM_ADD); |
521 | else | 524 | else |
522 | nvalue(top-2) += nvalue(top-1); | 525 | nvalue(top-2) += nvalue(top-1); |
523 | top--; | 526 | top--; |
@@ -527,7 +530,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
527 | if (tonumber(top-1)) { | 530 | if (tonumber(top-1)) { |
528 | ttype(top) = LUA_TNUMBER; | 531 | ttype(top) = LUA_TNUMBER; |
529 | nvalue(top) = (Number)GETARG_S(i); | 532 | nvalue(top) = (Number)GETARG_S(i); |
530 | call_arith(L, top+1, IM_ADD); | 533 | call_arith(L, top+1, TM_ADD); |
531 | } | 534 | } |
532 | else | 535 | else |
533 | nvalue(top-1) += (Number)GETARG_S(i); | 536 | nvalue(top-1) += (Number)GETARG_S(i); |
@@ -535,7 +538,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
535 | } | 538 | } |
536 | case OP_SUB: { | 539 | case OP_SUB: { |
537 | if (tonumber(top-2) || tonumber(top-1)) | 540 | if (tonumber(top-2) || tonumber(top-1)) |
538 | call_arith(L, top, IM_SUB); | 541 | call_arith(L, top, TM_SUB); |
539 | else | 542 | else |
540 | nvalue(top-2) -= nvalue(top-1); | 543 | nvalue(top-2) -= nvalue(top-1); |
541 | top--; | 544 | top--; |
@@ -543,7 +546,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
543 | } | 546 | } |
544 | case OP_MULT: { | 547 | case OP_MULT: { |
545 | if (tonumber(top-2) || tonumber(top-1)) | 548 | if (tonumber(top-2) || tonumber(top-1)) |
546 | call_arith(L, top, IM_MUL); | 549 | call_arith(L, top, TM_MUL); |
547 | else | 550 | else |
548 | nvalue(top-2) *= nvalue(top-1); | 551 | nvalue(top-2) *= nvalue(top-1); |
549 | top--; | 552 | top--; |
@@ -551,14 +554,14 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
551 | } | 554 | } |
552 | case OP_DIV: { | 555 | case OP_DIV: { |
553 | if (tonumber(top-2) || tonumber(top-1)) | 556 | if (tonumber(top-2) || tonumber(top-1)) |
554 | call_arith(L, top, IM_DIV); | 557 | call_arith(L, top, TM_DIV); |
555 | else | 558 | else |
556 | nvalue(top-2) /= nvalue(top-1); | 559 | nvalue(top-2) /= nvalue(top-1); |
557 | top--; | 560 | top--; |
558 | break; | 561 | break; |
559 | } | 562 | } |
560 | case OP_POW: { | 563 | case OP_POW: { |
561 | if (!call_binTM(L, top, IM_POW)) | 564 | if (!call_binTM(L, top, TM_POW)) |
562 | lua_error(L, "undefined operation"); | 565 | lua_error(L, "undefined operation"); |
563 | top--; | 566 | top--; |
564 | break; | 567 | break; |
@@ -574,7 +577,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
574 | case OP_MINUS: { | 577 | case OP_MINUS: { |
575 | if (tonumber(top-1)) { | 578 | if (tonumber(top-1)) { |
576 | ttype(top) = LUA_TNIL; | 579 | ttype(top) = LUA_TNIL; |
577 | call_arith(L, top+1, IM_UNM); | 580 | call_arith(L, top+1, TM_UNM); |
578 | } | 581 | } |
579 | else | 582 | else |
580 | nvalue(top-1) = -nvalue(top-1); | 583 | nvalue(top-1) = -nvalue(top-1); |