diff options
Diffstat (limited to '')
| -rw-r--r-- | lvm.c | 100 |
1 files changed, 56 insertions, 44 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lvm.c,v 1.115 2000/06/12 13:52:05 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 1.116 2000/06/19 18:04:41 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 | */ |
| @@ -67,6 +67,23 @@ int luaV_tostring (lua_State *L, TObject *obj) { /* LUA_NUMBER */ | |||
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | 69 | ||
| 70 | static void traceexec (lua_State *L, StkId base, int pc) { | ||
| 71 | CallInfo *ci = infovalue(base-1); | ||
| 72 | int oldpc = ci->pc; | ||
| 73 | pc--; /* pc has been already incremented */ | ||
| 74 | ci->pc = pc; | ||
| 75 | if (L->linehook && ci->func->f.l->debug) { | ||
| 76 | int *lines = ci->func->f.l->lines; | ||
| 77 | LUA_ASSERT(L, lines, "must have debug information"); | ||
| 78 | /* calls linehook when jumps back (a loop) or enters a new line */ | ||
| 79 | if (pc <= oldpc || lines[pc] != ci->line) { | ||
| 80 | ci->line = lines[pc]; | ||
| 81 | luaD_lineHook(L, base-2, lines[pc]); | ||
| 82 | } | ||
| 83 | } | ||
| 84 | } | ||
| 85 | |||
| 86 | |||
| 70 | static Closure *luaV_closure (lua_State *L, lua_Type t, int nelems) { | 87 | static Closure *luaV_closure (lua_State *L, lua_Type t, int nelems) { |
| 71 | Closure *c = luaF_newclosure(L, nelems); | 88 | Closure *c = luaF_newclosure(L, nelems); |
| 72 | L->top -= nelems; | 89 | L->top -= nelems; |
| @@ -226,13 +243,6 @@ static void call_arith (lua_State *L, StkId top, IMS event) { | |||
| 226 | } | 243 | } |
| 227 | 244 | ||
| 228 | 245 | ||
| 229 | static void addK (lua_State *L, StkId top, int k) { | ||
| 230 | ttype(top) = TAG_NUMBER; | ||
| 231 | nvalue(top) = (Number)k; | ||
| 232 | call_arith(L, top+1, IM_ADD); | ||
| 233 | } | ||
| 234 | |||
| 235 | |||
| 236 | static int luaV_strcomp (const TString *ls, const TString *rs) { | 246 | static int luaV_strcomp (const TString *ls, const TString *rs) { |
| 237 | const char *l = ls->str; | 247 | const char *l = ls->str; |
| 238 | size_t ll = ls->u.s.len; | 248 | size_t ll = ls->u.s.len; |
| @@ -338,6 +348,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
| 338 | StkId top; /* keep top local, for performance */ | 348 | StkId top; /* keep top local, for performance */ |
| 339 | const Instruction *pc = tf->code; | 349 | const Instruction *pc = tf->code; |
| 340 | TString **kstr = tf->kstr; | 350 | TString **kstr = tf->kstr; |
| 351 | int debug = tf->debug; | ||
| 341 | luaD_checkstack(L, tf->maxstacksize+EXTRA_STACK); | 352 | luaD_checkstack(L, tf->maxstacksize+EXTRA_STACK); |
| 342 | if (tf->is_vararg) { /* varargs? */ | 353 | if (tf->is_vararg) { /* varargs? */ |
| 343 | adjust_varargs(L, base, tf->numparams); | 354 | adjust_varargs(L, base, tf->numparams); |
| @@ -346,8 +357,13 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
| 346 | else | 357 | else |
| 347 | luaD_adjusttop(L, base, tf->numparams); | 358 | luaD_adjusttop(L, base, tf->numparams); |
| 348 | top = L->top; | 359 | top = L->top; |
| 360 | /* main loop of interpreter */ | ||
| 349 | for (;;) { | 361 | for (;;) { |
| 350 | Instruction i = *pc++; | 362 | Instruction i = *pc++; |
| 363 | if (debug) { | ||
| 364 | L->top = top; | ||
| 365 | traceexec(L, base, pc - tf->code); | ||
| 366 | } | ||
| 351 | switch (GET_OPCODE(i)) { | 367 | switch (GET_OPCODE(i)) { |
| 352 | 368 | ||
| 353 | case OP_END: | 369 | case OP_END: |
| @@ -499,8 +515,11 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
| 499 | break; | 515 | break; |
| 500 | 516 | ||
| 501 | case OP_ADDI: | 517 | case OP_ADDI: |
| 502 | if (tonumber(top-1)) | 518 | if (tonumber(top-1)) { |
| 503 | addK(L, top, GETARG_S(i)); | 519 | ttype(top) = TAG_NUMBER; |
| 520 | nvalue(top) = (Number)GETARG_S(i); | ||
| 521 | call_arith(L, top+1, IM_ADD); | ||
| 522 | } | ||
| 504 | else | 523 | else |
| 505 | nvalue(top-1) += (Number)GETARG_S(i); | 524 | nvalue(top-1) += (Number)GETARG_S(i); |
| 506 | break; | 525 | break; |
| @@ -622,35 +641,44 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
| 622 | lua_error(L, "`for' limit must be a number"); | 641 | lua_error(L, "`for' limit must be a number"); |
| 623 | if (tonumber(top-3)) | 642 | if (tonumber(top-3)) |
| 624 | lua_error(L, "`for' initial value must be a number"); | 643 | lua_error(L, "`for' initial value must be a number"); |
| 625 | /* number of steps */ | 644 | if (nvalue(top-1) > 0 ? |
| 626 | nvalue(top-2) = (nvalue(top-2)-nvalue(top-3))/nvalue(top-1); | 645 | nvalue(top-3) > nvalue(top-2) : |
| 627 | nvalue(top-3) -= nvalue(top-1); /* to be undone by first FORLOOP */ | 646 | nvalue(top-3) < nvalue(top-2)) { /* `empty' loop? */ |
| 628 | pc += GETARG_S(i); | 647 | top -= 3; /* remove control variables */ |
| 648 | pc += GETARG_S(i)+1; /* jump to loop end */ | ||
| 649 | } | ||
| 629 | break; | 650 | break; |
| 630 | 651 | ||
| 631 | case OP_FORLOOP: { | 652 | case OP_FORLOOP: { |
| 632 | LUA_ASSERT(L, ttype(top-1) == TAG_NUMBER, "invalid step"); | 653 | LUA_ASSERT(L, ttype(top-1) == TAG_NUMBER, "invalid step"); |
| 633 | LUA_ASSERT(L, ttype(top-2) == TAG_NUMBER, "invalid count"); | 654 | LUA_ASSERT(L, ttype(top-2) == TAG_NUMBER, "invalid limit"); |
| 634 | if (nvalue(top-2) < 0) | 655 | if (ttype(top-3) != TAG_NUMBER) |
| 656 | lua_error(L, "`for' index must be a number"); | ||
| 657 | nvalue(top-3) += nvalue(top-1); /* increment index */ | ||
| 658 | if (nvalue(top-1) > 0 ? | ||
| 659 | nvalue(top-3) > nvalue(top-2) : | ||
| 660 | nvalue(top-3) < nvalue(top-2)) | ||
| 635 | top -= 3; /* end loop: remove control variables */ | 661 | top -= 3; /* end loop: remove control variables */ |
| 636 | else { | 662 | else |
| 637 | nvalue(top-2)--; /* decrement count */ | 663 | pc += GETARG_S(i); /* repeat loop */ |
| 638 | if (ttype(top-3) != TAG_NUMBER) | ||
| 639 | lua_error(L, "`for' index must be a number"); | ||
| 640 | nvalue(top-3) += nvalue(top-1); /* increment index */ | ||
| 641 | pc += GETARG_S(i); | ||
| 642 | } | ||
| 643 | break; | 664 | break; |
| 644 | } | 665 | } |
| 645 | 666 | ||
| 646 | case OP_LFORPREP: { | 667 | case OP_LFORPREP: { |
| 647 | if (ttype(top-1) != TAG_TABLE) | 668 | if (ttype(top-1) != TAG_TABLE) |
| 648 | lua_error(L, "`for' table must be a table"); | 669 | lua_error(L, "`for' table must be a table"); |
| 649 | top += 3; /* counter + index,value */ | 670 | top++; /* counter */ |
| 650 | ttype(top-3) = TAG_NUMBER; | 671 | L->top = top; |
| 651 | nvalue(top-3) = 0.0; /* counter */ | 672 | ttype(top-1) = TAG_NUMBER; |
| 652 | ttype(top-2) = ttype(top-1) = TAG_NIL; | 673 | nvalue(top-1) = (Number)luaA_next(L, hvalue(top-2), 0); /* counter */ |
| 653 | pc += GETARG_S(i); | 674 | if (nvalue(top-1) == 0) { /* `empty' loop? */ |
| 675 | top -= 2; /* remove table and counter */ | ||
| 676 | pc += GETARG_S(i)+1; /* jump to loop end */ | ||
| 677 | } | ||
| 678 | else { | ||
| 679 | top += 2; /* index,value */ | ||
| 680 | LUA_ASSERT(L, top==L->top, "bad top"); | ||
| 681 | } | ||
| 654 | break; | 682 | break; |
| 655 | } | 683 | } |
| 656 | 684 | ||
| @@ -678,22 +706,6 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
| 678 | luaC_checkGC(L); | 706 | luaC_checkGC(L); |
| 679 | break; | 707 | break; |
| 680 | 708 | ||
| 681 | case OP_SETLINE: | ||
| 682 | if ((base-1)->ttype != TAG_LINE) { | ||
| 683 | /* open space for LINE value */ | ||
| 684 | int n = top-base; | ||
| 685 | while (n--) base[n+1] = base[n]; | ||
| 686 | base++; | ||
| 687 | top++; | ||
| 688 | (base-1)->ttype = TAG_LINE; | ||
| 689 | } | ||
| 690 | (base-1)->value.i = GETARG_U(i); | ||
| 691 | if (L->linehook) { | ||
| 692 | L->top = top; | ||
| 693 | luaD_lineHook(L, base-2, GETARG_U(i)); | ||
| 694 | } | ||
| 695 | break; | ||
| 696 | |||
| 697 | } | 709 | } |
| 698 | } | 710 | } |
| 699 | } | 711 | } |
