diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-09-05 16:33:32 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-09-05 16:33:32 -0300 |
commit | 6e80c1cde193b767d63d2cc30ebd71d65512e061 (patch) | |
tree | cb599bdc956c0dc9b3d469bb01de47185db3e4e2 /lvm.c | |
parent | f67f324377aff66d78479eaaffbb94a6b092ae45 (diff) | |
download | lua-6e80c1cde193b767d63d2cc30ebd71d65512e061.tar.gz lua-6e80c1cde193b767d63d2cc30ebd71d65512e061.tar.bz2 lua-6e80c1cde193b767d63d2cc30ebd71d65512e061.zip |
new version for API
Diffstat (limited to 'lvm.c')
-rw-r--r-- | lvm.c | 126 |
1 files changed, 67 insertions, 59 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 1.132 2000/08/31 14:08:27 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 1.133 2000/08/31 21:02:55 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 | */ |
@@ -112,10 +112,10 @@ void luaV_Lclosure (lua_State *L, Proto *l, int nelems) { | |||
112 | 112 | ||
113 | /* | 113 | /* |
114 | ** Function to index a table. | 114 | ** Function to index a table. |
115 | ** Receives the table at top-2 and the index at top-1. | 115 | ** Receives the table at `t' and the key at top. |
116 | */ | 116 | */ |
117 | void luaV_gettable (lua_State *L, StkId top) { | 117 | const TObject *luaV_gettable (lua_State *L, StkId t) { |
118 | StkId t = top-2; | 118 | const TObject *im; |
119 | int tg; | 119 | int tg; |
120 | if (ttype(t) == TAG_TABLE && /* `t' is a table? */ | 120 | if (ttype(t) == TAG_TABLE && /* `t' is a table? */ |
121 | ((tg = hvalue(t)->htag) == TAG_TABLE || /* with default tag? */ | 121 | ((tg = hvalue(t)->htag) == TAG_TABLE || /* with default tag? */ |
@@ -123,46 +123,49 @@ void luaV_gettable (lua_State *L, StkId top) { | |||
123 | /* do a primitive get */ | 123 | /* do a primitive get */ |
124 | const TObject *h = luaH_get(L, hvalue(t), t+1); | 124 | const TObject *h = luaH_get(L, hvalue(t), t+1); |
125 | /* result is no nil or there is no `index' tag method? */ | 125 | /* result is no nil or there is no `index' tag method? */ |
126 | const TObject *im; | ||
127 | if (ttype(h) != TAG_NIL || | 126 | if (ttype(h) != TAG_NIL || |
128 | (ttype(im=luaT_getim(L, tg, IM_INDEX)) == TAG_NIL)) | 127 | (ttype(im=luaT_getim(L, tg, IM_INDEX)) == TAG_NIL)) |
129 | *t = *h; /* put result into table position */ | 128 | return h; /* return result */ |
130 | else { /* call `index' tag method */ | 129 | /* else call `index' tag method */ |
131 | L->top = top; | ||
132 | luaD_callTM(L, im, 2, 1); | ||
133 | } | ||
134 | } | 130 | } |
135 | else { /* try a 'gettable' TM */ | 131 | else { /* try a 'gettable' TM */ |
136 | const TObject *im = luaT_getimbyObj(L, t, IM_GETTABLE); | 132 | im = luaT_getimbyObj(L, t, IM_GETTABLE); |
137 | L->top = top; | 133 | } |
138 | if (ttype(im) != TAG_NIL) /* call `gettable' tag method */ | 134 | if (ttype(im) != TAG_NIL) { /* is there a tag method? */ |
139 | luaD_callTM(L, im, 2, 1); | 135 | luaD_checkstack(L, 2); |
140 | else /* no tag method */ | 136 | *(L->top+1) = *(L->top-1); /* key */ |
141 | luaG_typeerror(L, t, "index"); | 137 | *L->top = *t; /* table */ |
138 | *(L->top-1) = *im; /* tag method */ | ||
139 | L->top += 2; | ||
140 | luaD_call(L, L->top - 3, 1); | ||
141 | return L->top - 1; /* call result */ | ||
142 | } | ||
143 | else { /* no tag method */ | ||
144 | luaG_typeerror(L, t, "index"); | ||
145 | return NULL; /* to avoid warnings */ | ||
142 | } | 146 | } |
143 | } | 147 | } |
144 | 148 | ||
145 | 149 | ||
146 | /* | 150 | /* |
147 | ** Receives table at *t, index at *(t+1) and value at `top'. | 151 | ** Receives table at `t', key at `key' and value at top. |
148 | */ | 152 | */ |
149 | void luaV_settable (lua_State *L, StkId t, StkId top) { | 153 | void luaV_settable (lua_State *L, StkId t, StkId key) { |
150 | int tg; | 154 | int tg; |
151 | if (ttype(t) == TAG_TABLE && /* `t' is a table? */ | 155 | if (ttype(t) == TAG_TABLE && /* `t' is a table? */ |
152 | ((tg = hvalue(t)->htag) == TAG_TABLE || /* with default tag? */ | 156 | ((tg = hvalue(t)->htag) == TAG_TABLE || /* with default tag? */ |
153 | ttype(luaT_getim(L, tg, IM_SETTABLE)) == TAG_NIL)) /* or no TM? */ | 157 | ttype(luaT_getim(L, tg, IM_SETTABLE)) == TAG_NIL)) /* or no TM? */ |
154 | *luaH_set(L, hvalue(t), t+1) = *(top-1); /* do a primitive set */ | 158 | *luaH_set(L, hvalue(t), key) = *(L->top-1); /* do a primitive set */ |
155 | else { /* try a `settable' tag method */ | 159 | else { /* try a `settable' tag method */ |
156 | const TObject *im = luaT_getimbyObj(L, t, IM_SETTABLE); | 160 | const TObject *im = luaT_getimbyObj(L, t, IM_SETTABLE); |
157 | L->top = top; | ||
158 | if (ttype(im) != TAG_NIL) { | 161 | if (ttype(im) != TAG_NIL) { |
159 | luaD_checkstack(L, 3); | 162 | luaD_checkstack(L, 3); |
160 | *(top+2) = *(top-1); | 163 | *(L->top+2) = *(L->top-1); |
161 | *(top+1) = *(t+1); | 164 | *(L->top+1) = *key; |
162 | *(top) = *t; | 165 | *(L->top) = *t; |
163 | *(top-1) = *im; | 166 | *(L->top-1) = *im; |
164 | L->top = top+3; | 167 | L->top += 3; |
165 | luaD_call(L, top-1, 0); /* call `settable' tag method */ | 168 | luaD_call(L, L->top - 4, 0); /* call `settable' tag method */ |
166 | } | 169 | } |
167 | else /* no tag method... */ | 170 | else /* no tag method... */ |
168 | luaG_typeerror(L, t, "index"); | 171 | luaG_typeerror(L, t, "index"); |
@@ -170,49 +173,48 @@ void luaV_settable (lua_State *L, StkId t, StkId top) { | |||
170 | } | 173 | } |
171 | 174 | ||
172 | 175 | ||
173 | void luaV_getglobal (lua_State *L, TString *s, StkId top) { | 176 | const TObject *luaV_getglobal (lua_State *L, TString *s) { |
174 | const TObject *value = luaH_getstr(L->gt, s); | 177 | const TObject *value = luaH_getstr(L->gt, s); |
175 | TObject *im = luaT_getimbyObj(L, value, IM_GETGLOBAL); | 178 | TObject *im = luaT_getimbyObj(L, value, IM_GETGLOBAL); |
176 | if (ttype(im) == TAG_NIL) /* is there a tag method? */ | 179 | if (ttype(im) == TAG_NIL) /* is there a tag method? */ |
177 | *top = *value; /* default behavior */ | 180 | return value; /* default behavior */ |
178 | else { /* tag method */ | 181 | else { /* tag method */ |
179 | L->top = top; | ||
180 | luaD_checkstack(L, 3); | 182 | luaD_checkstack(L, 3); |
181 | *top = *im; | 183 | *L->top = *im; |
182 | ttype(top+1) = TAG_STRING; | 184 | ttype(L->top+1) = TAG_STRING; |
183 | tsvalue(top+1) = s; /* global name */ | 185 | tsvalue(L->top+1) = s; /* global name */ |
184 | *(top+2) = *value; | 186 | *(L->top+2) = *value; |
185 | L->top = top+3; | 187 | L->top += 3; |
186 | luaD_call(L, top, 1); | 188 | luaD_call(L, L->top - 3, 1); |
189 | return L->top - 1; | ||
187 | } | 190 | } |
188 | } | 191 | } |
189 | 192 | ||
190 | 193 | ||
191 | void luaV_setglobal (lua_State *L, TString *s, StkId top) { | 194 | void luaV_setglobal (lua_State *L, TString *s) { |
192 | const TObject *oldvalue = luaH_getstr(L->gt, s); | 195 | const TObject *oldvalue = luaH_getstr(L->gt, s); |
193 | const TObject *im = luaT_getimbyObj(L, oldvalue, IM_SETGLOBAL); | 196 | const TObject *im = luaT_getimbyObj(L, oldvalue, IM_SETGLOBAL); |
194 | if (ttype(im) == TAG_NIL) { /* is there a tag method? */ | 197 | if (ttype(im) == TAG_NIL) { /* is there a tag method? */ |
195 | if (oldvalue != &luaO_nilobject) { | 198 | if (oldvalue != &luaO_nilobject) { |
196 | /* cast to remove `const' is OK, because `oldvalue' != luaO_nilobject */ | 199 | /* cast to remove `const' is OK, because `oldvalue' != luaO_nilobject */ |
197 | *(TObject *)oldvalue = *(top-1); | 200 | *(TObject *)oldvalue = *(L->top - 1); |
198 | } | 201 | } |
199 | else { | 202 | else { |
200 | TObject key; | 203 | TObject key; |
201 | ttype(&key) = TAG_STRING; | 204 | ttype(&key) = TAG_STRING; |
202 | tsvalue(&key) = s; | 205 | tsvalue(&key) = s; |
203 | *luaH_set(L, L->gt, &key) = *(top-1); | 206 | *luaH_set(L, L->gt, &key) = *(L->top - 1); |
204 | } | 207 | } |
205 | } | 208 | } |
206 | else { | 209 | else { |
207 | L->top = top; | ||
208 | luaD_checkstack(L, 3); | 210 | luaD_checkstack(L, 3); |
209 | *(top+2) = *(top-1); /* new value */ | 211 | *(L->top+2) = *(L->top-1); /* new value */ |
210 | *(top+1) = *oldvalue; | 212 | *(L->top+1) = *oldvalue; |
211 | ttype(top) = TAG_STRING; | 213 | ttype(L->top) = TAG_STRING; |
212 | tsvalue(top) = s; | 214 | tsvalue(L->top) = s; |
213 | *(top-1) = *im; | 215 | *(L->top-1) = *im; |
214 | L->top = top+3; | 216 | L->top += 3; |
215 | luaD_call(L, top-1, 0); | 217 | luaD_call(L, L->top - 4, 0); |
216 | } | 218 | } |
217 | } | 219 | } |
218 | 220 | ||
@@ -280,7 +282,7 @@ int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r, StkId top) | |||
280 | } | 282 | } |
281 | 283 | ||
282 | 284 | ||
283 | static void strconc (lua_State *L, int total, StkId top) { | 285 | void luaV_strconc (lua_State *L, int total, StkId top) { |
284 | do { | 286 | do { |
285 | int n = 2; /* number of elements handled in this pass (at least 2) */ | 287 | int n = 2; /* number of elements handled in this pass (at least 2) */ |
286 | if (tostring(L, top-2) || tostring(L, top-1)) { | 288 | if (tostring(L, top-2) || tostring(L, top-1)) { |
@@ -425,26 +427,28 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
425 | break; | 427 | break; |
426 | } | 428 | } |
427 | case OP_GETGLOBAL: { | 429 | case OP_GETGLOBAL: { |
428 | luaV_getglobal(L, kstr[GETARG_U(i)], top); | 430 | L->top = top; |
431 | *top = *luaV_getglobal(L, kstr[GETARG_U(i)]); | ||
429 | top++; | 432 | top++; |
430 | break; | 433 | break; |
431 | } | 434 | } |
432 | case OP_GETTABLE: { | 435 | case OP_GETTABLE: { |
433 | luaV_gettable(L, top); | 436 | L->top = top; |
434 | top--; | 437 | top--; |
438 | *(top-1) = *luaV_gettable(L, top-1); | ||
435 | break; | 439 | break; |
436 | } | 440 | } |
437 | case OP_GETDOTTED: { | 441 | case OP_GETDOTTED: { |
438 | ttype(top) = TAG_STRING; | 442 | ttype(top) = TAG_STRING; |
439 | tsvalue(top++) = kstr[GETARG_U(i)]; | 443 | tsvalue(top) = kstr[GETARG_U(i)]; |
440 | luaV_gettable(L, top); | 444 | L->top = top+1; |
441 | top--; | 445 | *(top-1) = *luaV_gettable(L, top-1); |
442 | break; | 446 | break; |
443 | } | 447 | } |
444 | case OP_GETINDEXED: { | 448 | case OP_GETINDEXED: { |
445 | *top++ = *(base+GETARG_U(i)); | 449 | *top = *(base+GETARG_U(i)); |
446 | luaV_gettable(L, top); | 450 | L->top = top+1; |
447 | top--; | 451 | *(top-1) = *luaV_gettable(L, top-1); |
448 | break; | 452 | break; |
449 | } | 453 | } |
450 | case OP_PUSHSELF: { | 454 | case OP_PUSHSELF: { |
@@ -452,7 +456,8 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
452 | receiver = *(top-1); | 456 | receiver = *(top-1); |
453 | ttype(top) = TAG_STRING; | 457 | ttype(top) = TAG_STRING; |
454 | tsvalue(top++) = kstr[GETARG_U(i)]; | 458 | tsvalue(top++) = kstr[GETARG_U(i)]; |
455 | luaV_gettable(L, top); | 459 | L->top = top; |
460 | *(top-2) = *luaV_gettable(L, top-2); | ||
456 | *(top-1) = receiver; | 461 | *(top-1) = receiver; |
457 | break; | 462 | break; |
458 | } | 463 | } |
@@ -469,12 +474,15 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
469 | break; | 474 | break; |
470 | } | 475 | } |
471 | case OP_SETGLOBAL: { | 476 | case OP_SETGLOBAL: { |
472 | luaV_setglobal(L, kstr[GETARG_U(i)], top); | 477 | L->top = top; |
478 | luaV_setglobal(L, kstr[GETARG_U(i)]); | ||
473 | top--; | 479 | top--; |
474 | break; | 480 | break; |
475 | } | 481 | } |
476 | case OP_SETTABLE: { | 482 | case OP_SETTABLE: { |
477 | luaV_settable(L, top-GETARG_A(i), top); | 483 | StkId t = top-GETARG_A(i); |
484 | L->top = top; | ||
485 | luaV_settable(L, t, t+1); | ||
478 | top -= GETARG_B(i); /* pop values */ | 486 | top -= GETARG_B(i); /* pop values */ |
479 | break; | 487 | break; |
480 | } | 488 | } |
@@ -548,7 +556,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
548 | } | 556 | } |
549 | case OP_CONCAT: { | 557 | case OP_CONCAT: { |
550 | int n = GETARG_U(i); | 558 | int n = GETARG_U(i); |
551 | strconc(L, n, top); | 559 | luaV_strconc(L, n, top); |
552 | top -= n-1; | 560 | top -= n-1; |
553 | L->top = top; | 561 | L->top = top; |
554 | luaC_checkGC(L); | 562 | luaC_checkGC(L); |