diff options
Diffstat (limited to 'lcode.c')
-rw-r--r-- | lcode.c | 113 |
1 files changed, 51 insertions, 62 deletions
@@ -22,7 +22,7 @@ | |||
22 | 22 | ||
23 | #define hasjumps(e) ((e)->t != (e)->f) | 23 | #define hasjumps(e) ((e)->t != (e)->f) |
24 | 24 | ||
25 | #define getcode(fs,e) ((fs)->f->code[(e)->u.i.info]) | 25 | #define getcode(fs,e) ((fs)->f->code[(e)->info]) |
26 | 26 | ||
27 | 27 | ||
28 | 28 | ||
@@ -202,7 +202,7 @@ static void freereg (FuncState *fs, int reg) { | |||
202 | 202 | ||
203 | static void freeexp (FuncState *fs, expdesc *e) { | 203 | static void freeexp (FuncState *fs, expdesc *e) { |
204 | if (e->k == VNONRELOC) | 204 | if (e->k == VNONRELOC) |
205 | freereg(fs, e->u.i.info); | 205 | freereg(fs, e->info); |
206 | } | 206 | } |
207 | 207 | ||
208 | 208 | ||
@@ -225,14 +225,14 @@ static int addk (FuncState *fs, TObject *k, TObject *v) { | |||
225 | } | 225 | } |
226 | 226 | ||
227 | 227 | ||
228 | int luaK_stringk (FuncState *fs, TString *s) { | 228 | int luaK_stringK (FuncState *fs, TString *s) { |
229 | TObject o; | 229 | TObject o; |
230 | setsvalue(&o, s); | 230 | setsvalue(&o, s); |
231 | return addk(fs, &o, &o); | 231 | return addk(fs, &o, &o); |
232 | } | 232 | } |
233 | 233 | ||
234 | 234 | ||
235 | static int number_constant (FuncState *fs, lua_Number r) { | 235 | int luaK_numberK (FuncState *fs, lua_Number r) { |
236 | TObject o; | 236 | TObject o; |
237 | setnvalue(&o, r); | 237 | setnvalue(&o, r); |
238 | return addk(fs, &o, &o); | 238 | return addk(fs, &o, &o); |
@@ -252,7 +252,7 @@ void luaK_setcallreturns (FuncState *fs, expdesc *e, int nresults) { | |||
252 | SETARG_C(getcode(fs, e), nresults+1); | 252 | SETARG_C(getcode(fs, e), nresults+1); |
253 | if (nresults == 1) { /* `regular' expression? */ | 253 | if (nresults == 1) { /* `regular' expression? */ |
254 | e->k = VNONRELOC; | 254 | e->k = VNONRELOC; |
255 | e->u.i.info = GETARG_A(getcode(fs, e)); | 255 | e->info = GETARG_A(getcode(fs, e)); |
256 | } | 256 | } |
257 | } | 257 | } |
258 | } | 258 | } |
@@ -265,19 +265,19 @@ void luaK_dischargevars (FuncState *fs, expdesc *e) { | |||
265 | break; | 265 | break; |
266 | } | 266 | } |
267 | case VUPVAL: { | 267 | case VUPVAL: { |
268 | e->u.i.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.i.info, 0); | 268 | e->info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->info, 0); |
269 | e->k = VRELOCABLE; | 269 | e->k = VRELOCABLE; |
270 | break; | 270 | break; |
271 | } | 271 | } |
272 | case VGLOBAL: { | 272 | case VGLOBAL: { |
273 | e->u.i.info = luaK_codeABc(fs, OP_GETGLOBAL, 0, e->u.i.info); | 273 | e->info = luaK_codeABc(fs, OP_GETGLOBAL, 0, e->info); |
274 | e->k = VRELOCABLE; | 274 | e->k = VRELOCABLE; |
275 | break; | 275 | break; |
276 | } | 276 | } |
277 | case VINDEXED: { | 277 | case VINDEXED: { |
278 | freereg(fs, e->u.i.aux); | 278 | freereg(fs, e->aux); |
279 | freereg(fs, e->u.i.info); | 279 | freereg(fs, e->info); |
280 | e->u.i.info = luaK_codeABC(fs, OP_GETTABLE, 0, e->u.i.info, e->u.i.aux); | 280 | e->info = luaK_codeABC(fs, OP_GETTABLE, 0, e->info, e->aux); |
281 | e->k = VRELOCABLE; | 281 | e->k = VRELOCABLE; |
282 | break; | 282 | break; |
283 | } | 283 | } |
@@ -334,17 +334,8 @@ static void discharge2reg (FuncState *fs, expdesc *e, int reg) { | |||
334 | luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0); | 334 | luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0); |
335 | break; | 335 | break; |
336 | } | 336 | } |
337 | case VNUMBER: { | ||
338 | lua_Number f = e->u.n; | ||
339 | int i = cast(int, f); | ||
340 | if ((lua_Number)i == f && -MAXARG_sBc <= i && i <= MAXARG_sBc) | ||
341 | luaK_codeAsBc(fs, OP_LOADINT, reg, i); /* f has a small int value */ | ||
342 | else | ||
343 | luaK_codeABc(fs, OP_LOADK, reg, number_constant(fs, f)); | ||
344 | break; | ||
345 | } | ||
346 | case VK: { | 337 | case VK: { |
347 | luaK_codeABc(fs, OP_LOADK, reg, e->u.i.info); | 338 | luaK_codeABc(fs, OP_LOADK, reg, e->info); |
348 | break; | 339 | break; |
349 | } | 340 | } |
350 | case VRELOCABLE: { | 341 | case VRELOCABLE: { |
@@ -354,7 +345,7 @@ static void discharge2reg (FuncState *fs, expdesc *e, int reg) { | |||
354 | } | 345 | } |
355 | default: return; | 346 | default: return; |
356 | } | 347 | } |
357 | e->u.i.info = reg; | 348 | e->info = reg; |
358 | e->k = VNONRELOC; | 349 | e->k = VNONRELOC; |
359 | } | 350 | } |
360 | 351 | ||
@@ -374,8 +365,8 @@ static void luaK_exp2reg (FuncState *fs, expdesc *e, int reg) { | |||
374 | return; /* nothing to do... */ | 365 | return; /* nothing to do... */ |
375 | } | 366 | } |
376 | case VNONRELOC: { | 367 | case VNONRELOC: { |
377 | if (reg != e->u.i.info) | 368 | if (reg != e->info) |
378 | luaK_codeABC(fs, OP_MOVE, reg, e->u.i.info, 0); | 369 | luaK_codeABC(fs, OP_MOVE, reg, e->info, 0); |
379 | break; | 370 | break; |
380 | } | 371 | } |
381 | case VJMP: { | 372 | case VJMP: { |
@@ -387,7 +378,7 @@ static void luaK_exp2reg (FuncState *fs, expdesc *e, int reg) { | |||
387 | } | 378 | } |
388 | } | 379 | } |
389 | dischargejumps(fs, e, reg); | 380 | dischargejumps(fs, e, reg); |
390 | e->u.i.info = reg; | 381 | e->info = reg; |
391 | e->k = VNONRELOC; | 382 | e->k = VNONRELOC; |
392 | } | 383 | } |
393 | 384 | ||
@@ -405,14 +396,14 @@ void luaK_exp2nextreg (FuncState *fs, expdesc *e) { | |||
405 | int luaK_exp2anyreg (FuncState *fs, expdesc *e) { | 396 | int luaK_exp2anyreg (FuncState *fs, expdesc *e) { |
406 | luaK_dischargevars(fs, e); | 397 | luaK_dischargevars(fs, e); |
407 | if (e->k == VNONRELOC) { | 398 | if (e->k == VNONRELOC) { |
408 | if (!hasjumps(e)) return e->u.i.info; /* exp is already in a register */ | 399 | if (!hasjumps(e)) return e->info; /* exp is already in a register */ |
409 | if (e->u.i.info >= fs->nactloc) { /* reg. is not a local? */ | 400 | if (e->info >= fs->nactloc) { /* reg. is not a local? */ |
410 | dischargejumps(fs, e, e->u.i.info); /* put value on it */ | 401 | dischargejumps(fs, e, e->info); /* put value on it */ |
411 | return e->u.i.info; | 402 | return e->info; |
412 | } | 403 | } |
413 | } | 404 | } |
414 | luaK_exp2nextreg(fs, e); /* default */ | 405 | luaK_exp2nextreg(fs, e); /* default */ |
415 | return e->u.i.info; | 406 | return e->info; |
416 | } | 407 | } |
417 | 408 | ||
418 | 409 | ||
@@ -427,18 +418,17 @@ void luaK_exp2val (FuncState *fs, expdesc *e) { | |||
427 | int luaK_exp2RK (FuncState *fs, expdesc *e) { | 418 | int luaK_exp2RK (FuncState *fs, expdesc *e) { |
428 | luaK_exp2val(fs, e); | 419 | luaK_exp2val(fs, e); |
429 | switch (e->k) { | 420 | switch (e->k) { |
430 | case VNUMBER: case VNIL: { | 421 | case VNIL: { |
431 | if (fs->nk + MAXSTACK <= MAXARG_C) { /* constant fit in argC? */ | 422 | if (fs->nk + MAXSTACK <= MAXARG_C) { /* constant fit in argC? */ |
432 | e->u.i.info = (e->k == VNIL) ? nil_constant(fs) : | 423 | e->info = nil_constant(fs); |
433 | number_constant(fs, e->u.n); | ||
434 | e->k = VK; | 424 | e->k = VK; |
435 | return e->u.i.info + MAXSTACK; | 425 | return e->info + MAXSTACK; |
436 | } | 426 | } |
437 | else break; | 427 | else break; |
438 | } | 428 | } |
439 | case VK: { | 429 | case VK: { |
440 | if (e->u.i.info + MAXSTACK <= MAXARG_C) /* constant fit in argC? */ | 430 | if (e->info + MAXSTACK <= MAXARG_C) /* constant fit in argC? */ |
441 | return e->u.i.info + MAXSTACK; | 431 | return e->info + MAXSTACK; |
442 | else break; | 432 | else break; |
443 | } | 433 | } |
444 | default: break; | 434 | default: break; |
@@ -452,25 +442,25 @@ void luaK_storevar (FuncState *fs, expdesc *var, expdesc *exp) { | |||
452 | switch (var->k) { | 442 | switch (var->k) { |
453 | case VLOCAL: { | 443 | case VLOCAL: { |
454 | freeexp(fs, exp); | 444 | freeexp(fs, exp); |
455 | luaK_exp2reg(fs, exp, var->u.i.info); | 445 | luaK_exp2reg(fs, exp, var->info); |
456 | break; | 446 | break; |
457 | } | 447 | } |
458 | case VUPVAL: { | 448 | case VUPVAL: { |
459 | int e = luaK_exp2anyreg(fs, exp); | 449 | int e = luaK_exp2anyreg(fs, exp); |
460 | freereg(fs, e); | 450 | freereg(fs, e); |
461 | luaK_codeABC(fs, OP_SETUPVAL, e, var->u.i.info, 0); | 451 | luaK_codeABC(fs, OP_SETUPVAL, e, var->info, 0); |
462 | break; | 452 | break; |
463 | } | 453 | } |
464 | case VGLOBAL: { | 454 | case VGLOBAL: { |
465 | int e = luaK_exp2anyreg(fs, exp); | 455 | int e = luaK_exp2anyreg(fs, exp); |
466 | freereg(fs, e); | 456 | freereg(fs, e); |
467 | luaK_codeABc(fs, OP_SETGLOBAL, e, var->u.i.info); | 457 | luaK_codeABc(fs, OP_SETGLOBAL, e, var->info); |
468 | break; | 458 | break; |
469 | } | 459 | } |
470 | case VINDEXED: { | 460 | case VINDEXED: { |
471 | int e = luaK_exp2anyreg(fs, exp); | 461 | int e = luaK_exp2anyreg(fs, exp); |
472 | freereg(fs, e); | 462 | freereg(fs, e); |
473 | luaK_codeABC(fs, OP_SETTABLE, e, var->u.i.info, var->u.i.aux); | 463 | luaK_codeABC(fs, OP_SETTABLE, e, var->info, var->aux); |
474 | break; | 464 | break; |
475 | } | 465 | } |
476 | default: { | 466 | default: { |
@@ -487,9 +477,9 @@ void luaK_self (FuncState *fs, expdesc *e, expdesc *key) { | |||
487 | freeexp(fs, e); | 477 | freeexp(fs, e); |
488 | func = fs->freereg; | 478 | func = fs->freereg; |
489 | luaK_reserveregs(fs, 2); | 479 | luaK_reserveregs(fs, 2); |
490 | luaK_codeABC(fs, OP_SELF, func, e->u.i.info, luaK_exp2RK(fs, key)); | 480 | luaK_codeABC(fs, OP_SELF, func, e->info, luaK_exp2RK(fs, key)); |
491 | freeexp(fs, key); | 481 | freeexp(fs, key); |
492 | e->u.i.info = func; | 482 | e->info = func; |
493 | e->k = VNONRELOC; | 483 | e->k = VNONRELOC; |
494 | } | 484 | } |
495 | 485 | ||
@@ -510,7 +500,7 @@ static OpCode invertoperator (OpCode op) { | |||
510 | 500 | ||
511 | 501 | ||
512 | static void invertjump (FuncState *fs, expdesc *e) { | 502 | static void invertjump (FuncState *fs, expdesc *e) { |
513 | Instruction *pc = getjumpcontrol(fs, e->u.i.info); | 503 | Instruction *pc = getjumpcontrol(fs, e->info); |
514 | *pc = SET_OPCODE(*pc, invertoperator(GET_OPCODE(*pc))); | 504 | *pc = SET_OPCODE(*pc, invertoperator(GET_OPCODE(*pc))); |
515 | } | 505 | } |
516 | 506 | ||
@@ -527,7 +517,7 @@ static int jumponcond (FuncState *fs, expdesc *e, OpCode op) { | |||
527 | } | 517 | } |
528 | discharge2anyreg(fs, e); | 518 | discharge2anyreg(fs, e); |
529 | freeexp(fs, e); | 519 | freeexp(fs, e); |
530 | return luaK_condjump(fs, op, NO_REG, e->u.i.info, 0); | 520 | return luaK_condjump(fs, op, NO_REG, e->info, 0); |
531 | } | 521 | } |
532 | 522 | ||
533 | 523 | ||
@@ -535,7 +525,7 @@ void luaK_goiftrue (FuncState *fs, expdesc *e) { | |||
535 | int pc; /* pc of last jump */ | 525 | int pc; /* pc of last jump */ |
536 | luaK_dischargevars(fs, e); | 526 | luaK_dischargevars(fs, e); |
537 | switch (e->k) { | 527 | switch (e->k) { |
538 | case VK: case VNUMBER: case VTRUE: { | 528 | case VK: case VTRUE: { |
539 | pc = NO_JUMP; /* always true; do nothing */ | 529 | pc = NO_JUMP; /* always true; do nothing */ |
540 | break; | 530 | break; |
541 | } | 531 | } |
@@ -545,7 +535,7 @@ void luaK_goiftrue (FuncState *fs, expdesc *e) { | |||
545 | } | 535 | } |
546 | case VJMP: { | 536 | case VJMP: { |
547 | invertjump(fs, e); | 537 | invertjump(fs, e); |
548 | pc = e->u.i.info; | 538 | pc = e->info; |
549 | break; | 539 | break; |
550 | } | 540 | } |
551 | default: { | 541 | default: { |
@@ -572,7 +562,7 @@ static void luaK_goiffalse (FuncState *fs, expdesc *e) { | |||
572 | break; | 562 | break; |
573 | } | 563 | } |
574 | case VJMP: { | 564 | case VJMP: { |
575 | pc = e->u.i.info; | 565 | pc = e->info; |
576 | break; | 566 | break; |
577 | } | 567 | } |
578 | default: { | 568 | default: { |
@@ -593,7 +583,7 @@ static void codenot (FuncState *fs, expdesc *e) { | |||
593 | e->k = VTRUE; | 583 | e->k = VTRUE; |
594 | break; | 584 | break; |
595 | } | 585 | } |
596 | case VK: case VNUMBER: case VTRUE: { | 586 | case VK: case VTRUE: { |
597 | e->k = VFALSE; | 587 | e->k = VFALSE; |
598 | break; | 588 | break; |
599 | } | 589 | } |
@@ -605,7 +595,7 @@ static void codenot (FuncState *fs, expdesc *e) { | |||
605 | case VNONRELOC: { | 595 | case VNONRELOC: { |
606 | discharge2anyreg(fs, e); | 596 | discharge2anyreg(fs, e); |
607 | freeexp(fs, e); | 597 | freeexp(fs, e); |
608 | e->u.i.info = luaK_codeABC(fs, OP_NOT, 0, e->u.i.info, 0); | 598 | e->info = luaK_codeABC(fs, OP_NOT, 0, e->info, 0); |
609 | e->k = VRELOCABLE; | 599 | e->k = VRELOCABLE; |
610 | break; | 600 | break; |
611 | } | 601 | } |
@@ -620,7 +610,7 @@ static void codenot (FuncState *fs, expdesc *e) { | |||
620 | 610 | ||
621 | 611 | ||
622 | void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { | 612 | void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { |
623 | t->u.i.aux = luaK_exp2RK(fs, k); | 613 | t->aux = luaK_exp2RK(fs, k); |
624 | t->k = VINDEXED; | 614 | t->k = VINDEXED; |
625 | } | 615 | } |
626 | 616 | ||
@@ -628,12 +618,12 @@ void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { | |||
628 | void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) { | 618 | void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) { |
629 | if (op == OPR_MINUS) { | 619 | if (op == OPR_MINUS) { |
630 | luaK_exp2val(fs, e); | 620 | luaK_exp2val(fs, e); |
631 | if (e->k == VNUMBER) | 621 | if (e->k == VK && ttype(&fs->f->k[e->info]) == LUA_TNUMBER) |
632 | e->u.n = -e->u.n; | 622 | e->info = luaK_numberK(fs, -nvalue(&fs->f->k[e->info])); |
633 | else { | 623 | else { |
634 | luaK_exp2anyreg(fs, e); | 624 | luaK_exp2anyreg(fs, e); |
635 | freeexp(fs, e); | 625 | freeexp(fs, e); |
636 | e->u.i.info = luaK_codeABC(fs, OP_UNM, 0, e->u.i.info, 0); | 626 | e->info = luaK_codeABC(fs, OP_UNM, 0, e->info, 0); |
637 | e->k = VRELOCABLE; | 627 | e->k = VRELOCABLE; |
638 | } | 628 | } |
639 | } | 629 | } |
@@ -695,30 +685,29 @@ void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) { | |||
695 | lua_assert(e1->t == NO_JUMP); /* list must be closed */ | 685 | lua_assert(e1->t == NO_JUMP); /* list must be closed */ |
696 | luaK_dischargevars(fs, e2); | 686 | luaK_dischargevars(fs, e2); |
697 | luaK_concat(fs, &e1->f, e2->f); | 687 | luaK_concat(fs, &e1->f, e2->f); |
698 | e1->k = e2->k; e1->u = e2->u; e1->t = e2->t; | 688 | e1->k = e2->k; e1->info = e2->info; e1->aux = e2->aux; e1->t = e2->t; |
699 | break; | 689 | break; |
700 | } | 690 | } |
701 | case OPR_OR: { | 691 | case OPR_OR: { |
702 | lua_assert(e1->f == NO_JUMP); /* list must be closed */ | 692 | lua_assert(e1->f == NO_JUMP); /* list must be closed */ |
703 | luaK_dischargevars(fs, e2); | 693 | luaK_dischargevars(fs, e2); |
704 | luaK_concat(fs, &e1->t, e2->t); | 694 | luaK_concat(fs, &e1->t, e2->t); |
705 | e1->k = e2->k; e1->u = e2->u; e1->f = e2->f; | 695 | e1->k = e2->k; e1->info = e2->info; e1->aux = e2->aux; e1->f = e2->f; |
706 | break; | 696 | break; |
707 | } | 697 | } |
708 | case OPR_CONCAT: { | 698 | case OPR_CONCAT: { |
709 | luaK_exp2val(fs, e2); | 699 | luaK_exp2val(fs, e2); |
710 | if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) { | 700 | if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) { |
711 | lua_assert(e1->u.i.info == GETARG_B(getcode(fs, e2))-1); | 701 | lua_assert(e1->info == GETARG_B(getcode(fs, e2))-1); |
712 | freeexp(fs, e1); | 702 | freeexp(fs, e1); |
713 | SETARG_B(getcode(fs, e2), e1->u.i.info); | 703 | SETARG_B(getcode(fs, e2), e1->info); |
714 | e1->k = e2->k; e1->u.i.info = e2->u.i.info; | 704 | e1->k = e2->k; e1->info = e2->info; |
715 | } | 705 | } |
716 | else { | 706 | else { |
717 | luaK_exp2nextreg(fs, e2); | 707 | luaK_exp2nextreg(fs, e2); |
718 | freeexp(fs, e2); | 708 | freeexp(fs, e2); |
719 | freeexp(fs, e1); | 709 | freeexp(fs, e1); |
720 | e1->u.i.info = luaK_codeABC(fs, codes[op], 0, e1->u.i.info, | 710 | e1->info = luaK_codeABC(fs, codes[op], 0, e1->info, e2->info); |
721 | e2->u.i.info); | ||
722 | e1->k = VRELOCABLE; | 711 | e1->k = VRELOCABLE; |
723 | } | 712 | } |
724 | break; | 713 | break; |
@@ -727,7 +716,7 @@ void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) { | |||
727 | int o1, o2; | 716 | int o1, o2; |
728 | OpCode opc; | 717 | OpCode opc; |
729 | if (e1->k != VK) { /* not a constant operator? */ | 718 | if (e1->k != VK) { /* not a constant operator? */ |
730 | o1 = e1->u.i.info; | 719 | o1 = e1->info; |
731 | o2 = luaK_exp2RK(fs, e2); /* maybe other operator is constant... */ | 720 | o2 = luaK_exp2RK(fs, e2); /* maybe other operator is constant... */ |
732 | opc = codes[op]; | 721 | opc = codes[op]; |
733 | } | 722 | } |
@@ -739,11 +728,11 @@ void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) { | |||
739 | freeexp(fs, e2); | 728 | freeexp(fs, e2); |
740 | freeexp(fs, e1); | 729 | freeexp(fs, e1); |
741 | if (op < OPR_NE) { /* ORDER OPR */ | 730 | if (op < OPR_NE) { /* ORDER OPR */ |
742 | e1->u.i.info = luaK_codeABC(fs, opc, 0, o1, o2); | 731 | e1->info = luaK_codeABC(fs, opc, 0, o1, o2); |
743 | e1->k = VRELOCABLE; | 732 | e1->k = VRELOCABLE; |
744 | } | 733 | } |
745 | else { /* jump */ | 734 | else { /* jump */ |
746 | e1->u.i.info = luaK_condjump(fs, opc, o1, 0, o2); | 735 | e1->info = luaK_condjump(fs, opc, o1, 0, o2); |
747 | e1->k = VJMP; | 736 | e1->k = VJMP; |
748 | } | 737 | } |
749 | } | 738 | } |