diff options
| -rw-r--r-- | lopcodes.h | 32 | ||||
| -rw-r--r-- | lparser.c | 196 | ||||
| -rw-r--r-- | lvm.c | 43 |
3 files changed, 152 insertions, 119 deletions
| @@ -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) */ | |||
| 100 | CALLFUNC,/* b c v_c...v_1 f r_b...r_1 f(v1,...,v_c) */ | 98 | CALLFUNC,/* b c v_c...v_1 f r_b...r_1 f(v1,...,v_c) */ |
| 101 | 99 | ||
| 102 | SETLINEW,/* w - - LINE=w */ | 100 | SETLINEW,/* w - - LINE=w */ |
| 103 | SETLINE /* b - - LINE=b */ | 101 | SETLINE,/* b - - LINE=b */ |
| 102 | |||
| 103 | LONGARG /* 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 |
| @@ -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 | */ | ||
| 102 | static int assignment (LexState *ls, vardesc *v, int nvars); | 105 | static int assignment (LexState *ls, vardesc *v, int nvars); |
| 103 | static int cond (LexState *ls); | 106 | static int cond (LexState *ls); |
| 104 | static int funcname (LexState *ls, vardesc *v); | 107 | static 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 | ||
| 157 | static int code_oparg_at (LexState *ls, int pc, OpCode op, int arg, int delta) { | 160 | static 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 | |||
| 182 | static 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 | ||
| 177 | static int fix_opcode (LexState *ls, int pc, OpCode op, int arg) { | 189 | static 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 | ||
| 189 | static void code_oparg (LexState *ls, OpCode op, int arg, int delta) { | 203 | static 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 | ||
| 206 | static int next_constant (FuncState *fs) { | 222 | static 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 | ||
| 254 | static void code_number (LexState *ls, real f) { | 269 | static 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 | ||
| 270 | static void flush_list (LexState *ls, int m, int n) { | 284 | static 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 | ||
| 296 | static void store_localvar (LexState *ls, TaggedString *name, int n) { | 311 | static 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) { | |||
| 320 | static void singlevar (LexState *ls, TaggedString *n, vardesc *var, int prev) { | 334 | static 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 | ||
| 356 | static void pushupvalue (LexState *ls, TaggedString *n) { | 370 | static 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) { | |||
| 384 | static void close_exp (LexState *ls, int pc, int nresults) { | 396 | static 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 | ||
| 494 | static void fix_upjmp (LexState *ls, OpCode op, int pos) { | 504 | static 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 | ||
| 501 | static void codeIf (LexState *ls, int thenAdd, int elseAdd) { | 510 | static 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 | |||
| 558 | static void close_func (LexState *ls) { | 566 | static 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) { | |||
| 575 | static int expfollow [] = {ELSE, ELSEIF, THEN, IF, WHILE, REPEAT, DO, NAME, | 583 | static 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 | |||
| 578 | static int is_in (int tok, int *toks) { | 587 | static 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 | ||
| 644 | static TaggedString *str_checkname (LexState *ls) { | 650 | static 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 | ||
| 879 | static void ret (LexState *ls) { | 883 | static 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}; | |||
| 913 | static OpCode opcodes [POW+1] = {NOTOP, MINUSOP, EQOP, NEQOP, GTOP, LTOP, | 919 | static 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 | ||
| 921 | typedef struct { | 924 | typedef struct { |
| 922 | int ops[MAXOPS]; | 925 | int ops[MAXOPS]; |
| @@ -934,16 +937,17 @@ static void exp1 (LexState *ls) { | |||
| 934 | 937 | ||
| 935 | 938 | ||
| 936 | static void exp0 (LexState *ls, vardesc *v) { | 939 | static 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 | ||
| 966 | static void push (LexState *ls, stack_op *s, int op) { | 969 | static 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 | ||
| 973 | static 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 | |||
| 980 | static void pop_to (LexState *ls, stack_op *s, int prio) { | 976 | static 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 | ||
| 1041 | static 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 | |||
| 1045 | static void exp2 (LexState *ls, vardesc *v) { | 1051 | static 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 | |||
| 1081 | static void var_or_func_tail (LexState *ls, vardesc *v) { | 1086 | static 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 | ||
| 1118 | static int funcparams (LexState *ls, int slf) { | 1123 | static 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 | } |
| @@ -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 | } |
