diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-02-14 14:51:08 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-02-14 14:51:08 -0200 |
commit | 3afe85b2ce9ffdc8eca819ddc1c05414701606fd (patch) | |
tree | 4433002ba359cfb376c61c69c93af9de13e29331 /lvm.c | |
parent | 52aad0ab5937d4df6fe07aedbf9987f2f792698c (diff) | |
download | lua-3afe85b2ce9ffdc8eca819ddc1c05414701606fd.tar.gz lua-3afe85b2ce9ffdc8eca819ddc1c05414701606fd.tar.bz2 lua-3afe85b2ce9ffdc8eca819ddc1c05414701606fd.zip |
new version for INSTRUCTION formats
Diffstat (limited to 'lvm.c')
-rw-r--r-- | lvm.c | 231 |
1 files changed, 97 insertions, 134 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 1.85 2000/02/08 16:39:42 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 1.86 2000/02/11 16:52:54 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 | */ |
@@ -280,6 +280,11 @@ void luaV_comparison (lua_State *L) { | |||
280 | } | 280 | } |
281 | 281 | ||
282 | 282 | ||
283 | #define setbool(o,cond) if (cond) { \ | ||
284 | ttype(o) = LUA_T_NUMBER; nvalue(o) = 1.0; } \ | ||
285 | else ttype(o) = LUA_T_NIL | ||
286 | |||
287 | |||
283 | void luaV_pack (lua_State *L, StkId firstelem, int nvararg, TObject *tab) { | 288 | void luaV_pack (lua_State *L, StkId firstelem, int nvararg, TObject *tab) { |
284 | int i; | 289 | int i; |
285 | Hash *htab; | 290 | Hash *htab; |
@@ -313,90 +318,80 @@ static void adjust_varargs (lua_State *L, StkId base, int nfixargs) { | |||
313 | StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf, | 318 | StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf, |
314 | register StkId base) { | 319 | register StkId base) { |
315 | register StkId top; /* keep top local, for performance */ | 320 | register StkId top; /* keep top local, for performance */ |
316 | register const Byte *pc = tf->code; | 321 | register const Instruction *pc = tf->code; |
317 | TaggedString **kstr = tf->kstr; | 322 | TaggedString **kstr = tf->kstr; |
318 | if (L->callhook) | 323 | if (L->callhook) |
319 | luaD_callHook(L, base-1, L->callhook, "call"); | 324 | luaD_callHook(L, base-1, L->callhook, "call"); |
320 | luaD_checkstack(L, (*pc++)+EXTRA_STACK); | 325 | luaD_checkstack(L, tf->maxstacksize+EXTRA_STACK); |
321 | if (*pc < ZEROVARARG) | 326 | if (tf->is_vararg) { /* varargs? */ |
322 | luaD_adjusttop(L, base, *(pc++)); | 327 | adjust_varargs(L, base, tf->numparams); |
323 | else { /* varargs */ | ||
324 | adjust_varargs(L, base, (*pc++)-ZEROVARARG); | ||
325 | luaC_checkGC(L); | 328 | luaC_checkGC(L); |
326 | } | 329 | } |
330 | else | ||
331 | luaD_adjusttop(L, base, tf->numparams); | ||
327 | top = L->top; | 332 | top = L->top; |
328 | for (;;) { | 333 | for (;;) { |
329 | register int aux = 0; | 334 | register Instruction i = *pc++; |
330 | switchentry: | 335 | switch (GET_OPCODE(i)) { |
331 | switch ((OpCode)*pc++) { | ||
332 | 336 | ||
333 | case ENDCODE: | 337 | case ENDCODE: |
334 | return L->top; /* no results */ | 338 | return L->top; /* no results */ |
335 | 339 | ||
336 | case RETCODE: | 340 | case RETCODE: |
337 | L->top = top; | 341 | L->top = top; |
338 | return base+(*pc++); | 342 | return base+GETARG_U(i); |
339 | 343 | ||
340 | case CALL: aux = *pc++; | 344 | case CALL: |
341 | L->top = top; | 345 | L->top = top; |
342 | luaD_call(L, base+(*pc++), aux); | 346 | luaD_call(L, base+GETARG_A(i), GETARG_B(i)); |
343 | top = L->top; | 347 | top = L->top; |
344 | break; | 348 | break; |
345 | 349 | ||
346 | case TAILCALL: aux = *pc++; | 350 | case TAILCALL: |
347 | L->top = top; | 351 | L->top = top; |
348 | luaD_call(L, base+(*pc++), MULT_RET); | 352 | luaD_call(L, base+GETARG_A(i), MULT_RET); |
349 | return base+aux; | 353 | return base+GETARG_B(i); |
350 | 354 | ||
351 | case PUSHNIL: aux = *pc++; | 355 | case PUSHNIL: { |
356 | register int n = GETARG_U(i); | ||
352 | do { | 357 | do { |
353 | ttype(top++) = LUA_T_NIL; | 358 | ttype(top++) = LUA_T_NIL; |
354 | } while (aux--); | 359 | } while (n--); |
355 | break; | ||
356 | |||
357 | case POP: aux = *pc++; | ||
358 | top -= aux; | ||
359 | break; | 360 | break; |
361 | } | ||
360 | 362 | ||
361 | case PUSHINTW: aux += highbyte(L, *pc++); | 363 | case POP: |
362 | case PUSHINT: aux += *pc++; | 364 | top -= GETARG_U(i); |
363 | ttype(top) = LUA_T_NUMBER; | ||
364 | nvalue(top) = aux; | ||
365 | top++; | ||
366 | break; | 365 | break; |
367 | 366 | ||
368 | case PUSHINTNEGW: aux += highbyte(L, *pc++); | 367 | case PUSHINT: |
369 | case PUSHINTNEG: aux += *pc++; | ||
370 | ttype(top) = LUA_T_NUMBER; | 368 | ttype(top) = LUA_T_NUMBER; |
371 | nvalue(top) = -aux; | 369 | nvalue(top) = (real)GETARG_S(i); |
372 | top++; | 370 | top++; |
373 | break; | 371 | break; |
374 | 372 | ||
375 | case PUSHSTRINGW: aux += highbyte(L, *pc++); | 373 | case PUSHSTRING: |
376 | case PUSHSTRING: aux += *pc++; | ||
377 | ttype(top) = LUA_T_STRING; | 374 | ttype(top) = LUA_T_STRING; |
378 | tsvalue(top) = kstr[aux]; | 375 | tsvalue(top) = kstr[GETARG_U(i)]; |
379 | top++; | 376 | top++; |
380 | break; | 377 | break; |
381 | 378 | ||
382 | case PUSHNUMBERW: aux += highbyte(L, *pc++); | 379 | case PUSHNUMBER: |
383 | case PUSHNUMBER: aux += *pc++; | ||
384 | ttype(top) = LUA_T_NUMBER; | 380 | ttype(top) = LUA_T_NUMBER; |
385 | nvalue(top) = tf->knum[aux]; | 381 | nvalue(top) = tf->knum[GETARG_U(i)]; |
386 | top++; | 382 | top++; |
387 | break; | 383 | break; |
388 | 384 | ||
389 | case PUSHUPVALUE: aux = *pc++; | 385 | case PUSHUPVALUE: |
390 | *top++ = cl->consts[aux+1]; | 386 | *top++ = cl->consts[GETARG_U(i)+1]; |
391 | break; | 387 | break; |
392 | 388 | ||
393 | case PUSHLOCAL: aux = *pc++; | 389 | case PUSHLOCAL: |
394 | *top++ = *(base+aux); | 390 | *top++ = *(base+GETARG_U(i)); |
395 | break; | 391 | break; |
396 | 392 | ||
397 | case GETGLOBALW: aux += highbyte(L, *pc++); | 393 | case GETGLOBAL: |
398 | case GETGLOBAL: aux += *pc++; | 394 | luaV_getglobal(L, kstr[GETARG_U(i)]->u.s.gv, top); |
399 | luaV_getglobal(L, kstr[aux]->u.s.gv, top); | ||
400 | top++; | 395 | top++; |
401 | break; | 396 | break; |
402 | 397 | ||
@@ -405,41 +400,37 @@ StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf, | |||
405 | top--; | 400 | top--; |
406 | break; | 401 | break; |
407 | 402 | ||
408 | case GETDOTTEDW: aux += highbyte(L, *pc++); | 403 | case GETDOTTED: |
409 | case GETDOTTED: aux += *pc++; | ||
410 | ttype(top) = LUA_T_STRING; | 404 | ttype(top) = LUA_T_STRING; |
411 | tsvalue(top++) = kstr[aux]; | 405 | tsvalue(top++) = kstr[GETARG_U(i)]; |
412 | luaV_gettable(L, top); | 406 | luaV_gettable(L, top); |
413 | top--; | 407 | top--; |
414 | break; | 408 | break; |
415 | 409 | ||
416 | case PUSHSELFW: aux += highbyte(L, *pc++); | 410 | case PUSHSELF: { |
417 | case PUSHSELF: aux += *pc++; { | ||
418 | TObject receiver; | 411 | TObject receiver; |
419 | receiver = *(top-1); | 412 | receiver = *(top-1); |
420 | ttype(top) = LUA_T_STRING; | 413 | ttype(top) = LUA_T_STRING; |
421 | tsvalue(top++) = kstr[aux]; | 414 | tsvalue(top++) = kstr[GETARG_U(i)]; |
422 | luaV_gettable(L, top); | 415 | luaV_gettable(L, top); |
423 | *(top-1) = receiver; | 416 | *(top-1) = receiver; |
424 | break; | 417 | break; |
425 | } | 418 | } |
426 | 419 | ||
427 | case CREATEARRAYW: aux += highbyte(L, *pc++); | 420 | case CREATETABLE: |
428 | case CREATEARRAY: aux += *pc++; | ||
429 | L->top = top; | 421 | L->top = top; |
430 | luaC_checkGC(L); | 422 | luaC_checkGC(L); |
431 | avalue(top) = luaH_new(L, aux); | 423 | avalue(top) = luaH_new(L, GETARG_U(i)); |
432 | ttype(top) = LUA_T_ARRAY; | 424 | ttype(top) = LUA_T_ARRAY; |
433 | top++; | 425 | top++; |
434 | break; | 426 | break; |
435 | 427 | ||
436 | case SETLOCAL: aux = *pc++; | 428 | case SETLOCAL: |
437 | *(base+aux) = *(--top); | 429 | *(base+GETARG_U(i)) = *(--top); |
438 | break; | 430 | break; |
439 | 431 | ||
440 | case SETGLOBALW: aux += highbyte(L, *pc++); | 432 | case SETGLOBAL: |
441 | case SETGLOBAL: aux += *pc++; | 433 | luaV_setglobal(L, kstr[GETARG_U(i)]->u.s.gv, top); |
442 | luaV_setglobal(L, kstr[aux]->u.s.gv, top); | ||
443 | top--; | 434 | top--; |
444 | break; | 435 | break; |
445 | 436 | ||
@@ -449,91 +440,81 @@ StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf, | |||
449 | break; | 440 | break; |
450 | 441 | ||
451 | case SETTABLE: | 442 | case SETTABLE: |
452 | luaV_settable(L, top-3-(*pc++), top); | 443 | luaV_settable(L, top-3-GETARG_U(i), top); |
453 | top--; /* pop value */ | 444 | top--; /* pop value */ |
454 | break; | 445 | break; |
455 | 446 | ||
456 | case SETLISTW: aux += highbyte(L, *pc++); | 447 | case SETLIST: { |
457 | case SETLIST: aux += *pc++; { | 448 | int aux = GETARG_A(i) * LFIELDS_PER_FLUSH; |
458 | int n = *(pc++); | 449 | int n = GETARG_B(i)+1; |
459 | Hash *arr = avalue(top-n-1); | 450 | Hash *arr = avalue(top-n-1); |
460 | L->top = top-n; /* final value of `top' (in case of errors) */ | 451 | L->top = top-n; /* final value of `top' (in case of errors) */ |
461 | aux *= LFIELDS_PER_FLUSH; | ||
462 | for (; n; n--) | 452 | for (; n; n--) |
463 | luaH_setint(L, arr, n+aux, --top); | 453 | luaH_setint(L, arr, n+aux, --top); |
464 | break; | 454 | break; |
465 | } | 455 | } |
466 | 456 | ||
467 | case SETMAP: aux = *pc++; { | 457 | case SETMAP: { |
468 | StkId finaltop = top-2*(aux+1); | 458 | int n = GETARG_U(i); |
459 | StkId finaltop = top-2*(n+1); | ||
469 | Hash *arr = avalue(finaltop-1); | 460 | Hash *arr = avalue(finaltop-1); |
470 | L->top = finaltop; /* final value of `top' (in case of errors) */ | 461 | L->top = finaltop; /* final value of `top' (in case of errors) */ |
471 | do { | 462 | do { |
472 | luaH_set(L, arr, top-2, top-1); | 463 | luaH_set(L, arr, top-2, top-1); |
473 | top-=2; | 464 | top-=2; |
474 | } while (aux--); | 465 | } while (n--); |
475 | break; | 466 | break; |
476 | } | 467 | } |
477 | 468 | ||
478 | case NEQOP: aux = 1; | 469 | case NEQOP: |
470 | top--; | ||
471 | setbool(top-1, !luaO_equalObj(top-1, top)); | ||
472 | break; | ||
473 | |||
479 | case EQOP: | 474 | case EQOP: |
480 | top--; | 475 | top--; |
481 | aux = (luaO_equalObj(top-1, top) != aux); | 476 | setbool(top-1, luaO_equalObj(top-1, top)); |
482 | booleanresult: | ||
483 | if (aux) { | ||
484 | ttype(top-1) = LUA_T_NUMBER; | ||
485 | nvalue(top-1) = 1.0; | ||
486 | } | ||
487 | else ttype(top-1) = LUA_T_NIL; | ||
488 | break; | 477 | break; |
489 | 478 | ||
490 | case LTOP: | 479 | case LTOP: |
491 | top--; | 480 | top--; |
492 | if (ttype(top-1) == LUA_T_NUMBER && ttype(top) == LUA_T_NUMBER) | 481 | if (ttype(top-1) == LUA_T_NUMBER && ttype(top) == LUA_T_NUMBER) |
493 | aux = nvalue(top-1) < nvalue(top); | 482 | setbool(top-1, nvalue(top-1) < nvalue(top)); |
494 | else if (ttype(top-1) == LUA_T_STRING && ttype(top) == LUA_T_STRING) | 483 | else if (ttype(top-1) == LUA_T_STRING && ttype(top) == LUA_T_STRING) |
495 | aux = luaV_strcomp(tsvalue(top-1), tsvalue(top)) < 0; | 484 | setbool(top-1, luaV_strcomp(tsvalue(top-1), tsvalue(top)) < 0); |
496 | else { | 485 | else |
497 | call_binTM(L, top+1, IM_LT, "unexpected type in comparison"); | 486 | call_binTM(L, top+1, IM_LT, "unexpected type in comparison"); |
498 | break; | 487 | break; |
499 | } | ||
500 | goto booleanresult; | ||
501 | 488 | ||
502 | case LEOP: | 489 | case LEOP: |
503 | top--; | 490 | top--; |
504 | if (ttype(top-1) == LUA_T_NUMBER && ttype(top) == LUA_T_NUMBER) | 491 | if (ttype(top-1) == LUA_T_NUMBER && ttype(top) == LUA_T_NUMBER) |
505 | aux = nvalue(top-1) <= nvalue(top); | 492 | setbool(top-1, nvalue(top-1) <= nvalue(top)); |
506 | else if (ttype(top-1) == LUA_T_STRING && ttype(top) == LUA_T_STRING) | 493 | else if (ttype(top-1) == LUA_T_STRING && ttype(top) == LUA_T_STRING) |
507 | aux = luaV_strcomp(tsvalue(top-1), tsvalue(top)) <= 0; | 494 | setbool(top-1, luaV_strcomp(tsvalue(top-1), tsvalue(top)) <= 0); |
508 | else { | 495 | else |
509 | call_binTM(L, top+1, IM_LE, "unexpected type in comparison"); | 496 | call_binTM(L, top+1, IM_LE, "unexpected type in comparison"); |
510 | break; | 497 | break; |
511 | } | ||
512 | goto booleanresult; | ||
513 | 498 | ||
514 | case GTOP: | 499 | case GTOP: |
515 | top--; | 500 | top--; |
516 | if (ttype(top-1) == LUA_T_NUMBER && ttype(top) == LUA_T_NUMBER) | 501 | if (ttype(top-1) == LUA_T_NUMBER && ttype(top) == LUA_T_NUMBER) |
517 | aux = nvalue(top-1) > nvalue(top); | 502 | setbool(top-1, nvalue(top-1) > nvalue(top)); |
518 | else if (ttype(top-1) == LUA_T_STRING && ttype(top) == LUA_T_STRING) | 503 | else if (ttype(top-1) == LUA_T_STRING && ttype(top) == LUA_T_STRING) |
519 | aux = luaV_strcomp(tsvalue(top-1), tsvalue(top)) > 0; | 504 | setbool(top-1, luaV_strcomp(tsvalue(top-1), tsvalue(top)) > 0); |
520 | else { | 505 | else |
521 | call_binTM(L, top+1, IM_GT, "unexpected type in comparison"); | 506 | call_binTM(L, top+1, IM_GT, "unexpected type in comparison"); |
522 | break; | 507 | break; |
523 | } | ||
524 | goto booleanresult; | ||
525 | 508 | ||
526 | case GEOP: | 509 | case GEOP: |
527 | top--; | 510 | top--; |
528 | if (ttype(top-1) == LUA_T_NUMBER && ttype(top) == LUA_T_NUMBER) | 511 | if (ttype(top-1) == LUA_T_NUMBER && ttype(top) == LUA_T_NUMBER) |
529 | aux = nvalue(top-1) >= nvalue(top); | 512 | setbool(top-1, nvalue(top-1) >= nvalue(top)); |
530 | else if (ttype(top-1) == LUA_T_STRING && ttype(top) == LUA_T_STRING) | 513 | else if (ttype(top-1) == LUA_T_STRING && ttype(top) == LUA_T_STRING) |
531 | aux = luaV_strcomp(tsvalue(top-1), tsvalue(top)) >= 0; | 514 | setbool(top-1, luaV_strcomp(tsvalue(top-1), tsvalue(top)) >= 0); |
532 | else { | 515 | else |
533 | call_binTM(L, top+1, IM_GE, "unexpected type in comparison"); | 516 | call_binTM(L, top+1, IM_GE, "unexpected type in comparison"); |
534 | break; | 517 | break; |
535 | } | ||
536 | goto booleanresult; | ||
537 | 518 | ||
538 | case ADDOP: | 519 | case ADDOP: |
539 | if (tonumber(top-1) || tonumber(top-2)) | 520 | if (tonumber(top-1) || tonumber(top-2)) |
@@ -597,71 +578,53 @@ StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf, | |||
597 | nvalue(top-1) = 1; | 578 | nvalue(top-1) = 1; |
598 | break; | 579 | break; |
599 | 580 | ||
600 | case ONTJMPW: aux += highbyte(L, *pc++); | 581 | case ONTJMP: |
601 | case ONTJMP: aux += *pc++; | 582 | if (ttype(top-1) != LUA_T_NIL) pc += GETARG_S(i); |
602 | if (ttype(top-1) != LUA_T_NIL) pc += aux; | ||
603 | else top--; | 583 | else top--; |
604 | break; | 584 | break; |
605 | 585 | ||
606 | case ONFJMPW: aux += highbyte(L, *pc++); | 586 | case ONFJMP: |
607 | case ONFJMP: aux += *pc++; | 587 | if (ttype(top-1) == LUA_T_NIL) pc += GETARG_S(i); |
608 | if (ttype(top-1) == LUA_T_NIL) pc += aux; | ||
609 | else top--; | 588 | else top--; |
610 | break; | 589 | break; |
611 | 590 | ||
612 | case JMPW: aux += highbyte(L, *pc++); | 591 | case JMP: |
613 | case JMP: aux += *pc++; | 592 | pc += GETARG_S(i); |
614 | pc += aux; | ||
615 | break; | 593 | break; |
616 | 594 | ||
617 | case IFFJMPW: aux += highbyte(L, *pc++); | 595 | case IFTJMP: |
618 | case IFFJMP: aux += *pc++; | 596 | if (ttype(--top) != LUA_T_NIL) pc += GETARG_S(i); |
619 | if (ttype(--top) == LUA_T_NIL) pc += aux; | ||
620 | break; | 597 | break; |
621 | 598 | ||
622 | case IFTUPJMPW: aux += highbyte(L, *pc++); | 599 | case IFFJMP: |
623 | case IFTUPJMP: aux += *pc++; | 600 | if (ttype(--top) == LUA_T_NIL) pc += GETARG_S(i); |
624 | if (ttype(--top) != LUA_T_NIL) pc -= aux; | ||
625 | break; | 601 | break; |
626 | 602 | ||
627 | case IFFUPJMPW: aux += highbyte(L, *pc++); | 603 | case CLOSURE: |
628 | case IFFUPJMP: aux += *pc++; | ||
629 | if (ttype(--top) == LUA_T_NIL) pc -= aux; | ||
630 | break; | ||
631 | |||
632 | case CLOSUREW: aux += highbyte(L, *pc++); | ||
633 | case CLOSURE: aux += *pc++; | ||
634 | ttype(top) = LUA_T_LPROTO; | 604 | ttype(top) = LUA_T_LPROTO; |
635 | tfvalue(top) = tf->kproto[aux]; | 605 | tfvalue(top) = tf->kproto[GETARG_A(i)]; |
636 | L->top = ++top; | 606 | L->top = ++top; |
637 | aux = *pc++; /* number of upvalues */ | 607 | luaV_closure(L, GETARG_B(i)); |
638 | luaV_closure(L, aux); | 608 | top -= GETARG_B(i); |
639 | luaC_checkGC(L); | 609 | luaC_checkGC(L); |
640 | top -= aux; | ||
641 | break; | 610 | break; |
642 | 611 | ||
643 | case SETLINEW: aux += highbyte(L, *pc++); | 612 | case SETLINE: |
644 | case SETLINE: aux += *pc++; | ||
645 | if ((base-1)->ttype != LUA_T_LINE) { | 613 | if ((base-1)->ttype != LUA_T_LINE) { |
646 | /* open space for LINE value */ | 614 | /* open space for LINE value */ |
647 | int i = top-base; | 615 | int n = top-base; |
648 | while (i--) base[i+1] = base[i]; | 616 | while (n--) base[n+1] = base[n]; |
649 | base++; | 617 | base++; |
650 | top++; | 618 | top++; |
651 | (base-1)->ttype = LUA_T_LINE; | 619 | (base-1)->ttype = LUA_T_LINE; |
652 | } | 620 | } |
653 | (base-1)->value.i = aux; | 621 | (base-1)->value.i = GETARG_U(i); |
654 | if (L->linehook) { | 622 | if (L->linehook) { |
655 | L->top = top; | 623 | L->top = top; |
656 | luaD_lineHook(L, base-2, aux); | 624 | luaD_lineHook(L, base-2, GETARG_U(i)); |
657 | } | 625 | } |
658 | break; | 626 | break; |
659 | 627 | ||
660 | case LONGARGW: aux += highbyte(L, *pc++); | ||
661 | case LONGARG: aux += *pc++; | ||
662 | aux = highbyte(L, highbyte(L, aux)); | ||
663 | goto switchentry; /* do not reset `aux' */ | ||
664 | |||
665 | } | 628 | } |
666 | } | 629 | } |
667 | } | 630 | } |