diff options
-rw-r--r-- | lobject.h | 16 | ||||
-rw-r--r-- | lopcodes.h | 147 | ||||
-rw-r--r-- | lparser.c | 332 | ||||
-rw-r--r-- | lvm.c | 231 |
4 files changed, 293 insertions, 433 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lobject.h,v 1.45 2000/01/28 16:53:00 roberto Exp roberto $ | 2 | ** $Id: lobject.h,v 1.46 2000/02/11 16:52:54 roberto Exp roberto $ |
3 | ** Type definitions for Lua objects | 3 | ** Type definitions for Lua objects |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -36,11 +36,14 @@ | |||
36 | #define LUA_NUM_TYPE double | 36 | #define LUA_NUM_TYPE double |
37 | #endif | 37 | #endif |
38 | 38 | ||
39 | |||
40 | typedef LUA_NUM_TYPE real; | 39 | typedef LUA_NUM_TYPE real; |
41 | 40 | ||
42 | #define Byte lua_Byte /* some systems have Byte as a predefined type */ | 41 | |
43 | typedef unsigned char Byte; /* unsigned 8 bits */ | 42 | /* |
43 | ** type for virtual-machine instructions | ||
44 | ** must be an unsigned with 4 bytes (see details in lopcodes.h) | ||
45 | */ | ||
46 | typedef unsigned long Instruction; | ||
44 | 47 | ||
45 | 48 | ||
46 | #define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */ | 49 | #define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */ |
@@ -157,9 +160,12 @@ typedef struct TProtoFunc { | |||
157 | int nknum; /* size of `knum' */ | 160 | int nknum; /* size of `knum' */ |
158 | struct TProtoFunc **kproto; /* functions defined inside the function */ | 161 | struct TProtoFunc **kproto; /* functions defined inside the function */ |
159 | int nkproto; /* size of `kproto' */ | 162 | int nkproto; /* size of `kproto' */ |
160 | Byte *code; /* ends with opcode ENDCODE */ | 163 | Instruction *code; /* ends with opcode ENDCODE */ |
161 | int lineDefined; | 164 | int lineDefined; |
162 | TaggedString *source; | 165 | TaggedString *source; |
166 | short numparams; | ||
167 | short is_vararg; | ||
168 | short maxstacksize; | ||
163 | struct LocVar *locvars; /* ends with line = -1 */ | 169 | struct LocVar *locvars; /* ends with line = -1 */ |
164 | } TProtoFunc; | 170 | } TProtoFunc; |
165 | 171 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lopcodes.h,v 1.38 2000/01/28 16:53:00 roberto Exp roberto $ | 2 | ** $Id: lopcodes.h,v 1.39 2000/02/11 16:52:54 roberto Exp roberto $ |
3 | ** Opcodes for Lua virtual machine | 3 | ** Opcodes for Lua virtual machine |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -8,67 +8,79 @@ | |||
8 | #define lopcodes_h | 8 | #define lopcodes_h |
9 | 9 | ||
10 | 10 | ||
11 | /* | ||
12 | ** NOTICE: variants of the same opcode must be consecutive: First, those | ||
13 | ** with word parameter, then with byte parameter. | ||
14 | */ | ||
15 | 11 | ||
12 | /*=========================================================================== | ||
13 | We assume that instructions are unsigned numbers with 4 bytes. | ||
14 | All instructions have an opcode in the lower byte. Moreover, | ||
15 | an instruction can have 0, 1, or 2 arguments. There are 4 types of | ||
16 | Instructions: | ||
17 | type 0: no arguments | ||
18 | type 1: 1 unsigned argument in the higher 24 bits (called `U') | ||
19 | type 2: 1 signed argument in the higher 24 bits (`S') | ||
20 | type 3: 1st unsigned argument in the higher 16 bits (`A') | ||
21 | 2nd unsigned argument in the middle 8 bits (`B') | ||
16 | 22 | ||
17 | typedef enum { | 23 | The signed argument is represented in excess 2^23; that is, the real value |
18 | /* name parm before after side effect | 24 | is 2^23 minus the usigned value. |
19 | -----------------------------------------------------------------------------*/ | 25 | ===========================================================================*/ |
20 | ENDCODE,/* - - (return) */ | ||
21 | RETCODE,/* b - (return) */ | ||
22 | |||
23 | CALL,/* b c v_n-v_1 f(at c) r_b-r_1 f(v1,...,v_n) */ | ||
24 | 26 | ||
25 | TAILCALL,/* b c v_c-v_1 f (return) f(v1,...,v_c) */ | 27 | /* |
28 | ** the following macros help to manipulate instructions | ||
29 | */ | ||
26 | 30 | ||
27 | PUSHNIL,/* b - nil_0-nil_b */ | 31 | #define MAXARG_U ((1<<24)-1) |
28 | POP,/* b a_b-a_1 - */ | 32 | #define MAXARG_S ((1<<23)-1) |
33 | #define MAXARG_A ((1<<16)-1) | ||
34 | #define MAXARG_B ((1<<8)-1) | ||
29 | 35 | ||
30 | PUSHINTW,/* w - (float)w */ | 36 | #define GET_OPCODE(i) ((OpCode)((i)&0xFF)) |
31 | PUSHINT,/* b - (float)b */ | 37 | #define GETARG_U(i) ((int)((i)>>8)) |
38 | #define GETARG_S(i) ((int)((i)>>8)-(1<<23)) | ||
39 | #define GETARG_A(i) ((int)((i)>>16)) | ||
40 | #define GETARG_B(i) ((int)(((i)>>8) & 0xFF)) | ||
32 | 41 | ||
33 | PUSHINTNEGW,/* w - (float)-w */ | 42 | #define SET_OPCODE(i,o) (((i)&0xFFFFFF00u) | (Instruction)(o)) |
34 | PUSHINTNEG,/* b - (float)-b */ | 43 | #define SETARG_U(i,u) (((i)&0x000000FFu) | ((Instruction)(u)<<8)) |
44 | #define SETARG_S(i,s) (((i)&0x000000FFu) | ((Instruction)((s)+(1<<23))<<8)) | ||
45 | #define SETARG_A(i,a) (((i)&0x0000FFFFu) | ((Instruction)(a)<<16)) | ||
46 | #define SETARG_B(i,b) (((i)&0xFFFF00FFu) | ((Instruction)(b)<<8)) | ||
35 | 47 | ||
36 | PUSHSTRINGW,/* w - KSTR[w] */ | ||
37 | PUSHSTRING,/* b - KSTR[b] */ | ||
38 | PUSHNUMBERW,/* w - KNUM[w] */ | ||
39 | PUSHNUMBER,/* b - KNUM[b] */ | ||
40 | 48 | ||
41 | PUSHUPVALUE,/* b - Closure[b] */ | ||
42 | 49 | ||
43 | PUSHLOCAL,/* b - LOC[b] */ | 50 | typedef enum { |
51 | /* name parm before after side effect | ||
52 | -----------------------------------------------------------------------------*/ | ||
53 | ENDCODE,/* - - (return) */ | ||
54 | RETCODE,/* U - (return) */ | ||
44 | 55 | ||
45 | GETGLOBALW,/* w - VAR[CNST[w]] */ | 56 | CALL,/* A B v_n-v_1 f(at a) r_b-r_1 f(v1,...,v_n) */ |
46 | GETGLOBAL,/* b - VAR[CNST[b]] */ | 57 | TAILCALL,/* A B v_a-v_1 f (return) f(v1,...,v_a) */ |
47 | 58 | ||
48 | GETTABLE,/* - i t t[i] */ | 59 | PUSHNIL,/* U - nil_0-nil_u */ |
60 | POP,/* U a_u-a_1 - */ | ||
49 | 61 | ||
50 | GETDOTTEDW,/* w t t[CNST[w]] */ | 62 | PUSHINT,/* S - (real)s */ |
51 | GETDOTTED,/* b t t[CNST[b]] */ | 63 | PUSHSTRING,/* U - KSTR[u] */ |
64 | PUSHNUMBER,/* U - KNUM[u] */ | ||
52 | 65 | ||
53 | PUSHSELFW,/* w t t t[CNST[w]] */ | 66 | PUSHUPVALUE,/* U - Closure[u] */ |
54 | PUSHSELF,/* b t t t[CNST[b]] */ | ||
55 | 67 | ||
56 | CREATEARRAYW,/* w - newarray(size = w) */ | 68 | PUSHLOCAL,/* U - LOC[u] */ |
57 | CREATEARRAY,/* b - newarray(size = b) */ | 69 | GETGLOBAL,/* U - VAR[CNST[u]] */ |
58 | 70 | ||
59 | SETLOCAL,/* b x - LOC[b]=x */ | 71 | GETTABLE,/* - i t t[i] */ |
72 | GETDOTTED,/* U t t[CNST[u]] */ | ||
73 | PUSHSELF,/* U t t t[CNST[u]] */ | ||
60 | 74 | ||
61 | SETGLOBALW,/* w x - VAR[CNST[w]]=x */ | 75 | CREATETABLE,/* U - newarray(size = u) */ |
62 | SETGLOBAL,/* b x - VAR[CNST[b]]=x */ | ||
63 | 76 | ||
77 | SETLOCAL,/* U x - LOC[u]=x */ | ||
78 | SETGLOBAL,/* U x - VAR[CNST[u]]=x */ | ||
64 | SETTABLEPOP,/* - v i t - t[i]=v */ | 79 | SETTABLEPOP,/* - v i t - t[i]=v */ |
80 | SETTABLE,/* U v a_u-a_1 i t a_u-a_1 i t t[i]=v */ | ||
65 | 81 | ||
66 | SETTABLE,/* b v a_b-a_1 i t a_b-a_1 i t t[i]=v */ | 82 | SETLIST,/* A B v_b-v_0 t t t[i+a*FPF]=v_i */ |
67 | 83 | SETMAP,/* U v_u k_u - v_0 k_0 t t t[k_i]=v_i */ | |
68 | SETLISTW,/* w c v_c-v_1 t t t[i+w*FPF]=v_i */ | ||
69 | SETLIST,/* b c v_c-v_1 t t t[i+b*FPF]=v_i */ | ||
70 | |||
71 | SETMAP,/* b v_b k_b - v_0 k_0 t t t[k_i]=v_i */ | ||
72 | 84 | ||
73 | NEQOP,/* - y x (x~=y)? 1 : nil */ | 85 | NEQOP,/* - y x (x~=y)? 1 : nil */ |
74 | EQOP,/* - y x (x==y)? 1 : nil */ | 86 | EQOP,/* - y x (x==y)? 1 : nil */ |
@@ -85,54 +97,21 @@ CONCOP,/* - y x x..y */ | |||
85 | MINUSOP,/* - x -x */ | 97 | MINUSOP,/* - x -x */ |
86 | NOTOP,/* - x (x==nil)? 1 : nil */ | 98 | NOTOP,/* - x (x==nil)? 1 : nil */ |
87 | 99 | ||
88 | ONTJMPW,/* w x (x!=nil)? x : - (x!=nil)? PC+=w */ | 100 | ONTJMP,/* S x (x!=nil)? x : - (x!=nil)? PC+=s */ |
89 | ONTJMP,/* b x (x!=nil)? x : - (x!=nil)? PC+=b */ | 101 | ONFJMP,/* S x (x==nil)? x : - (x==nil)? PC+=s */ |
90 | ONFJMPW,/* w x (x==nil)? x : - (x==nil)? PC+=w */ | 102 | JMP,/* S - - PC+=s */ |
91 | ONFJMP,/* b x (x==nil)? x : - (x==nil)? PC+=b */ | 103 | IFTJMP,/* S x - (x!=nil)? PC+=s */ |
92 | JMPW,/* w - - PC+=w */ | 104 | IFFJMP,/* S x - (x==nil)? PC+=s */ |
93 | JMP,/* b - - PC+=b */ | ||
94 | IFFJMPW,/* w x - (x==nil)? PC+=w */ | ||
95 | IFFJMP,/* b x - (x==nil)? PC+=b */ | ||
96 | IFTUPJMPW,/* w x - (x!=nil)? PC-=w */ | ||
97 | IFTUPJMP,/* b x - (x!=nil)? PC-=b */ | ||
98 | IFFUPJMPW,/* w x - (x==nil)? PC-=w */ | ||
99 | IFFUPJMP,/* b x - (x==nil)? PC-=b */ | ||
100 | 105 | ||
101 | CLOSUREW,/* w c v_c-v_1 closure(CNST[w], v_c-v_1) */ | 106 | CLOSURE,/* A B v_b-v_1 closure(CNST[a], v_b-v_1) */ |
102 | CLOSURE,/* b c v_c-v_1 closure(CNST[b], v_c-v_1) */ | ||
103 | 107 | ||
104 | SETLINEW,/* w - - LINE=w */ | 108 | SETLINE/* U - - LINE=u */ |
105 | SETLINE,/* b - - LINE=b */ | ||
106 | |||
107 | LONGARGW,/* w (add w*(1<<16) to arg of next instruction) */ | ||
108 | LONGARG /* b (add b*(1<<16) to arg of next instruction) */ | ||
109 | 109 | ||
110 | } OpCode; | 110 | } OpCode; |
111 | 111 | ||
112 | 112 | ||
113 | #define RFIELDS_PER_FLUSH 32 /* records (SETMAP) */ | 113 | #define RFIELDS_PER_FLUSH 32 /* records (SETMAP) */ |
114 | #define LFIELDS_PER_FLUSH 64 /* FPF - lists (SETLIST) */ | 114 | #define LFIELDS_PER_FLUSH 64 /* FPF - lists (SETLIST) (<MAXARG_B) */ |
115 | |||
116 | #define ZEROVARARG 128 | ||
117 | |||
118 | |||
119 | /* maximum value of an arg of 3 bytes; must fit in an "int" */ | ||
120 | #if MAX_INT < (1<<24) | ||
121 | #define MAX_ARG MAX_INT | ||
122 | #else | ||
123 | #define MAX_ARG ((1<<24)-1) | ||
124 | #endif | ||
125 | |||
126 | /* maximum value of a word of 2 bytes; cannot be larger than MAX_ARG */ | ||
127 | #if MAX_ARG < (1<<16) | ||
128 | #define MAX_WORD MAX_ARG | ||
129 | #else | ||
130 | #define MAX_WORD ((1<<16)-1) | ||
131 | #endif | ||
132 | |||
133 | |||
134 | /* maximum value of a byte */ | ||
135 | #define MAX_BYTE ((1<<8)-1) | ||
136 | 115 | ||
137 | 116 | ||
138 | #endif | 117 | #endif |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lparser.c,v 1.57 2000/01/28 16:53:00 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 1.58 2000/02/11 16:52:54 roberto Exp roberto $ |
3 | ** LL(1) Parser and code generator for Lua | 3 | ** LL(1) Parser and code generator for Lua |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -20,30 +20,27 @@ | |||
20 | 20 | ||
21 | 21 | ||
22 | 22 | ||
23 | /* size of a "normal" jump instruction: OpCode + 1 byte */ | ||
24 | #define JMPSIZE 2 | ||
25 | |||
26 | /* maximum number of local variables */ | 23 | /* maximum number of local variables */ |
27 | #ifndef MAXLOCALS | 24 | #ifndef MAXLOCALS |
28 | #define MAXLOCALS 200 /* arbitrary limit (<256) */ | 25 | #define MAXLOCALS 200 /* arbitrary limit (<MAXARG_B) */ |
29 | #endif | 26 | #endif |
30 | 27 | ||
31 | 28 | ||
32 | /* maximum number of upvalues */ | 29 | /* maximum number of upvalues */ |
33 | #ifndef MAXUPVALUES | 30 | #ifndef MAXUPVALUES |
34 | #define MAXUPVALUES 32 /* arbitrary limit (<256) */ | 31 | #define MAXUPVALUES 32 /* arbitrary limit (<MAXARG_B) */ |
35 | #endif | 32 | #endif |
36 | 33 | ||
37 | 34 | ||
38 | /* maximum number of variables in the left side of an assignment */ | 35 | /* maximum number of variables in the left side of an assignment */ |
39 | #ifndef MAXVARSLH | 36 | #ifndef MAXVARSLH |
40 | #define MAXVARSLH 100 /* arbitrary limit (<255) */ | 37 | #define MAXVARSLH 100 /* arbitrary limit (<MAXARG_B) */ |
41 | #endif | 38 | #endif |
42 | 39 | ||
43 | 40 | ||
44 | /* maximum number of parameters in a function */ | 41 | /* maximum number of parameters in a function */ |
45 | #ifndef MAXPARAMS | 42 | #ifndef MAXPARAMS |
46 | #define MAXPARAMS 100 /* arbitrary limit (<ZEROVARARG) */ | 43 | #define MAXPARAMS 100 /* arbitrary limit (<MAXLOCALS) */ |
47 | #endif | 44 | #endif |
48 | 45 | ||
49 | 46 | ||
@@ -57,7 +54,7 @@ typedef enum { | |||
57 | VLOCAL, /* info is stack index */ | 54 | VLOCAL, /* info is stack index */ |
58 | VDOT, /* info is constant index of index name */ | 55 | VDOT, /* info is constant index of index name */ |
59 | VINDEXED, /* no info (table and index are on the stack) */ | 56 | VINDEXED, /* no info (table and index are on the stack) */ |
60 | VEXP /* info is pc index of `nparam' of a call (or 0 if exp is closed) */ | 57 | VEXP /* info is pc index of a call (or 0 if exp is closed) */ |
61 | } varkind; | 58 | } varkind; |
62 | 59 | ||
63 | typedef struct vardesc { | 60 | typedef struct vardesc { |
@@ -70,7 +67,7 @@ typedef struct vardesc { | |||
70 | ** Expression List descriptor: | 67 | ** Expression List descriptor: |
71 | ** tells number of expressions in the list, | 68 | ** tells number of expressions in the list, |
72 | ** and, if last expression is open (a function call), | 69 | ** and, if last expression is open (a function call), |
73 | ** where is its pc index of `nparam' | 70 | ** where is the call pc index. |
74 | */ | 71 | */ |
75 | typedef struct listdesc { | 72 | typedef struct listdesc { |
76 | int n; | 73 | int n; |
@@ -96,7 +93,6 @@ typedef struct FuncState { | |||
96 | struct FuncState *prev; /* enclosing function */ | 93 | struct FuncState *prev; /* enclosing function */ |
97 | int pc; /* next position to code */ | 94 | int pc; /* next position to code */ |
98 | int stacksize; /* number of values on activation register */ | 95 | int stacksize; /* number of values on activation register */ |
99 | int maxstacksize; /* maximum number of values on activation register */ | ||
100 | int nlocalvar; /* number of active local variables */ | 96 | int nlocalvar; /* number of active local variables */ |
101 | int nupvalues; /* number of upvalues */ | 97 | int nupvalues; /* number of upvalues */ |
102 | int nvars; /* number of entries in f->locvars (-1 if no debug information) */ | 98 | 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) { | |||
131 | } | 127 | } |
132 | 128 | ||
133 | 129 | ||
134 | static void check_pc (LexState *ls, int n) { | 130 | static int code_instruction (LexState *ls, Instruction i) { |
135 | luaM_growvector(ls->L, ls->fs->f->code, ls->fs->pc, n, | 131 | FuncState *fs = ls->fs; |
136 | Byte, codeEM, MAX_INT); | 132 | luaM_growvector(ls->L, fs->f->code, fs->pc, 1, Instruction, codeEM, MAXARG_S); |
133 | fs->f->code[fs->pc] = i; | ||
134 | return fs->pc++; | ||
137 | } | 135 | } |
138 | 136 | ||
139 | 137 | ||
140 | static void code_byte (LexState *ls, Byte c) { | 138 | static void fix_jump (LexState *ls, int pc, int dest) { |
141 | check_pc(ls, 1); | 139 | Instruction *jmp = &ls->fs->f->code[pc]; |
142 | ls->fs->f->code[ls->fs->pc++] = c; | 140 | /* jump is relative to position following jump instruction */ |
141 | *jmp = SETARG_S(*jmp, dest-(pc+1)); | ||
143 | } | 142 | } |
144 | 143 | ||
145 | 144 | ||
146 | static void deltastack (LexState *ls, int delta) { | 145 | static void deltastack (LexState *ls, int delta) { |
147 | FuncState *fs = ls->fs; | 146 | FuncState *fs = ls->fs; |
148 | fs->stacksize += delta; | 147 | fs->stacksize += delta; |
149 | if (fs->stacksize > fs->maxstacksize) { | 148 | if (delta > 0 && fs->stacksize > fs->f->maxstacksize) { |
150 | if (fs->stacksize > MAX_BYTE) | 149 | fs->f->maxstacksize = fs->stacksize; |
151 | luaY_error(ls, "function or expression too complex"); | ||
152 | fs->maxstacksize = fs->stacksize; | ||
153 | } | 150 | } |
154 | } | 151 | } |
155 | 152 | ||
156 | 153 | ||
157 | static void code_oparg_at (LexState *ls, int pc, OpCode op, | 154 | static int aux_code (LexState *ls, OpCode op, Instruction i, int delta) { |
158 | int arg, int delta) { | ||
159 | Byte *code = ls->fs->f->code; | ||
160 | deltastack(ls, delta); | 155 | deltastack(ls, delta); |
161 | if (arg <= MAX_BYTE) { | 156 | return code_instruction(ls, SET_OPCODE(i, op)); |
162 | code[pc] = (Byte)op; | ||
163 | code[pc+1] = (Byte)arg; | ||
164 | } | ||
165 | else if (arg > MAX_ARG) | ||
166 | luaY_error(ls, "code too long"); | ||
167 | else { /* MAX_BYTE < arg < MAX_ARG */ | ||
168 | if (arg > MAX_WORD) { | ||
169 | code[pc] = (Byte)LONGARG; | ||
170 | code[pc+1] = (Byte)(arg>>16); | ||
171 | pc += 2; | ||
172 | } | ||
173 | code[pc] = (Byte)(op-1); /* opcode for word argument */ | ||
174 | code[pc+1] = (Byte)((arg&0xFFFF)>>8); | ||
175 | code[pc+2] = (Byte)(arg&0xFF); | ||
176 | } | ||
177 | } | 157 | } |
178 | 158 | ||
179 | 159 | ||
180 | static int codesize (int arg) { | 160 | static int code_0 (LexState *ls, OpCode op, int delta) { |
181 | if (arg <= MAX_BYTE) return 2; /* opcode + 1 byte */ | 161 | return aux_code(ls, op, 0, delta); |
182 | else if (arg <= MAX_WORD) return 3; /* opcode + 1 word (2 bytes) */ | ||
183 | else return 5; /* LONGARG + 1 byte + opcode + 1 word (2 bytes) */ | ||
184 | } | 162 | } |
185 | 163 | ||
186 | 164 | ||
187 | static int fix_opcode (LexState *ls, int pc, OpCode op, int arg) { | 165 | |
188 | int tomove = codesize(arg)-2; | 166 | static int code_U (LexState *ls, OpCode op, int u, int delta) { |
189 | if (tomove > 0) { /* need to open space? */ | 167 | Instruction i = SETARG_U(0, u); |
190 | FuncState *fs = ls->fs; | 168 | return aux_code(ls, op, i, delta); |
191 | TProtoFunc *f = fs->f; | ||
192 | check_pc(ls, tomove); | ||
193 | luaO_memup(f->code+pc+tomove, f->code+pc, fs->pc-pc); | ||
194 | fs->pc += tomove; | ||
195 | } | ||
196 | code_oparg_at(ls, pc, op, arg, 0); | ||
197 | return tomove; | ||
198 | } | 169 | } |
199 | 170 | ||
200 | 171 | ||
201 | static void code_oparg (LexState *ls, OpCode op, int arg, int delta) { | 172 | static int code_S (LexState *ls, OpCode op, int s, int delta) { |
202 | int size = codesize(arg); | 173 | Instruction i = SETARG_S(0, s); |
203 | check_pc(ls, size); | 174 | return aux_code(ls, op, i, delta); |
204 | code_oparg_at(ls, ls->fs->pc, op, arg, delta); | ||
205 | ls->fs->pc += size; | ||
206 | } | 175 | } |
207 | 176 | ||
208 | 177 | ||
209 | static void code_opcode (LexState *ls, OpCode op, int delta) { | 178 | static int code_AB (LexState *ls, OpCode op, int a, int b, int delta) { |
210 | deltastack(ls, delta); | 179 | Instruction i = SETARG_A(0, a); |
211 | code_byte(ls, (Byte)op); | 180 | i = SETARG_B(i, b); |
181 | return aux_code(ls, op, i, delta); | ||
212 | } | 182 | } |
213 | 183 | ||
214 | 184 | ||
215 | static void code_kstr (LexState *ls, int c) { | 185 | static void code_kstr (LexState *ls, int c) { |
216 | code_oparg(ls, PUSHSTRING, c, 1); | 186 | code_U(ls, PUSHSTRING, c, 1); |
217 | } | 187 | } |
218 | 188 | ||
219 | 189 | ||
@@ -226,8 +196,8 @@ static int string_constant (LexState *ls, FuncState *fs, TaggedString *s) { | |||
226 | TProtoFunc *f = fs->f; | 196 | TProtoFunc *f = fs->f; |
227 | int c = s->constindex; | 197 | int c = s->constindex; |
228 | if (c >= f->nkstr || f->kstr[c] != s) { | 198 | if (c >= f->nkstr || f->kstr[c] != s) { |
229 | luaM_growvector(ls->L, f->kstr, f->nkstr, 1, | 199 | luaM_growvector(ls->L, f->kstr, f->nkstr, 1, TaggedString *, |
230 | TaggedString *, constantEM, MAX_ARG); | 200 | constantEM, MAXARG_U); |
231 | c = f->nkstr++; | 201 | c = f->nkstr++; |
232 | f->kstr[c] = s; | 202 | f->kstr[c] = s; |
233 | s->constindex = c; /* hint for next time */ | 203 | s->constindex = c; /* hint for next time */ |
@@ -250,8 +220,7 @@ static int real_constant (LexState *ls, real r) { | |||
250 | while (--c >= lim) | 220 | while (--c >= lim) |
251 | if (f->knum[c] == r) return c; | 221 | if (f->knum[c] == r) return c; |
252 | /* not found; create a new entry */ | 222 | /* not found; create a new entry */ |
253 | luaM_growvector(ls->L, f->knum, f->nknum, 1, | 223 | luaM_growvector(ls->L, f->knum, f->nknum, 1, real, constantEM, MAXARG_U); |
254 | real, constantEM, MAX_ARG); | ||
255 | c = f->nknum++; | 224 | c = f->nknum++; |
256 | f->knum[c] = r; | 225 | f->knum[c] = r; |
257 | return c; | 226 | return c; |
@@ -259,27 +228,10 @@ static int real_constant (LexState *ls, real r) { | |||
259 | 228 | ||
260 | 229 | ||
261 | static void code_number (LexState *ls, real f) { | 230 | static void code_number (LexState *ls, real f) { |
262 | real af = (f<0) ? -f : f; | 231 | if ((real)(-MAXARG_S) <= f && f <= (real)MAXARG_S && (int)f == f) |
263 | if (0 <= af && af <= (real)MAX_WORD && (int)af == af) { | 232 | code_S(ls, PUSHINT, (int)f, 1); /* f has a short integer value */ |
264 | /* abs(f) has a short integer value */ | ||
265 | code_oparg(ls, (f<0) ? PUSHINTNEG : PUSHINT, (int)af, 1); | ||
266 | } | ||
267 | else | 233 | else |
268 | code_oparg(ls, PUSHNUMBER, real_constant(ls, f), 1); | 234 | code_U(ls, PUSHNUMBER, real_constant(ls, f), 1); |
269 | } | ||
270 | |||
271 | |||
272 | static void flush_record (LexState *ls, int n) { | ||
273 | if (n > 0) | ||
274 | code_oparg(ls, SETMAP, n-1, -2*n); | ||
275 | } | ||
276 | |||
277 | |||
278 | static void flush_list (LexState *ls, int m, int n) { | ||
279 | if (n > 0) { | ||
280 | code_oparg(ls, SETLIST, m, -n); | ||
281 | code_byte(ls, (Byte)n); | ||
282 | } | ||
283 | } | 235 | } |
284 | 236 | ||
285 | 237 | ||
@@ -371,14 +323,14 @@ static void pushupvalue (LexState *ls, TaggedString *n) { | |||
371 | luaX_syntaxerror(ls, "cannot access upvalue in main", n->str); | 323 | luaX_syntaxerror(ls, "cannot access upvalue in main", n->str); |
372 | if (aux_localname(ls->fs, n) >= 0) | 324 | if (aux_localname(ls->fs, n) >= 0) |
373 | luaX_syntaxerror(ls, "cannot access an upvalue in current scope", n->str); | 325 | luaX_syntaxerror(ls, "cannot access an upvalue in current scope", n->str); |
374 | code_oparg(ls, PUSHUPVALUE, indexupvalue(ls, n), 1); | 326 | code_U(ls, PUSHUPVALUE, indexupvalue(ls, n), 1); |
375 | } | 327 | } |
376 | 328 | ||
377 | 329 | ||
378 | 330 | ||
379 | static void check_debugline (LexState *ls) { | 331 | static void check_debugline (LexState *ls) { |
380 | if (ls->L->debug && ls->linenumber != ls->fs->lastsetline) { | 332 | if (ls->L->debug && ls->linenumber != ls->fs->lastsetline) { |
381 | code_oparg(ls, SETLINE, ls->linenumber, 0); | 333 | code_U(ls, SETLINE, ls->linenumber, 0); |
382 | ls->fs->lastsetline = ls->linenumber; | 334 | ls->fs->lastsetline = ls->linenumber; |
383 | } | 335 | } |
384 | } | 336 | } |
@@ -386,16 +338,16 @@ static void check_debugline (LexState *ls) { | |||
386 | 338 | ||
387 | static void adjuststack (LexState *ls, int n) { | 339 | static void adjuststack (LexState *ls, int n) { |
388 | if (n > 0) | 340 | if (n > 0) |
389 | code_oparg(ls, POP, n, -n); | 341 | code_U(ls, POP, n, -n); |
390 | else if (n < 0) | 342 | else if (n < 0) |
391 | code_oparg(ls, PUSHNIL, (-n)-1, -n); | 343 | code_U(ls, PUSHNIL, (-n)-1, -n); |
392 | } | 344 | } |
393 | 345 | ||
394 | 346 | ||
395 | static void close_exp (LexState *ls, int pc, int nresults) { | 347 | static void close_exp (LexState *ls, int pc, int nresults) { |
396 | if (pc > 0) { /* expression is an open function call? */ | 348 | if (pc > 0) { /* expression is an open function call? */ |
397 | Byte *code = ls->fs->f->code; | 349 | Instruction *i = &ls->fs->f->code[pc]; |
398 | code[pc-1] = (Byte)nresults; /* set nresults */ | 350 | *i = SETARG_B(*i, nresults); /* set nresults */ |
399 | if (nresults != MULT_RET) | 351 | if (nresults != MULT_RET) |
400 | deltastack(ls, nresults); /* push results */ | 352 | deltastack(ls, nresults); /* push results */ |
401 | } | 353 | } |
@@ -426,13 +378,12 @@ static void code_args (LexState *ls, int nparams, int dots) { | |||
426 | FuncState *fs = ls->fs; | 378 | FuncState *fs = ls->fs; |
427 | adjustlocalvars(ls, nparams, 0); | 379 | adjustlocalvars(ls, nparams, 0); |
428 | checklimit(ls, fs->nlocalvar, MAXPARAMS, "parameters"); | 380 | checklimit(ls, fs->nlocalvar, MAXPARAMS, "parameters"); |
429 | nparams = fs->nlocalvar; | 381 | nparams = fs->nlocalvar; /* `self' could be there already */ |
430 | if (!dots) { | 382 | fs->f->numparams = nparams; |
431 | fs->f->code[1] = (Byte)nparams; /* fill-in arg information */ | 383 | fs->f->is_vararg = dots; |
384 | if (!dots) | ||
432 | deltastack(ls, nparams); | 385 | deltastack(ls, nparams); |
433 | } | ||
434 | else { | 386 | else { |
435 | fs->f->code[1] = (Byte)(nparams+ZEROVARARG); | ||
436 | deltastack(ls, nparams+1); | 387 | deltastack(ls, nparams+1); |
437 | add_localvar(ls, luaS_newfixed(ls->L, "arg")); | 388 | add_localvar(ls, luaS_newfixed(ls->L, "arg")); |
438 | } | 389 | } |
@@ -451,17 +402,17 @@ static void unloaddot (LexState *ls, vardesc *v) { | |||
451 | static void lua_pushvar (LexState *ls, vardesc *var) { | 402 | static void lua_pushvar (LexState *ls, vardesc *var) { |
452 | switch (var->k) { | 403 | switch (var->k) { |
453 | case VLOCAL: | 404 | case VLOCAL: |
454 | code_oparg(ls, PUSHLOCAL, var->info, 1); | 405 | code_U(ls, PUSHLOCAL, var->info, 1); |
455 | break; | 406 | break; |
456 | case VGLOBAL: | 407 | case VGLOBAL: |
457 | code_oparg(ls, GETGLOBAL, var->info, 1); | 408 | code_U(ls, GETGLOBAL, var->info, 1); |
458 | assertglobal(ls, var->info); /* make sure that there is a global */ | 409 | assertglobal(ls, var->info); /* make sure that there is a global */ |
459 | break; | 410 | break; |
460 | case VDOT: | 411 | case VDOT: |
461 | code_oparg(ls, GETDOTTED, var->info, 0); | 412 | code_U(ls, GETDOTTED, var->info, 0); |
462 | break; | 413 | break; |
463 | case VINDEXED: | 414 | case VINDEXED: |
464 | code_opcode(ls, GETTABLE, -1); | 415 | code_0(ls, GETTABLE, -1); |
465 | break; | 416 | break; |
466 | case VEXP: | 417 | case VEXP: |
467 | close_exp(ls, var->info, 1); /* function must return 1 value */ | 418 | close_exp(ls, var->info, 1); /* function must return 1 value */ |
@@ -475,14 +426,14 @@ static void lua_pushvar (LexState *ls, vardesc *var) { | |||
475 | static void storevar (LexState *ls, const vardesc *var) { | 426 | static void storevar (LexState *ls, const vardesc *var) { |
476 | switch (var->k) { | 427 | switch (var->k) { |
477 | case VLOCAL: | 428 | case VLOCAL: |
478 | code_oparg(ls, SETLOCAL, var->info, -1); | 429 | code_U(ls, SETLOCAL, var->info, -1); |
479 | break; | 430 | break; |
480 | case VGLOBAL: | 431 | case VGLOBAL: |
481 | code_oparg(ls, SETGLOBAL, var->info, -1); | 432 | code_U(ls, SETGLOBAL, var->info, -1); |
482 | assertglobal(ls, var->info); /* make sure that there is a global */ | 433 | assertglobal(ls, var->info); /* make sure that there is a global */ |
483 | break; | 434 | break; |
484 | case VINDEXED: | 435 | case VINDEXED: |
485 | code_opcode(ls, SETTABLEPOP, -3); | 436 | code_0(ls, SETTABLEPOP, -3); |
486 | break; | 437 | break; |
487 | default: | 438 | default: |
488 | LUA_INTERNALERROR(ls->L, "invalid var kind to store"); | 439 | LUA_INTERNALERROR(ls->L, "invalid var kind to store"); |
@@ -490,43 +441,16 @@ static void storevar (LexState *ls, const vardesc *var) { | |||
490 | } | 441 | } |
491 | 442 | ||
492 | 443 | ||
493 | static int fix_jump (LexState *ls, int pc, OpCode op, int n) { | ||
494 | /* jump is relative to position following jump instruction */ | ||
495 | return fix_opcode(ls, pc, op, n-(pc+JMPSIZE)); | ||
496 | } | ||
497 | |||
498 | |||
499 | static void fix_upjmp (LexState *ls, OpCode op, int pos) { | ||
500 | int delta = ls->fs->pc+JMPSIZE - pos; /* jump is relative */ | ||
501 | code_oparg(ls, op, delta+(codesize(delta)-2), 0); | ||
502 | } | ||
503 | |||
504 | |||
505 | static void codeIf (LexState *ls, int thenAdd, int elseAdd) { | ||
506 | FuncState *fs = ls->fs; | ||
507 | int elseinit = elseAdd+JMPSIZE; | ||
508 | if (fs->pc == elseinit) { /* no else part? */ | ||
509 | fs->pc -= JMPSIZE; | ||
510 | elseinit = fs->pc; | ||
511 | } | ||
512 | else | ||
513 | elseinit += fix_jump(ls, elseAdd, JMP, fs->pc); | ||
514 | fix_jump(ls, thenAdd, IFFJMP, elseinit); | ||
515 | } | ||
516 | |||
517 | |||
518 | static void func_onstack (LexState *ls, FuncState *func) { | 444 | static void func_onstack (LexState *ls, FuncState *func) { |
519 | FuncState *fs = ls->fs; | 445 | TProtoFunc *f = ls->fs->f; |
520 | TProtoFunc *f = fs->f; | ||
521 | int i; | 446 | int i; |
522 | luaM_growvector(ls->L, f->kproto, f->nkproto, 1, | ||
523 | TProtoFunc *, constantEM, MAX_ARG); | ||
524 | f->kproto[f->nkproto] = func->f; | ||
525 | for (i=0; i<func->nupvalues; i++) | 447 | for (i=0; i<func->nupvalues; i++) |
526 | lua_pushvar(ls, &func->upvalues[i]); | 448 | lua_pushvar(ls, &func->upvalues[i]); |
449 | luaM_growvector(ls->L, f->kproto, f->nkproto, 1, TProtoFunc *, | ||
450 | constantEM, MAXARG_A); | ||
451 | f->kproto[f->nkproto++] = func->f; | ||
527 | deltastack(ls, 1); /* CLOSURE puts one extra element (before popping) */ | 452 | deltastack(ls, 1); /* CLOSURE puts one extra element (before popping) */ |
528 | code_oparg(ls, CLOSURE, f->nkproto++, -func->nupvalues); | 453 | code_AB(ls, CLOSURE, f->nkproto-1, func->nupvalues, -func->nupvalues); |
529 | code_byte(ls, (Byte)func->nupvalues); | ||
530 | } | 454 | } |
531 | 455 | ||
532 | 456 | ||
@@ -536,7 +460,6 @@ static void init_state (LexState *ls, FuncState *fs, TaggedString *source) { | |||
536 | fs->prev = ls->fs; /* linked list of funcstates */ | 460 | fs->prev = ls->fs; /* linked list of funcstates */ |
537 | ls->fs = fs; | 461 | ls->fs = fs; |
538 | fs->stacksize = 0; | 462 | fs->stacksize = 0; |
539 | fs->maxstacksize = 0; | ||
540 | fs->nlocalvar = 0; | 463 | fs->nlocalvar = 0; |
541 | fs->nupvalues = 0; | 464 | fs->nupvalues = 0; |
542 | fs->lastsetline = 0; | 465 | fs->lastsetline = 0; |
@@ -544,9 +467,10 @@ static void init_state (LexState *ls, FuncState *fs, TaggedString *source) { | |||
544 | f->source = source; | 467 | f->source = source; |
545 | fs->pc = 0; | 468 | fs->pc = 0; |
546 | f->code = NULL; | 469 | f->code = NULL; |
470 | f->maxstacksize = 0; | ||
471 | f->numparams = 0; /* default for main chunk */ | ||
472 | f->is_vararg = 0; /* default for main chunk */ | ||
547 | fs->nvars = (L->debug) ? 0 : -1; /* flag no debug information? */ | 473 | fs->nvars = (L->debug) ? 0 : -1; /* flag no debug information? */ |
548 | code_byte(ls, 0); /* to be filled with maxstacksize */ | ||
549 | code_byte(ls, 0); /* to be filled with arg information */ | ||
550 | /* push function (to avoid GC) */ | 474 | /* push function (to avoid GC) */ |
551 | tfvalue(L->top) = f; | 475 | tfvalue(L->top) = f; |
552 | ttype(L->top) = LUA_T_LPROTO; | 476 | ttype(L->top) = LUA_T_LPROTO; |
@@ -557,9 +481,8 @@ static void init_state (LexState *ls, FuncState *fs, TaggedString *source) { | |||
557 | static void close_func (LexState *ls) { | 481 | static void close_func (LexState *ls) { |
558 | FuncState *fs = ls->fs; | 482 | FuncState *fs = ls->fs; |
559 | TProtoFunc *f = fs->f; | 483 | TProtoFunc *f = fs->f; |
560 | code_opcode(ls, ENDCODE, 0); | 484 | code_0(ls, ENDCODE, 0); |
561 | f->code[0] = (Byte)fs->maxstacksize; | 485 | luaM_reallocvector(ls->L, f->code, fs->pc, Instruction); |
562 | luaM_reallocvector(ls->L, f->code, fs->pc, Byte); | ||
563 | luaM_reallocvector(ls->L, f->kstr, f->nkstr, TaggedString *); | 486 | luaM_reallocvector(ls->L, f->kstr, f->nkstr, TaggedString *); |
564 | luaM_reallocvector(ls->L, f->knum, f->nknum, real); | 487 | luaM_reallocvector(ls->L, f->knum, f->nknum, real); |
565 | luaM_reallocvector(ls->L, f->kproto, f->nkproto, TProtoFunc *); | 488 | luaM_reallocvector(ls->L, f->kproto, f->nkproto, TProtoFunc *); |
@@ -662,28 +585,6 @@ TProtoFunc *luaY_parser (lua_State *L, ZIO *z) { | |||
662 | /*============================================================*/ | 585 | /*============================================================*/ |
663 | 586 | ||
664 | 587 | ||
665 | |||
666 | static int SaveWord (LexState *ls) { | ||
667 | int res = ls->fs->pc; | ||
668 | check_pc(ls, JMPSIZE); | ||
669 | ls->fs->pc += JMPSIZE; /* open space */ | ||
670 | return res; | ||
671 | } | ||
672 | |||
673 | |||
674 | static int SaveWordPop (LexState *ls) { | ||
675 | deltastack(ls, -1); /* pop condition */ | ||
676 | return SaveWord(ls); | ||
677 | } | ||
678 | |||
679 | |||
680 | static int cond (LexState *ls) { | ||
681 | /* cond -> exp1 */ | ||
682 | exp1(ls); | ||
683 | return SaveWordPop(ls); | ||
684 | } | ||
685 | |||
686 | |||
687 | static void explist1 (LexState *ls, listdesc *d) { | 588 | static void explist1 (LexState *ls, listdesc *d) { |
688 | vardesc v; | 589 | vardesc v; |
689 | expr(ls, &v); | 590 | expr(ls, &v); |
@@ -744,11 +645,8 @@ static int funcparams (LexState *ls, int slf) { | |||
744 | luaY_error(ls, "function arguments expected"); | 645 | luaY_error(ls, "function arguments expected"); |
745 | break; | 646 | break; |
746 | } | 647 | } |
747 | code_byte(ls, CALL); | ||
748 | code_byte(ls, 0); /* save space for nresult */ | ||
749 | code_byte(ls, (Byte)slevel); | ||
750 | fs->stacksize = slevel; /* call will remove func and params */ | 648 | fs->stacksize = slevel; /* call will remove func and params */ |
751 | return fs->pc-1; | 649 | return code_AB(ls, CALL, slevel, 0, 0); |
752 | } | 650 | } |
753 | 651 | ||
754 | 652 | ||
@@ -775,7 +673,7 @@ static void var_or_func_tail (LexState *ls, vardesc *v) { | |||
775 | next(ls); | 673 | next(ls); |
776 | name = checkname(ls); | 674 | name = checkname(ls); |
777 | lua_pushvar(ls, v); /* `v' must be on stack */ | 675 | lua_pushvar(ls, v); /* `v' must be on stack */ |
778 | code_oparg(ls, PUSHSELF, name, 1); | 676 | code_U(ls, PUSHSELF, name, 1); |
779 | v->k = VEXP; | 677 | v->k = VEXP; |
780 | v->info = funcparams(ls, 1); | 678 | v->info = funcparams(ls, 1); |
781 | break; | 679 | break; |
@@ -836,16 +734,20 @@ static void recfield (LexState *ls) { | |||
836 | static int recfields (LexState *ls) { | 734 | static int recfields (LexState *ls) { |
837 | /* recfields -> { ',' recfield } [','] */ | 735 | /* recfields -> { ',' recfield } [','] */ |
838 | int n = 1; /* one has been read before */ | 736 | int n = 1; /* one has been read before */ |
737 | int mod_n = 1; /* mod_n == n%RFIELDS_PER_FLUSH */ | ||
839 | while (ls->token == ',') { | 738 | while (ls->token == ',') { |
840 | next(ls); | 739 | next(ls); |
841 | if (ls->token == ';' || ls->token == '}') | 740 | if (ls->token == ';' || ls->token == '}') |
842 | break; | 741 | break; |
843 | recfield(ls); | 742 | recfield(ls); |
844 | n++; | 743 | n++; |
845 | if (n%RFIELDS_PER_FLUSH == 0) | 744 | if (++mod_n == RFIELDS_PER_FLUSH) { |
846 | flush_record(ls, RFIELDS_PER_FLUSH); | 745 | code_U(ls, SETMAP, RFIELDS_PER_FLUSH-1, -2*RFIELDS_PER_FLUSH); |
746 | mod_n = 0; | ||
747 | } | ||
847 | } | 748 | } |
848 | flush_record(ls, n%RFIELDS_PER_FLUSH); | 749 | if (mod_n) |
750 | code_U(ls, SETMAP, mod_n-1, -2*mod_n); | ||
849 | return n; | 751 | return n; |
850 | } | 752 | } |
851 | 753 | ||
@@ -853,16 +755,23 @@ static int recfields (LexState *ls) { | |||
853 | static int listfields (LexState *ls) { | 755 | static int listfields (LexState *ls) { |
854 | /* listfields -> { ',' exp1 } [','] */ | 756 | /* listfields -> { ',' exp1 } [','] */ |
855 | int n = 1; /* one has been read before */ | 757 | int n = 1; /* one has been read before */ |
758 | int mod_n = 1; /* mod_n == n%LFIELDS_PER_FLUSH */ | ||
856 | while (ls->token == ',') { | 759 | while (ls->token == ',') { |
857 | next(ls); | 760 | next(ls); |
858 | if (ls->token == ';' || ls->token == '}') | 761 | if (ls->token == ';' || ls->token == '}') |
859 | break; | 762 | break; |
860 | exp1(ls); | 763 | exp1(ls); |
861 | n++; | 764 | n++; |
862 | if (n%LFIELDS_PER_FLUSH == 0) | 765 | checklimit(ls, n, MAXARG_A*LFIELDS_PER_FLUSH, |
863 | flush_list(ls, n/LFIELDS_PER_FLUSH - 1, LFIELDS_PER_FLUSH); | 766 | "items in a list initializer"); |
767 | if (++mod_n == LFIELDS_PER_FLUSH) { | ||
768 | code_AB(ls, SETLIST, n/LFIELDS_PER_FLUSH - 1, LFIELDS_PER_FLUSH-1, | ||
769 | -LFIELDS_PER_FLUSH); | ||
770 | mod_n = 0; | ||
771 | } | ||
864 | } | 772 | } |
865 | flush_list(ls, n/LFIELDS_PER_FLUSH, n%LFIELDS_PER_FLUSH); | 773 | if (mod_n > 0) |
774 | code_AB(ls, SETLIST, n/LFIELDS_PER_FLUSH, mod_n-1, -mod_n); | ||
866 | return n; | 775 | return n; |
867 | } | 776 | } |
868 | 777 | ||
@@ -920,10 +829,9 @@ static void constructor_part (LexState *ls, constdesc *cd) { | |||
920 | static void constructor (LexState *ls) { | 829 | static void constructor (LexState *ls) { |
921 | /* constructor -> '{' constructor_part [';' constructor_part] '}' */ | 830 | /* constructor -> '{' constructor_part [';' constructor_part] '}' */ |
922 | int line = ls->linenumber; | 831 | int line = ls->linenumber; |
923 | int pc = SaveWord(ls); | 832 | int pc = code_U(ls, CREATETABLE, 0, 1); |
924 | int nelems; | 833 | int nelems; |
925 | constdesc cd; | 834 | constdesc cd; |
926 | deltastack(ls, 1); | ||
927 | check(ls, '{'); | 835 | check(ls, '{'); |
928 | constructor_part(ls, &cd); | 836 | constructor_part(ls, &cd); |
929 | nelems = cd.n; | 837 | nelems = cd.n; |
@@ -936,7 +844,8 @@ static void constructor (LexState *ls) { | |||
936 | nelems += other_cd.n; | 844 | nelems += other_cd.n; |
937 | } | 845 | } |
938 | check_match(ls, '}', '{', line); | 846 | check_match(ls, '}', '{', line); |
939 | fix_opcode(ls, pc, CREATEARRAY, nelems); | 847 | /* set initial table size */ |
848 | ls->fs->f->code[pc] = SETARG_U(ls->fs->f->code[pc], nelems); | ||
940 | } | 849 | } |
941 | 850 | ||
942 | /* }====================================================================== */ | 851 | /* }====================================================================== */ |
@@ -1009,7 +918,7 @@ static void push (LexState *ls, stack_op *s, int op) { | |||
1009 | static void pop_to (LexState *ls, stack_op *s, int prio) { | 918 | static void pop_to (LexState *ls, stack_op *s, int prio) { |
1010 | int op; | 919 | int op; |
1011 | while (s->top > 0 && priority[(op=s->ops[s->top-1])] >= prio) { | 920 | while (s->top > 0 && priority[(op=s->ops[s->top-1])] >= prio) { |
1012 | code_opcode(ls, opcodes[op], op<FIRSTBIN?0:-1); | 921 | code_0(ls, opcodes[op], op<FIRSTBIN?0:-1); |
1013 | s->top--; | 922 | s->top--; |
1014 | } | 923 | } |
1015 | } | 924 | } |
@@ -1113,10 +1022,10 @@ static void expr (LexState *ls, vardesc *v) { | |||
1113 | int pc; | 1022 | int pc; |
1114 | lua_pushvar(ls, v); | 1023 | lua_pushvar(ls, v); |
1115 | next(ls); | 1024 | next(ls); |
1116 | pc = SaveWordPop(ls); | 1025 | pc = code_S(ls, op, 0, -1); |
1117 | arith_exp(ls, v); | 1026 | arith_exp(ls, v); |
1118 | lua_pushvar(ls, v); | 1027 | lua_pushvar(ls, v); |
1119 | fix_jump(ls, pc, op, ls->fs->pc); | 1028 | fix_jump(ls, pc, ls->fs->pc); |
1120 | } | 1029 | } |
1121 | } | 1030 | } |
1122 | 1031 | ||
@@ -1167,7 +1076,7 @@ static int assignment (LexState *ls, vardesc *v, int nvars) { | |||
1167 | storevar(ls, v); | 1076 | storevar(ls, v); |
1168 | } | 1077 | } |
1169 | else { /* indexed var with values in between*/ | 1078 | else { /* indexed var with values in between*/ |
1170 | code_oparg(ls, SETTABLE, left+(nvars-1), -1); | 1079 | code_U(ls, SETTABLE, left+(nvars-1), -1); |
1171 | left += 2; /* table&index are not popped, because they aren't on top */ | 1080 | left += 2; /* table&index are not popped, because they aren't on top */ |
1172 | } | 1081 | } |
1173 | return left; | 1082 | return left; |
@@ -1175,22 +1084,18 @@ static int assignment (LexState *ls, vardesc *v, int nvars) { | |||
1175 | 1084 | ||
1176 | 1085 | ||
1177 | static void whilestat (LexState *ls, int line) { | 1086 | static void whilestat (LexState *ls, int line) { |
1178 | /* whilestat -> WHILE cond DO block END */ | 1087 | /* whilestat -> WHILE exp1 DO block END */ |
1179 | FuncState *fs = ls->fs; | 1088 | FuncState *fs = ls->fs; |
1180 | TProtoFunc *f = fs->f; | ||
1181 | int while_init = fs->pc; | 1089 | int while_init = fs->pc; |
1182 | int cond_end, cond_size; | 1090 | int j1; |
1183 | next(ls); | 1091 | next(ls); |
1184 | cond_end = cond(ls); | 1092 | exp1(ls); |
1093 | j1 = code_U(ls, IFFJMP, 0, -1); /* jump to exit loop */ | ||
1185 | check(ls, DO); | 1094 | check(ls, DO); |
1186 | block(ls); | 1095 | block(ls); |
1187 | check_match(ls, END, WHILE, line); | 1096 | check_match(ls, END, WHILE, line); |
1188 | cond_size = cond_end-while_init; | 1097 | fix_jump(ls, code_U(ls, JMP, 0, 0), while_init); /* jump to keep loop */ |
1189 | check_pc(ls, cond_size); | 1098 | fix_jump(ls, j1, fs->pc); |
1190 | memcpy(f->code+fs->pc, f->code+while_init, cond_size); | ||
1191 | luaO_memdown(f->code+while_init, f->code+cond_end, fs->pc-while_init); | ||
1192 | while_init += JMPSIZE + fix_jump(ls, while_init, JMP, fs->pc-cond_size); | ||
1193 | fix_upjmp(ls, IFTUPJMP, while_init); | ||
1194 | } | 1099 | } |
1195 | 1100 | ||
1196 | 1101 | ||
@@ -1202,8 +1107,7 @@ static void repeatstat (LexState *ls, int line) { | |||
1202 | block(ls); | 1107 | block(ls); |
1203 | check_match(ls, UNTIL, REPEAT, line); | 1108 | check_match(ls, UNTIL, REPEAT, line); |
1204 | exp1(ls); | 1109 | exp1(ls); |
1205 | fix_upjmp(ls, IFFUPJMP, repeat_init); | 1110 | fix_jump(ls, code_U(ls, IFFJMP, 0, -1), repeat_init); |
1206 | deltastack(ls, -1); /* pops condition */ | ||
1207 | } | 1111 | } |
1208 | 1112 | ||
1209 | 1113 | ||
@@ -1295,21 +1199,29 @@ static void namestat (LexState *ls) { | |||
1295 | 1199 | ||
1296 | static void ifpart (LexState *ls, int line) { | 1200 | static void ifpart (LexState *ls, int line) { |
1297 | /* ifpart -> cond THEN block [ELSE block | ELSEIF ifpart] */ | 1201 | /* ifpart -> cond THEN block [ELSE block | ELSEIF ifpart] */ |
1202 | FuncState *fs = ls->fs; | ||
1298 | int c; | 1203 | int c; |
1299 | int e; | 1204 | int je; |
1300 | next(ls); /* skip IF or ELSEIF */ | 1205 | next(ls); /* skip IF or ELSEIF */ |
1301 | c = cond(ls); | 1206 | exp1(ls); /* cond */ |
1207 | c = code_U(ls, IFFJMP, 0, -1); /* jump `then' if `cond' is false */ | ||
1302 | check(ls, THEN); | 1208 | check(ls, THEN); |
1303 | block(ls); | 1209 | block(ls); /* `then' part */ |
1304 | e = SaveWord(ls); | 1210 | je = code_U(ls, JMP, 0, 0); /* jump `else' part after `then' */ |
1305 | if (ls->token == ELSEIF) | 1211 | if (ls->token == ELSEIF) |
1306 | ifpart(ls, line); | 1212 | ifpart(ls, line); |
1307 | else { | 1213 | else { |
1308 | if (optional(ls, ELSE)) | 1214 | if (optional(ls, ELSE)) |
1309 | block(ls); | 1215 | block(ls); /* `else' part */ |
1310 | check_match(ls, END, IF, line); | 1216 | check_match(ls, END, IF, line); |
1311 | } | 1217 | } |
1312 | codeIf(ls, c, e); | 1218 | if (fs->pc == je+1) { /* `else' part empty? */ |
1219 | fs->pc--; /* remove last jump */ | ||
1220 | je--; /* first jump will be smaller */ | ||
1221 | } | ||
1222 | else | ||
1223 | fix_jump(ls, je, fs->pc); /* fix last jump */ | ||
1224 | fix_jump(ls, c, je+1); /* fix first jump to beginning of `else' part */ | ||
1313 | } | 1225 | } |
1314 | 1226 | ||
1315 | 1227 | ||
@@ -1395,9 +1307,9 @@ static void parlist (LexState *ls) { | |||
1395 | 1307 | ||
1396 | static void body (LexState *ls, int needself, int line) { | 1308 | static void body (LexState *ls, int needself, int line) { |
1397 | /* body -> '(' parlist ')' chunk END */ | 1309 | /* body -> '(' parlist ')' chunk END */ |
1398 | FuncState newfs; | 1310 | FuncState new_fs; |
1399 | init_state(ls, &newfs, ls->fs->f->source); | 1311 | init_state(ls, &new_fs, ls->fs->f->source); |
1400 | newfs.f->lineDefined = line; | 1312 | new_fs.f->lineDefined = line; |
1401 | check(ls, '('); | 1313 | check(ls, '('); |
1402 | if (needself) | 1314 | if (needself) |
1403 | add_localvar(ls, luaS_newfixed(ls->L, "self")); | 1315 | add_localvar(ls, luaS_newfixed(ls->L, "self")); |
@@ -1406,7 +1318,7 @@ static void body (LexState *ls, int needself, int line) { | |||
1406 | chunk(ls); | 1318 | chunk(ls); |
1407 | check_match(ls, END, FUNCTION, line); | 1319 | check_match(ls, END, FUNCTION, line); |
1408 | close_func(ls); | 1320 | close_func(ls); |
1409 | func_onstack(ls, &newfs); | 1321 | func_onstack(ls, &new_fs); |
1410 | } | 1322 | } |
1411 | 1323 | ||
1412 | 1324 | ||
@@ -1418,12 +1330,12 @@ static void ret (LexState *ls) { | |||
1418 | next(ls); | 1330 | next(ls); |
1419 | explist(ls, &e); | 1331 | explist(ls, &e); |
1420 | if (e.pc > 0) { /* expression is an open function call? */ | 1332 | if (e.pc > 0) { /* expression is an open function call? */ |
1421 | Byte *code = ls->fs->f->code; | 1333 | Instruction *i = &ls->fs->f->code[e.pc]; |
1422 | code[e.pc-2] = TAILCALL; /* instead of a conventional CALL */ | 1334 | *i = SET_OPCODE(*i, TAILCALL); /* instead of a conventional CALL */ |
1423 | code[e.pc-1] = (Byte)ls->fs->nlocalvar; | 1335 | *i = SETARG_B(*i, ls->fs->nlocalvar); |
1424 | } | 1336 | } |
1425 | else | 1337 | else |
1426 | code_oparg(ls, RETCODE, ls->fs->nlocalvar, 0); | 1338 | code_U(ls, RETCODE, ls->fs->nlocalvar, 0); |
1427 | ls->fs->stacksize = ls->fs->nlocalvar; /* removes all temp values */ | 1339 | ls->fs->stacksize = ls->fs->nlocalvar; /* removes all temp values */ |
1428 | optional(ls, ';'); | 1340 | optional(ls, ';'); |
1429 | } | 1341 | } |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 1.85 2000/02/08 16:39:42 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 1.86 2000/02/11 16:52:54 roberto Exp roberto $ |
3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -280,6 +280,11 @@ void luaV_comparison (lua_State *L) { | |||
280 | } | 280 | } |
281 | 281 | ||
282 | 282 | ||
283 | #define setbool(o,cond) if (cond) { \ | ||
284 | ttype(o) = LUA_T_NUMBER; nvalue(o) = 1.0; } \ | ||
285 | else ttype(o) = LUA_T_NIL | ||
286 | |||
287 | |||
283 | void luaV_pack (lua_State *L, StkId firstelem, int nvararg, TObject *tab) { | 288 | void luaV_pack (lua_State *L, StkId firstelem, int nvararg, TObject *tab) { |
284 | int i; | 289 | int i; |
285 | Hash *htab; | 290 | Hash *htab; |
@@ -313,90 +318,80 @@ static void adjust_varargs (lua_State *L, StkId base, int nfixargs) { | |||
313 | StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf, | 318 | StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf, |
314 | register StkId base) { | 319 | register StkId base) { |
315 | register StkId top; /* keep top local, for performance */ | 320 | register StkId top; /* keep top local, for performance */ |
316 | register const Byte *pc = tf->code; | 321 | register const Instruction *pc = tf->code; |
317 | TaggedString **kstr = tf->kstr; | 322 | TaggedString **kstr = tf->kstr; |
318 | if (L->callhook) | 323 | if (L->callhook) |
319 | luaD_callHook(L, base-1, L->callhook, "call"); | 324 | luaD_callHook(L, base-1, L->callhook, "call"); |
320 | luaD_checkstack(L, (*pc++)+EXTRA_STACK); | 325 | luaD_checkstack(L, tf->maxstacksize+EXTRA_STACK); |
321 | if (*pc < ZEROVARARG) | 326 | if (tf->is_vararg) { /* varargs? */ |
322 | luaD_adjusttop(L, base, *(pc++)); | 327 | adjust_varargs(L, base, tf->numparams); |
323 | else { /* varargs */ | ||
324 | adjust_varargs(L, base, (*pc++)-ZEROVARARG); | ||
325 | luaC_checkGC(L); | 328 | luaC_checkGC(L); |
326 | } | 329 | } |
330 | else | ||
331 | luaD_adjusttop(L, base, tf->numparams); | ||
327 | top = L->top; | 332 | top = L->top; |
328 | for (;;) { | 333 | for (;;) { |
329 | register int aux = 0; | 334 | register Instruction i = *pc++; |
330 | switchentry: | 335 | switch (GET_OPCODE(i)) { |
331 | switch ((OpCode)*pc++) { | ||
332 | 336 | ||
333 | case ENDCODE: | 337 | case ENDCODE: |
334 | return L->top; /* no results */ | 338 | return L->top; /* no results */ |
335 | 339 | ||
336 | case RETCODE: | 340 | case RETCODE: |
337 | L->top = top; | 341 | L->top = top; |
338 | return base+(*pc++); | 342 | return base+GETARG_U(i); |
339 | 343 | ||
340 | case CALL: aux = *pc++; | 344 | case CALL: |
341 | L->top = top; | 345 | L->top = top; |
342 | luaD_call(L, base+(*pc++), aux); | 346 | luaD_call(L, base+GETARG_A(i), GETARG_B(i)); |
343 | top = L->top; | 347 | top = L->top; |
344 | break; | 348 | break; |
345 | 349 | ||
346 | case TAILCALL: aux = *pc++; | 350 | case TAILCALL: |
347 | L->top = top; | 351 | L->top = top; |
348 | luaD_call(L, base+(*pc++), MULT_RET); | 352 | luaD_call(L, base+GETARG_A(i), MULT_RET); |
349 | return base+aux; | 353 | return base+GETARG_B(i); |
350 | 354 | ||
351 | case PUSHNIL: aux = *pc++; | 355 | case PUSHNIL: { |
356 | register int n = GETARG_U(i); | ||
352 | do { | 357 | do { |
353 | ttype(top++) = LUA_T_NIL; | 358 | ttype(top++) = LUA_T_NIL; |
354 | } while (aux--); | 359 | } while (n--); |
355 | break; | ||
356 | |||
357 | case POP: aux = *pc++; | ||
358 | top -= aux; | ||
359 | break; | 360 | break; |
361 | } | ||
360 | 362 | ||
361 | case PUSHINTW: aux += highbyte(L, *pc++); | 363 | case POP: |
362 | case PUSHINT: aux += *pc++; | 364 | top -= GETARG_U(i); |
363 | ttype(top) = LUA_T_NUMBER; | ||
364 | nvalue(top) = aux; | ||
365 | top++; | ||
366 | break; | 365 | break; |
367 | 366 | ||
368 | case PUSHINTNEGW: aux += highbyte(L, *pc++); | 367 | case PUSHINT: |
369 | case PUSHINTNEG: aux += *pc++; | ||
370 | ttype(top) = LUA_T_NUMBER; | 368 | ttype(top) = LUA_T_NUMBER; |
371 | nvalue(top) = -aux; | 369 | nvalue(top) = (real)GETARG_S(i); |
372 | top++; | 370 | top++; |
373 | break; | 371 | break; |
374 | 372 | ||
375 | case PUSHSTRINGW: aux += highbyte(L, *pc++); | 373 | case PUSHSTRING: |
376 | case PUSHSTRING: aux += *pc++; | ||
377 | ttype(top) = LUA_T_STRING; | 374 | ttype(top) = LUA_T_STRING; |
378 | tsvalue(top) = kstr[aux]; | 375 | tsvalue(top) = kstr[GETARG_U(i)]; |
379 | top++; | 376 | top++; |
380 | break; | 377 | break; |
381 | 378 | ||
382 | case PUSHNUMBERW: aux += highbyte(L, *pc++); | 379 | case PUSHNUMBER: |
383 | case PUSHNUMBER: aux += *pc++; | ||
384 | ttype(top) = LUA_T_NUMBER; | 380 | ttype(top) = LUA_T_NUMBER; |
385 | nvalue(top) = tf->knum[aux]; | 381 | nvalue(top) = tf->knum[GETARG_U(i)]; |
386 | top++; | 382 | top++; |
387 | break; | 383 | break; |
388 | 384 | ||
389 | case PUSHUPVALUE: aux = *pc++; | 385 | case PUSHUPVALUE: |
390 | *top++ = cl->consts[aux+1]; | 386 | *top++ = cl->consts[GETARG_U(i)+1]; |
391 | break; | 387 | break; |
392 | 388 | ||
393 | case PUSHLOCAL: aux = *pc++; | 389 | case PUSHLOCAL: |
394 | *top++ = *(base+aux); | 390 | *top++ = *(base+GETARG_U(i)); |
395 | break; | 391 | break; |
396 | 392 | ||
397 | case GETGLOBALW: aux += highbyte(L, *pc++); | 393 | case GETGLOBAL: |
398 | case GETGLOBAL: aux += *pc++; | 394 | luaV_getglobal(L, kstr[GETARG_U(i)]->u.s.gv, top); |
399 | luaV_getglobal(L, kstr[aux]->u.s.gv, top); | ||
400 | top++; | 395 | top++; |
401 | break; | 396 | break; |
402 | 397 | ||
@@ -405,41 +400,37 @@ StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf, | |||
405 | top--; | 400 | top--; |
406 | break; | 401 | break; |
407 | 402 | ||
408 | case GETDOTTEDW: aux += highbyte(L, *pc++); | 403 | case GETDOTTED: |
409 | case GETDOTTED: aux += *pc++; | ||
410 | ttype(top) = LUA_T_STRING; | 404 | ttype(top) = LUA_T_STRING; |
411 | tsvalue(top++) = kstr[aux]; | 405 | tsvalue(top++) = kstr[GETARG_U(i)]; |
412 | luaV_gettable(L, top); | 406 | luaV_gettable(L, top); |
413 | top--; | 407 | top--; |
414 | break; | 408 | break; |
415 | 409 | ||
416 | case PUSHSELFW: aux += highbyte(L, *pc++); | 410 | case PUSHSELF: { |
417 | case PUSHSELF: aux += *pc++; { | ||
418 | TObject receiver; | 411 | TObject receiver; |
419 | receiver = *(top-1); | 412 | receiver = *(top-1); |
420 | ttype(top) = LUA_T_STRING; | 413 | ttype(top) = LUA_T_STRING; |
421 | tsvalue(top++) = kstr[aux]; | 414 | tsvalue(top++) = kstr[GETARG_U(i)]; |
422 | luaV_gettable(L, top); | 415 | luaV_gettable(L, top); |
423 | *(top-1) = receiver; | 416 | *(top-1) = receiver; |
424 | break; | 417 | break; |
425 | } | 418 | } |
426 | 419 | ||
427 | case CREATEARRAYW: aux += highbyte(L, *pc++); | 420 | case CREATETABLE: |
428 | case CREATEARRAY: aux += *pc++; | ||
429 | L->top = top; | 421 | L->top = top; |
430 | luaC_checkGC(L); | 422 | luaC_checkGC(L); |
431 | avalue(top) = luaH_new(L, aux); | 423 | avalue(top) = luaH_new(L, GETARG_U(i)); |
432 | ttype(top) = LUA_T_ARRAY; | 424 | ttype(top) = LUA_T_ARRAY; |
433 | top++; | 425 | top++; |
434 | break; | 426 | break; |
435 | 427 | ||
436 | case SETLOCAL: aux = *pc++; | 428 | case SETLOCAL: |
437 | *(base+aux) = *(--top); | 429 | *(base+GETARG_U(i)) = *(--top); |
438 | break; | 430 | break; |
439 | 431 | ||
440 | case SETGLOBALW: aux += highbyte(L, *pc++); | 432 | case SETGLOBAL: |
441 | case SETGLOBAL: aux += *pc++; | 433 | luaV_setglobal(L, kstr[GETARG_U(i)]->u.s.gv, top); |
442 | luaV_setglobal(L, kstr[aux]->u.s.gv, top); | ||
443 | top--; | 434 | top--; |
444 | break; | 435 | break; |
445 | 436 | ||
@@ -449,91 +440,81 @@ StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf, | |||
449 | break; | 440 | break; |
450 | 441 | ||
451 | case SETTABLE: | 442 | case SETTABLE: |
452 | luaV_settable(L, top-3-(*pc++), top); | 443 | luaV_settable(L, top-3-GETARG_U(i), top); |
453 | top--; /* pop value */ | 444 | top--; /* pop value */ |
454 | break; | 445 | break; |
455 | 446 | ||
456 | case SETLISTW: aux += highbyte(L, *pc++); | 447 | case SETLIST: { |
457 | case SETLIST: aux += *pc++; { | 448 | int aux = GETARG_A(i) * LFIELDS_PER_FLUSH; |
458 | int n = *(pc++); | 449 | int n = GETARG_B(i)+1; |
459 | Hash *arr = avalue(top-n-1); | 450 | Hash *arr = avalue(top-n-1); |
460 | L->top = top-n; /* final value of `top' (in case of errors) */ | 451 | L->top = top-n; /* final value of `top' (in case of errors) */ |
461 | aux *= LFIELDS_PER_FLUSH; | ||
462 | for (; n; n--) | 452 | for (; n; n--) |
463 | luaH_setint(L, arr, n+aux, --top); | 453 | luaH_setint(L, arr, n+aux, --top); |
464 | break; | 454 | break; |
465 | } | 455 | } |
466 | 456 | ||
467 | case SETMAP: aux = *pc++; { | 457 | case SETMAP: { |
468 | StkId finaltop = top-2*(aux+1); | 458 | int n = GETARG_U(i); |
459 | StkId finaltop = top-2*(n+1); | ||
469 | Hash *arr = avalue(finaltop-1); | 460 | Hash *arr = avalue(finaltop-1); |
470 | L->top = finaltop; /* final value of `top' (in case of errors) */ | 461 | L->top = finaltop; /* final value of `top' (in case of errors) */ |
471 | do { | 462 | do { |
472 | luaH_set(L, arr, top-2, top-1); | 463 | luaH_set(L, arr, top-2, top-1); |
473 | top-=2; | 464 | top-=2; |
474 | } while (aux--); | 465 | } while (n--); |
475 | break; | 466 | break; |
476 | } | 467 | } |
477 | 468 | ||
478 | case NEQOP: aux = 1; | 469 | case NEQOP: |
470 | top--; | ||
471 | setbool(top-1, !luaO_equalObj(top-1, top)); | ||
472 | break; | ||
473 | |||
479 | case EQOP: | 474 | case EQOP: |
480 | top--; | 475 | top--; |
481 | aux = (luaO_equalObj(top-1, top) != aux); | 476 | setbool(top-1, luaO_equalObj(top-1, top)); |
482 | booleanresult: | ||
483 | if (aux) { | ||
484 | ttype(top-1) = LUA_T_NUMBER; | ||
485 | nvalue(top-1) = 1.0; | ||
486 | } | ||
487 | else ttype(top-1) = LUA_T_NIL; | ||
488 | break; | 477 | break; |
489 | 478 | ||
490 | case LTOP: | 479 | case LTOP: |
491 | top--; | 480 | top--; |
492 | if (ttype(top-1) == LUA_T_NUMBER && ttype(top) == LUA_T_NUMBER) | 481 | if (ttype(top-1) == LUA_T_NUMBER && ttype(top) == LUA_T_NUMBER) |
493 | aux = nvalue(top-1) < nvalue(top); | 482 | setbool(top-1, nvalue(top-1) < nvalue(top)); |
494 | else if (ttype(top-1) == LUA_T_STRING && ttype(top) == LUA_T_STRING) | 483 | else if (ttype(top-1) == LUA_T_STRING && ttype(top) == LUA_T_STRING) |
495 | aux = luaV_strcomp(tsvalue(top-1), tsvalue(top)) < 0; | 484 | setbool(top-1, luaV_strcomp(tsvalue(top-1), tsvalue(top)) < 0); |
496 | else { | 485 | else |
497 | call_binTM(L, top+1, IM_LT, "unexpected type in comparison"); | 486 | call_binTM(L, top+1, IM_LT, "unexpected type in comparison"); |
498 | break; | 487 | break; |
499 | } | ||
500 | goto booleanresult; | ||
501 | 488 | ||
502 | case LEOP: | 489 | case LEOP: |
503 | top--; | 490 | top--; |
504 | if (ttype(top-1) == LUA_T_NUMBER && ttype(top) == LUA_T_NUMBER) | 491 | if (ttype(top-1) == LUA_T_NUMBER && ttype(top) == LUA_T_NUMBER) |
505 | aux = nvalue(top-1) <= nvalue(top); | 492 | setbool(top-1, nvalue(top-1) <= nvalue(top)); |
506 | else if (ttype(top-1) == LUA_T_STRING && ttype(top) == LUA_T_STRING) | 493 | else if (ttype(top-1) == LUA_T_STRING && ttype(top) == LUA_T_STRING) |
507 | aux = luaV_strcomp(tsvalue(top-1), tsvalue(top)) <= 0; | 494 | setbool(top-1, luaV_strcomp(tsvalue(top-1), tsvalue(top)) <= 0); |
508 | else { | 495 | else |
509 | call_binTM(L, top+1, IM_LE, "unexpected type in comparison"); | 496 | call_binTM(L, top+1, IM_LE, "unexpected type in comparison"); |
510 | break; | 497 | break; |
511 | } | ||
512 | goto booleanresult; | ||
513 | 498 | ||
514 | case GTOP: | 499 | case GTOP: |
515 | top--; | 500 | top--; |
516 | if (ttype(top-1) == LUA_T_NUMBER && ttype(top) == LUA_T_NUMBER) | 501 | if (ttype(top-1) == LUA_T_NUMBER && ttype(top) == LUA_T_NUMBER) |
517 | aux = nvalue(top-1) > nvalue(top); | 502 | setbool(top-1, nvalue(top-1) > nvalue(top)); |
518 | else if (ttype(top-1) == LUA_T_STRING && ttype(top) == LUA_T_STRING) | 503 | else if (ttype(top-1) == LUA_T_STRING && ttype(top) == LUA_T_STRING) |
519 | aux = luaV_strcomp(tsvalue(top-1), tsvalue(top)) > 0; | 504 | setbool(top-1, luaV_strcomp(tsvalue(top-1), tsvalue(top)) > 0); |
520 | else { | 505 | else |
521 | call_binTM(L, top+1, IM_GT, "unexpected type in comparison"); | 506 | call_binTM(L, top+1, IM_GT, "unexpected type in comparison"); |
522 | break; | 507 | break; |
523 | } | ||
524 | goto booleanresult; | ||
525 | 508 | ||
526 | case GEOP: | 509 | case GEOP: |
527 | top--; | 510 | top--; |
528 | if (ttype(top-1) == LUA_T_NUMBER && ttype(top) == LUA_T_NUMBER) | 511 | if (ttype(top-1) == LUA_T_NUMBER && ttype(top) == LUA_T_NUMBER) |
529 | aux = nvalue(top-1) >= nvalue(top); | 512 | setbool(top-1, nvalue(top-1) >= nvalue(top)); |
530 | else if (ttype(top-1) == LUA_T_STRING && ttype(top) == LUA_T_STRING) | 513 | else if (ttype(top-1) == LUA_T_STRING && ttype(top) == LUA_T_STRING) |
531 | aux = luaV_strcomp(tsvalue(top-1), tsvalue(top)) >= 0; | 514 | setbool(top-1, luaV_strcomp(tsvalue(top-1), tsvalue(top)) >= 0); |
532 | else { | 515 | else |
533 | call_binTM(L, top+1, IM_GE, "unexpected type in comparison"); | 516 | call_binTM(L, top+1, IM_GE, "unexpected type in comparison"); |
534 | break; | 517 | break; |
535 | } | ||
536 | goto booleanresult; | ||
537 | 518 | ||
538 | case ADDOP: | 519 | case ADDOP: |
539 | if (tonumber(top-1) || tonumber(top-2)) | 520 | if (tonumber(top-1) || tonumber(top-2)) |
@@ -597,71 +578,53 @@ StkId luaV_execute (lua_State *L, const Closure *cl, const TProtoFunc *tf, | |||
597 | nvalue(top-1) = 1; | 578 | nvalue(top-1) = 1; |
598 | break; | 579 | break; |
599 | 580 | ||
600 | case ONTJMPW: aux += highbyte(L, *pc++); | 581 | case ONTJMP: |
601 | case ONTJMP: aux += *pc++; | 582 | if (ttype(top-1) != LUA_T_NIL) pc += GETARG_S(i); |
602 | if (ttype(top-1) != LUA_T_NIL) pc += aux; | ||
603 | else top--; | 583 | else top--; |
604 | break; | 584 | break; |
605 | 585 | ||
606 | case ONFJMPW: aux += highbyte(L, *pc++); | 586 | case ONFJMP: |
607 | case ONFJMP: aux += *pc++; | 587 | if (ttype(top-1) == LUA_T_NIL) pc += GETARG_S(i); |
608 | if (ttype(top-1) == LUA_T_NIL) pc += aux; | ||
609 | else top--; | 588 | else top--; |
610 | break; | 589 | break; |
611 | 590 | ||
612 | case JMPW: aux += highbyte(L, *pc++); | 591 | case JMP: |
613 | case JMP: aux += *pc++; | 592 | pc += GETARG_S(i); |
614 | pc += aux; | ||
615 | break; | 593 | break; |
616 | 594 | ||
617 | case IFFJMPW: aux += highbyte(L, *pc++); | 595 | case IFTJMP: |
618 | case IFFJMP: aux += *pc++; | 596 | if (ttype(--top) != LUA_T_NIL) pc += GETARG_S(i); |
619 | if (ttype(--top) == LUA_T_NIL) pc += aux; | ||
620 | break; | 597 | break; |
621 | 598 | ||
622 | case IFTUPJMPW: aux += highbyte(L, *pc++); | 599 | case IFFJMP: |
623 | case IFTUPJMP: aux += *pc++; | 600 | if (ttype(--top) == LUA_T_NIL) pc += GETARG_S(i); |
624 | if (ttype(--top) != LUA_T_NIL) pc -= aux; | ||
625 | break; | 601 | break; |
626 | 602 | ||
627 | case IFFUPJMPW: aux += highbyte(L, *pc++); | 603 | case CLOSURE: |
628 | case IFFUPJMP: aux += *pc++; | ||
629 | if (ttype(--top) == LUA_T_NIL) pc -= aux; | ||
630 | break; | ||
631 | |||
632 | case CLOSUREW: aux += highbyte(L, *pc++); | ||
633 | case CLOSURE: aux += *pc++; | ||
634 | ttype(top) = LUA_T_LPROTO; | 604 | ttype(top) = LUA_T_LPROTO; |
635 | tfvalue(top) = tf->kproto[aux]; | 605 | tfvalue(top) = tf->kproto[GETARG_A(i)]; |
636 | L->top = ++top; | 606 | L->top = ++top; |
637 | aux = *pc++; /* number of upvalues */ | 607 | luaV_closure(L, GETARG_B(i)); |
638 | luaV_closure(L, aux); | 608 | top -= GETARG_B(i); |
639 | luaC_checkGC(L); | 609 | luaC_checkGC(L); |
640 | top -= aux; | ||
641 | break; | 610 | break; |
642 | 611 | ||
643 | case SETLINEW: aux += highbyte(L, *pc++); | 612 | case SETLINE: |
644 | case SETLINE: aux += *pc++; | ||
645 | if ((base-1)->ttype != LUA_T_LINE) { | 613 | if ((base-1)->ttype != LUA_T_LINE) { |
646 | /* open space for LINE value */ | 614 | /* open space for LINE value */ |
647 | int i = top-base; | 615 | int n = top-base; |
648 | while (i--) base[i+1] = base[i]; | 616 | while (n--) base[n+1] = base[n]; |
649 | base++; | 617 | base++; |
650 | top++; | 618 | top++; |
651 | (base-1)->ttype = LUA_T_LINE; | 619 | (base-1)->ttype = LUA_T_LINE; |
652 | } | 620 | } |
653 | (base-1)->value.i = aux; | 621 | (base-1)->value.i = GETARG_U(i); |
654 | if (L->linehook) { | 622 | if (L->linehook) { |
655 | L->top = top; | 623 | L->top = top; |
656 | luaD_lineHook(L, base-2, aux); | 624 | luaD_lineHook(L, base-2, GETARG_U(i)); |
657 | } | 625 | } |
658 | break; | 626 | break; |
659 | 627 | ||
660 | case LONGARGW: aux += highbyte(L, *pc++); | ||
661 | case LONGARG: aux += *pc++; | ||
662 | aux = highbyte(L, highbyte(L, aux)); | ||
663 | goto switchentry; /* do not reset `aux' */ | ||
664 | |||
665 | } | 628 | } |
666 | } | 629 | } |
667 | } | 630 | } |