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); |
