diff options
Diffstat (limited to 'lvm.c')
| -rw-r--r-- | lvm.c | 143 |
1 files changed, 59 insertions, 84 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lvm.c,v 1.152 2001/01/11 18:59:32 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 1.153 2001/01/15 16:13:24 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 | */ |
| @@ -57,8 +57,7 @@ int luaV_tostring (lua_State *L, TObject *obj) { /* LUA_NUMBER */ | |||
| 57 | else { | 57 | else { |
| 58 | char s[32]; /* 16 digits, sign, point and \0 (+ some extra...) */ | 58 | char s[32]; /* 16 digits, sign, point and \0 (+ some extra...) */ |
| 59 | lua_number2str(s, nvalue(obj)); /* convert `s' to number */ | 59 | lua_number2str(s, nvalue(obj)); /* convert `s' to number */ |
| 60 | tsvalue(obj) = luaS_new(L, s); | 60 | setsvalue(obj, luaS_new(L, s)); |
| 61 | ttype(obj) = LUA_TSTRING; | ||
| 62 | return 0; | 61 | return 0; |
| 63 | } | 62 | } |
| 64 | } | 63 | } |
| @@ -89,9 +88,8 @@ static Closure *luaV_closure (lua_State *L, int nelems) { | |||
| 89 | Closure *c = luaF_newclosure(L, nelems); | 88 | Closure *c = luaF_newclosure(L, nelems); |
| 90 | L->top -= nelems; | 89 | L->top -= nelems; |
| 91 | while (nelems--) | 90 | while (nelems--) |
| 92 | c->upvalue[nelems] = *(L->top+nelems); | 91 | setobj(&c->upvalue[nelems], L->top+nelems); |
| 93 | clvalue(L->top) = c; | 92 | setclvalue(L->top, c); |
| 94 | ttype(L->top) = LUA_TFUNCTION; | ||
| 95 | incr_top; | 93 | incr_top; |
| 96 | return c; | 94 | return c; |
| 97 | } | 95 | } |
| @@ -133,10 +131,9 @@ const TObject *luaV_gettable (lua_State *L, StkId t) { | |||
| 133 | } | 131 | } |
| 134 | if (tm != NULL) { /* is there a tag method? */ | 132 | if (tm != NULL) { /* is there a tag method? */ |
| 135 | luaD_checkstack(L, 2); | 133 | luaD_checkstack(L, 2); |
| 136 | *(L->top+1) = *(L->top-1); /* key */ | 134 | setobj(L->top+1, L->top-1); /* key */ |
| 137 | *L->top = *t; /* table */ | 135 | setobj(L->top, t); /* table */ |
| 138 | clvalue(L->top-1) = tm; /* tag method */ | 136 | setclvalue(L->top-1, tm); /* tag method */ |
| 139 | ttype(L->top-1) = LUA_TFUNCTION; | ||
| 140 | L->top += 2; | 137 | L->top += 2; |
| 141 | luaD_call(L, L->top - 3, 1); | 138 | luaD_call(L, L->top - 3, 1); |
| 142 | return L->top - 1; /* call result */ | 139 | return L->top - 1; /* call result */ |
| @@ -155,17 +152,17 @@ void luaV_settable (lua_State *L, StkId t, StkId key) { | |||
| 155 | int tg; | 152 | int tg; |
| 156 | if (ttype(t) == LUA_TTABLE && /* `t' is a table? */ | 153 | if (ttype(t) == LUA_TTABLE && /* `t' is a table? */ |
| 157 | ((tg = hvalue(t)->htag) == LUA_TTABLE || /* with default tag? */ | 154 | ((tg = hvalue(t)->htag) == LUA_TTABLE || /* with default tag? */ |
| 158 | luaT_gettm(L, tg, TM_SETTABLE) == NULL)) /* or no TM? */ | 155 | luaT_gettm(L, tg, TM_SETTABLE) == NULL)) { /* or no TM? */ |
| 159 | *luaH_set(L, hvalue(t), key) = *(L->top-1); /* do a primitive set */ | 156 | setobj(luaH_set(L, hvalue(t), key), L->top-1); /* do a primitive set */ |
| 157 | } | ||
| 160 | else { /* try a `settable' tag method */ | 158 | else { /* try a `settable' tag method */ |
| 161 | Closure *tm = luaT_gettmbyObj(L, t, TM_SETTABLE); | 159 | Closure *tm = luaT_gettmbyObj(L, t, TM_SETTABLE); |
| 162 | if (tm != NULL) { | 160 | if (tm != NULL) { |
| 163 | luaD_checkstack(L, 3); | 161 | luaD_checkstack(L, 3); |
| 164 | *(L->top+2) = *(L->top-1); | 162 | setobj(L->top+2, L->top-1); |
| 165 | *(L->top+1) = *key; | 163 | setobj(L->top+1, key); |
| 166 | *(L->top) = *t; | 164 | setobj(L->top, t); |
| 167 | clvalue(L->top-1) = tm; | 165 | setclvalue(L->top-1, tm); |
| 168 | ttype(L->top-1) = LUA_TFUNCTION; | ||
| 169 | L->top += 3; | 166 | L->top += 3; |
| 170 | luaD_call(L, L->top - 4, 0); /* call `settable' tag method */ | 167 | luaD_call(L, L->top - 4, 0); /* call `settable' tag method */ |
| 171 | } | 168 | } |
| @@ -182,11 +179,9 @@ const TObject *luaV_getglobal (lua_State *L, TString *s) { | |||
| 182 | return value; /* default behavior */ | 179 | return value; /* default behavior */ |
| 183 | else { /* tag method */ | 180 | else { /* tag method */ |
| 184 | luaD_checkstack(L, 3); | 181 | luaD_checkstack(L, 3); |
| 185 | clvalue(L->top) = tm; | 182 | setclvalue(L->top, tm); |
| 186 | ttype(L->top) = LUA_TFUNCTION; | 183 | setsvalue(L->top+1, s); /* global name */ |
| 187 | tsvalue(L->top+1) = s; /* global name */ | 184 | setobj(L->top+2, value); |
| 188 | ttype(L->top+1) = LUA_TSTRING; | ||
| 189 | *(L->top+2) = *value; | ||
| 190 | L->top += 3; | 185 | L->top += 3; |
| 191 | luaD_call(L, L->top - 3, 1); | 186 | luaD_call(L, L->top - 3, 1); |
| 192 | return L->top - 1; | 187 | return L->top - 1; |
| @@ -197,16 +192,15 @@ const TObject *luaV_getglobal (lua_State *L, TString *s) { | |||
| 197 | void luaV_setglobal (lua_State *L, TString *s) { | 192 | void luaV_setglobal (lua_State *L, TString *s) { |
| 198 | TObject *oldvalue = luaH_setstr(L, L->gt, s); | 193 | TObject *oldvalue = luaH_setstr(L, L->gt, s); |
| 199 | Closure *tm = luaT_gettmbyObj(L, oldvalue, TM_SETGLOBAL); | 194 | Closure *tm = luaT_gettmbyObj(L, oldvalue, TM_SETGLOBAL); |
| 200 | if (tm == NULL) /* no tag methods? */ | 195 | if (tm == NULL) { /* no tag methods? */ |
| 201 | *oldvalue = *(L->top - 1); /* raw set */ | 196 | setobj(oldvalue, L->top - 1); /* raw set */ |
| 197 | } | ||
| 202 | else { /* call tag method */ | 198 | else { /* call tag method */ |
| 203 | luaD_checkstack(L, 3); | 199 | luaD_checkstack(L, 3); |
| 204 | *(L->top+2) = *(L->top-1); /* new value */ | 200 | setobj(L->top+2, L->top-1); /* new value */ |
| 205 | *(L->top+1) = *oldvalue; | 201 | setobj(L->top+1, oldvalue); /* old value */ |
| 206 | ttype(L->top) = LUA_TSTRING; | 202 | setsvalue(L->top, s); /* var name */ |
| 207 | tsvalue(L->top) = s; | 203 | setclvalue(L->top-1, tm); /* tag method */ |
| 208 | clvalue(L->top-1) = tm; | ||
| 209 | ttype(L->top-1) = LUA_TFUNCTION; | ||
| 210 | L->top += 3; | 204 | L->top += 3; |
| 211 | luaD_call(L, L->top - 4, 0); | 205 | luaD_call(L, L->top - 4, 0); |
| 212 | } | 206 | } |
| @@ -266,8 +260,8 @@ int luaV_lessthan (lua_State *L, const TObject *l, const TObject *r, StkId top) | |||
| 266 | return luaV_strlessthan(tsvalue(l), tsvalue(r)); | 260 | return luaV_strlessthan(tsvalue(l), tsvalue(r)); |
| 267 | else { /* call TM */ | 261 | else { /* call TM */ |
| 268 | luaD_checkstack(L, 2); | 262 | luaD_checkstack(L, 2); |
| 269 | *top++ = *l; | 263 | setobj(top++, l); |
| 270 | *top++ = *r; | 264 | setobj(top++, r); |
| 271 | if (!call_binTM(L, top, TM_LT)) | 265 | if (!call_binTM(L, top, TM_LT)) |
| 272 | luaG_ordererror(L, top-2); | 266 | luaG_ordererror(L, top-2); |
| 273 | L->top--; | 267 | L->top--; |
| @@ -301,7 +295,7 @@ void luaV_strconc (lua_State *L, int total, StkId top) { | |||
| 301 | memcpy(buffer+tl, tsvalue(top-i)->str, l); | 295 | memcpy(buffer+tl, tsvalue(top-i)->str, l); |
| 302 | tl += l; | 296 | tl += l; |
| 303 | } | 297 | } |
| 304 | tsvalue(top-n) = luaS_newlstr(L, buffer, tl); | 298 | setsvalue(top-n, luaS_newlstr(L, buffer, tl)); |
| 305 | } | 299 | } |
| 306 | total -= n-1; /* got `n' strings to create 1 new */ | 300 | total -= n-1; /* got `n' strings to create 1 new */ |
| 307 | top -= n-1; | 301 | top -= n-1; |
| @@ -310,18 +304,14 @@ void luaV_strconc (lua_State *L, int total, StkId top) { | |||
| 310 | 304 | ||
| 311 | 305 | ||
| 312 | static void luaV_pack (lua_State *L, StkId firstelem) { | 306 | static void luaV_pack (lua_State *L, StkId firstelem) { |
| 313 | TObject *nf; | ||
| 314 | int i; | 307 | int i; |
| 315 | Hash *htab = luaH_new(L, 0); | 308 | Hash *htab = luaH_new(L, 0); |
| 316 | for (i=0; firstelem+i<L->top; i++) | 309 | for (i=0; firstelem+i<L->top; i++) |
| 317 | *luaH_setnum(L, htab, i+1) = *(firstelem+i); | 310 | setobj(luaH_setnum(L, htab, i+1), firstelem+i); |
| 318 | /* store counter in field `n' */ | 311 | /* store counter in field `n' */ |
| 319 | nf = luaH_setstr(L, htab, luaS_newliteral(L, "n")); | 312 | setnvalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")), i); |
| 320 | ttype(nf) = LUA_TNUMBER; | ||
| 321 | nvalue(nf) = i; | ||
| 322 | L->top = firstelem; /* remove elements from the stack */ | 313 | L->top = firstelem; /* remove elements from the stack */ |
| 323 | ttype(L->top) = LUA_TTABLE; | 314 | sethvalue(L->top, htab); |
| 324 | hvalue(L->top) = htab; | ||
| 325 | incr_top; | 315 | incr_top; |
| 326 | } | 316 | } |
| 327 | 317 | ||
| @@ -381,7 +371,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
| 381 | int n = GETARG_U(i); | 371 | int n = GETARG_U(i); |
| 382 | LUA_ASSERT(n>0, "invalid argument"); | 372 | LUA_ASSERT(n>0, "invalid argument"); |
| 383 | do { | 373 | do { |
| 384 | ttype(top++) = LUA_TNIL; | 374 | setnilvalue(top++); |
| 385 | } while (--n > 0); | 375 | } while (--n > 0); |
| 386 | break; | 376 | break; |
| 387 | } | 377 | } |
| @@ -390,88 +380,74 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
| 390 | break; | 380 | break; |
| 391 | } | 381 | } |
| 392 | case OP_PUSHINT: { | 382 | case OP_PUSHINT: { |
| 393 | ttype(top) = LUA_TNUMBER; | 383 | setnvalue(top++, (lua_Number)GETARG_S(i)); |
| 394 | nvalue(top) = (lua_Number)GETARG_S(i); | ||
| 395 | top++; | ||
| 396 | break; | 384 | break; |
| 397 | } | 385 | } |
| 398 | case OP_PUSHSTRING: { | 386 | case OP_PUSHSTRING: { |
| 399 | ttype(top) = LUA_TSTRING; | 387 | setsvalue(top++, kstr[GETARG_U(i)]); |
| 400 | tsvalue(top) = kstr[GETARG_U(i)]; | ||
| 401 | top++; | ||
| 402 | break; | 388 | break; |
| 403 | } | 389 | } |
| 404 | case OP_PUSHNUM: { | 390 | case OP_PUSHNUM: { |
| 405 | ttype(top) = LUA_TNUMBER; | 391 | setnvalue(top++, tf->knum[GETARG_U(i)]); |
| 406 | nvalue(top) = tf->knum[GETARG_U(i)]; | ||
| 407 | top++; | ||
| 408 | break; | 392 | break; |
| 409 | } | 393 | } |
| 410 | case OP_PUSHNEGNUM: { | 394 | case OP_PUSHNEGNUM: { |
| 411 | ttype(top) = LUA_TNUMBER; | 395 | setnvalue(top++, -tf->knum[GETARG_U(i)]); |
| 412 | nvalue(top) = -tf->knum[GETARG_U(i)]; | ||
| 413 | top++; | ||
| 414 | break; | 396 | break; |
| 415 | } | 397 | } |
| 416 | case OP_PUSHUPVALUE: { | 398 | case OP_PUSHUPVALUE: { |
| 417 | *top++ = cl->upvalue[GETARG_U(i)]; | 399 | setobj(top++, &cl->upvalue[GETARG_U(i)]); |
| 418 | break; | 400 | break; |
| 419 | } | 401 | } |
| 420 | case OP_GETLOCAL: { | 402 | case OP_GETLOCAL: { |
| 421 | *top++ = *(base+GETARG_U(i)); | 403 | setobj(top++, base+GETARG_U(i)); |
| 422 | break; | 404 | break; |
| 423 | } | 405 | } |
| 424 | case OP_GETGLOBAL: { | 406 | case OP_GETGLOBAL: { |
| 425 | L->top = top; | 407 | L->top = top; |
| 426 | *top = *luaV_getglobal(L, kstr[GETARG_U(i)]); | 408 | setobj(top++, luaV_getglobal(L, kstr[GETARG_U(i)])); |
| 427 | top++; | ||
| 428 | break; | 409 | break; |
| 429 | } | 410 | } |
| 430 | case OP_GETTABLE: { | 411 | case OP_GETTABLE: { |
| 431 | L->top = top; | 412 | L->top = top; |
| 432 | top--; | 413 | top--; |
| 433 | *(top-1) = *luaV_gettable(L, top-1); | 414 | setobj(top-1, luaV_gettable(L, top-1)); |
| 434 | break; | 415 | break; |
| 435 | } | 416 | } |
| 436 | case OP_GETDOTTED: { | 417 | case OP_GETDOTTED: { |
| 437 | ttype(top) = LUA_TSTRING; | 418 | setsvalue(top, kstr[GETARG_U(i)]); |
| 438 | tsvalue(top) = kstr[GETARG_U(i)]; | ||
| 439 | L->top = top+1; | 419 | L->top = top+1; |
| 440 | *(top-1) = *luaV_gettable(L, top-1); | 420 | setobj(top-1, luaV_gettable(L, top-1)); |
| 441 | break; | 421 | break; |
| 442 | } | 422 | } |
| 443 | case OP_GETINDEXED: { | 423 | case OP_GETINDEXED: { |
| 444 | *top = *(base+GETARG_U(i)); | 424 | setobj(top, base+GETARG_U(i)); |
| 445 | L->top = top+1; | 425 | L->top = top+1; |
| 446 | *(top-1) = *luaV_gettable(L, top-1); | 426 | setobj(top-1, luaV_gettable(L, top-1)); |
| 447 | break; | 427 | break; |
| 448 | } | 428 | } |
| 449 | case OP_PUSHSELF: { | 429 | case OP_PUSHSELF: { |
| 450 | TObject receiver; | 430 | TObject receiver; |
| 451 | receiver = *(top-1); | 431 | setobj(&receiver, top-1); |
| 452 | ttype(top) = LUA_TSTRING; | 432 | setsvalue(top++, kstr[GETARG_U(i)]); |
| 453 | tsvalue(top++) = kstr[GETARG_U(i)]; | ||
| 454 | L->top = top; | 433 | L->top = top; |
| 455 | *(top-2) = *luaV_gettable(L, top-2); | 434 | setobj(top-2, luaV_gettable(L, top-2)); |
| 456 | *(top-1) = receiver; | 435 | setobj(top-1, &receiver); |
| 457 | break; | 436 | break; |
| 458 | } | 437 | } |
| 459 | case OP_CREATETABLE: { | 438 | case OP_CREATETABLE: { |
| 460 | L->top = top; | 439 | L->top = top; |
| 461 | luaC_checkGC(L); | 440 | luaC_checkGC(L); |
| 462 | hvalue(top) = luaH_new(L, GETARG_U(i)); | 441 | sethvalue(top++, luaH_new(L, GETARG_U(i))); |
| 463 | ttype(top) = LUA_TTABLE; | ||
| 464 | top++; | ||
| 465 | break; | 442 | break; |
| 466 | } | 443 | } |
| 467 | case OP_SETLOCAL: { | 444 | case OP_SETLOCAL: { |
| 468 | *(base+GETARG_U(i)) = *(--top); | 445 | setobj(base+GETARG_U(i), --top); |
| 469 | break; | 446 | break; |
| 470 | } | 447 | } |
| 471 | case OP_SETGLOBAL: { | 448 | case OP_SETGLOBAL: { |
| 472 | L->top = top; | 449 | L->top = top--; |
| 473 | luaV_setglobal(L, kstr[GETARG_U(i)]); | 450 | luaV_setglobal(L, kstr[GETARG_U(i)]); |
| 474 | top--; | ||
| 475 | break; | 451 | break; |
| 476 | } | 452 | } |
| 477 | case OP_SETTABLE: { | 453 | case OP_SETTABLE: { |
| @@ -487,7 +463,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
| 487 | Hash *arr = hvalue(top-n-1); | 463 | Hash *arr = hvalue(top-n-1); |
| 488 | L->top = top-n; /* final value of `top' (in case of errors) */ | 464 | L->top = top-n; /* final value of `top' (in case of errors) */ |
| 489 | for (; n; n--) | 465 | for (; n; n--) |
| 490 | *luaH_setnum(L, arr, n+aux) = *(--top); | 466 | setobj(luaH_setnum(L, arr, n+aux), --top); |
| 491 | break; | 467 | break; |
| 492 | } | 468 | } |
| 493 | case OP_SETMAP: { | 469 | case OP_SETMAP: { |
| @@ -497,7 +473,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
| 497 | L->top = finaltop; /* final value of `top' (in case of errors) */ | 473 | L->top = finaltop; /* final value of `top' (in case of errors) */ |
| 498 | for (; n; n--) { | 474 | for (; n; n--) { |
| 499 | top-=2; | 475 | top-=2; |
| 500 | *luaH_set(L, arr, top) = *(top+1); | 476 | setobj(luaH_set(L, arr, top), top+1); |
| 501 | } | 477 | } |
| 502 | break; | 478 | break; |
| 503 | } | 479 | } |
| @@ -511,8 +487,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
| 511 | } | 487 | } |
| 512 | case OP_ADDI: { | 488 | case OP_ADDI: { |
| 513 | if (tonumber(top-1)) { | 489 | if (tonumber(top-1)) { |
| 514 | ttype(top) = LUA_TNUMBER; | 490 | setnvalue(top, (lua_Number)GETARG_S(i)); |
| 515 | nvalue(top) = (lua_Number)GETARG_S(i); | ||
| 516 | call_arith(L, top+1, TM_ADD); | 491 | call_arith(L, top+1, TM_ADD); |
| 517 | } | 492 | } |
| 518 | else | 493 | else |
| @@ -559,7 +534,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
| 559 | } | 534 | } |
| 560 | case OP_MINUS: { | 535 | case OP_MINUS: { |
| 561 | if (tonumber(top-1)) { | 536 | if (tonumber(top-1)) { |
| 562 | ttype(top) = LUA_TNIL; | 537 | setnilvalue(top); |
| 563 | call_arith(L, top+1, TM_UNM); | 538 | call_arith(L, top+1, TM_UNM); |
| 564 | } | 539 | } |
| 565 | else | 540 | else |
| @@ -625,7 +600,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
| 625 | break; | 600 | break; |
| 626 | } | 601 | } |
| 627 | case OP_PUSHNILJMP: { | 602 | case OP_PUSHNILJMP: { |
| 628 | ttype(top++) = LUA_TNIL; | 603 | setnilvalue(top++); |
| 629 | pc++; | 604 | pc++; |
| 630 | break; | 605 | break; |
| 631 | } | 606 | } |
| @@ -669,8 +644,8 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
| 669 | } | 644 | } |
| 670 | else { | 645 | else { |
| 671 | top += 2; /* index,value */ | 646 | top += 2; /* index,value */ |
| 672 | *(top-2) = *key(node); | 647 | setobj(top-2, key(node)); |
| 673 | *(top-1) = *val(node); | 648 | setobj(top-1, val(node)); |
| 674 | } | 649 | } |
| 675 | break; | 650 | break; |
| 676 | } | 651 | } |
| @@ -681,8 +656,8 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
| 681 | if (node == NULL) /* end loop? */ | 656 | if (node == NULL) /* end loop? */ |
| 682 | top -= 3; /* remove table, key, and value */ | 657 | top -= 3; /* remove table, key, and value */ |
| 683 | else { | 658 | else { |
| 684 | *(top-2) = *key(node); | 659 | setobj(top-2, key(node)); |
| 685 | *(top-1) = *val(node); | 660 | setobj(top-1, val(node)); |
| 686 | dojump(pc, i); /* repeat loop */ | 661 | dojump(pc, i); /* repeat loop */ |
| 687 | } | 662 | } |
| 688 | break; | 663 | break; |
