small optimizations (bit scrubbing)

This commit is contained in:
Roberto Ierusalimschy 1997-09-19 15:40:32 -03:00
parent 8cd67ac676
commit dfe03c7abe
3 changed files with 142 additions and 177 deletions

View File

@ -1,5 +1,5 @@
/* /*
** $Id: $ ** $Id: lopcodes.h,v 1.1 1997/09/16 19:25:59 roberto Exp roberto $
** Opcodes for Lua virtual machine ** Opcodes for Lua virtual machine
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -36,7 +36,7 @@ PUSHLOCAL8,/* - LOC[8] */
PUSHLOCAL9,/* - LOC[9] */ PUSHLOCAL9,/* - LOC[9] */
PUSHLOCAL,/* b - LOC[b] */ PUSHLOCAL,/* b - LOC[b] */
PUSHGLOBAL,/* w - VAR[w] */ PUSHGLOBAL,/* w - VAR[w] */
PUSHTABLE,/* i t t[i] */ GETTABLE,/* i t t[i] */
PUSHSELF,/* w t t t[CNST[w]] */ PUSHSELF,/* w t t t[CNST[w]] */
CREATEARRAY,/* w - newarray(size = w) */ CREATEARRAY,/* w - newarray(size = w) */

126
lua.stx
View File

@ -1,6 +1,6 @@
%{ %{
/* /*
** $Id: $ ** $Id: lua.stx,v 1.1 1997/09/16 19:33:21 roberto Exp roberto $
** Syntax analizer and code generator ** Syntax analizer and code generator
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -111,6 +111,27 @@ static void code_opcode (OpCode op, int delta)
} }
static void code_push (OpCode op)
{
code_opcode(op, 1);
}
static void code_pop (OpCode op)
{
code_opcode(op, -1);
}
/* binary operations get 2 arguments and leave one, so they pop one */
#define code_binop(op) code_pop(op)
#define code_neutralop(op) code_byte(op)
/* unary operations get 1 argument and leave one, so they are neutral */
#define code_unop(op) code_neutralop(op)
static void code_word_at (int pc, int n) static void code_word_at (int pc, int n)
{ {
Word w = n; Word w = n;
@ -129,11 +150,11 @@ static void code_word (int n)
static void code_constant (int c) static void code_constant (int c)
{ {
if (c <= 255) { if (c <= 255) {
code_opcode(PUSHCONSTANTB, 1); code_push(PUSHCONSTANTB);
code_byte(c); code_byte(c);
} }
else { else {
code_opcode(PUSHCONSTANT, 1); code_push(PUSHCONSTANT);
code_word(c); code_word(c);
} }
} }
@ -197,13 +218,13 @@ static void code_number (real f)
Word i; Word i;
if (f >= 0 && f <= (real)MAX_WORD && (real)(i=(Word)f) == f) { if (f >= 0 && f <= (real)MAX_WORD && (real)(i=(Word)f) == f) {
/* f has an (short) integer value */ /* f has an (short) integer value */
if (i <= 2) code_opcode(PUSH0 + i, 1); if (i <= 2) code_push(PUSH0 + i);
else if (i <= 255) { else if (i <= 255) {
code_opcode(PUSHBYTE, 1); code_push(PUSHBYTE);
code_byte(i); code_byte(i);
} }
else { else {
code_opcode(PUSHWORD, 1); code_push(PUSHWORD);
code_word(i); code_word(i);
} }
} }
@ -324,9 +345,9 @@ static void pushupvalue (TaggedString *n)
luaY_syntaxerror("cannot access an upvalue in current scope", n->str); luaY_syntaxerror("cannot access an upvalue in current scope", n->str);
i = indexupvalue(n); i = indexupvalue(n);
if (i == 0) if (i == 0)
code_opcode(PUSHUPVALUE0, 1); code_push(PUSHUPVALUE0);
else { else {
code_opcode(PUSHUPVALUE, 1); code_push(PUSHUPVALUE);
code_byte(i); code_byte(i);
} }
} }
@ -336,7 +357,7 @@ void luaY_codedebugline (int line)
{ {
static int lastline = 0; static int lastline = 0;
if (lua_debug && line != lastline) { if (lua_debug && line != lastline) {
code_opcode(SETLINE, 0); code_neutralop(SETLINE);
code_word(line); code_word(line);
lastline = line; lastline = line;
} }
@ -351,7 +372,7 @@ static void adjuststack (int n)
} }
else if (n < 0) { else if (n < 0) {
if (n == -1) if (n == -1)
code_opcode(PUSHNIL, 1); code_push(PUSHNIL);
else { else {
code_opcode(PUSHNILS, -n); code_opcode(PUSHNILS, -n);
code_byte(-n); code_byte(-n);
@ -406,20 +427,20 @@ static void code_args (int dots)
static void lua_pushvar (vardesc number) static void lua_pushvar (vardesc number)
{ {
if (number > 0) { /* global var */ if (number > 0) { /* global var */
code_opcode(PUSHGLOBAL, 1); code_push(PUSHGLOBAL);
code_word(number-1); code_word(number-1);
} }
else if (number < 0) { /* local var */ else if (number < 0) { /* local var */
number = (-number) - 1; number = (-number) - 1;
if (number < 10) if (number < 10)
code_opcode(PUSHLOCAL0 + number, 1); code_push(PUSHLOCAL0 + number);
else { else {
code_opcode(PUSHLOCAL, 1); code_push(PUSHLOCAL);
code_byte(number); code_byte(number);
} }
} }
else { else {
code_opcode(PUSHTABLE, -1); code_pop(GETTABLE);
} }
} }
@ -429,15 +450,15 @@ static void storevar (vardesc number)
if (number == 0) /* indexed var */ if (number == 0) /* indexed var */
code_opcode(SETTABLE0, -3); code_opcode(SETTABLE0, -3);
else if (number > 0) { /* global var */ else if (number > 0) { /* global var */
code_opcode(SETGLOBAL, -1); code_pop(SETGLOBAL);
code_word(number-1); code_word(number-1);
} }
else { /* number < 0 - local var */ else { /* number < 0 - local var */
number = (-number) - 1; number = (-number) - 1;
if (number < 10) if (number < 10)
code_opcode(SETLOCAL0 + number, -1); code_pop(SETLOCAL0 + number);
else { else {
code_opcode(SETLOCAL, -1); code_pop(SETLOCAL);
code_byte(number); code_byte(number);
} }
} }
@ -453,7 +474,7 @@ static int lua_codestore (int i, int left)
return left; return left;
} }
else { /* indexed var with values in between*/ else { /* indexed var with values in between*/
code_opcode(SETTABLE, -1); code_pop(SETTABLE);
code_byte(left+i); /* number of elements between table/index and value */ code_byte(left+i); /* number of elements between table/index and value */
return left+2; /* table/index are not poped, since they are not on top */ return left+2; /* table/index are not poped, since they are not on top */
} }
@ -485,7 +506,7 @@ static void code_shortcircuit (int pc, Byte jmp)
static void codereturn (void) static void codereturn (void)
{ {
code_opcode(RETCODE, 0); code_neutralop(RETCODE);
code_byte(currState->nlocalvar); code_byte(currState->nlocalvar);
currState->stacksize = currState->nlocalvar; currState->stacksize = currState->nlocalvar;
} }
@ -542,7 +563,7 @@ static void init_func (void)
static TProtoFunc *close_func (void) static TProtoFunc *close_func (void)
{ {
TProtoFunc *f = currState->f; TProtoFunc *f = currState->f;
code_opcode(ENDCODE, 0); code_neutralop(ENDCODE);
f->code[0] = currState->maxstacksize; f->code[0] = currState->maxstacksize;
f->code = luaM_reallocvector(f->code, currState->pc, Byte); f->code = luaM_reallocvector(f->code, currState->pc, Byte);
f->consts = luaM_reallocvector(f->consts, f->nconsts, TObject); f->consts = luaM_reallocvector(f->consts, f->nconsts, TObject);
@ -624,8 +645,7 @@ chunk : statlist ret
; ;
statlist : /* empty */ statlist : /* empty */
| statlist stat sc { if (currState->stacksize != currState->nlocalvar) | statlist stat sc
{ luaY_error("contagem"); exit(1); }}
; ;
sc : /* empty */ | ';' ; sc : /* empty */ | ';' ;
@ -707,7 +727,7 @@ ret : /* empty */
PrepJump : /* empty */ PrepJump : /* empty */
{ {
$$ = currState->pc; $$ = currState->pc;
code_opcode(0, 0); /* open space */ code_byte(0); /* open space */
code_word(0); code_word(0);
} }
; ;
@ -718,47 +738,35 @@ PrepJumpPop : PrepJump { $$ = $1; deltastack(-1); /* pop condition */ }
expr1 : expr { adjust_functioncall($1, 1); } expr1 : expr { adjust_functioncall($1, 1); }
; ;
expr : '(' expr ')' { $$ = $2; } expr : '(' expr ')' { $$ = $2; }
| expr1 EQ expr1 { code_opcode(EQOP, -1); $$ = 0; } | expr1 EQ expr1 { code_binop(EQOP); $$ = 0; }
| expr1 '<' expr1 { code_opcode(LTOP, -1); $$ = 0; } | expr1 '<' expr1 { code_binop(LTOP); $$ = 0; }
| expr1 '>' expr1 { code_opcode(GTOP, -1); $$ = 0; } | expr1 '>' expr1 { code_binop(GTOP); $$ = 0; }
| expr1 NE expr1 { code_opcode(NEQOP, -1); $$ = 0; } | expr1 NE expr1 { code_binop(NEQOP); $$ = 0; }
| expr1 LE expr1 { code_opcode(LEOP, -1); $$ = 0; } | expr1 LE expr1 { code_binop(LEOP); $$ = 0; }
| expr1 GE expr1 { code_opcode(GEOP, -1); $$ = 0; } | expr1 GE expr1 { code_binop(GEOP); $$ = 0; }
| expr1 '+' expr1 { code_opcode(ADDOP, -1); $$ = 0; } | expr1 '+' expr1 { code_binop(ADDOP); $$ = 0; }
| expr1 '-' expr1 { code_opcode(SUBOP, -1); $$ = 0; } | expr1 '-' expr1 { code_binop(SUBOP); $$ = 0; }
| expr1 '*' expr1 { code_opcode(MULTOP, -1); $$ = 0; } | expr1 '*' expr1 { code_binop(MULTOP); $$ = 0; }
| expr1 '/' expr1 { code_opcode(DIVOP, -1); $$ = 0; } | expr1 '/' expr1 { code_binop(DIVOP); $$ = 0; }
| expr1 '^' expr1 { code_opcode(POWOP, -1); $$ = 0; } | expr1 '^' expr1 { code_binop(POWOP); $$ = 0; }
| expr1 CONC expr1 { code_opcode(CONCOP, -1); $$ = 0; } | expr1 CONC expr1 { code_binop(CONCOP); $$ = 0; }
| '-' expr1 %prec UNARY { code_opcode(MINUSOP, 0); $$ = 0;} | '-' expr1 %prec UNARY { code_unop(MINUSOP); $$ = 0;}
| NOT expr1 { code_unop(NOTOP); $$ = 0;}
| table { $$ = 0; } | table { $$ = 0; }
| varexp { $$ = 0;} | varexp { $$ = 0;}
| NUMBER { code_number($1); $$ = 0; } | NUMBER { code_number($1); $$ = 0; }
| STRING | STRING { code_string($1); $$ = 0; }
{ | NIL {code_push(PUSHNIL); $$ = 0; }
code_string($1); | functioncall { $$ = $1; }
$$ = 0; | expr1 AND PrepJumpPop expr1 { code_shortcircuit($3, ONFJMP); $$ = 0; }
} | expr1 OR PrepJumpPop expr1 { code_shortcircuit($3, ONTJMP); $$ = 0; }
| NIL {code_opcode(PUSHNIL, 1); $$ = 0; }
| functioncall { $$ = $1; }
| NOT expr1 { code_opcode(NOTOP, 0); $$ = 0;}
| expr1 AND PrepJumpPop expr1
{
code_shortcircuit($3, ONFJMP);
$$ = 0;
}
| expr1 OR PrepJumpPop expr1
{
code_shortcircuit($3, ONTJMP);
$$ = 0;
}
| FUNCTION { init_func(); } body { func_onstack($3); $$ = 0; } | FUNCTION { init_func(); } body { func_onstack($3); $$ = 0; }
; ;
table : table :
{ {
code_opcode(CREATEARRAY, 1); code_push(CREATEARRAY);
$<vInt>$ = currState->pc; code_word(0); $<vInt>$ = currState->pc; code_word(0);
} }
'{' fieldlist '}' '{' fieldlist '}'
@ -779,7 +787,7 @@ functioncall : funcvalue funcParams
funcvalue : varexp { $$ = 0; } funcvalue : varexp { $$ = 0; }
| varexp ':' NAME | varexp ':' NAME
{ {
code_opcode(PUSHSELF, 1); code_push(PUSHSELF);
code_word(string_constant($3)); code_word(string_constant($3));
$$ = 1; $$ = 1;
} }

189
lvm.c
View File

@ -1,5 +1,5 @@
/* /*
** $Id: $ ** $Id: lvm.c,v 1.1 1997/09/16 19:25:59 roberto Exp roberto $
** Lua virtual machine ** Lua virtual machine
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -22,7 +22,9 @@
#include "lvm.h" #include "lvm.h"
#define get_word(w,pc) {w=*pc+(*(pc+1)<<8); pc+=2;} #define get_prevword(pc) (*(pc-2)+(*(pc-1)<<8))
#define get_word(pc) (pc+=2, get_prevword(pc))
#define skip_word(pc) {pc+=2;}
/* Extra stack to run a function: LUA_T_LINE(1), TM calls(2), ... */ /* Extra stack to run a function: LUA_T_LINE(1), TM calls(2), ... */
@ -159,15 +161,13 @@ void luaV_getglobal (Word n)
TObject *value = &luaG_global[n].object; TObject *value = &luaG_global[n].object;
TObject *im = luaT_getimbyObj(value, IM_GETGLOBAL); TObject *im = luaT_getimbyObj(value, IM_GETGLOBAL);
if (ttype(im) == LUA_T_NIL) { /* default behavior */ if (ttype(im) == LUA_T_NIL) { /* default behavior */
*luaD_stack.top = *value; *luaD_stack.top++ = *value;
luaD_stack.top++;
} }
else { else {
ttype(luaD_stack.top) = LUA_T_STRING; ttype(luaD_stack.top) = LUA_T_STRING;
tsvalue(luaD_stack.top) = luaG_global[n].varname; tsvalue(luaD_stack.top) = luaG_global[n].varname;
luaD_stack.top++; luaD_stack.top++;
*luaD_stack.top = *value; *luaD_stack.top++ = *value;
luaD_stack.top++;
luaD_callTM(im, 2, 1); luaD_callTM(im, 2, 1);
} }
} }
@ -184,10 +184,8 @@ void luaV_setglobal (Word n)
TObject newvalue = *(luaD_stack.top-1); TObject newvalue = *(luaD_stack.top-1);
ttype(luaD_stack.top-1) = LUA_T_STRING; ttype(luaD_stack.top-1) = LUA_T_STRING;
tsvalue(luaD_stack.top-1) = luaG_global[n].varname; tsvalue(luaD_stack.top-1) = luaG_global[n].varname;
*luaD_stack.top = *oldvalue; *luaD_stack.top++ = *oldvalue;
luaD_stack.top++; *luaD_stack.top++ = newvalue;
*luaD_stack.top = newvalue;
luaD_stack.top++;
luaD_callTM(im, 3, 0); luaD_callTM(im, 3, 0);
} }
} }
@ -266,8 +264,7 @@ static void adjust_varargs (StkId first_extra_arg)
luaV_pack(first_extra_arg, luaV_pack(first_extra_arg,
(luaD_stack.top-luaD_stack.stack)-first_extra_arg, &arg); (luaD_stack.top-luaD_stack.stack)-first_extra_arg, &arg);
luaD_adjusttop(first_extra_arg); luaD_adjusttop(first_extra_arg);
*luaD_stack.top = arg; *luaD_stack.top++ = arg;
luaD_stack.top++;
} }
@ -289,8 +286,7 @@ StkId luaV_execute (Closure *cl, StkId base)
switch (opcode = (OpCode)*pc++) { switch (opcode = (OpCode)*pc++) {
case PUSHNIL: case PUSHNIL:
ttype(luaD_stack.top) = LUA_T_NIL; ttype(luaD_stack.top++) = LUA_T_NIL;
luaD_stack.top++;
break; break;
case PUSHNILS: { case PUSHNILS: {
@ -312,72 +308,55 @@ StkId luaV_execute (Closure *cl, StkId base)
luaD_stack.top++; luaD_stack.top++;
break; break;
case PUSHWORD: { case PUSHWORD:
Word w;
get_word(w,pc);
ttype(luaD_stack.top) = LUA_T_NUMBER; ttype(luaD_stack.top) = LUA_T_NUMBER;
nvalue(luaD_stack.top) = w; nvalue(luaD_stack.top) = get_word(pc);
luaD_stack.top++; luaD_stack.top++;
break; break;
}
case PUSHLOCAL0: case PUSHLOCAL1: case PUSHLOCAL2: case PUSHLOCAL0: case PUSHLOCAL1: case PUSHLOCAL2:
case PUSHLOCAL3: case PUSHLOCAL4: case PUSHLOCAL5: case PUSHLOCAL3: case PUSHLOCAL4: case PUSHLOCAL5:
case PUSHLOCAL6: case PUSHLOCAL7: case PUSHLOCAL8: case PUSHLOCAL6: case PUSHLOCAL7: case PUSHLOCAL8:
case PUSHLOCAL9: case PUSHLOCAL9:
*luaD_stack.top = *((luaD_stack.stack+base) + (int)(opcode-PUSHLOCAL0)); *luaD_stack.top++ =
luaD_stack.top++; *((luaD_stack.stack+base) + (int)(opcode-PUSHLOCAL0));
break; break;
case PUSHLOCAL: case PUSHLOCAL:
*luaD_stack.top = *((luaD_stack.stack+base) + (*pc++)); *luaD_stack.top++ = *((luaD_stack.stack+base) + (*pc++));
luaD_stack.top++;
break; break;
case PUSHGLOBAL: { case PUSHGLOBAL:
Word w; luaV_getglobal(get_word(pc));
get_word(w,pc);
luaV_getglobal(w);
break; break;
}
case PUSHTABLE: case GETTABLE:
luaV_gettable(); luaV_gettable();
break; break;
case PUSHSELF: { case PUSHSELF: {
TObject receiver = *(luaD_stack.top-1); TObject receiver = *(luaD_stack.top-1);
Word w; *luaD_stack.top++ = func->consts[get_word(pc)];
get_word(w,pc);
*luaD_stack.top = func->consts[w];
luaD_stack.top++;
luaV_gettable(); luaV_gettable();
*luaD_stack.top = receiver; *luaD_stack.top++ = receiver;
luaD_stack.top++;
break; break;
} }
case PUSHCONSTANTB: { case PUSHCONSTANTB:
*luaD_stack.top = func->consts[*pc++]; *luaD_stack.top++ = func->consts[*pc++];
luaD_stack.top++;
break; break;
}
case PUSHCONSTANT: { case PUSHCONSTANT:
Word w; *luaD_stack.top++ = func->consts[get_word(pc)];
get_word(w,pc);
*luaD_stack.top = func->consts[w];
luaD_stack.top++;
break; break;
}
case PUSHUPVALUE0: case PUSHUPVALUE0:
case PUSHUPVALUE: { *luaD_stack.top++ = cl->consts[1];
int i = (opcode == PUSHUPVALUE0) ? 0 : *pc++; break;
*luaD_stack.top = cl->consts[i+1];
luaD_stack.top++; case PUSHUPVALUE:
*luaD_stack.top++ = cl->consts[(*pc++)+1];
break; break;
}
case SETLOCAL0: case SETLOCAL1: case SETLOCAL2: case SETLOCAL0: case SETLOCAL1: case SETLOCAL2:
case SETLOCAL3: case SETLOCAL4: case SETLOCAL5: case SETLOCAL3: case SETLOCAL4: case SETLOCAL5:
@ -390,36 +369,28 @@ StkId luaV_execute (Closure *cl, StkId base)
case SETLOCAL: case SETLOCAL:
*((luaD_stack.stack+base) + (*pc++)) = *(--luaD_stack.top); break; *((luaD_stack.stack+base) + (*pc++)) = *(--luaD_stack.top); break;
case SETGLOBAL: { case SETGLOBAL:
Word w; luaV_setglobal(get_word(pc));
get_word(w,pc);
luaV_setglobal(w);
break; break;
}
case SETTABLE0: case SETTABLE0:
luaV_settable(luaD_stack.top-3, 1); luaV_settable(luaD_stack.top-3, 1);
break; break;
case SETTABLE: { case SETTABLE:
int n = *pc++; luaV_settable(luaD_stack.top-3-(*pc++), 2);
luaV_settable(luaD_stack.top-3-n, 2);
break; break;
}
case SETLIST0: case SETLIST0:
case SETLIST: { case SETLIST: {
int m, n; int m = (opcode == SETLIST0) ? 0 : *(pc++) * LFIELDS_PER_FLUSH;
TObject *arr; int n = *(pc++);
if (opcode == SETLIST0) m = 0; TObject *arr = luaD_stack.top-n-1;
else m = *(pc++) * LFIELDS_PER_FLUSH; for (; n; n--) {
n = *(pc++); ttype(luaD_stack.top) = LUA_T_NUMBER;
arr = luaD_stack.top-n-1; nvalue(luaD_stack.top) = n+m;
while (n) {
ttype(luaD_stack.top) = LUA_T_NUMBER; nvalue(luaD_stack.top) = n+m;
*(luaH_set (avalue(arr), luaD_stack.top)) = *(luaD_stack.top-1); *(luaH_set (avalue(arr), luaD_stack.top)) = *(luaD_stack.top-1);
luaD_stack.top--; luaD_stack.top--;
n--;
} }
break; break;
} }
@ -447,19 +418,16 @@ StkId luaV_execute (Closure *cl, StkId base)
adjust_varargs(base + *(pc++)); adjust_varargs(base + *(pc++));
break; break;
case CREATEARRAY: { case CREATEARRAY:
Word size;
luaC_checkGC(); luaC_checkGC();
get_word(size,pc); avalue(luaD_stack.top) = luaH_new(get_word(pc));
avalue(luaD_stack.top) = luaH_new(size);
ttype(luaD_stack.top) = LUA_T_ARRAY; ttype(luaD_stack.top) = LUA_T_ARRAY;
luaD_stack.top++; luaD_stack.top++;
break; break;
}
case EQOP: case NEQOP: { case EQOP: case NEQOP: {
int res = luaO_equalObj(luaD_stack.top-2, luaD_stack.top-1); int res = luaO_equalObj(luaD_stack.top-2, luaD_stack.top-1);
--luaD_stack.top; luaD_stack.top--;
if (opcode == NEQOP) res = !res; if (opcode == NEQOP) res = !res;
ttype(luaD_stack.top-1) = res ? LUA_T_NUMBER : LUA_T_NIL; ttype(luaD_stack.top-1) = res ? LUA_T_NUMBER : LUA_T_NIL;
nvalue(luaD_stack.top-1) = 1; nvalue(luaD_stack.top-1) = 1;
@ -563,51 +531,43 @@ StkId luaV_execute (Closure *cl, StkId base)
nvalue(luaD_stack.top-1) = 1; nvalue(luaD_stack.top-1) = 1;
break; break;
case ONTJMP: { case ONTJMP:
Word w; skip_word(pc);
get_word(w,pc); if (ttype(luaD_stack.top-1) != LUA_T_NIL)
if (ttype(luaD_stack.top-1) != LUA_T_NIL) pc += w; pc += get_prevword(pc);
else luaD_stack.top--; else
} luaD_stack.top--;
break;
case ONFJMP: {
Word w;
get_word(w,pc);
if (ttype(luaD_stack.top-1) == LUA_T_NIL) pc += w;
else luaD_stack.top--;
break; break;
}
case JMP: { case ONFJMP:
Word w; skip_word(pc);
get_word(w,pc); if (ttype(luaD_stack.top-1) == LUA_T_NIL)
pc += w; pc += get_prevword(pc);
else
luaD_stack.top--;
break; break;
}
case UPJMP: { case JMP:
Word w; skip_word(pc);
get_word(w,pc); pc += get_prevword(pc);
pc -= w;
break; break;
}
case IFFJMP: { case UPJMP:
Word w; skip_word(pc);
get_word(w,pc); pc -= get_prevword(pc);
luaD_stack.top--;
if (ttype(luaD_stack.top) == LUA_T_NIL) pc += w;
break; break;
}
case IFFUPJMP: { case IFFJMP:
Word w; skip_word(pc);
get_word(w,pc); if (ttype(--luaD_stack.top) == LUA_T_NIL)
luaD_stack.top--; pc += get_prevword(pc);
if (ttype(luaD_stack.top) == LUA_T_NIL) pc -= w; break;
case IFFUPJMP:
skip_word(pc);
if (ttype(--luaD_stack.top) == LUA_T_NIL)
pc -= get_prevword(pc);
break; break;
}
case CLOSURE: case CLOSURE:
luaV_closure(); luaV_closure();
@ -615,10 +575,8 @@ StkId luaV_execute (Closure *cl, StkId base)
break; break;
case CALLFUNC: { case CALLFUNC: {
int nParams = *pc++; StkId newBase = (luaD_stack.top-luaD_stack.stack)-(*pc++);
int nResults = *pc++; luaD_call(newBase, *pc++);
StkId newBase = (luaD_stack.top-luaD_stack.stack)-nParams;
luaD_call(newBase, nResults);
break; break;
} }
@ -631,8 +589,7 @@ StkId luaV_execute (Closure *cl, StkId base)
return (base + ((opcode==RETCODE) ? *pc : 0)); return (base + ((opcode==RETCODE) ? *pc : 0));
case SETLINE: { case SETLINE: {
Word line; int line = get_word(pc);
get_word(line,pc);
if ((luaD_stack.stack+base-1)->ttype != LUA_T_LINE) { if ((luaD_stack.stack+base-1)->ttype != LUA_T_LINE) {
/* open space for LINE value */ /* open space for LINE value */
luaD_openstack((luaD_stack.top-luaD_stack.stack)-base); luaD_openstack((luaD_stack.top-luaD_stack.stack)-base);