new version for INSTRUCTION formats
This commit is contained in:
16
lobject.h
16
lobject.h
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lobject.h,v 1.45 2000/01/28 16:53:00 roberto Exp roberto $
|
** $Id: lobject.h,v 1.46 2000/02/11 16:52:54 roberto Exp roberto $
|
||||||
** Type definitions for Lua objects
|
** Type definitions for Lua objects
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -36,11 +36,14 @@
|
|||||||
#define LUA_NUM_TYPE double
|
#define LUA_NUM_TYPE double
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
typedef LUA_NUM_TYPE real;
|
typedef LUA_NUM_TYPE real;
|
||||||
|
|
||||||
#define Byte lua_Byte /* some systems have Byte as a predefined type */
|
|
||||||
typedef unsigned char Byte; /* unsigned 8 bits */
|
/*
|
||||||
|
** type for virtual-machine instructions
|
||||||
|
** must be an unsigned with 4 bytes (see details in lopcodes.h)
|
||||||
|
*/
|
||||||
|
typedef unsigned long Instruction;
|
||||||
|
|
||||||
|
|
||||||
#define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */
|
#define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */
|
||||||
@@ -157,9 +160,12 @@ typedef struct TProtoFunc {
|
|||||||
int nknum; /* size of `knum' */
|
int nknum; /* size of `knum' */
|
||||||
struct TProtoFunc **kproto; /* functions defined inside the function */
|
struct TProtoFunc **kproto; /* functions defined inside the function */
|
||||||
int nkproto; /* size of `kproto' */
|
int nkproto; /* size of `kproto' */
|
||||||
Byte *code; /* ends with opcode ENDCODE */
|
Instruction *code; /* ends with opcode ENDCODE */
|
||||||
int lineDefined;
|
int lineDefined;
|
||||||
TaggedString *source;
|
TaggedString *source;
|
||||||
|
short numparams;
|
||||||
|
short is_vararg;
|
||||||
|
short maxstacksize;
|
||||||
struct LocVar *locvars; /* ends with line = -1 */
|
struct LocVar *locvars; /* ends with line = -1 */
|
||||||
} TProtoFunc;
|
} TProtoFunc;
|
||||||
|
|
||||||
|
|||||||
147
lopcodes.h
147
lopcodes.h
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lopcodes.h,v 1.38 2000/01/28 16:53:00 roberto Exp roberto $
|
** $Id: lopcodes.h,v 1.39 2000/02/11 16:52:54 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,67 +8,79 @@
|
|||||||
#define lopcodes_h
|
#define lopcodes_h
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*===========================================================================
|
||||||
|
We assume that instructions are unsigned numbers with 4 bytes.
|
||||||
|
All instructions have an opcode in the lower byte. Moreover,
|
||||||
|
an instruction can have 0, 1, or 2 arguments. There are 4 types of
|
||||||
|
Instructions:
|
||||||
|
type 0: no arguments
|
||||||
|
type 1: 1 unsigned argument in the higher 24 bits (called `U')
|
||||||
|
type 2: 1 signed argument in the higher 24 bits (`S')
|
||||||
|
type 3: 1st unsigned argument in the higher 16 bits (`A')
|
||||||
|
2nd unsigned argument in the middle 8 bits (`B')
|
||||||
|
|
||||||
|
The signed argument is represented in excess 2^23; that is, the real value
|
||||||
|
is 2^23 minus the usigned value.
|
||||||
|
===========================================================================*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** NOTICE: variants of the same opcode must be consecutive: First, those
|
** the following macros help to manipulate instructions
|
||||||
** with word parameter, then with byte parameter.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define MAXARG_U ((1<<24)-1)
|
||||||
|
#define MAXARG_S ((1<<23)-1)
|
||||||
|
#define MAXARG_A ((1<<16)-1)
|
||||||
|
#define MAXARG_B ((1<<8)-1)
|
||||||
|
|
||||||
|
#define GET_OPCODE(i) ((OpCode)((i)&0xFF))
|
||||||
|
#define GETARG_U(i) ((int)((i)>>8))
|
||||||
|
#define GETARG_S(i) ((int)((i)>>8)-(1<<23))
|
||||||
|
#define GETARG_A(i) ((int)((i)>>16))
|
||||||
|
#define GETARG_B(i) ((int)(((i)>>8) & 0xFF))
|
||||||
|
|
||||||
|
#define SET_OPCODE(i,o) (((i)&0xFFFFFF00u) | (Instruction)(o))
|
||||||
|
#define SETARG_U(i,u) (((i)&0x000000FFu) | ((Instruction)(u)<<8))
|
||||||
|
#define SETARG_S(i,s) (((i)&0x000000FFu) | ((Instruction)((s)+(1<<23))<<8))
|
||||||
|
#define SETARG_A(i,a) (((i)&0x0000FFFFu) | ((Instruction)(a)<<16))
|
||||||
|
#define SETARG_B(i,b) (((i)&0xFFFF00FFu) | ((Instruction)(b)<<8))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
/* name parm before after side effect
|
/* name parm before after side effect
|
||||||
-----------------------------------------------------------------------------*/
|
-----------------------------------------------------------------------------*/
|
||||||
ENDCODE,/* - - (return) */
|
ENDCODE,/* - - (return) */
|
||||||
RETCODE,/* b - (return) */
|
RETCODE,/* U - (return) */
|
||||||
|
|
||||||
CALL,/* b c v_n-v_1 f(at c) r_b-r_1 f(v1,...,v_n) */
|
CALL,/* A B v_n-v_1 f(at a) r_b-r_1 f(v1,...,v_n) */
|
||||||
|
TAILCALL,/* A B v_a-v_1 f (return) f(v1,...,v_a) */
|
||||||
|
|
||||||
TAILCALL,/* b c v_c-v_1 f (return) f(v1,...,v_c) */
|
PUSHNIL,/* U - nil_0-nil_u */
|
||||||
|
POP,/* U a_u-a_1 - */
|
||||||
|
|
||||||
PUSHNIL,/* b - nil_0-nil_b */
|
PUSHINT,/* S - (real)s */
|
||||||
POP,/* b a_b-a_1 - */
|
PUSHSTRING,/* U - KSTR[u] */
|
||||||
|
PUSHNUMBER,/* U - KNUM[u] */
|
||||||
|
|
||||||
PUSHINTW,/* w - (float)w */
|
PUSHUPVALUE,/* U - Closure[u] */
|
||||||
PUSHINT,/* b - (float)b */
|
|
||||||
|
|
||||||
PUSHINTNEGW,/* w - (float)-w */
|
PUSHLOCAL,/* U - LOC[u] */
|
||||||
PUSHINTNEG,/* b - (float)-b */
|
GETGLOBAL,/* U - VAR[CNST[u]] */
|
||||||
|
|
||||||
PUSHSTRINGW,/* w - KSTR[w] */
|
|
||||||
PUSHSTRING,/* b - KSTR[b] */
|
|
||||||
PUSHNUMBERW,/* w - KNUM[w] */
|
|
||||||
PUSHNUMBER,/* b - KNUM[b] */
|
|
||||||
|
|
||||||
PUSHUPVALUE,/* b - Closure[b] */
|
|
||||||
|
|
||||||
PUSHLOCAL,/* b - LOC[b] */
|
|
||||||
|
|
||||||
GETGLOBALW,/* w - VAR[CNST[w]] */
|
|
||||||
GETGLOBAL,/* b - VAR[CNST[b]] */
|
|
||||||
|
|
||||||
GETTABLE,/* - i t t[i] */
|
GETTABLE,/* - i t t[i] */
|
||||||
|
GETDOTTED,/* U t t[CNST[u]] */
|
||||||
|
PUSHSELF,/* U t t t[CNST[u]] */
|
||||||
|
|
||||||
GETDOTTEDW,/* w t t[CNST[w]] */
|
CREATETABLE,/* U - newarray(size = u) */
|
||||||
GETDOTTED,/* b t t[CNST[b]] */
|
|
||||||
|
|
||||||
PUSHSELFW,/* w t t t[CNST[w]] */
|
|
||||||
PUSHSELF,/* b t t t[CNST[b]] */
|
|
||||||
|
|
||||||
CREATEARRAYW,/* w - newarray(size = w) */
|
|
||||||
CREATEARRAY,/* b - newarray(size = b) */
|
|
||||||
|
|
||||||
SETLOCAL,/* b x - LOC[b]=x */
|
|
||||||
|
|
||||||
SETGLOBALW,/* w x - VAR[CNST[w]]=x */
|
|
||||||
SETGLOBAL,/* b x - VAR[CNST[b]]=x */
|
|
||||||
|
|
||||||
|
SETLOCAL,/* U x - LOC[u]=x */
|
||||||
|
SETGLOBAL,/* U x - VAR[CNST[u]]=x */
|
||||||
SETTABLEPOP,/* - v i t - t[i]=v */
|
SETTABLEPOP,/* - v i t - t[i]=v */
|
||||||
|
SETTABLE,/* U v a_u-a_1 i t a_u-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 */
|
SETLIST,/* A B v_b-v_0 t t t[i+a*FPF]=v_i */
|
||||||
|
SETMAP,/* U v_u k_u - v_0 k_0 t t t[k_i]=v_i */
|
||||||
SETLISTW,/* w c v_c-v_1 t t t[i+w*FPF]=v_i */
|
|
||||||
SETLIST,/* b c v_c-v_1 t t t[i+b*FPF]=v_i */
|
|
||||||
|
|
||||||
SETMAP,/* b v_b k_b - v_0 k_0 t t t[k_i]=v_i */
|
|
||||||
|
|
||||||
NEQOP,/* - y x (x~=y)? 1 : nil */
|
NEQOP,/* - y x (x~=y)? 1 : nil */
|
||||||
EQOP,/* - y x (x==y)? 1 : nil */
|
EQOP,/* - y x (x==y)? 1 : nil */
|
||||||
@@ -85,54 +97,21 @@ CONCOP,/* - y x x..y */
|
|||||||
MINUSOP,/* - x -x */
|
MINUSOP,/* - x -x */
|
||||||
NOTOP,/* - x (x==nil)? 1 : nil */
|
NOTOP,/* - x (x==nil)? 1 : nil */
|
||||||
|
|
||||||
ONTJMPW,/* w x (x!=nil)? x : - (x!=nil)? PC+=w */
|
ONTJMP,/* S x (x!=nil)? x : - (x!=nil)? PC+=s */
|
||||||
ONTJMP,/* b x (x!=nil)? x : - (x!=nil)? PC+=b */
|
ONFJMP,/* S x (x==nil)? x : - (x==nil)? PC+=s */
|
||||||
ONFJMPW,/* w x (x==nil)? x : - (x==nil)? PC+=w */
|
JMP,/* S - - PC+=s */
|
||||||
ONFJMP,/* b x (x==nil)? x : - (x==nil)? PC+=b */
|
IFTJMP,/* S x - (x!=nil)? PC+=s */
|
||||||
JMPW,/* w - - PC+=w */
|
IFFJMP,/* S x - (x==nil)? PC+=s */
|
||||||
JMP,/* b - - PC+=b */
|
|
||||||
IFFJMPW,/* w x - (x==nil)? PC+=w */
|
|
||||||
IFFJMP,/* b x - (x==nil)? PC+=b */
|
|
||||||
IFTUPJMPW,/* w x - (x!=nil)? PC-=w */
|
|
||||||
IFTUPJMP,/* b x - (x!=nil)? PC-=b */
|
|
||||||
IFFUPJMPW,/* w x - (x==nil)? PC-=w */
|
|
||||||
IFFUPJMP,/* b x - (x==nil)? PC-=b */
|
|
||||||
|
|
||||||
CLOSUREW,/* w c v_c-v_1 closure(CNST[w], v_c-v_1) */
|
CLOSURE,/* A B v_b-v_1 closure(CNST[a], v_b-v_1) */
|
||||||
CLOSURE,/* b c v_c-v_1 closure(CNST[b], v_c-v_1) */
|
|
||||||
|
|
||||||
SETLINEW,/* w - - LINE=w */
|
SETLINE/* U - - LINE=u */
|
||||||
SETLINE,/* b - - LINE=b */
|
|
||||||
|
|
||||||
LONGARGW,/* w (add w*(1<<16) to arg of next instruction) */
|
|
||||||
LONGARG /* b (add b*(1<<16) to arg of next instruction) */
|
|
||||||
|
|
||||||
} OpCode;
|
} OpCode;
|
||||||
|
|
||||||
|
|
||||||
#define RFIELDS_PER_FLUSH 32 /* records (SETMAP) */
|
#define RFIELDS_PER_FLUSH 32 /* records (SETMAP) */
|
||||||
#define LFIELDS_PER_FLUSH 64 /* FPF - lists (SETLIST) */
|
#define LFIELDS_PER_FLUSH 64 /* FPF - lists (SETLIST) (<MAXARG_B) */
|
||||||
|
|
||||||
#define ZEROVARARG 128
|
|
||||||
|
|
||||||
|
|
||||||
/* maximum value of an arg of 3 bytes; must fit in an "int" */
|
|
||||||
#if MAX_INT < (1<<24)
|
|
||||||
#define MAX_ARG MAX_INT
|
|
||||||
#else
|
|
||||||
#define MAX_ARG ((1<<24)-1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* maximum value of a word of 2 bytes; cannot be larger than MAX_ARG */
|
|
||||||
#if MAX_ARG < (1<<16)
|
|
||||||
#define MAX_WORD MAX_ARG
|
|
||||||
#else
|
|
||||||
#define MAX_WORD ((1<<16)-1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* maximum value of a byte */
|
|
||||||
#define MAX_BYTE ((1<<8)-1)
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
332
lparser.c
332
lparser.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lparser.c,v 1.57 2000/01/28 16:53:00 roberto Exp roberto $
|
** $Id: lparser.c,v 1.58 2000/02/11 16:52:54 roberto Exp roberto $
|
||||||
** LL(1) Parser and code generator for Lua
|
** LL(1) Parser and code generator for Lua
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -20,30 +20,27 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* size of a "normal" jump instruction: OpCode + 1 byte */
|
|
||||||
#define JMPSIZE 2
|
|
||||||
|
|
||||||
/* maximum number of local variables */
|
/* maximum number of local variables */
|
||||||
#ifndef MAXLOCALS
|
#ifndef MAXLOCALS
|
||||||
#define MAXLOCALS 200 /* arbitrary limit (<256) */
|
#define MAXLOCALS 200 /* arbitrary limit (<MAXARG_B) */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* maximum number of upvalues */
|
/* maximum number of upvalues */
|
||||||
#ifndef MAXUPVALUES
|
#ifndef MAXUPVALUES
|
||||||
#define MAXUPVALUES 32 /* arbitrary limit (<256) */
|
#define MAXUPVALUES 32 /* arbitrary limit (<MAXARG_B) */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* maximum number of variables in the left side of an assignment */
|
/* maximum number of variables in the left side of an assignment */
|
||||||
#ifndef MAXVARSLH
|
#ifndef MAXVARSLH
|
||||||
#define MAXVARSLH 100 /* arbitrary limit (<255) */
|
#define MAXVARSLH 100 /* arbitrary limit (<MAXARG_B) */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* maximum number of parameters in a function */
|
/* maximum number of parameters in a function */
|
||||||
#ifndef MAXPARAMS
|
#ifndef MAXPARAMS
|
||||||
#define MAXPARAMS 100 /* arbitrary limit (<ZEROVARARG) */
|
#define MAXPARAMS 100 /* arbitrary limit (<MAXLOCALS) */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -57,7 +54,7 @@ typedef enum {
|
|||||||
VLOCAL, /* info is stack index */
|
VLOCAL, /* info is stack index */
|
||||||
VDOT, /* info is constant index of index name */
|
VDOT, /* info is constant index of index name */
|
||||||
VINDEXED, /* no info (table and index are on the stack) */
|
VINDEXED, /* no info (table and index are on the stack) */
|
||||||
VEXP /* info is pc index of `nparam' of a call (or 0 if exp is closed) */
|
VEXP /* info is pc index of a call (or 0 if exp is closed) */
|
||||||
} varkind;
|
} varkind;
|
||||||
|
|
||||||
typedef struct vardesc {
|
typedef struct vardesc {
|
||||||
@@ -70,7 +67,7 @@ typedef struct vardesc {
|
|||||||
** Expression List descriptor:
|
** Expression List descriptor:
|
||||||
** tells number of expressions in the list,
|
** tells number of expressions in the list,
|
||||||
** and, if last expression is open (a function call),
|
** and, if last expression is open (a function call),
|
||||||
** where is its pc index of `nparam'
|
** where is the call pc index.
|
||||||
*/
|
*/
|
||||||
typedef struct listdesc {
|
typedef struct listdesc {
|
||||||
int n;
|
int n;
|
||||||
@@ -96,7 +93,6 @@ typedef struct FuncState {
|
|||||||
struct FuncState *prev; /* enclosing function */
|
struct FuncState *prev; /* enclosing function */
|
||||||
int pc; /* next position to code */
|
int pc; /* next position to code */
|
||||||
int stacksize; /* number of values on activation register */
|
int stacksize; /* number of values on activation register */
|
||||||
int maxstacksize; /* maximum number of values on activation register */
|
|
||||||
int nlocalvar; /* number of active local variables */
|
int nlocalvar; /* number of active local variables */
|
||||||
int nupvalues; /* number of upvalues */
|
int nupvalues; /* number of upvalues */
|
||||||
int nvars; /* number of entries in f->locvars (-1 if no debug information) */
|
int nvars; /* number of entries in f->locvars (-1 if no debug information) */
|
||||||
@@ -131,89 +127,63 @@ static void checklimit (LexState *ls, int val, int limit, const char *msg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void check_pc (LexState *ls, int n) {
|
static int code_instruction (LexState *ls, Instruction i) {
|
||||||
luaM_growvector(ls->L, ls->fs->f->code, ls->fs->pc, n,
|
FuncState *fs = ls->fs;
|
||||||
Byte, codeEM, MAX_INT);
|
luaM_growvector(ls->L, fs->f->code, fs->pc, 1, Instruction, codeEM, MAXARG_S);
|
||||||
|
fs->f->code[fs->pc] = i;
|
||||||
|
return fs->pc++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void code_byte (LexState *ls, Byte c) {
|
static void fix_jump (LexState *ls, int pc, int dest) {
|
||||||
check_pc(ls, 1);
|
Instruction *jmp = &ls->fs->f->code[pc];
|
||||||
ls->fs->f->code[ls->fs->pc++] = c;
|
/* jump is relative to position following jump instruction */
|
||||||
|
*jmp = SETARG_S(*jmp, dest-(pc+1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void deltastack (LexState *ls, int delta) {
|
static void deltastack (LexState *ls, int delta) {
|
||||||
FuncState *fs = ls->fs;
|
FuncState *fs = ls->fs;
|
||||||
fs->stacksize += delta;
|
fs->stacksize += delta;
|
||||||
if (fs->stacksize > fs->maxstacksize) {
|
if (delta > 0 && fs->stacksize > fs->f->maxstacksize) {
|
||||||
if (fs->stacksize > MAX_BYTE)
|
fs->f->maxstacksize = fs->stacksize;
|
||||||
luaY_error(ls, "function or expression too complex");
|
|
||||||
fs->maxstacksize = fs->stacksize;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void code_oparg_at (LexState *ls, int pc, OpCode op,
|
static int aux_code (LexState *ls, OpCode op, Instruction i, int delta) {
|
||||||
int arg, int delta) {
|
|
||||||
Byte *code = ls->fs->f->code;
|
|
||||||
deltastack(ls, delta);
|
deltastack(ls, delta);
|
||||||
if (arg <= MAX_BYTE) {
|
return code_instruction(ls, SET_OPCODE(i, op));
|
||||||
code[pc] = (Byte)op;
|
|
||||||
code[pc+1] = (Byte)arg;
|
|
||||||
}
|
|
||||||
else if (arg > MAX_ARG)
|
|
||||||
luaY_error(ls, "code too long");
|
|
||||||
else { /* MAX_BYTE < arg < MAX_ARG */
|
|
||||||
if (arg > MAX_WORD) {
|
|
||||||
code[pc] = (Byte)LONGARG;
|
|
||||||
code[pc+1] = (Byte)(arg>>16);
|
|
||||||
pc += 2;
|
|
||||||
}
|
|
||||||
code[pc] = (Byte)(op-1); /* opcode for word argument */
|
|
||||||
code[pc+1] = (Byte)((arg&0xFFFF)>>8);
|
|
||||||
code[pc+2] = (Byte)(arg&0xFF);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int codesize (int arg) {
|
static int code_0 (LexState *ls, OpCode op, int delta) {
|
||||||
if (arg <= MAX_BYTE) return 2; /* opcode + 1 byte */
|
return aux_code(ls, op, 0, delta);
|
||||||
else if (arg <= MAX_WORD) return 3; /* opcode + 1 word (2 bytes) */
|
|
||||||
else return 5; /* LONGARG + 1 byte + opcode + 1 word (2 bytes) */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int fix_opcode (LexState *ls, int pc, OpCode op, int arg) {
|
|
||||||
int tomove = codesize(arg)-2;
|
static int code_U (LexState *ls, OpCode op, int u, int delta) {
|
||||||
if (tomove > 0) { /* need to open space? */
|
Instruction i = SETARG_U(0, u);
|
||||||
FuncState *fs = ls->fs;
|
return aux_code(ls, op, i, delta);
|
||||||
TProtoFunc *f = fs->f;
|
|
||||||
check_pc(ls, tomove);
|
|
||||||
luaO_memup(f->code+pc+tomove, f->code+pc, fs->pc-pc);
|
|
||||||
fs->pc += tomove;
|
|
||||||
}
|
|
||||||
code_oparg_at(ls, pc, op, arg, 0);
|
|
||||||
return tomove;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void code_oparg (LexState *ls, OpCode op, int arg, int delta) {
|
static int code_S (LexState *ls, OpCode op, int s, int delta) {
|
||||||
int size = codesize(arg);
|
Instruction i = SETARG_S(0, s);
|
||||||
check_pc(ls, size);
|
return aux_code(ls, op, i, delta);
|
||||||
code_oparg_at(ls, ls->fs->pc, op, arg, delta);
|
|
||||||
ls->fs->pc += size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void code_opcode (LexState *ls, OpCode op, int delta) {
|
static int code_AB (LexState *ls, OpCode op, int a, int b, int delta) {
|
||||||
deltastack(ls, delta);
|
Instruction i = SETARG_A(0, a);
|
||||||
code_byte(ls, (Byte)op);
|
i = SETARG_B(i, b);
|
||||||
|
return aux_code(ls, op, i, delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void code_kstr (LexState *ls, int c) {
|
static void code_kstr (LexState *ls, int c) {
|
||||||
code_oparg(ls, PUSHSTRING, c, 1);
|
code_U(ls, PUSHSTRING, c, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -226,8 +196,8 @@ static int string_constant (LexState *ls, FuncState *fs, TaggedString *s) {
|
|||||||
TProtoFunc *f = fs->f;
|
TProtoFunc *f = fs->f;
|
||||||
int c = s->constindex;
|
int c = s->constindex;
|
||||||
if (c >= f->nkstr || f->kstr[c] != s) {
|
if (c >= f->nkstr || f->kstr[c] != s) {
|
||||||
luaM_growvector(ls->L, f->kstr, f->nkstr, 1,
|
luaM_growvector(ls->L, f->kstr, f->nkstr, 1, TaggedString *,
|
||||||
TaggedString *, constantEM, MAX_ARG);
|
constantEM, MAXARG_U);
|
||||||
c = f->nkstr++;
|
c = f->nkstr++;
|
||||||
f->kstr[c] = s;
|
f->kstr[c] = s;
|
||||||
s->constindex = c; /* hint for next time */
|
s->constindex = c; /* hint for next time */
|
||||||
@@ -250,8 +220,7 @@ static int real_constant (LexState *ls, real r) {
|
|||||||
while (--c >= lim)
|
while (--c >= lim)
|
||||||
if (f->knum[c] == r) return c;
|
if (f->knum[c] == r) return c;
|
||||||
/* not found; create a new entry */
|
/* not found; create a new entry */
|
||||||
luaM_growvector(ls->L, f->knum, f->nknum, 1,
|
luaM_growvector(ls->L, f->knum, f->nknum, 1, real, constantEM, MAXARG_U);
|
||||||
real, constantEM, MAX_ARG);
|
|
||||||
c = f->nknum++;
|
c = f->nknum++;
|
||||||
f->knum[c] = r;
|
f->knum[c] = r;
|
||||||
return c;
|
return c;
|
||||||
@@ -259,27 +228,10 @@ static int real_constant (LexState *ls, real r) {
|
|||||||
|
|
||||||
|
|
||||||
static void code_number (LexState *ls, real f) {
|
static void code_number (LexState *ls, real f) {
|
||||||
real af = (f<0) ? -f : f;
|
if ((real)(-MAXARG_S) <= f && f <= (real)MAXARG_S && (int)f == f)
|
||||||
if (0 <= af && af <= (real)MAX_WORD && (int)af == af) {
|
code_S(ls, PUSHINT, (int)f, 1); /* f has a short integer value */
|
||||||
/* abs(f) has a short integer value */
|
|
||||||
code_oparg(ls, (f<0) ? PUSHINTNEG : PUSHINT, (int)af, 1);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
code_oparg(ls, PUSHNUMBER, real_constant(ls, f), 1);
|
code_U(ls, PUSHNUMBER, real_constant(ls, f), 1);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void flush_record (LexState *ls, int n) {
|
|
||||||
if (n > 0)
|
|
||||||
code_oparg(ls, SETMAP, n-1, -2*n);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void flush_list (LexState *ls, int m, int n) {
|
|
||||||
if (n > 0) {
|
|
||||||
code_oparg(ls, SETLIST, m, -n);
|
|
||||||
code_byte(ls, (Byte)n);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -371,14 +323,14 @@ static void pushupvalue (LexState *ls, TaggedString *n) {
|
|||||||
luaX_syntaxerror(ls, "cannot access upvalue in main", n->str);
|
luaX_syntaxerror(ls, "cannot access upvalue in main", n->str);
|
||||||
if (aux_localname(ls->fs, n) >= 0)
|
if (aux_localname(ls->fs, n) >= 0)
|
||||||
luaX_syntaxerror(ls, "cannot access an upvalue in current scope", n->str);
|
luaX_syntaxerror(ls, "cannot access an upvalue in current scope", n->str);
|
||||||
code_oparg(ls, PUSHUPVALUE, indexupvalue(ls, n), 1);
|
code_U(ls, PUSHUPVALUE, indexupvalue(ls, n), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void check_debugline (LexState *ls) {
|
static void check_debugline (LexState *ls) {
|
||||||
if (ls->L->debug && ls->linenumber != ls->fs->lastsetline) {
|
if (ls->L->debug && ls->linenumber != ls->fs->lastsetline) {
|
||||||
code_oparg(ls, SETLINE, ls->linenumber, 0);
|
code_U(ls, SETLINE, ls->linenumber, 0);
|
||||||
ls->fs->lastsetline = ls->linenumber;
|
ls->fs->lastsetline = ls->linenumber;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -386,16 +338,16 @@ static void check_debugline (LexState *ls) {
|
|||||||
|
|
||||||
static void adjuststack (LexState *ls, int n) {
|
static void adjuststack (LexState *ls, int n) {
|
||||||
if (n > 0)
|
if (n > 0)
|
||||||
code_oparg(ls, POP, n, -n);
|
code_U(ls, POP, n, -n);
|
||||||
else if (n < 0)
|
else if (n < 0)
|
||||||
code_oparg(ls, PUSHNIL, (-n)-1, -n);
|
code_U(ls, PUSHNIL, (-n)-1, -n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void close_exp (LexState *ls, int pc, int nresults) {
|
static void close_exp (LexState *ls, int pc, int nresults) {
|
||||||
if (pc > 0) { /* expression is an open function call? */
|
if (pc > 0) { /* expression is an open function call? */
|
||||||
Byte *code = ls->fs->f->code;
|
Instruction *i = &ls->fs->f->code[pc];
|
||||||
code[pc-1] = (Byte)nresults; /* set nresults */
|
*i = SETARG_B(*i, nresults); /* set nresults */
|
||||||
if (nresults != MULT_RET)
|
if (nresults != MULT_RET)
|
||||||
deltastack(ls, nresults); /* push results */
|
deltastack(ls, nresults); /* push results */
|
||||||
}
|
}
|
||||||
@@ -426,13 +378,12 @@ static void code_args (LexState *ls, int nparams, int dots) {
|
|||||||
FuncState *fs = ls->fs;
|
FuncState *fs = ls->fs;
|
||||||
adjustlocalvars(ls, nparams, 0);
|
adjustlocalvars(ls, nparams, 0);
|
||||||
checklimit(ls, fs->nlocalvar, MAXPARAMS, "parameters");
|
checklimit(ls, fs->nlocalvar, MAXPARAMS, "parameters");
|
||||||
nparams = fs->nlocalvar;
|
nparams = fs->nlocalvar; /* `self' could be there already */
|
||||||
if (!dots) {
|
fs->f->numparams = nparams;
|
||||||
fs->f->code[1] = (Byte)nparams; /* fill-in arg information */
|
fs->f->is_vararg = dots;
|
||||||
|
if (!dots)
|
||||||
deltastack(ls, nparams);
|
deltastack(ls, nparams);
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
fs->f->code[1] = (Byte)(nparams+ZEROVARARG);
|
|
||||||
deltastack(ls, nparams+1);
|
deltastack(ls, nparams+1);
|
||||||
add_localvar(ls, luaS_newfixed(ls->L, "arg"));
|
add_localvar(ls, luaS_newfixed(ls->L, "arg"));
|
||||||
}
|
}
|
||||||
@@ -451,17 +402,17 @@ static void unloaddot (LexState *ls, vardesc *v) {
|
|||||||
static void lua_pushvar (LexState *ls, vardesc *var) {
|
static void lua_pushvar (LexState *ls, vardesc *var) {
|
||||||
switch (var->k) {
|
switch (var->k) {
|
||||||
case VLOCAL:
|
case VLOCAL:
|
||||||
code_oparg(ls, PUSHLOCAL, var->info, 1);
|
code_U(ls, PUSHLOCAL, var->info, 1);
|
||||||
break;
|
break;
|
||||||
case VGLOBAL:
|
case VGLOBAL:
|
||||||
code_oparg(ls, GETGLOBAL, var->info, 1);
|
code_U(ls, GETGLOBAL, var->info, 1);
|
||||||
assertglobal(ls, var->info); /* make sure that there is a global */
|
assertglobal(ls, var->info); /* make sure that there is a global */
|
||||||
break;
|
break;
|
||||||
case VDOT:
|
case VDOT:
|
||||||
code_oparg(ls, GETDOTTED, var->info, 0);
|
code_U(ls, GETDOTTED, var->info, 0);
|
||||||
break;
|
break;
|
||||||
case VINDEXED:
|
case VINDEXED:
|
||||||
code_opcode(ls, GETTABLE, -1);
|
code_0(ls, GETTABLE, -1);
|
||||||
break;
|
break;
|
||||||
case VEXP:
|
case VEXP:
|
||||||
close_exp(ls, var->info, 1); /* function must return 1 value */
|
close_exp(ls, var->info, 1); /* function must return 1 value */
|
||||||
@@ -475,14 +426,14 @@ static void lua_pushvar (LexState *ls, vardesc *var) {
|
|||||||
static void storevar (LexState *ls, const vardesc *var) {
|
static void storevar (LexState *ls, const vardesc *var) {
|
||||||
switch (var->k) {
|
switch (var->k) {
|
||||||
case VLOCAL:
|
case VLOCAL:
|
||||||
code_oparg(ls, SETLOCAL, var->info, -1);
|
code_U(ls, SETLOCAL, var->info, -1);
|
||||||
break;
|
break;
|
||||||
case VGLOBAL:
|
case VGLOBAL:
|
||||||
code_oparg(ls, SETGLOBAL, var->info, -1);
|
code_U(ls, SETGLOBAL, var->info, -1);
|
||||||
assertglobal(ls, var->info); /* make sure that there is a global */
|
assertglobal(ls, var->info); /* make sure that there is a global */
|
||||||
break;
|
break;
|
||||||
case VINDEXED:
|
case VINDEXED:
|
||||||
code_opcode(ls, SETTABLEPOP, -3);
|
code_0(ls, SETTABLEPOP, -3);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LUA_INTERNALERROR(ls->L, "invalid var kind to store");
|
LUA_INTERNALERROR(ls->L, "invalid var kind to store");
|
||||||
@@ -490,43 +441,16 @@ static void storevar (LexState *ls, const vardesc *var) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int fix_jump (LexState *ls, int pc, OpCode op, int n) {
|
|
||||||
/* jump is relative to position following jump instruction */
|
|
||||||
return fix_opcode(ls, pc, op, n-(pc+JMPSIZE));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void fix_upjmp (LexState *ls, OpCode op, int pos) {
|
|
||||||
int delta = ls->fs->pc+JMPSIZE - pos; /* jump is relative */
|
|
||||||
code_oparg(ls, op, delta+(codesize(delta)-2), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void codeIf (LexState *ls, int thenAdd, int elseAdd) {
|
|
||||||
FuncState *fs = ls->fs;
|
|
||||||
int elseinit = elseAdd+JMPSIZE;
|
|
||||||
if (fs->pc == elseinit) { /* no else part? */
|
|
||||||
fs->pc -= JMPSIZE;
|
|
||||||
elseinit = fs->pc;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
elseinit += fix_jump(ls, elseAdd, JMP, fs->pc);
|
|
||||||
fix_jump(ls, thenAdd, IFFJMP, elseinit);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void func_onstack (LexState *ls, FuncState *func) {
|
static void func_onstack (LexState *ls, FuncState *func) {
|
||||||
FuncState *fs = ls->fs;
|
TProtoFunc *f = ls->fs->f;
|
||||||
TProtoFunc *f = fs->f;
|
|
||||||
int i;
|
int i;
|
||||||
luaM_growvector(ls->L, f->kproto, f->nkproto, 1,
|
|
||||||
TProtoFunc *, constantEM, MAX_ARG);
|
|
||||||
f->kproto[f->nkproto] = func->f;
|
|
||||||
for (i=0; i<func->nupvalues; i++)
|
for (i=0; i<func->nupvalues; i++)
|
||||||
lua_pushvar(ls, &func->upvalues[i]);
|
lua_pushvar(ls, &func->upvalues[i]);
|
||||||
|
luaM_growvector(ls->L, f->kproto, f->nkproto, 1, TProtoFunc *,
|
||||||
|
constantEM, MAXARG_A);
|
||||||
|
f->kproto[f->nkproto++] = func->f;
|
||||||
deltastack(ls, 1); /* CLOSURE puts one extra element (before popping) */
|
deltastack(ls, 1); /* CLOSURE puts one extra element (before popping) */
|
||||||
code_oparg(ls, CLOSURE, f->nkproto++, -func->nupvalues);
|
code_AB(ls, CLOSURE, f->nkproto-1, func->nupvalues, -func->nupvalues);
|
||||||
code_byte(ls, (Byte)func->nupvalues);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -536,7 +460,6 @@ static void init_state (LexState *ls, FuncState *fs, TaggedString *source) {
|
|||||||
fs->prev = ls->fs; /* linked list of funcstates */
|
fs->prev = ls->fs; /* linked list of funcstates */
|
||||||
ls->fs = fs;
|
ls->fs = fs;
|
||||||
fs->stacksize = 0;
|
fs->stacksize = 0;
|
||||||
fs->maxstacksize = 0;
|
|
||||||
fs->nlocalvar = 0;
|
fs->nlocalvar = 0;
|
||||||
fs->nupvalues = 0;
|
fs->nupvalues = 0;
|
||||||
fs->lastsetline = 0;
|
fs->lastsetline = 0;
|
||||||
@@ -544,9 +467,10 @@ static void init_state (LexState *ls, FuncState *fs, TaggedString *source) {
|
|||||||
f->source = source;
|
f->source = source;
|
||||||
fs->pc = 0;
|
fs->pc = 0;
|
||||||
f->code = NULL;
|
f->code = NULL;
|
||||||
|
f->maxstacksize = 0;
|
||||||
|
f->numparams = 0; /* default for main chunk */
|
||||||
|
f->is_vararg = 0; /* default for main chunk */
|
||||||
fs->nvars = (L->debug) ? 0 : -1; /* flag no debug information? */
|
fs->nvars = (L->debug) ? 0 : -1; /* flag no debug information? */
|
||||||
code_byte(ls, 0); /* to be filled with maxstacksize */
|
|
||||||
code_byte(ls, 0); /* to be filled with arg information */
|
|
||||||
/* push function (to avoid GC) */
|
/* push function (to avoid GC) */
|
||||||
tfvalue(L->top) = f;
|
tfvalue(L->top) = f;
|
||||||
ttype(L->top) = LUA_T_LPROTO;
|
ttype(L->top) = LUA_T_LPROTO;
|
||||||
@@ -557,9 +481,8 @@ static void init_state (LexState *ls, FuncState *fs, TaggedString *source) {
|
|||||||
static void close_func (LexState *ls) {
|
static void close_func (LexState *ls) {
|
||||||
FuncState *fs = ls->fs;
|
FuncState *fs = ls->fs;
|
||||||
TProtoFunc *f = fs->f;
|
TProtoFunc *f = fs->f;
|
||||||
code_opcode(ls, ENDCODE, 0);
|
code_0(ls, ENDCODE, 0);
|
||||||
f->code[0] = (Byte)fs->maxstacksize;
|
luaM_reallocvector(ls->L, f->code, fs->pc, Instruction);
|
||||||
luaM_reallocvector(ls->L, f->code, fs->pc, Byte);
|
|
||||||
luaM_reallocvector(ls->L, f->kstr, f->nkstr, TaggedString *);
|
luaM_reallocvector(ls->L, f->kstr, f->nkstr, TaggedString *);
|
||||||
luaM_reallocvector(ls->L, f->knum, f->nknum, real);
|
luaM_reallocvector(ls->L, f->knum, f->nknum, real);
|
||||||
luaM_reallocvector(ls->L, f->kproto, f->nkproto, TProtoFunc *);
|
luaM_reallocvector(ls->L, f->kproto, f->nkproto, TProtoFunc *);
|
||||||
@@ -662,28 +585,6 @@ TProtoFunc *luaY_parser (lua_State *L, ZIO *z) {
|
|||||||
/*============================================================*/
|
/*============================================================*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int SaveWord (LexState *ls) {
|
|
||||||
int res = ls->fs->pc;
|
|
||||||
check_pc(ls, JMPSIZE);
|
|
||||||
ls->fs->pc += JMPSIZE; /* open space */
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int SaveWordPop (LexState *ls) {
|
|
||||||
deltastack(ls, -1); /* pop condition */
|
|
||||||
return SaveWord(ls);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int cond (LexState *ls) {
|
|
||||||
/* cond -> exp1 */
|
|
||||||
exp1(ls);
|
|
||||||
return SaveWordPop(ls);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void explist1 (LexState *ls, listdesc *d) {
|
static void explist1 (LexState *ls, listdesc *d) {
|
||||||
vardesc v;
|
vardesc v;
|
||||||
expr(ls, &v);
|
expr(ls, &v);
|
||||||
@@ -744,11 +645,8 @@ static int funcparams (LexState *ls, int slf) {
|
|||||||
luaY_error(ls, "function arguments expected");
|
luaY_error(ls, "function arguments expected");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
code_byte(ls, CALL);
|
|
||||||
code_byte(ls, 0); /* save space for nresult */
|
|
||||||
code_byte(ls, (Byte)slevel);
|
|
||||||
fs->stacksize = slevel; /* call will remove func and params */
|
fs->stacksize = slevel; /* call will remove func and params */
|
||||||
return fs->pc-1;
|
return code_AB(ls, CALL, slevel, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -775,7 +673,7 @@ static void var_or_func_tail (LexState *ls, vardesc *v) {
|
|||||||
next(ls);
|
next(ls);
|
||||||
name = checkname(ls);
|
name = checkname(ls);
|
||||||
lua_pushvar(ls, v); /* `v' must be on stack */
|
lua_pushvar(ls, v); /* `v' must be on stack */
|
||||||
code_oparg(ls, PUSHSELF, name, 1);
|
code_U(ls, PUSHSELF, name, 1);
|
||||||
v->k = VEXP;
|
v->k = VEXP;
|
||||||
v->info = funcparams(ls, 1);
|
v->info = funcparams(ls, 1);
|
||||||
break;
|
break;
|
||||||
@@ -836,16 +734,20 @@ static void recfield (LexState *ls) {
|
|||||||
static int recfields (LexState *ls) {
|
static int recfields (LexState *ls) {
|
||||||
/* recfields -> { ',' recfield } [','] */
|
/* recfields -> { ',' recfield } [','] */
|
||||||
int n = 1; /* one has been read before */
|
int n = 1; /* one has been read before */
|
||||||
|
int mod_n = 1; /* mod_n == n%RFIELDS_PER_FLUSH */
|
||||||
while (ls->token == ',') {
|
while (ls->token == ',') {
|
||||||
next(ls);
|
next(ls);
|
||||||
if (ls->token == ';' || ls->token == '}')
|
if (ls->token == ';' || ls->token == '}')
|
||||||
break;
|
break;
|
||||||
recfield(ls);
|
recfield(ls);
|
||||||
n++;
|
n++;
|
||||||
if (n%RFIELDS_PER_FLUSH == 0)
|
if (++mod_n == RFIELDS_PER_FLUSH) {
|
||||||
flush_record(ls, RFIELDS_PER_FLUSH);
|
code_U(ls, SETMAP, RFIELDS_PER_FLUSH-1, -2*RFIELDS_PER_FLUSH);
|
||||||
|
mod_n = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
flush_record(ls, n%RFIELDS_PER_FLUSH);
|
if (mod_n)
|
||||||
|
code_U(ls, SETMAP, mod_n-1, -2*mod_n);
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -853,16 +755,23 @@ static int recfields (LexState *ls) {
|
|||||||
static int listfields (LexState *ls) {
|
static int listfields (LexState *ls) {
|
||||||
/* listfields -> { ',' exp1 } [','] */
|
/* listfields -> { ',' exp1 } [','] */
|
||||||
int n = 1; /* one has been read before */
|
int n = 1; /* one has been read before */
|
||||||
|
int mod_n = 1; /* mod_n == n%LFIELDS_PER_FLUSH */
|
||||||
while (ls->token == ',') {
|
while (ls->token == ',') {
|
||||||
next(ls);
|
next(ls);
|
||||||
if (ls->token == ';' || ls->token == '}')
|
if (ls->token == ';' || ls->token == '}')
|
||||||
break;
|
break;
|
||||||
exp1(ls);
|
exp1(ls);
|
||||||
n++;
|
n++;
|
||||||
if (n%LFIELDS_PER_FLUSH == 0)
|
checklimit(ls, n, MAXARG_A*LFIELDS_PER_FLUSH,
|
||||||
flush_list(ls, n/LFIELDS_PER_FLUSH - 1, LFIELDS_PER_FLUSH);
|
"items in a list initializer");
|
||||||
|
if (++mod_n == LFIELDS_PER_FLUSH) {
|
||||||
|
code_AB(ls, SETLIST, n/LFIELDS_PER_FLUSH - 1, LFIELDS_PER_FLUSH-1,
|
||||||
|
-LFIELDS_PER_FLUSH);
|
||||||
|
mod_n = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
flush_list(ls, n/LFIELDS_PER_FLUSH, n%LFIELDS_PER_FLUSH);
|
if (mod_n > 0)
|
||||||
|
code_AB(ls, SETLIST, n/LFIELDS_PER_FLUSH, mod_n-1, -mod_n);
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -920,10 +829,9 @@ static void constructor_part (LexState *ls, constdesc *cd) {
|
|||||||
static void constructor (LexState *ls) {
|
static void constructor (LexState *ls) {
|
||||||
/* constructor -> '{' constructor_part [';' constructor_part] '}' */
|
/* constructor -> '{' constructor_part [';' constructor_part] '}' */
|
||||||
int line = ls->linenumber;
|
int line = ls->linenumber;
|
||||||
int pc = SaveWord(ls);
|
int pc = code_U(ls, CREATETABLE, 0, 1);
|
||||||
int nelems;
|
int nelems;
|
||||||
constdesc cd;
|
constdesc cd;
|
||||||
deltastack(ls, 1);
|
|
||||||
check(ls, '{');
|
check(ls, '{');
|
||||||
constructor_part(ls, &cd);
|
constructor_part(ls, &cd);
|
||||||
nelems = cd.n;
|
nelems = cd.n;
|
||||||
@@ -936,7 +844,8 @@ static void constructor (LexState *ls) {
|
|||||||
nelems += other_cd.n;
|
nelems += other_cd.n;
|
||||||
}
|
}
|
||||||
check_match(ls, '}', '{', line);
|
check_match(ls, '}', '{', line);
|
||||||
fix_opcode(ls, pc, CREATEARRAY, nelems);
|
/* set initial table size */
|
||||||
|
ls->fs->f->code[pc] = SETARG_U(ls->fs->f->code[pc], nelems);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* }====================================================================== */
|
/* }====================================================================== */
|
||||||
@@ -1009,7 +918,7 @@ static void push (LexState *ls, stack_op *s, int op) {
|
|||||||
static void pop_to (LexState *ls, stack_op *s, int prio) {
|
static void pop_to (LexState *ls, stack_op *s, int prio) {
|
||||||
int op;
|
int op;
|
||||||
while (s->top > 0 && priority[(op=s->ops[s->top-1])] >= prio) {
|
while (s->top > 0 && priority[(op=s->ops[s->top-1])] >= prio) {
|
||||||
code_opcode(ls, opcodes[op], op<FIRSTBIN?0:-1);
|
code_0(ls, opcodes[op], op<FIRSTBIN?0:-1);
|
||||||
s->top--;
|
s->top--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1113,10 +1022,10 @@ static void expr (LexState *ls, vardesc *v) {
|
|||||||
int pc;
|
int pc;
|
||||||
lua_pushvar(ls, v);
|
lua_pushvar(ls, v);
|
||||||
next(ls);
|
next(ls);
|
||||||
pc = SaveWordPop(ls);
|
pc = code_S(ls, op, 0, -1);
|
||||||
arith_exp(ls, v);
|
arith_exp(ls, v);
|
||||||
lua_pushvar(ls, v);
|
lua_pushvar(ls, v);
|
||||||
fix_jump(ls, pc, op, ls->fs->pc);
|
fix_jump(ls, pc, ls->fs->pc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1167,7 +1076,7 @@ static int assignment (LexState *ls, vardesc *v, int nvars) {
|
|||||||
storevar(ls, v);
|
storevar(ls, v);
|
||||||
}
|
}
|
||||||
else { /* indexed var with values in between*/
|
else { /* indexed var with values in between*/
|
||||||
code_oparg(ls, SETTABLE, left+(nvars-1), -1);
|
code_U(ls, SETTABLE, left+(nvars-1), -1);
|
||||||
left += 2; /* table&index are not popped, because they aren't on top */
|
left += 2; /* table&index are not popped, because they aren't on top */
|
||||||
}
|
}
|
||||||
return left;
|
return left;
|
||||||
@@ -1175,22 +1084,18 @@ static int assignment (LexState *ls, vardesc *v, int nvars) {
|
|||||||
|
|
||||||
|
|
||||||
static void whilestat (LexState *ls, int line) {
|
static void whilestat (LexState *ls, int line) {
|
||||||
/* whilestat -> WHILE cond DO block END */
|
/* whilestat -> WHILE exp1 DO block END */
|
||||||
FuncState *fs = ls->fs;
|
FuncState *fs = ls->fs;
|
||||||
TProtoFunc *f = fs->f;
|
|
||||||
int while_init = fs->pc;
|
int while_init = fs->pc;
|
||||||
int cond_end, cond_size;
|
int j1;
|
||||||
next(ls);
|
next(ls);
|
||||||
cond_end = cond(ls);
|
exp1(ls);
|
||||||
|
j1 = code_U(ls, IFFJMP, 0, -1); /* jump to exit loop */
|
||||||
check(ls, DO);
|
check(ls, DO);
|
||||||
block(ls);
|
block(ls);
|
||||||
check_match(ls, END, WHILE, line);
|
check_match(ls, END, WHILE, line);
|
||||||
cond_size = cond_end-while_init;
|
fix_jump(ls, code_U(ls, JMP, 0, 0), while_init); /* jump to keep loop */
|
||||||
check_pc(ls, cond_size);
|
fix_jump(ls, j1, fs->pc);
|
||||||
memcpy(f->code+fs->pc, f->code+while_init, cond_size);
|
|
||||||
luaO_memdown(f->code+while_init, f->code+cond_end, fs->pc-while_init);
|
|
||||||
while_init += JMPSIZE + fix_jump(ls, while_init, JMP, fs->pc-cond_size);
|
|
||||||
fix_upjmp(ls, IFTUPJMP, while_init);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1202,8 +1107,7 @@ static void repeatstat (LexState *ls, int line) {
|
|||||||
block(ls);
|
block(ls);
|
||||||
check_match(ls, UNTIL, REPEAT, line);
|
check_match(ls, UNTIL, REPEAT, line);
|
||||||
exp1(ls);
|
exp1(ls);
|
||||||
fix_upjmp(ls, IFFUPJMP, repeat_init);
|
fix_jump(ls, code_U(ls, IFFJMP, 0, -1), repeat_init);
|
||||||
deltastack(ls, -1); /* pops condition */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1295,21 +1199,29 @@ static void namestat (LexState *ls) {
|
|||||||
|
|
||||||
static void ifpart (LexState *ls, int line) {
|
static void ifpart (LexState *ls, int line) {
|
||||||
/* ifpart -> cond THEN block [ELSE block | ELSEIF ifpart] */
|
/* ifpart -> cond THEN block [ELSE block | ELSEIF ifpart] */
|
||||||
|
FuncState *fs = ls->fs;
|
||||||
int c;
|
int c;
|
||||||
int e;
|
int je;
|
||||||
next(ls); /* skip IF or ELSEIF */
|
next(ls); /* skip IF or ELSEIF */
|
||||||
c = cond(ls);
|
exp1(ls); /* cond */
|
||||||
|
c = code_U(ls, IFFJMP, 0, -1); /* jump `then' if `cond' is false */
|
||||||
check(ls, THEN);
|
check(ls, THEN);
|
||||||
block(ls);
|
block(ls); /* `then' part */
|
||||||
e = SaveWord(ls);
|
je = code_U(ls, JMP, 0, 0); /* jump `else' part after `then' */
|
||||||
if (ls->token == ELSEIF)
|
if (ls->token == ELSEIF)
|
||||||
ifpart(ls, line);
|
ifpart(ls, line);
|
||||||
else {
|
else {
|
||||||
if (optional(ls, ELSE))
|
if (optional(ls, ELSE))
|
||||||
block(ls);
|
block(ls); /* `else' part */
|
||||||
check_match(ls, END, IF, line);
|
check_match(ls, END, IF, line);
|
||||||
}
|
}
|
||||||
codeIf(ls, c, e);
|
if (fs->pc == je+1) { /* `else' part empty? */
|
||||||
|
fs->pc--; /* remove last jump */
|
||||||
|
je--; /* first jump will be smaller */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
fix_jump(ls, je, fs->pc); /* fix last jump */
|
||||||
|
fix_jump(ls, c, je+1); /* fix first jump to beginning of `else' part */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1395,9 +1307,9 @@ static void parlist (LexState *ls) {
|
|||||||
|
|
||||||
static void body (LexState *ls, int needself, int line) {
|
static void body (LexState *ls, int needself, int line) {
|
||||||
/* body -> '(' parlist ')' chunk END */
|
/* body -> '(' parlist ')' chunk END */
|
||||||
FuncState newfs;
|
FuncState new_fs;
|
||||||
init_state(ls, &newfs, ls->fs->f->source);
|
init_state(ls, &new_fs, ls->fs->f->source);
|
||||||
newfs.f->lineDefined = line;
|
new_fs.f->lineDefined = line;
|
||||||
check(ls, '(');
|
check(ls, '(');
|
||||||
if (needself)
|
if (needself)
|
||||||
add_localvar(ls, luaS_newfixed(ls->L, "self"));
|
add_localvar(ls, luaS_newfixed(ls->L, "self"));
|
||||||
@@ -1406,7 +1318,7 @@ static void body (LexState *ls, int needself, int line) {
|
|||||||
chunk(ls);
|
chunk(ls);
|
||||||
check_match(ls, END, FUNCTION, line);
|
check_match(ls, END, FUNCTION, line);
|
||||||
close_func(ls);
|
close_func(ls);
|
||||||
func_onstack(ls, &newfs);
|
func_onstack(ls, &new_fs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1418,12 +1330,12 @@ static void ret (LexState *ls) {
|
|||||||
next(ls);
|
next(ls);
|
||||||
explist(ls, &e);
|
explist(ls, &e);
|
||||||
if (e.pc > 0) { /* expression is an open function call? */
|
if (e.pc > 0) { /* expression is an open function call? */
|
||||||
Byte *code = ls->fs->f->code;
|
Instruction *i = &ls->fs->f->code[e.pc];
|
||||||
code[e.pc-2] = TAILCALL; /* instead of a conventional CALL */
|
*i = SET_OPCODE(*i, TAILCALL); /* instead of a conventional CALL */
|
||||||
code[e.pc-1] = (Byte)ls->fs->nlocalvar;
|
*i = SETARG_B(*i, ls->fs->nlocalvar);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
code_oparg(ls, RETCODE, ls->fs->nlocalvar, 0);
|
code_U(ls, RETCODE, ls->fs->nlocalvar, 0);
|
||||||
ls->fs->stacksize = ls->fs->nlocalvar; /* removes all temp values */
|
ls->fs->stacksize = ls->fs->nlocalvar; /* removes all temp values */
|
||||||
optional(ls, ';');
|
optional(ls, ';');
|
||||||
}
|
}
|
||||||
|
|||||||
235
lvm.c
235
lvm.c
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: lvm.c,v 1.85 2000/02/08 16:39:42 roberto Exp roberto $
|
** $Id: lvm.c,v 1.86 2000/02/11 16:52:54 roberto Exp roberto $
|
||||||
** Lua virtual machine
|
** Lua virtual machine
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
*/
|
*/
|
||||||
@@ -280,6 +280,11 @@ void luaV_comparison (lua_State *L) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define setbool(o,cond) if (cond) { \
|
||||||
|
ttype(o) = LUA_T_NUMBER; nvalue(o) = 1.0; } \
|
||||||
|
else ttype(o) = LUA_T_NIL
|
||||||
|
|
||||||
|
|
||||||
void luaV_pack (lua_State *L, StkId firstelem, int nvararg, TObject *tab) {
|
void luaV_pack (lua_State *L, StkId firstelem, int nvararg, TObject *tab) {
|
||||||
int i;
|
int i;
|
||||||
Hash *htab;
|
Hash *htab;
|
||||||
@@ -313,90 +318,80 @@ static void adjust_varargs (lua_State *L, StkId base, int nfixargs) {
|
|||||||
StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf,
|
StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf,
|
||||||
register StkId base) {
|
register StkId base) {
|
||||||
register StkId top; /* keep top local, for performance */
|
register StkId top; /* keep top local, for performance */
|
||||||
register const Byte *pc = tf->code;
|
register const Instruction *pc = tf->code;
|
||||||
TaggedString **kstr = tf->kstr;
|
TaggedString **kstr = tf->kstr;
|
||||||
if (L->callhook)
|
if (L->callhook)
|
||||||
luaD_callHook(L, base-1, L->callhook, "call");
|
luaD_callHook(L, base-1, L->callhook, "call");
|
||||||
luaD_checkstack(L, (*pc++)+EXTRA_STACK);
|
luaD_checkstack(L, tf->maxstacksize+EXTRA_STACK);
|
||||||
if (*pc < ZEROVARARG)
|
if (tf->is_vararg) { /* varargs? */
|
||||||
luaD_adjusttop(L, base, *(pc++));
|
adjust_varargs(L, base, tf->numparams);
|
||||||
else { /* varargs */
|
|
||||||
adjust_varargs(L, base, (*pc++)-ZEROVARARG);
|
|
||||||
luaC_checkGC(L);
|
luaC_checkGC(L);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
luaD_adjusttop(L, base, tf->numparams);
|
||||||
top = L->top;
|
top = L->top;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
register int aux = 0;
|
register Instruction i = *pc++;
|
||||||
switchentry:
|
switch (GET_OPCODE(i)) {
|
||||||
switch ((OpCode)*pc++) {
|
|
||||||
|
|
||||||
case ENDCODE:
|
case ENDCODE:
|
||||||
return L->top; /* no results */
|
return L->top; /* no results */
|
||||||
|
|
||||||
case RETCODE:
|
case RETCODE:
|
||||||
L->top = top;
|
L->top = top;
|
||||||
return base+(*pc++);
|
return base+GETARG_U(i);
|
||||||
|
|
||||||
case CALL: aux = *pc++;
|
case CALL:
|
||||||
L->top = top;
|
L->top = top;
|
||||||
luaD_call(L, base+(*pc++), aux);
|
luaD_call(L, base+GETARG_A(i), GETARG_B(i));
|
||||||
top = L->top;
|
top = L->top;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TAILCALL: aux = *pc++;
|
case TAILCALL:
|
||||||
L->top = top;
|
L->top = top;
|
||||||
luaD_call(L, base+(*pc++), MULT_RET);
|
luaD_call(L, base+GETARG_A(i), MULT_RET);
|
||||||
return base+aux;
|
return base+GETARG_B(i);
|
||||||
|
|
||||||
case PUSHNIL: aux = *pc++;
|
case PUSHNIL: {
|
||||||
|
register int n = GETARG_U(i);
|
||||||
do {
|
do {
|
||||||
ttype(top++) = LUA_T_NIL;
|
ttype(top++) = LUA_T_NIL;
|
||||||
} while (aux--);
|
} while (n--);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case POP:
|
||||||
|
top -= GETARG_U(i);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case POP: aux = *pc++;
|
case PUSHINT:
|
||||||
top -= aux;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PUSHINTW: aux += highbyte(L, *pc++);
|
|
||||||
case PUSHINT: aux += *pc++;
|
|
||||||
ttype(top) = LUA_T_NUMBER;
|
ttype(top) = LUA_T_NUMBER;
|
||||||
nvalue(top) = aux;
|
nvalue(top) = (real)GETARG_S(i);
|
||||||
top++;
|
top++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PUSHINTNEGW: aux += highbyte(L, *pc++);
|
case PUSHSTRING:
|
||||||
case PUSHINTNEG: aux += *pc++;
|
|
||||||
ttype(top) = LUA_T_NUMBER;
|
|
||||||
nvalue(top) = -aux;
|
|
||||||
top++;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PUSHSTRINGW: aux += highbyte(L, *pc++);
|
|
||||||
case PUSHSTRING: aux += *pc++;
|
|
||||||
ttype(top) = LUA_T_STRING;
|
ttype(top) = LUA_T_STRING;
|
||||||
tsvalue(top) = kstr[aux];
|
tsvalue(top) = kstr[GETARG_U(i)];
|
||||||
top++;
|
top++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PUSHNUMBERW: aux += highbyte(L, *pc++);
|
case PUSHNUMBER:
|
||||||
case PUSHNUMBER: aux += *pc++;
|
|
||||||
ttype(top) = LUA_T_NUMBER;
|
ttype(top) = LUA_T_NUMBER;
|
||||||
nvalue(top) = tf->knum[aux];
|
nvalue(top) = tf->knum[GETARG_U(i)];
|
||||||
top++;
|
top++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PUSHUPVALUE: aux = *pc++;
|
case PUSHUPVALUE:
|
||||||
*top++ = cl->consts[aux+1];
|
*top++ = cl->consts[GETARG_U(i)+1];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PUSHLOCAL: aux = *pc++;
|
case PUSHLOCAL:
|
||||||
*top++ = *(base+aux);
|
*top++ = *(base+GETARG_U(i));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GETGLOBALW: aux += highbyte(L, *pc++);
|
case GETGLOBAL:
|
||||||
case GETGLOBAL: aux += *pc++;
|
luaV_getglobal(L, kstr[GETARG_U(i)]->u.s.gv, top);
|
||||||
luaV_getglobal(L, kstr[aux]->u.s.gv, top);
|
|
||||||
top++;
|
top++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -405,41 +400,37 @@ StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf,
|
|||||||
top--;
|
top--;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GETDOTTEDW: aux += highbyte(L, *pc++);
|
case GETDOTTED:
|
||||||
case GETDOTTED: aux += *pc++;
|
|
||||||
ttype(top) = LUA_T_STRING;
|
ttype(top) = LUA_T_STRING;
|
||||||
tsvalue(top++) = kstr[aux];
|
tsvalue(top++) = kstr[GETARG_U(i)];
|
||||||
luaV_gettable(L, top);
|
luaV_gettable(L, top);
|
||||||
top--;
|
top--;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PUSHSELFW: aux += highbyte(L, *pc++);
|
case PUSHSELF: {
|
||||||
case PUSHSELF: aux += *pc++; {
|
|
||||||
TObject receiver;
|
TObject receiver;
|
||||||
receiver = *(top-1);
|
receiver = *(top-1);
|
||||||
ttype(top) = LUA_T_STRING;
|
ttype(top) = LUA_T_STRING;
|
||||||
tsvalue(top++) = kstr[aux];
|
tsvalue(top++) = kstr[GETARG_U(i)];
|
||||||
luaV_gettable(L, top);
|
luaV_gettable(L, top);
|
||||||
*(top-1) = receiver;
|
*(top-1) = receiver;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case CREATEARRAYW: aux += highbyte(L, *pc++);
|
case CREATETABLE:
|
||||||
case CREATEARRAY: aux += *pc++;
|
|
||||||
L->top = top;
|
L->top = top;
|
||||||
luaC_checkGC(L);
|
luaC_checkGC(L);
|
||||||
avalue(top) = luaH_new(L, aux);
|
avalue(top) = luaH_new(L, GETARG_U(i));
|
||||||
ttype(top) = LUA_T_ARRAY;
|
ttype(top) = LUA_T_ARRAY;
|
||||||
top++;
|
top++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SETLOCAL: aux = *pc++;
|
case SETLOCAL:
|
||||||
*(base+aux) = *(--top);
|
*(base+GETARG_U(i)) = *(--top);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SETGLOBALW: aux += highbyte(L, *pc++);
|
case SETGLOBAL:
|
||||||
case SETGLOBAL: aux += *pc++;
|
luaV_setglobal(L, kstr[GETARG_U(i)]->u.s.gv, top);
|
||||||
luaV_setglobal(L, kstr[aux]->u.s.gv, top);
|
|
||||||
top--;
|
top--;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -449,91 +440,81 @@ StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SETTABLE:
|
case SETTABLE:
|
||||||
luaV_settable(L, top-3-(*pc++), top);
|
luaV_settable(L, top-3-GETARG_U(i), top);
|
||||||
top--; /* pop value */
|
top--; /* pop value */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SETLISTW: aux += highbyte(L, *pc++);
|
case SETLIST: {
|
||||||
case SETLIST: aux += *pc++; {
|
int aux = GETARG_A(i) * LFIELDS_PER_FLUSH;
|
||||||
int n = *(pc++);
|
int n = GETARG_B(i)+1;
|
||||||
Hash *arr = avalue(top-n-1);
|
Hash *arr = avalue(top-n-1);
|
||||||
L->top = top-n; /* final value of `top' (in case of errors) */
|
L->top = top-n; /* final value of `top' (in case of errors) */
|
||||||
aux *= LFIELDS_PER_FLUSH;
|
|
||||||
for (; n; n--)
|
for (; n; n--)
|
||||||
luaH_setint(L, arr, n+aux, --top);
|
luaH_setint(L, arr, n+aux, --top);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SETMAP: aux = *pc++; {
|
case SETMAP: {
|
||||||
StkId finaltop = top-2*(aux+1);
|
int n = GETARG_U(i);
|
||||||
|
StkId finaltop = top-2*(n+1);
|
||||||
Hash *arr = avalue(finaltop-1);
|
Hash *arr = avalue(finaltop-1);
|
||||||
L->top = finaltop; /* final value of `top' (in case of errors) */
|
L->top = finaltop; /* final value of `top' (in case of errors) */
|
||||||
do {
|
do {
|
||||||
luaH_set(L, arr, top-2, top-1);
|
luaH_set(L, arr, top-2, top-1);
|
||||||
top-=2;
|
top-=2;
|
||||||
} while (aux--);
|
} while (n--);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case NEQOP: aux = 1;
|
case NEQOP:
|
||||||
|
top--;
|
||||||
|
setbool(top-1, !luaO_equalObj(top-1, top));
|
||||||
|
break;
|
||||||
|
|
||||||
case EQOP:
|
case EQOP:
|
||||||
top--;
|
top--;
|
||||||
aux = (luaO_equalObj(top-1, top) != aux);
|
setbool(top-1, luaO_equalObj(top-1, top));
|
||||||
booleanresult:
|
|
||||||
if (aux) {
|
|
||||||
ttype(top-1) = LUA_T_NUMBER;
|
|
||||||
nvalue(top-1) = 1.0;
|
|
||||||
}
|
|
||||||
else ttype(top-1) = LUA_T_NIL;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LTOP:
|
case LTOP:
|
||||||
top--;
|
top--;
|
||||||
if (ttype(top-1) == LUA_T_NUMBER && ttype(top) == LUA_T_NUMBER)
|
if (ttype(top-1) == LUA_T_NUMBER && ttype(top) == LUA_T_NUMBER)
|
||||||
aux = nvalue(top-1) < nvalue(top);
|
setbool(top-1, nvalue(top-1) < nvalue(top));
|
||||||
else if (ttype(top-1) == LUA_T_STRING && ttype(top) == LUA_T_STRING)
|
else if (ttype(top-1) == LUA_T_STRING && ttype(top) == LUA_T_STRING)
|
||||||
aux = luaV_strcomp(tsvalue(top-1), tsvalue(top)) < 0;
|
setbool(top-1, luaV_strcomp(tsvalue(top-1), tsvalue(top)) < 0);
|
||||||
else {
|
else
|
||||||
call_binTM(L, top+1, IM_LT, "unexpected type in comparison");
|
call_binTM(L, top+1, IM_LT, "unexpected type in comparison");
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
goto booleanresult;
|
|
||||||
|
|
||||||
case LEOP:
|
case LEOP:
|
||||||
top--;
|
top--;
|
||||||
if (ttype(top-1) == LUA_T_NUMBER && ttype(top) == LUA_T_NUMBER)
|
if (ttype(top-1) == LUA_T_NUMBER && ttype(top) == LUA_T_NUMBER)
|
||||||
aux = nvalue(top-1) <= nvalue(top);
|
setbool(top-1, nvalue(top-1) <= nvalue(top));
|
||||||
else if (ttype(top-1) == LUA_T_STRING && ttype(top) == LUA_T_STRING)
|
else if (ttype(top-1) == LUA_T_STRING && ttype(top) == LUA_T_STRING)
|
||||||
aux = luaV_strcomp(tsvalue(top-1), tsvalue(top)) <= 0;
|
setbool(top-1, luaV_strcomp(tsvalue(top-1), tsvalue(top)) <= 0);
|
||||||
else {
|
else
|
||||||
call_binTM(L, top+1, IM_LE, "unexpected type in comparison");
|
call_binTM(L, top+1, IM_LE, "unexpected type in comparison");
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
goto booleanresult;
|
|
||||||
|
|
||||||
case GTOP:
|
case GTOP:
|
||||||
top--;
|
top--;
|
||||||
if (ttype(top-1) == LUA_T_NUMBER && ttype(top) == LUA_T_NUMBER)
|
if (ttype(top-1) == LUA_T_NUMBER && ttype(top) == LUA_T_NUMBER)
|
||||||
aux = nvalue(top-1) > nvalue(top);
|
setbool(top-1, nvalue(top-1) > nvalue(top));
|
||||||
else if (ttype(top-1) == LUA_T_STRING && ttype(top) == LUA_T_STRING)
|
else if (ttype(top-1) == LUA_T_STRING && ttype(top) == LUA_T_STRING)
|
||||||
aux = luaV_strcomp(tsvalue(top-1), tsvalue(top)) > 0;
|
setbool(top-1, luaV_strcomp(tsvalue(top-1), tsvalue(top)) > 0);
|
||||||
else {
|
else
|
||||||
call_binTM(L, top+1, IM_GT, "unexpected type in comparison");
|
call_binTM(L, top+1, IM_GT, "unexpected type in comparison");
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
goto booleanresult;
|
|
||||||
|
|
||||||
case GEOP:
|
case GEOP:
|
||||||
top--;
|
top--;
|
||||||
if (ttype(top-1) == LUA_T_NUMBER && ttype(top) == LUA_T_NUMBER)
|
if (ttype(top-1) == LUA_T_NUMBER && ttype(top) == LUA_T_NUMBER)
|
||||||
aux = nvalue(top-1) >= nvalue(top);
|
setbool(top-1, nvalue(top-1) >= nvalue(top));
|
||||||
else if (ttype(top-1) == LUA_T_STRING && ttype(top) == LUA_T_STRING)
|
else if (ttype(top-1) == LUA_T_STRING && ttype(top) == LUA_T_STRING)
|
||||||
aux = luaV_strcomp(tsvalue(top-1), tsvalue(top)) >= 0;
|
setbool(top-1, luaV_strcomp(tsvalue(top-1), tsvalue(top)) >= 0);
|
||||||
else {
|
else
|
||||||
call_binTM(L, top+1, IM_GE, "unexpected type in comparison");
|
call_binTM(L, top+1, IM_GE, "unexpected type in comparison");
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
goto booleanresult;
|
|
||||||
|
|
||||||
case ADDOP:
|
case ADDOP:
|
||||||
if (tonumber(top-1) || tonumber(top-2))
|
if (tonumber(top-1) || tonumber(top-2))
|
||||||
@@ -597,71 +578,53 @@ StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf,
|
|||||||
nvalue(top-1) = 1;
|
nvalue(top-1) = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ONTJMPW: aux += highbyte(L, *pc++);
|
case ONTJMP:
|
||||||
case ONTJMP: aux += *pc++;
|
if (ttype(top-1) != LUA_T_NIL) pc += GETARG_S(i);
|
||||||
if (ttype(top-1) != LUA_T_NIL) pc += aux;
|
|
||||||
else top--;
|
else top--;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ONFJMPW: aux += highbyte(L, *pc++);
|
case ONFJMP:
|
||||||
case ONFJMP: aux += *pc++;
|
if (ttype(top-1) == LUA_T_NIL) pc += GETARG_S(i);
|
||||||
if (ttype(top-1) == LUA_T_NIL) pc += aux;
|
|
||||||
else top--;
|
else top--;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case JMPW: aux += highbyte(L, *pc++);
|
case JMP:
|
||||||
case JMP: aux += *pc++;
|
pc += GETARG_S(i);
|
||||||
pc += aux;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IFFJMPW: aux += highbyte(L, *pc++);
|
case IFTJMP:
|
||||||
case IFFJMP: aux += *pc++;
|
if (ttype(--top) != LUA_T_NIL) pc += GETARG_S(i);
|
||||||
if (ttype(--top) == LUA_T_NIL) pc += aux;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IFTUPJMPW: aux += highbyte(L, *pc++);
|
case IFFJMP:
|
||||||
case IFTUPJMP: aux += *pc++;
|
if (ttype(--top) == LUA_T_NIL) pc += GETARG_S(i);
|
||||||
if (ttype(--top) != LUA_T_NIL) pc -= aux;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IFFUPJMPW: aux += highbyte(L, *pc++);
|
case CLOSURE:
|
||||||
case IFFUPJMP: aux += *pc++;
|
|
||||||
if (ttype(--top) == LUA_T_NIL) pc -= aux;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CLOSUREW: aux += highbyte(L, *pc++);
|
|
||||||
case CLOSURE: aux += *pc++;
|
|
||||||
ttype(top) = LUA_T_LPROTO;
|
ttype(top) = LUA_T_LPROTO;
|
||||||
tfvalue(top) = tf->kproto[aux];
|
tfvalue(top) = tf->kproto[GETARG_A(i)];
|
||||||
L->top = ++top;
|
L->top = ++top;
|
||||||
aux = *pc++; /* number of upvalues */
|
luaV_closure(L, GETARG_B(i));
|
||||||
luaV_closure(L, aux);
|
top -= GETARG_B(i);
|
||||||
luaC_checkGC(L);
|
luaC_checkGC(L);
|
||||||
top -= aux;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SETLINEW: aux += highbyte(L, *pc++);
|
case SETLINE:
|
||||||
case SETLINE: aux += *pc++;
|
|
||||||
if ((base-1)->ttype != LUA_T_LINE) {
|
if ((base-1)->ttype != LUA_T_LINE) {
|
||||||
/* open space for LINE value */
|
/* open space for LINE value */
|
||||||
int i = top-base;
|
int n = top-base;
|
||||||
while (i--) base[i+1] = base[i];
|
while (n--) base[n+1] = base[n];
|
||||||
base++;
|
base++;
|
||||||
top++;
|
top++;
|
||||||
(base-1)->ttype = LUA_T_LINE;
|
(base-1)->ttype = LUA_T_LINE;
|
||||||
}
|
}
|
||||||
(base-1)->value.i = aux;
|
(base-1)->value.i = GETARG_U(i);
|
||||||
if (L->linehook) {
|
if (L->linehook) {
|
||||||
L->top = top;
|
L->top = top;
|
||||||
luaD_lineHook(L, base-2, aux);
|
luaD_lineHook(L, base-2, GETARG_U(i));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LONGARGW: aux += highbyte(L, *pc++);
|
|
||||||
case LONGARG: aux += *pc++;
|
|
||||||
aux = highbyte(L, highbyte(L, aux));
|
|
||||||
goto switchentry; /* do not reset `aux' */
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user