summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-02-04 14:36:16 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1999-02-04 14:36:16 -0200
commitcbc58af26094ad6498c4160cf9710adc7883aa94 (patch)
tree8caa9f7162543ec4e224b2abbf038cb06d0f94ad
parent80001ab0eb3ad95f370796b26dacfdd7e9874877 (diff)
downloadlua-cbc58af26094ad6498c4160cf9710adc7883aa94.tar.gz
lua-cbc58af26094ad6498c4160cf9710adc7883aa94.tar.bz2
lua-cbc58af26094ad6498c4160cf9710adc7883aa94.zip
new opcode for "long" arguments (3 bytes)
-rw-r--r--lopcodes.h32
-rw-r--r--lparser.c196
-rw-r--r--lvm.c43
3 files changed, 152 insertions, 119 deletions
diff --git a/lopcodes.h b/lopcodes.h
index 66af79f1..9d29fed9 100644
--- a/lopcodes.h
+++ b/lopcodes.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lopcodes.h,v 1.19 1999/02/02 17:57:49 roberto Exp roberto $ 2** $Id: lopcodes.h,v 1.20 1999/02/02 19:41:17 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,8 +8,6 @@
8#define lopcodes_h 8#define lopcodes_h
9 9
10 10
11#define NUMOFFSET 100
12
13/* 11/*
14** NOTICE: variants of the same opcode must be consecutive: First, those 12** NOTICE: variants of the same opcode must be consecutive: First, those
15** with word parameter, then with byte parameter. 13** with word parameter, then with byte parameter.
@@ -100,14 +98,38 @@ CLOSURE,/* b c v_c...v_1 closure(CNST[b], v_c...v_1) */
100CALLFUNC,/* b c v_c...v_1 f r_b...r_1 f(v1,...,v_c) */ 98CALLFUNC,/* b c v_c...v_1 f r_b...r_1 f(v1,...,v_c) */
101 99
102SETLINEW,/* w - - LINE=w */ 100SETLINEW,/* w - - LINE=w */
103SETLINE /* b - - LINE=b */ 101SETLINE,/* b - - LINE=b */
102
103LONGARG /* b (add b*(1<<16) to arg of next instruction) */
104 104
105} OpCode; 105} OpCode;
106 106
107 107
108#define NUMOFFSET 100 /* offset for immediate numbers */
109
108#define RFIELDS_PER_FLUSH 32 /* records (SETMAP) */ 110#define RFIELDS_PER_FLUSH 32 /* records (SETMAP) */
109#define LFIELDS_PER_FLUSH 64 /* lists (SETLIST) */ 111#define LFIELDS_PER_FLUSH 64 /* FPF - lists (SETLIST) */
110 112
111#define ZEROVARARG 64 113#define ZEROVARARG 64
112 114
115
116/* maximum value of an arg of 3 bytes; must fit in an "int" */
117#if MAX_INT < (1<<24)
118#define MAX_ARG MAX_INT
119#else
120#define MAX_ARG ((1<<24)-1)
121#endif
122
123/* maximum value of a word of 2 bytes; cannot be bigger than MAX_ARG */
124#if MAX_ARG < (1<<16)
125#define MAX_WORD MAX_ARG
126#else
127#define MAX_WORD ((1<<16)-1)
128#endif
129
130
131/* maximum value of a byte */
132#define MAX_BYTE ((1<<8)-1)
133
134
113#endif 135#endif
diff --git a/lparser.c b/lparser.c
index a960dc13..c6fe6547 100644
--- a/lparser.c
+++ b/lparser.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lparser.c,v 1.13 1999/02/02 17:57:49 roberto Exp roberto $ 2** $Id: lparser.c,v 1.14 1999/02/02 19:41:17 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*/
@@ -99,6 +99,9 @@ typedef struct FuncState {
99} FuncState; 99} FuncState;
100 100
101 101
102/*
103** prototypes for non-terminal functions
104*/
102static int assignment (LexState *ls, vardesc *v, int nvars); 105static int assignment (LexState *ls, vardesc *v, int nvars);
103static int cond (LexState *ls); 106static int cond (LexState *ls);
104static int funcname (LexState *ls, vardesc *v); 107static int funcname (LexState *ls, vardesc *v);
@@ -147,48 +150,61 @@ static void deltastack (LexState *ls, int delta) {
147 FuncState *fs = ls->fs; 150 FuncState *fs = ls->fs;
148 fs->stacksize += delta; 151 fs->stacksize += delta;
149 if (fs->stacksize > fs->maxstacksize) { 152 if (fs->stacksize > fs->maxstacksize) {
150 if (fs->stacksize > 255) 153 if (fs->stacksize > MAX_BYTE)
151 luaX_error(ls, "function/expression too complex"); 154 luaX_error(ls, "function/expression too complex");
152 fs->maxstacksize = fs->stacksize; 155 fs->maxstacksize = fs->stacksize;
153 } 156 }
154} 157}
155 158
156 159
157static int code_oparg_at (LexState *ls, int pc, OpCode op, int arg, int delta) { 160static void code_oparg_at (LexState *ls, int pc, OpCode op,
161 int arg, int delta) {
158 Byte *code = ls->fs->f->code; 162 Byte *code = ls->fs->f->code;
159 deltastack(ls, delta); 163 deltastack(ls, delta);
160 if (arg <= 255) { 164 if (arg <= MAX_BYTE) {
161 code[pc] = (Byte)op; 165 code[pc] = (Byte)op;
162 code[pc+1] = (Byte)arg; 166 code[pc+1] = (Byte)arg;
163 return 2; /* code size (opcode + 1 byte) */
164 } 167 }
165 else if (arg <= MAX_WORD) { 168 else if (arg <= MAX_WORD) {
166 code[pc] = (Byte)(op-1); 169 code[pc] = (Byte)(op-1); /* opcode for word argument */
167 code[pc+1] = (Byte)(arg>>8); 170 code[pc+1] = (Byte)(arg>>8);
168 code[pc+2] = (Byte)(arg&0xFF); 171 code[pc+2] = (Byte)(arg&0xFF);
169 return 3; /* code size (opcode + 1 word) */
170 } 172 }
171 else luaX_error(ls, "code too long " MES_LIM("64K") 173 else if (arg <= MAX_ARG) {
172 " (try turning off debug mode)"); 174 code[pc] = (Byte)LONGARG;
173 return 0; /* to avoid warnings */ 175 code[pc+1] = (Byte)(arg>>16);
176 code_oparg_at(ls, pc+2, op, arg&0xFFFF, 0);
177 }
178 else luaX_error(ls, "code too long");
179}
180
181
182static int codesize (int arg) {
183 if (arg <= MAX_BYTE) return 2; /* opcode + 1 byte */
184 else if (arg <= MAX_WORD) return 3; /* opcode + 1 word */
185 else return 2+codesize(arg&0xFFFF); /* LONGARG + 1 byte + original opcode */
174} 186}
175 187
176 188
177static int fix_opcode (LexState *ls, int pc, OpCode op, int arg) { 189static int fix_opcode (LexState *ls, int pc, OpCode op, int arg) {
178 FuncState *fs = ls->fs; 190 int tomove = codesize(arg)-2;
179 TProtoFunc *f = fs->f; 191 if (tomove > 0) { /* need to open space? */
180 if (arg > 255) { /* open space */ 192 FuncState *fs = ls->fs;
181 check_pc(fs, 1); 193 TProtoFunc *f = fs->f;
182 luaO_memup(f->code+pc+1, f->code+pc, fs->pc-pc); 194 check_pc(fs, tomove);
183 fs->pc++; 195 luaO_memup(f->code+pc+tomove, f->code+pc, fs->pc-pc);
196 fs->pc += tomove;
184 } 197 }
185 return code_oparg_at(ls, pc, op, arg, 0) - 2; 198 code_oparg_at(ls, pc, op, arg, 0);
199 return tomove;
186} 200}
187 201
188 202
189static void code_oparg (LexState *ls, OpCode op, int arg, int delta) { 203static void code_oparg (LexState *ls, OpCode op, int arg, int delta) {
190 check_pc(ls->fs, 3); /* maximum code size */ 204 int size = codesize(arg);
191 ls->fs->pc += code_oparg_at(ls, ls->fs->pc, op, arg, delta); 205 check_pc(ls->fs, size);
206 code_oparg_at(ls, ls->fs->pc, op, arg, delta);
207 ls->fs->pc += size;
192} 208}
193 209
194 210
@@ -205,10 +221,9 @@ static void code_constant (LexState *ls, int c) {
205 221
206static int next_constant (FuncState *fs) { 222static int next_constant (FuncState *fs) {
207 TProtoFunc *f = fs->f; 223 TProtoFunc *f = fs->f;
208 if (f->nconsts >= fs->maxconsts) { 224 if (f->nconsts >= fs->maxconsts)
209 fs->maxconsts = luaM_growvector(&f->consts, fs->maxconsts, TObject, 225 fs->maxconsts = luaM_growvector(&f->consts, fs->maxconsts, TObject,
210 constantEM, MAX_WORD); 226 constantEM, MAX_ARG);
211 }
212 return f->nconsts++; 227 return f->nconsts++;
213} 228}
214 229
@@ -242,9 +257,9 @@ static int real_constant (FuncState *fs, real r) {
242 if (ttype(&cnt[c]) == LUA_T_NUMBER && nvalue(&cnt[c]) == r) 257 if (ttype(&cnt[c]) == LUA_T_NUMBER && nvalue(&cnt[c]) == r)
243 return c; 258 return c;
244 } 259 }
245 /* not found; create a luaM_new entry */ 260 /* not found; create a new entry */
246 c = next_constant(fs); 261 c = next_constant(fs);
247 cnt = fs->f->consts; /* 'next_constant' may reallocate this vector */ 262 cnt = fs->f->consts; /* 'next_constant' may have reallocated this vector */
248 ttype(&cnt[c]) = LUA_T_NUMBER; 263 ttype(&cnt[c]) = LUA_T_NUMBER;
249 nvalue(&cnt[c]) = r; 264 nvalue(&cnt[c]) = r;
250 return c; 265 return c;
@@ -252,10 +267,9 @@ static int real_constant (FuncState *fs, real r) {
252 267
253 268
254static void code_number (LexState *ls, real f) { 269static void code_number (LexState *ls, real f) {
255 int i; 270 if (-NUMOFFSET <= f && f <= (real)(MAX_WORD-NUMOFFSET) &&
256 if (0 <= f+NUMOFFSET && f+NUMOFFSET <= (real)MAX_WORD && 271 (int)f == f) /* f+NUMOFFSET has a short integer value? */
257 (real)(i=(int)f) == f) /* f+NUMOFFSET has a short integer value? */ 272 code_oparg(ls, PUSHNUMBER, (int)f+NUMOFFSET, 1);
258 code_oparg(ls, PUSHNUMBER, i+NUMOFFSET, 1);
259 else 273 else
260 code_constant(ls, real_constant(ls->fs, f)); 274 code_constant(ls, real_constant(ls->fs, f));
261} 275}
@@ -268,9 +282,10 @@ static void flush_record (LexState *ls, int n) {
268 282
269 283
270static void flush_list (LexState *ls, int m, int n) { 284static void flush_list (LexState *ls, int m, int n) {
271 if (n == 0) return; 285 if (n > 0) {
272 code_oparg(ls, SETLIST, m, -n); 286 code_oparg(ls, SETLIST, m, -n);
273 code_byte(ls->fs, (Byte)n); 287 code_byte(ls->fs, (Byte)n);
288 }
274} 289}
275 290
276 291
@@ -280,7 +295,7 @@ static void luaI_registerlocalvar (FuncState *fs, TaggedString *varname,
280 TProtoFunc *f = fs->f; 295 TProtoFunc *f = fs->f;
281 if (fs->nvars+1 > fs->maxvars) 296 if (fs->nvars+1 > fs->maxvars)
282 fs->maxvars = luaM_growvector(&f->locvars, fs->maxvars+1, 297 fs->maxvars = luaM_growvector(&f->locvars, fs->maxvars+1,
283 LocVar, "", MAX_WORD); 298 LocVar, "", MAX_INT);
284 f->locvars[fs->nvars].varname = varname; 299 f->locvars[fs->nvars].varname = varname;
285 f->locvars[fs->nvars].line = line; 300 f->locvars[fs->nvars].line = line;
286 fs->nvars++; 301 fs->nvars++;
@@ -295,10 +310,9 @@ static void luaI_unregisterlocalvar (FuncState *fs, int line) {
295 310
296static void store_localvar (LexState *ls, TaggedString *name, int n) { 311static void store_localvar (LexState *ls, TaggedString *name, int n) {
297 FuncState *fs = ls->fs; 312 FuncState *fs = ls->fs;
298 if (fs->nlocalvar+n < MAXLOCALS) 313 if (fs->nlocalvar+n >= MAXLOCALS)
299 fs->localvar[fs->nlocalvar+n] = name;
300 else
301 luaX_error(ls, "too many local variables " MES_LIM(SMAXLOCALS)); 314 luaX_error(ls, "too many local variables " MES_LIM(SMAXLOCALS));
315 fs->localvar[fs->nlocalvar+n] = name;
302 luaI_registerlocalvar(fs, name, ls->linenumber); 316 luaI_registerlocalvar(fs, name, ls->linenumber);
303} 317}
304 318
@@ -320,13 +334,13 @@ static int aux_localname (FuncState *fs, TaggedString *n) {
320static void singlevar (LexState *ls, TaggedString *n, vardesc *var, int prev) { 334static void singlevar (LexState *ls, TaggedString *n, vardesc *var, int prev) {
321 FuncState *fs = prev ? ls->fs->prev : ls->fs; 335 FuncState *fs = prev ? ls->fs->prev : ls->fs;
322 int i = aux_localname(fs, n); 336 int i = aux_localname(fs, n);
323 if (i >= 0) { /* local value */ 337 if (i >= 0) { /* local value? */
324 var->k = VLOCAL; 338 var->k = VLOCAL;
325 var->info = i; 339 var->info = i;
326 } 340 }
327 else { /* check shadowing */ 341 else {
328 FuncState *level = fs; 342 FuncState *level = fs;
329 while ((level = level->prev) != NULL) 343 while ((level = level->prev) != NULL) /* check shadowing */
330 if (aux_localname(level, n) >= 0) 344 if (aux_localname(level, n) >= 0)
331 luaX_syntaxerror(ls, "cannot access a variable in outer scope", n->str); 345 luaX_syntaxerror(ls, "cannot access a variable in outer scope", n->str);
332 var->k = VGLOBAL; 346 var->k = VGLOBAL;
@@ -354,13 +368,11 @@ static int indexupvalue (LexState *ls, TaggedString *n) {
354 368
355 369
356static void pushupvalue (LexState *ls, TaggedString *n) { 370static void pushupvalue (LexState *ls, TaggedString *n) {
357 int i;
358 if (ls->fs->prev == NULL) 371 if (ls->fs->prev == NULL)
359 luaX_syntaxerror(ls, "cannot access upvalue in main", n->str); 372 luaX_syntaxerror(ls, "cannot access upvalue in main", n->str);
360 if (aux_localname(ls->fs, n) >= 0) 373 if (aux_localname(ls->fs, n) >= 0)
361 luaX_syntaxerror(ls, "cannot access an upvalue in current scope", n->str); 374 luaX_syntaxerror(ls, "cannot access an upvalue in current scope", n->str);
362 i = indexupvalue(ls, n); 375 code_oparg(ls, PUSHUPVALUE, indexupvalue(ls, n), 1);
363 code_oparg(ls, PUSHUPVALUE, i, 1);
364} 376}
365 377
366 378
@@ -384,12 +396,10 @@ static void adjuststack (LexState *ls, int n) {
384static void close_exp (LexState *ls, int pc, int nresults) { 396static void close_exp (LexState *ls, int pc, int nresults) {
385 if (pc > 0) { /* expression is an open function call */ 397 if (pc > 0) { /* expression is an open function call */
386 Byte *code = ls->fs->f->code; 398 Byte *code = ls->fs->f->code;
387 Byte nparams = code[pc]; /* save nparams */ 399 code[pc-1] = nresults; /* set nresults */
388 pc += fix_opcode(ls, pc-2, CALLFUNC, nresults);
389 code[pc] = nparams; /* restore nparams */
390 if (nresults != MULT_RET) 400 if (nresults != MULT_RET)
391 deltastack(ls, nresults); /* "push" results */ 401 deltastack(ls, nresults); /* push results */
392 deltastack(ls, -(nparams+1)); /* "pop" params and function */ 402 deltastack(ls, -(code[pc]+1)); /* pop params (at code[pc]) and function */
393 } 403 }
394} 404}
395 405
@@ -402,7 +412,7 @@ static void adjust_mult_assign (LexState *ls, int nvars, listdesc *d) {
402 } 412 }
403 else { /* must correct function call */ 413 else { /* must correct function call */
404 diff--; /* do not count function call itself */ 414 diff--; /* do not count function call itself */
405 if (diff < 0) { /* more variables than values */ 415 if (diff <= 0) { /* more variables than values? */
406 /* function call must provide extra values */ 416 /* function call must provide extra values */
407 close_exp(ls, d->pc, -diff); 417 close_exp(ls, d->pc, -diff);
408 } 418 }
@@ -493,15 +503,14 @@ static int fix_jump (LexState *ls, int pc, OpCode op, int n) {
493 503
494static void fix_upjmp (LexState *ls, OpCode op, int pos) { 504static void fix_upjmp (LexState *ls, OpCode op, int pos) {
495 int delta = ls->fs->pc+JMPSIZE - pos; /* jump is relative */ 505 int delta = ls->fs->pc+JMPSIZE - pos; /* jump is relative */
496 if (delta > 255) delta++; 506 code_oparg(ls, op, delta+(codesize(delta)-2), 0);
497 code_oparg(ls, op, delta, 0);
498} 507}
499 508
500 509
501static void codeIf (LexState *ls, int thenAdd, int elseAdd) { 510static void codeIf (LexState *ls, int thenAdd, int elseAdd) {
502 FuncState *fs = ls->fs; 511 FuncState *fs = ls->fs;
503 int elseinit = elseAdd+JMPSIZE; 512 int elseinit = elseAdd+JMPSIZE;
504 if (fs->pc == elseinit) { /* no else part */ 513 if (fs->pc == elseinit) { /* no else part? */
505 fs->pc -= JMPSIZE; 514 fs->pc -= JMPSIZE;
506 elseinit = fs->pc; 515 elseinit = fs->pc;
507 } 516 }
@@ -547,14 +556,13 @@ static void init_state (LexState *ls, FuncState *fs, TaggedString *filename) {
547 fs->nvars = fs->maxvars = 0; 556 fs->nvars = fs->maxvars = 0;
548 else 557 else
549 fs->maxvars = -1; /* flag no debug information */ 558 fs->maxvars = -1; /* flag no debug information */
550 code_byte(fs, 0); /* to be filled with stacksize */ 559 code_byte(fs, 0); /* to be filled with maxstacksize */
551 code_byte(fs, 0); /* to be filled with arg information */ 560 code_byte(fs, 0); /* to be filled with arg information */
552 /* push function (to avoid GC) */ 561 /* push function (to avoid GC) */
553 tfvalue(L->stack.top) = f; ttype(L->stack.top) = LUA_T_PROTO; 562 tfvalue(L->stack.top) = f; ttype(L->stack.top) = LUA_T_PROTO;
554 incr_top; 563 incr_top;
555} 564}
556 565
557
558static void close_func (LexState *ls) { 566static void close_func (LexState *ls) {
559 FuncState *fs = ls->fs; 567 FuncState *fs = ls->fs;
560 TProtoFunc *f = fs->f; 568 TProtoFunc *f = fs->f;
@@ -575,13 +583,11 @@ static void close_func (LexState *ls) {
575static int expfollow [] = {ELSE, ELSEIF, THEN, IF, WHILE, REPEAT, DO, NAME, 583static int expfollow [] = {ELSE, ELSEIF, THEN, IF, WHILE, REPEAT, DO, NAME,
576 LOCAL, FUNCTION, END, UNTIL, RETURN, ')', ']', '}', ';', EOS, ',', 0}; 584 LOCAL, FUNCTION, END, UNTIL, RETURN, ')', ']', '}', ';', EOS, ',', 0};
577 585
586
578static int is_in (int tok, int *toks) { 587static int is_in (int tok, int *toks) {
579 int *t = toks; 588 int *t;
580 while (*t) { 589 for (t=toks; *t; t++)
581 if (*t == tok) 590 if (*t == tok) return t-toks;
582 return t-toks;
583 t++;
584 }
585 return -1; 591 return -1;
586} 592}
587 593
@@ -642,9 +648,7 @@ static int checkname (LexState *ls) {
642 648
643 649
644static TaggedString *str_checkname (LexState *ls) { 650static TaggedString *str_checkname (LexState *ls) {
645 /* call "checkname" to put string at constant table (to avoid GC) */ 651 return tsvalue(&ls->fs->f->consts[checkname(ls)]);
646 int i = checkname(ls);
647 return tsvalue(&ls->fs->f->consts[i]);
648} 652}
649 653
650 654
@@ -855,7 +859,7 @@ static void ifpart (LexState *ls, int isexp, int line) {
855 check(ls, THEN); 859 check(ls, THEN);
856 if (isexp) { 860 if (isexp) {
857 exp1(ls); 861 exp1(ls);
858 deltastack(ls, -1); /* only then xor else part will stay on the stack */ 862 deltastack(ls, -1); /* only 'then' x-or 'else' will stay on the stack */
859 } 863 }
860 else block(ls); 864 else block(ls);
861 e = SaveWord(ls); 865 e = SaveWord(ls);
@@ -878,10 +882,9 @@ static void ifpart (LexState *ls, int isexp, int line) {
878 882
879static void ret (LexState *ls) { 883static void ret (LexState *ls) {
880 /* ret -> [RETURN explist sc] */ 884 /* ret -> [RETURN explist sc] */
881 if (ls->token == RETURN) { 885 check_debugline(ls);
886 if (optional(ls, RETURN)) {
882 listdesc e; 887 listdesc e;
883 check_debugline(ls);
884 next(ls);
885 explist(ls, &e); 888 explist(ls, &e);
886 close_exp(ls, e.pc, MULT_RET); 889 close_exp(ls, e.pc, MULT_RET);
887 code_oparg(ls, RETCODE, ls->fs->nlocalvar, 0); 890 code_oparg(ls, RETCODE, ls->fs->nlocalvar, 0);
@@ -897,6 +900,9 @@ static void ret (LexState *ls) {
897** (EQ=2, NE=3, ... '^'=13). The unary NOT is 0 and UNMINUS is 1. 900** (EQ=2, NE=3, ... '^'=13). The unary NOT is 0 and UNMINUS is 1.
898*/ 901*/
899 902
903#define INDNOT 0
904#define INDMINUS 1
905
900/* code of first binary operator */ 906/* code of first binary operator */
901#define FIRSTBIN 2 907#define FIRSTBIN 2
902 908
@@ -913,10 +919,7 @@ static int priority [POW+1] = {5, 5, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 4, 6};
913static OpCode opcodes [POW+1] = {NOTOP, MINUSOP, EQOP, NEQOP, GTOP, LTOP, 919static OpCode opcodes [POW+1] = {NOTOP, MINUSOP, EQOP, NEQOP, GTOP, LTOP,
914 LEOP, GEOP, CONCOP, ADDOP, SUBOP, MULTOP, DIVOP, POWOP}; 920 LEOP, GEOP, CONCOP, ADDOP, SUBOP, MULTOP, DIVOP, POWOP};
915 921
916#define INDNOT 0 922#define MAXOPS 20 /* op's stack size */
917#define INDMINUS 1
918
919#define MAXOPS 20
920 923
921typedef struct { 924typedef struct {
922 int ops[MAXOPS]; 925 int ops[MAXOPS];
@@ -934,16 +937,17 @@ static void exp1 (LexState *ls) {
934 937
935 938
936static void exp0 (LexState *ls, vardesc *v) { 939static void exp0 (LexState *ls, vardesc *v) {
940 /* exp0 -> exp2 {(AND | OR) exp2} */
937 exp2(ls, v); 941 exp2(ls, v);
938 while (ls->token == AND || ls->token == OR) { 942 while (ls->token == AND || ls->token == OR) {
939 int is_and = (ls->token == AND); 943 int op = (ls->token == AND) ? ONFJMP : ONTJMP;
940 int pc; 944 int pc;
941 lua_pushvar(ls, v); 945 lua_pushvar(ls, v);
942 next(ls); 946 next(ls);
943 pc = SaveWordPop(ls); 947 pc = SaveWordPop(ls);
944 exp2(ls, v); 948 exp2(ls, v);
945 lua_pushvar(ls, v); 949 lua_pushvar(ls, v);
946 fix_jump(ls, pc, (is_and?ONFJMP:ONTJMP), ls->fs->pc); 950 fix_jump(ls, pc, op, ls->fs->pc);
947 } 951 }
948} 952}
949 953
@@ -952,31 +956,23 @@ static void Gexp (LexState *ls, vardesc *v) {
952 /* Gexp -> exp0 | var '=' exp1 */ 956 /* Gexp -> exp0 | var '=' exp1 */
953 static OpCode codes[] = {SETLOCALDUP, SETGLOBALDUP, SETTABLEDUP}; 957 static OpCode codes[] = {SETLOCALDUP, SETGLOBALDUP, SETTABLEDUP};
954 exp0(ls, v); 958 exp0(ls, v);
955 if (ls->token == '=' && v->k != VEXP) { /* assignment expression? */ 959 if (v->k != VEXP && optional(ls, '=')) { /* assignment expression? */
956 next(ls); /* skip '=' */
957 unloaddot(ls, v); 960 unloaddot(ls, v);
958 exp1(ls); 961 exp1(ls);
959 genstorevar(ls, v, codes); 962 genstorevar(ls, v, codes);
960 deltastack(ls, 1); /* DUP operations push an extra value */ 963 deltastack(ls, 1); /* DUP operations push an extra value */
961 v->k = VEXP; v->info = 0; 964 v->k = VEXP; v->info = 0; /* this expression is closed now */
962 } 965 }
963} 966}
964 967
965 968
966static void push (LexState *ls, stack_op *s, int op) { 969static void push (LexState *ls, stack_op *s, int op) {
967 if (s->top == MAXOPS) 970 if (s->top >= MAXOPS)
968 luaX_error(ls, "expression too complex"); 971 luaX_error(ls, "expression too complex");
969 s->ops[s->top++] = op; 972 s->ops[s->top++] = op;
970} 973}
971 974
972 975
973static void prefix (LexState *ls, stack_op *s) {
974 while (ls->token == NOT || ls->token == '-') {
975 push(ls, s, ls->token==NOT?INDNOT:INDMINUS);
976 next(ls);
977 }
978}
979
980static void pop_to (LexState *ls, stack_op *s, int prio) { 976static void pop_to (LexState *ls, stack_op *s, int prio) {
981 int op; 977 int op;
982 while (s->top > 0 && priority[(op=s->ops[s->top-1])] >= prio) { 978 while (s->top > 0 && priority[(op=s->ops[s->top-1])] >= prio) {
@@ -991,10 +987,10 @@ static void simpleexp (LexState *ls, vardesc *v, stack_op *s) {
991 case NUMBER: { /* simpleexp -> NUMBER */ 987 case NUMBER: { /* simpleexp -> NUMBER */
992 real r = ls->seminfo.r; 988 real r = ls->seminfo.r;
993 next(ls); 989 next(ls);
994 /* dirty trick: check whether is a -NUMBER not followed by "^" */ 990 /* dirty trick: check whether it is a -NUMBER not followed by '^' */
995 /* (because the priority of "^" is closer than "-"...) */ 991 /* (because the priority of '^' is closer than '-'...) */
996 if (s->top > 0 && s->ops[s->top-1] == INDMINUS && ls->token != '^') { 992 if (s->top > 0 && s->ops[s->top-1] == INDMINUS && ls->token != '^') {
997 s->top--; 993 s->top--; /* remove '-' from stack */
998 r = -r; 994 r = -r;
999 } 995 }
1000 code_number(ls, r); 996 code_number(ls, r);
@@ -1002,7 +998,7 @@ static void simpleexp (LexState *ls, vardesc *v, stack_op *s) {
1002 } 998 }
1003 999
1004 case STRING: /* simpleexp -> STRING */ 1000 case STRING: /* simpleexp -> STRING */
1005 code_string(ls, ls->seminfo.ts); /* must use before "next" */ 1001 code_string(ls, ls->seminfo.ts); /* must use 'seminfo' before "next" */
1006 next(ls); 1002 next(ls);
1007 break; 1003 break;
1008 1004
@@ -1042,12 +1038,21 @@ static void simpleexp (LexState *ls, vardesc *v, stack_op *s) {
1042} 1038}
1043 1039
1044 1040
1041static void prefixexp (LexState *ls, vardesc *v, stack_op *s) {
1042 /* prefixexp -> {NOT | '-'} simpleexp */
1043 while (ls->token == NOT || ls->token == '-') {
1044 push(ls, s, (ls->token==NOT)?INDNOT:INDMINUS);
1045 next(ls);
1046 }
1047 simpleexp(ls, v, s);
1048}
1049
1050
1045static void exp2 (LexState *ls, vardesc *v) { 1051static void exp2 (LexState *ls, vardesc *v) {
1046 stack_op s; 1052 stack_op s;
1047 int op; 1053 int op;
1048 s.top = 0; 1054 s.top = 0;
1049 prefix(ls, &s); 1055 prefixexp(ls, v, &s);
1050 simpleexp(ls, v, &s);
1051 while ((op = is_in(ls->token, binop)) >= 0) { 1056 while ((op = is_in(ls->token, binop)) >= 0) {
1052 op += FIRSTBIN; 1057 op += FIRSTBIN;
1053 lua_pushvar(ls, v); 1058 lua_pushvar(ls, v);
@@ -1055,8 +1060,7 @@ static void exp2 (LexState *ls, vardesc *v) {
1055 pop_to(ls, &s, (op == POW)?priority[op]+1:priority[op]); 1060 pop_to(ls, &s, (op == POW)?priority[op]+1:priority[op]);
1056 push(ls, &s, op); 1061 push(ls, &s, op);
1057 next(ls); 1062 next(ls);
1058 prefix(ls, &s); 1063 prefixexp(ls, v, &s);
1059 simpleexp(ls, v, &s);
1060 lua_pushvar(ls, v); 1064 lua_pushvar(ls, v);
1061 } 1065 }
1062 if (s.top > 0) { 1066 if (s.top > 0) {
@@ -1078,6 +1082,7 @@ static void var_or_func (LexState *ls, vardesc *v) {
1078 var_or_func_tail(ls, v); 1082 var_or_func_tail(ls, v);
1079} 1083}
1080 1084
1085
1081static void var_or_func_tail (LexState *ls, vardesc *v) { 1086static void var_or_func_tail (LexState *ls, vardesc *v) {
1082 for (;;) { 1087 for (;;) {
1083 switch (ls->token) { 1088 switch (ls->token) {
@@ -1117,13 +1122,14 @@ static void var_or_func_tail (LexState *ls, vardesc *v) {
1117 1122
1118static int funcparams (LexState *ls, int slf) { 1123static int funcparams (LexState *ls, int slf) {
1119 FuncState *fs = ls->fs; 1124 FuncState *fs = ls->fs;
1120 int nparams = 1; /* default value */ 1125 int nparams = 1; /* in cases STRING and constructor */
1121 switch (ls->token) { 1126 switch (ls->token) {
1122 case '(': { /* funcparams -> '(' explist ')' */ 1127 case '(': { /* funcparams -> '(' explist ')' */
1128 int line = ls->linenumber;
1123 listdesc e; 1129 listdesc e;
1124 next(ls); 1130 next(ls);
1125 explist(ls, &e); 1131 explist(ls, &e);
1126 check(ls, ')'); 1132 check_match(ls, ')', '(', line);
1127 close_exp(ls, e.pc, 1); 1133 close_exp(ls, e.pc, 1);
1128 nparams = e.n; 1134 nparams = e.n;
1129 break; 1135 break;
@@ -1134,7 +1140,7 @@ static int funcparams (LexState *ls, int slf) {
1134 break; 1140 break;
1135 1141
1136 case STRING: /* funcparams -> STRING */ 1142 case STRING: /* funcparams -> STRING */
1137 code_string(ls, ls->seminfo.ts); /* must use before "next" */ 1143 code_string(ls, ls->seminfo.ts); /* must use 'seminfo' before "next" */
1138 next(ls); 1144 next(ls);
1139 break; 1145 break;
1140 1146
@@ -1142,8 +1148,8 @@ static int funcparams (LexState *ls, int slf) {
1142 luaX_error(ls, "function arguments expected"); 1148 luaX_error(ls, "function arguments expected");
1143 break; 1149 break;
1144 } 1150 }
1145 code_byte(fs, 0); /* save space for opcode */ 1151 code_byte(fs, CALLFUNC);
1146 code_byte(fs, 0); /* and nresult */ 1152 code_byte(fs, 0); /* save space for nresult */
1147 code_byte(fs, (Byte)(nparams+slf)); 1153 code_byte(fs, (Byte)(nparams+slf));
1148 return fs->pc-1; 1154 return fs->pc-1;
1149} 1155}
diff --git a/lvm.c b/lvm.c
index d10dae92..d6befc1a 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 1.42 1999/02/02 17:57:49 roberto Exp roberto $ 2** $Id: lvm.c,v 1.43 1999/02/02 19:41:17 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*/
@@ -328,6 +328,7 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base) {
328 } 328 }
329 for (;;) { 329 for (;;) {
330 register int aux = 0; 330 register int aux = 0;
331 switchentry:
331 switch ((OpCode)*pc++) { 332 switch ((OpCode)*pc++) {
332 333
333 case ENDCODE: aux = 1; 334 case ENDCODE: aux = 1;
@@ -348,14 +349,14 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base) {
348 S->top -= (aux+1); 349 S->top -= (aux+1);
349 break; 350 break;
350 351
351 case PUSHNUMBERW: aux = highbyte(*pc++); 352 case PUSHNUMBERW: aux += highbyte(*pc++);
352 case PUSHNUMBER: aux += *pc++; 353 case PUSHNUMBER: aux += *pc++;
353 ttype(S->top) = LUA_T_NUMBER; 354 ttype(S->top) = LUA_T_NUMBER;
354 nvalue(S->top) = aux-NUMOFFSET; 355 nvalue(S->top) = aux-NUMOFFSET;
355 S->top++; 356 S->top++;
356 break; 357 break;
357 358
358 case PUSHCONSTANTW: aux = highbyte(*pc++); 359 case PUSHCONSTANTW: aux += highbyte(*pc++);
359 case PUSHCONSTANT: aux += *pc++; 360 case PUSHCONSTANT: aux += *pc++;
360 *S->top++ = consts[aux]; 361 *S->top++ = consts[aux];
361 break; 362 break;
@@ -368,22 +369,22 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base) {
368 *S->top++ = *((S->stack+base) + aux); 369 *S->top++ = *((S->stack+base) + aux);
369 break; 370 break;
370 371
371 case GETGLOBALW: aux = highbyte(*pc++); 372 case GETGLOBALW: aux += highbyte(*pc++);
372 case GETGLOBAL: aux += *pc++; 373 case GETGLOBAL: aux += *pc++;
373 luaV_getglobal(tsvalue(&consts[aux])); 374 luaV_getglobal(tsvalue(&consts[aux]));
374 break; 375 break;
375 376
376 case GETTABLE: 377 case GETTABLE:
377 luaV_gettable(); 378 luaV_gettable();
378 break; 379 break;
379 380
380 case GETDOTTEDW: aux = highbyte(*pc++); 381 case GETDOTTEDW: aux += highbyte(*pc++);
381 case GETDOTTED: aux += *pc++; 382 case GETDOTTED: aux += *pc++;
382 *S->top++ = consts[aux]; 383 *S->top++ = consts[aux];
383 luaV_gettable(); 384 luaV_gettable();
384 break; 385 break;
385 386
386 case PUSHSELFW: aux = highbyte(*pc++); 387 case PUSHSELFW: aux += highbyte(*pc++);
387 case PUSHSELF: aux += *pc++; { 388 case PUSHSELF: aux += *pc++; {
388 TObject receiver = *(S->top-1); 389 TObject receiver = *(S->top-1);
389 *S->top++ = consts[aux]; 390 *S->top++ = consts[aux];
@@ -392,7 +393,7 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base) {
392 break; 393 break;
393 } 394 }
394 395
395 case CREATEARRAYW: aux = highbyte(*pc++); 396 case CREATEARRAYW: aux += highbyte(*pc++);
396 case CREATEARRAY: aux += *pc++; 397 case CREATEARRAY: aux += *pc++;
397 luaC_checkGC(); 398 luaC_checkGC();
398 avalue(S->top) = luaH_new(aux); 399 avalue(S->top) = luaH_new(aux);
@@ -408,12 +409,12 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base) {
408 *((S->stack+base) + aux) = *(S->top-1); 409 *((S->stack+base) + aux) = *(S->top-1);
409 break; 410 break;
410 411
411 case SETGLOBALW: aux = highbyte(*pc++); 412 case SETGLOBALW: aux += highbyte(*pc++);
412 case SETGLOBAL: aux += *pc++; 413 case SETGLOBAL: aux += *pc++;
413 luaV_setglobal(tsvalue(&consts[aux])); 414 luaV_setglobal(tsvalue(&consts[aux]));
414 break; 415 break;
415 416
416 case SETGLOBALDUPW: aux = highbyte(*pc++); 417 case SETGLOBALDUPW: aux += highbyte(*pc++);
417 case SETGLOBALDUP: aux += *pc++; 418 case SETGLOBALDUP: aux += *pc++;
418 *S->top = *(S->top-1); 419 *S->top = *(S->top-1);
419 S->top++; 420 S->top++;
@@ -435,7 +436,7 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base) {
435 luaV_settable(S->top-3-(*pc++), 1); 436 luaV_settable(S->top-3-(*pc++), 1);
436 break; 437 break;
437 438
438 case SETLISTW: aux = highbyte(*pc++); 439 case SETLISTW: aux += highbyte(*pc++);
439 case SETLIST: aux += *pc++; { 440 case SETLIST: aux += *pc++; {
440 int n = *(pc++); 441 int n = *(pc++);
441 TObject *arr = S->top-n-1; 442 TObject *arr = S->top-n-1;
@@ -561,34 +562,34 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base) {
561 nvalue(S->top-1) = 1; 562 nvalue(S->top-1) = 1;
562 break; 563 break;
563 564
564 case ONTJMPW: aux = highbyte(*pc++); 565 case ONTJMPW: aux += highbyte(*pc++);
565 case ONTJMP: aux += *pc++; 566 case ONTJMP: aux += *pc++;
566 if (ttype(S->top-1) != LUA_T_NIL) pc += aux; 567 if (ttype(S->top-1) != LUA_T_NIL) pc += aux;
567 else S->top--; 568 else S->top--;
568 break; 569 break;
569 570
570 case ONFJMPW: aux = highbyte(*pc++); 571 case ONFJMPW: aux += highbyte(*pc++);
571 case ONFJMP: aux += *pc++; 572 case ONFJMP: aux += *pc++;
572 if (ttype(S->top-1) == LUA_T_NIL) pc += aux; 573 if (ttype(S->top-1) == LUA_T_NIL) pc += aux;
573 else S->top--; 574 else S->top--;
574 break; 575 break;
575 576
576 case JMPW: aux = highbyte(*pc++); 577 case JMPW: aux += highbyte(*pc++);
577 case JMP: aux += *pc++; 578 case JMP: aux += *pc++;
578 pc += aux; 579 pc += aux;
579 break; 580 break;
580 581
581 case IFFJMPW: aux = highbyte(*pc++); 582 case IFFJMPW: aux += highbyte(*pc++);
582 case IFFJMP: aux += *pc++; 583 case IFFJMP: aux += *pc++;
583 if (ttype(--S->top) == LUA_T_NIL) pc += aux; 584 if (ttype(--S->top) == LUA_T_NIL) pc += aux;
584 break; 585 break;
585 586
586 case IFTUPJMPW: aux = highbyte(*pc++); 587 case IFTUPJMPW: aux += highbyte(*pc++);
587 case IFTUPJMP: aux += *pc++; 588 case IFTUPJMP: aux += *pc++;
588 if (ttype(--S->top) != LUA_T_NIL) pc -= aux; 589 if (ttype(--S->top) != LUA_T_NIL) pc -= aux;
589 break; 590 break;
590 591
591 case IFFUPJMPW: aux = highbyte(*pc++); 592 case IFFUPJMPW: aux += highbyte(*pc++);
592 case IFFUPJMP: aux += *pc++; 593 case IFFUPJMP: aux += *pc++;
593 if (ttype(--S->top) == LUA_T_NIL) pc -= aux; 594 if (ttype(--S->top) == LUA_T_NIL) pc -= aux;
594 break; 595 break;
@@ -605,7 +606,7 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base) {
605 break; 606 break;
606 } 607 }
607 608
608 case SETLINEW: aux = highbyte(*pc++); 609 case SETLINEW: aux += highbyte(*pc++);
609 case SETLINE: aux += *pc++; 610 case SETLINE: aux += *pc++;
610 if ((S->stack+base-1)->ttype != LUA_T_LINE) { 611 if ((S->stack+base-1)->ttype != LUA_T_LINE) {
611 /* open space for LINE value */ 612 /* open space for LINE value */
@@ -618,6 +619,10 @@ StkId luaV_execute (Closure *cl, TProtoFunc *tf, StkId base) {
618 luaD_lineHook(aux); 619 luaD_lineHook(aux);
619 break; 620 break;
620 621
622 case LONGARG:
623 aux = highbyte(highbyte(*pc++));
624 goto switchentry; /* do not reset "aux" */
625
621 } 626 }
622 } 627 }
623} 628}