1
0
mirror of https://github.com/lua/lua.git synced 2025-01-14 05:43:00 +08:00

better way to cope with opcode variants

This commit is contained in:
Roberto Ierusalimschy 1997-09-22 17:53:20 -03:00
parent 2079cfe8fa
commit d6c867ea50
3 changed files with 162 additions and 179 deletions

View File

@ -1,5 +1,5 @@
/* /*
** $Id: lopcodes.h,v 1.2 1997/09/19 18:40:32 roberto Exp roberto $ ** $Id: lopcodes.h,v 1.3 1997/09/19 21:17:52 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
*/ */
@ -8,6 +8,13 @@
#define lopcodes_h #define lopcodes_h
/*
** NOTICE: variants of the same opcode (like PUSH0, PUSHBYTE, PUSHWORD) must
** be consecutive: First, those with built-in parameters, then with byte
** parameter and last with word parameter.
*/
typedef enum { typedef enum {
/* name parm before after side effect /* name parm before after side effect
-----------------------------------------------------------------------------*/ -----------------------------------------------------------------------------*/
@ -15,15 +22,19 @@ ENDCODE,
PUSHNIL,/* - nil */ PUSHNIL,/* - nil */
PUSHNILS,/* b - nil_1...nil_b */ PUSHNILS,/* b - nil_1...nil_b */
PUSH0,/* - 0.0 */ PUSH0,/* - 0.0 */
PUSH1,/* - 1.0 */ PUSH1,/* - 1.0 */
PUSH2,/* - 2.0 */ PUSH2,/* - 2.0 */
PUSHBYTE,/* b - (float)b */ PUSHBYTE,/* b - (float)b */
PUSHWORD,/* w - (float)w */ PUSHWORD,/* w - (float)w */
PUSHCONSTANTB,/*b - CNST[b] */ PUSHCONSTANTB,/*b - CNST[b] */
PUSHCONSTANT,/* w - CNST[w] */ PUSHCONSTANT,/* w - CNST[w] */
PUSHUPVALUE0, PUSHUPVALUE0,
PUSHUPVALUE,/* b - Closure[b] */ PUSHUPVALUE,/* b - Closure[b] */
PUSHLOCAL0,/* - LOC[0] */ PUSHLOCAL0,/* - LOC[0] */
PUSHLOCAL1,/* - LOC[1] */ PUSHLOCAL1,/* - LOC[1] */
PUSHLOCAL2,/* - LOC[2] */ PUSHLOCAL2,/* - LOC[2] */
@ -35,10 +46,15 @@ PUSHLOCAL7,/* - LOC[7] */
PUSHLOCAL8,/* - LOC[8] */ PUSHLOCAL8,/* - LOC[8] */
PUSHLOCAL9,/* - LOC[9] */ PUSHLOCAL9,/* - LOC[9] */
PUSHLOCAL,/* b - LOC[b] */ PUSHLOCAL,/* b - LOC[b] */
PUSHGLOBALB,/* b - VAR[CNST[b]] */
PUSHGLOBAL,/* w - VAR[CNST[w]] */ GETGLOBALB,/* b - VAR[CNST[b]] */
GETGLOBAL,/* w - VAR[CNST[w]] */
GETTABLE,/* i t t[i] */ GETTABLE,/* i t t[i] */
PUSHSELFB,/* b t t t[CNST[b]] */
PUSHSELF,/* w t t t[CNST[w]] */ PUSHSELF,/* w t t t[CNST[w]] */
CREATEARRAY,/* w - newarray(size = w) */ CREATEARRAY,/* w - newarray(size = w) */
SETLOCAL0,/* x - LOC[0]=x */ SETLOCAL0,/* x - LOC[0]=x */
@ -52,10 +68,13 @@ SETLOCAL7,/* x - LOC[7]=x */
SETLOCAL8,/* x - LOC[8]=x */ SETLOCAL8,/* x - LOC[8]=x */
SETLOCAL9,/* x - LOC[9]=x */ SETLOCAL9,/* x - LOC[9]=x */
SETLOCAL,/* b x - LOC[b]=x */ SETLOCAL,/* b x - LOC[b]=x */
SETGLOBALB,/* b x - VAR[CNST[b]]=x */ SETGLOBALB,/* b x - VAR[CNST[b]]=x */
SETGLOBAL,/* w x - VAR[CNST[w]]=x */ SETGLOBAL,/* w x - VAR[CNST[w]]=x */
SETTABLE0,/* v i t - t[i]=v */ SETTABLE0,/* v i t - t[i]=v */
SETTABLE,/* b v a_b...a_1 i t a_b...a_1 i t t[i]=v */ SETTABLE,/* b v a_b...a_1 i t a_b...a_1 i t t[i]=v */
SETLIST0,/* b v_b...v_1 t - t[i]=v_i */ SETLIST0,/* b v_b...v_1 t - t[i]=v_i */
SETLIST,/* b c v_b...v_1 t - t[i+c*FPF]=v_i */ SETLIST,/* b c v_b...v_1 t - t[i+c*FPF]=v_i */
SETMAP,/* b v_b k_b ...v_1 k_1 t t t[k_i]=v_i */ SETMAP,/* b v_b k_b ...v_1 k_1 t t t[k_i]=v_i */
@ -82,10 +101,14 @@ UPJMP,/* w - - PC-=w */
IFFJMP,/* w x - (x==nil)? PC+=w */ IFFJMP,/* w x - (x==nil)? PC+=w */
IFFUPJMP,/* w x - (x==nil)? PC-=w */ IFFUPJMP,/* w x - (x==nil)? PC-=w */
CLOSURE,/* f v_1...v_n c(f) */ CLOSUREB,/* b v_1...v_n c(CNST[b]) */
CLOSURE,/* w v_1...v_n c(CNST[w]) */
CALLFUNC,/* b c v_b...v_1 f r_c...r_1 f(v1,...,v_b) */ CALLFUNC,/* b c v_b...v_1 f r_c...r_1 f(v1,...,v_b) */
RETCODE,/* b - - */ RETCODE,/* b - - */
SETLINE,/* w - - LINE=w */ SETLINE,/* w - - LINE=w */
POP1,/* - - TOP-=1 */
POP2,/* - - TOP-=2 */
POPS,/* b - - TOP-=b */ POPS,/* b - - TOP-=b */
ARGS,/* b - - TOP=BASE+b */ ARGS,/* b - - TOP=BASE+b */
VARARGS/* b v_x...v_1 {v_1...v_x;n=x} TOP=BASE+b+1 */ VARARGS/* b v_x...v_1 {v_1...v_x;n=x} TOP=BASE+b+1 */

180
lua.stx
View File

@ -1,6 +1,6 @@
%{ %{
/* /*
** $Id: lua.stx,v 1.2 1997/09/19 18:40:32 roberto Exp roberto $ ** $Id: lua.stx,v 1.3 1997/09/19 21:17:52 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
*/ */
@ -94,6 +94,22 @@ static void code_byte (Byte c)
} }
static void code_word_at (int pc, int n)
{
Word w = n;
if (w != n)
luaY_error("block too big");
currState->f->code[pc] = n&0xFF;
currState->f->code[pc+1] = n>>8;
}
static void code_word (int n)
{
code_byte(n&0xFF);
code_byte(n>>8);
}
static void deltastack (int delta) static void deltastack (int delta)
{ {
currState->stacksize += delta; currState->stacksize += delta;
@ -112,9 +128,25 @@ static void code_opcode (OpCode op, int delta)
} }
static void code_push (OpCode op) static void code_opborw(OpCode opbyte, int arg, int delta)
{ {
code_opcode(op, 1); if (arg <= 255) {
code_opcode(opbyte, delta);
code_byte(arg);
}
else {
code_opcode(opbyte+1, delta);
code_word(arg);
}
}
static void code_oparg (OpCode firstop, OpCode opbyte, int arg, int delta)
{
if (firstop+arg < opbyte)
code_opcode(firstop+arg, delta);
else
code_opborw(opbyte, arg, delta);
} }
@ -133,31 +165,9 @@ static void code_pop (OpCode op)
#define code_unop(op) code_neutralop(op) #define code_unop(op) code_neutralop(op)
static void code_word_at (int pc, int n)
{
Word w = n;
if (w != n)
luaY_error("block too big");
currState->f->code[pc] = n&0xFF;
currState->f->code[pc+1] = n>>8;
}
static void code_word (int n)
{
code_byte(n&0xFF);
code_byte(n>>8);
}
static void code_constant (int c) static void code_constant (int c)
{ {
if (c <= 255) { code_opborw(PUSHCONSTANTB, c, 1);
code_push(PUSHCONSTANTB);
code_byte(c);
}
else {
code_push(PUSHCONSTANT);
code_word(c);
}
} }
@ -216,18 +226,8 @@ static int real_constant (real r)
static void code_number (real f) 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 */ code_oparg(PUSH0, PUSHBYTE, i, 1); /* f has an (short) integer value */
if (i <= 2) code_push(PUSH0 + i);
else if (i <= 255) {
code_push(PUSHBYTE);
code_byte(i);
}
else {
code_push(PUSHWORD);
code_word(i);
}
}
else else
code_constant(real_constant(f)); code_constant(real_constant(f));
} }
@ -344,12 +344,7 @@ static void pushupvalue (TaggedString *n)
if (aux_localname(n, currState) >= 0) if (aux_localname(n, currState) >= 0)
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) code_oparg(PUSHUPVALUE0, PUSHUPVALUE, i, 1);
code_push(PUSHUPVALUE0);
else {
code_push(PUSHUPVALUE);
code_byte(i);
}
} }
@ -366,18 +361,10 @@ void luaY_codedebugline (int line)
static void adjuststack (int n) static void adjuststack (int n)
{ {
if (n > 0) { if (n > 0)
code_opcode(POPS, -n); code_oparg(POP1-1, POPS, n, -n); /* POP1-1 = POP0 */
code_byte(n); else if (n < 0)
} code_oparg(PUSHNIL-1, PUSHNILS, -n, -n); /* PUSHNIL1-1 = PUSHNIL0 */
else if (n < 0) {
if (n == -1)
code_push(PUSHNIL);
else {
code_opcode(PUSHNILS, -n);
code_byte(-n);
}
}
} }
@ -426,29 +413,12 @@ 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 */
number--; code_opborw(GETGLOBALB, number-1, 1);
if (number <= 255) { else if (number < 0) /* local var */
code_push(PUSHGLOBALB); code_oparg(PUSHLOCAL0, PUSHLOCAL, (-number)-1, 1);
code_byte(number); else
}
else {
code_push(PUSHGLOBAL);
code_word(number);
}
}
else if (number < 0) { /* local var */
number = (-number) - 1;
if (number < 10)
code_push(PUSHLOCAL0 + number);
else {
code_push(PUSHLOCAL);
code_byte(number);
}
}
else {
code_pop(GETTABLE); code_pop(GETTABLE);
}
} }
@ -456,26 +426,10 @@ 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 */
number--; code_opborw(SETGLOBALB, number-1, -1);
if (number <= 255) { else /* number < 0 - local var */
code_pop(SETGLOBALB); code_oparg(SETLOCAL0, SETLOCAL, (-number)-1, -1);
code_byte(number);
}
else {
code_pop(SETGLOBAL);
code_word(number);
}
}
else { /* number < 0 - local var */
number = (-number) - 1;
if (number < 10)
code_pop(SETLOCAL0 + number);
else {
code_pop(SETLOCAL);
code_byte(number);
}
}
} }
@ -535,8 +489,7 @@ static void func_onstack (TProtoFunc *f)
currState->f->consts[c].value.tf = (currState+1)->f; currState->f->consts[c].value.tf = (currState+1)->f;
for (i=0; i<nupvalues; i++) for (i=0; i<nupvalues; i++)
lua_pushvar((currState+1)->upvalues[i]); lua_pushvar((currState+1)->upvalues[i]);
code_constant(c); code_opborw(CLOSUREB, c, 1-nupvalues);
code_opcode(CLOSURE, -nupvalues);
} }
@ -771,7 +724,7 @@ expr : '(' expr ')' { $$ = $2; }
| varexp { $$ = 0;} | varexp { $$ = 0;}
| NUMBER { code_number($1); $$ = 0; } | NUMBER { code_number($1); $$ = 0; }
| STRING { code_string($1); $$ = 0; } | STRING { code_string($1); $$ = 0; }
| NIL {code_push(PUSHNIL); $$ = 0; } | NIL {code_opcode(PUSHNIL, 1); $$ = 0; }
| functioncall { $$ = $1; } | functioncall { $$ = $1; }
| expr1 AND PrepJumpPop expr1 { code_shortcircuit($3, ONFJMP); $$ = 0; } | expr1 AND PrepJumpPop expr1 { code_shortcircuit($3, ONFJMP); $$ = 0; }
| expr1 OR PrepJumpPop expr1 { code_shortcircuit($3, ONTJMP); $$ = 0; } | expr1 OR PrepJumpPop expr1 { code_shortcircuit($3, ONTJMP); $$ = 0; }
@ -779,14 +732,9 @@ expr : '(' expr ')' { $$ = $2; }
; ;
table : table :
{ { code_opcode(CREATEARRAY, 1); $<vInt>$ = currState->pc; code_word(0); }
code_push(CREATEARRAY); '{' fieldlist '}'
$<vInt>$ = currState->pc; code_word(0); { code_word_at($<vInt>1, $3); }
}
'{' fieldlist '}'
{
code_word_at($<vInt>1, $3);
}
; ;
functioncall : funcvalue funcParams functioncall : funcvalue funcParams
@ -801,8 +749,7 @@ functioncall : funcvalue funcParams
funcvalue : varexp { $$ = 0; } funcvalue : varexp { $$ = 0; }
| varexp ':' NAME | varexp ':' NAME
{ {
code_push(PUSHSELF); code_opborw(PUSHSELFB, string_constant($3, currState), 1);
code_word(string_constant($3, currState));
$$ = 1; $$ = 1;
} }
; ;
@ -909,15 +856,8 @@ varlist1 : var
; ;
var : singlevar { $$ = $1; } var : singlevar { $$ = $1; }
| varexp '[' expr1 ']' | varexp '[' expr1 ']' { $$ = 0; } /* indexed variable */
{ | varexp '.' NAME { code_string($3); $$ = 0; }/* ind. var. */
$$ = 0; /* indexed variable */
}
| varexp '.' NAME
{
code_string($3);
$$ = 0; /* indexed variable */
}
; ;
singlevar : NAME { $$ = singlevar($1, currState); } singlevar : NAME { $$ = singlevar($1, currState); }

130
lvm.c
View File

@ -1,5 +1,5 @@
/* /*
** $Id: lvm.c,v 1.2 1997/09/19 18:40:32 roberto Exp roberto $ ** $Id: lvm.c,v 1.3 1997/09/19 21:17:52 roberto Exp roberto $
** Lua virtual machine ** Lua virtual machine
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -28,7 +28,7 @@
/* 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), ... */
#define EXTRA_STACK 4 #define EXTRA_STACK 5
@ -276,14 +276,14 @@ static void adjust_varargs (StkId first_extra_arg)
*/ */
StkId luaV_execute (Closure *cl, StkId base) StkId luaV_execute (Closure *cl, StkId base)
{ {
TProtoFunc *func = cl->consts[0].value.tf; Byte *pc = cl->consts[0].value.tf->code;
Byte *pc = func->code; TObject *consts = cl->consts[0].value.tf->consts;
if (lua_callhook) if (lua_callhook)
luaD_callHook(base, LUA_T_MARK, 0); luaD_callHook(base, LUA_T_MARK, 0);
luaD_checkstack((*pc++)+EXTRA_STACK); luaD_checkstack((*pc++)+EXTRA_STACK);
while (1) { while (1) {
OpCode opcode; int aux;
switch (opcode = (OpCode)*pc++) { switch ((OpCode)(aux = *pc++)) {
case PUSHNIL: case PUSHNIL:
ttype(luaD_stack.top++) = LUA_T_NIL; ttype(luaD_stack.top++) = LUA_T_NIL;
@ -296,89 +296,95 @@ StkId luaV_execute (Closure *cl, StkId base)
break; break;
} }
case PUSH0: case PUSH1: case PUSH2:
ttype(luaD_stack.top) = LUA_T_NUMBER;
nvalue(luaD_stack.top) = opcode-PUSH0;
luaD_stack.top++;
break;
case PUSHBYTE: case PUSHBYTE:
ttype(luaD_stack.top) = LUA_T_NUMBER; aux = *pc++; goto pushnumber;
nvalue(luaD_stack.top) = *pc++;
luaD_stack.top++;
break;
case PUSHWORD: case PUSHWORD:
aux = get_word(pc); goto pushnumber;
case PUSH0: case PUSH1: case PUSH2:
aux -= PUSH0;
pushnumber:
ttype(luaD_stack.top) = LUA_T_NUMBER; ttype(luaD_stack.top) = LUA_T_NUMBER;
nvalue(luaD_stack.top) = get_word(pc); nvalue(luaD_stack.top) = aux;
luaD_stack.top++; luaD_stack.top++;
break; break;
case PUSHLOCAL:
aux = *pc++; goto pushlocal;
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++ = aux -= PUSHLOCAL0;
*((luaD_stack.stack+base) + (int)(opcode-PUSHLOCAL0)); pushlocal:
*luaD_stack.top++ = *((luaD_stack.stack+base) + aux);
break; break;
case PUSHLOCAL: case GETGLOBAL:
*luaD_stack.top++ = *((luaD_stack.stack+base) + (*pc++)); aux = get_word(pc); goto getglobal;
break;
case PUSHGLOBALB: case GETGLOBALB:
luaV_getglobal(luaG_findsymbol(tsvalue(&func->consts[*pc++]))); aux = *pc++;
break; getglobal:
luaV_getglobal(luaG_findsymbol(tsvalue(&consts[aux])));
case PUSHGLOBAL:
luaV_getglobal(luaG_findsymbol(tsvalue(&func->consts[get_word(pc)])));
break; break;
case GETTABLE: case GETTABLE:
luaV_gettable(); luaV_gettable();
break; break;
case PUSHSELF: { case PUSHSELF:
aux = get_word(pc); goto pushself;
case PUSHSELFB:
aux = *pc++;
pushself: {
TObject receiver = *(luaD_stack.top-1); TObject receiver = *(luaD_stack.top-1);
*luaD_stack.top++ = func->consts[get_word(pc)]; *luaD_stack.top++ = consts[aux];
luaV_gettable(); luaV_gettable();
*luaD_stack.top++ = receiver; *luaD_stack.top++ = receiver;
break; break;
} }
case PUSHCONSTANTB:
*luaD_stack.top++ = func->consts[*pc++];
break;
case PUSHCONSTANT: case PUSHCONSTANT:
*luaD_stack.top++ = func->consts[get_word(pc)]; aux = get_word(pc); goto pushconstant;
break;
case PUSHUPVALUE0: case PUSHCONSTANTB:
*luaD_stack.top++ = cl->consts[1]; aux = *pc++;
pushconstant:
*luaD_stack.top++ = consts[aux];
break; break;
case PUSHUPVALUE: case PUSHUPVALUE:
*luaD_stack.top++ = cl->consts[(*pc++)+1]; aux = *pc++; goto pushupvalue;
case PUSHUPVALUE0:
aux = 0;
pushupvalue:
*luaD_stack.top++ = cl->consts[aux+1];
break; break;
case SETLOCAL:
aux = *pc++; goto setlocal;
case SETLOCAL0: case SETLOCAL1: case SETLOCAL2: case SETLOCAL0: case SETLOCAL1: case SETLOCAL2:
case SETLOCAL3: case SETLOCAL4: case SETLOCAL5: case SETLOCAL3: case SETLOCAL4: case SETLOCAL5:
case SETLOCAL6: case SETLOCAL7: case SETLOCAL8: case SETLOCAL6: case SETLOCAL7: case SETLOCAL8:
case SETLOCAL9: case SETLOCAL9:
*((luaD_stack.stack+base) + (int)(opcode-SETLOCAL0)) = aux -= SETLOCAL0;
*(--luaD_stack.top); setlocal:
break; *((luaD_stack.stack+base) + aux) = *(--luaD_stack.top);
case SETLOCAL:
*((luaD_stack.stack+base) + (*pc++)) = *(--luaD_stack.top); break;
case SETGLOBALB:
luaV_setglobal(luaG_findsymbol(tsvalue(&func->consts[*pc++])));
break; break;
case SETGLOBAL: case SETGLOBAL:
luaV_setglobal(luaG_findsymbol(tsvalue(&func->consts[get_word(pc)]))); aux = get_word(pc); goto setglobal;
case SETGLOBALB:
aux = *pc++;
setglobal:
luaV_setglobal(luaG_findsymbol(tsvalue(&consts[aux])));
break; break;
case SETTABLE0: case SETTABLE0:
@ -389,14 +395,17 @@ StkId luaV_execute (Closure *cl, StkId base)
luaV_settable(luaD_stack.top-3-(*pc++), 2); luaV_settable(luaD_stack.top-3-(*pc++), 2);
break; break;
case SETLIST:
aux = *(pc++) * LFIELDS_PER_FLUSH; goto setlist;
case SETLIST0: case SETLIST0:
case SETLIST: { aux = 0;
int m = (opcode == SETLIST0) ? 0 : *(pc++) * LFIELDS_PER_FLUSH; setlist: {
int n = *(pc++); int n = *(pc++);
TObject *arr = luaD_stack.top-n-1; TObject *arr = luaD_stack.top-n-1;
for (; n; n--) { for (; n; n--) {
ttype(luaD_stack.top) = LUA_T_NUMBER; ttype(luaD_stack.top) = LUA_T_NUMBER;
nvalue(luaD_stack.top) = n+m; nvalue(luaD_stack.top) = n+aux;
*(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--;
} }
@ -414,7 +423,12 @@ StkId luaV_execute (Closure *cl, StkId base)
} }
case POPS: case POPS:
luaD_stack.top -= *(pc++); aux = *pc++; goto pop;
case POP1: case POP2:
aux -= (POP1-1);
pop:
luaD_stack.top -= aux;
break; break;
case ARGS: case ARGS:
@ -436,7 +450,7 @@ StkId luaV_execute (Closure *cl, StkId base)
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 (aux == 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;
break; break;
@ -578,6 +592,12 @@ StkId luaV_execute (Closure *cl, StkId base)
break; break;
case CLOSURE: case CLOSURE:
aux = get_word(pc); goto closure;
case CLOSUREB:
aux = *pc++;
closure:
*luaD_stack.top++ = consts[aux];
luaV_closure(); luaV_closure();
luaC_checkGC(); luaC_checkGC();
break; break;
@ -594,7 +614,7 @@ StkId luaV_execute (Closure *cl, StkId base)
case RETCODE: case RETCODE:
if (lua_callhook) if (lua_callhook)
luaD_callHook(base, LUA_T_MARK, 1); luaD_callHook(base, LUA_T_MARK, 1);
return (base + ((opcode==RETCODE) ? *pc : 0)); return (base + ((aux==RETCODE) ? *pc : 0));
case SETLINE: { case SETLINE: {
int line = get_word(pc); int line = get_word(pc);