diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-05-22 15:44:46 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2000-05-22 15:44:46 -0300 |
commit | 5c2dd7a9e0a5b871a71ba66c4683cd88fe4f5aa4 (patch) | |
tree | c5c7f73e8d10b6081d07999a44bb5f93769440f8 | |
parent | 93d93a0bfbc30f1176e973e1238b51e560eeb233 (diff) | |
download | lua-5c2dd7a9e0a5b871a71ba66c4683cd88fe4f5aa4.tar.gz lua-5c2dd7a9e0a5b871a71ba66c4683cd88fe4f5aa4.tar.bz2 lua-5c2dd7a9e0a5b871a71ba66c4683cd88fe4f5aa4.zip |
array `luaK_opproperties' keeps delta stack and mode for each opcode
-rw-r--r-- | lcode.c | 258 | ||||
-rw-r--r-- | lcode.h | 10 | ||||
-rw-r--r-- | lopcodes.h | 4 | ||||
-rw-r--r-- | lparser.c | 10 | ||||
-rw-r--r-- | ltests.c | 87 | ||||
-rw-r--r-- | lvm.c | 4 |
6 files changed, 166 insertions, 207 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lcode.c,v 1.29 2000/05/08 19:32:53 roberto Exp roberto $ | 2 | ** $Id: lcode.c,v 1.30 2000/05/15 19:48:04 roberto Exp roberto $ |
3 | ** Code generator for Lua | 3 | ** Code generator for Lua |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -37,7 +37,7 @@ static Instruction previous_instruction (FuncState *fs) { | |||
37 | 37 | ||
38 | 38 | ||
39 | int luaK_jump (FuncState *fs) { | 39 | int luaK_jump (FuncState *fs) { |
40 | int j = luaK_code0(fs, OP_JMP); | 40 | int j = luaK_code1(fs, OP_JMP, NO_JUMP); |
41 | if (j == fs->lasttarget) { /* possible jumps to this jump? */ | 41 | if (j == fs->lasttarget) { /* possible jumps to this jump? */ |
42 | luaK_concat(fs, &j, fs->jlt); /* keep them on hold */ | 42 | luaK_concat(fs, &j, fs->jlt); /* keep them on hold */ |
43 | fs->jlt = NO_JUMP; | 43 | fs->jlt = NO_JUMP; |
@@ -279,7 +279,7 @@ static void luaK_testgo (FuncState *fs, expdesc *v, int invert, OpCode jump) { | |||
279 | SET_OPCODE(*previous, invertjump(GET_OPCODE(*previous))); | 279 | SET_OPCODE(*previous, invertjump(GET_OPCODE(*previous))); |
280 | } | 280 | } |
281 | else | 281 | else |
282 | luaK_code0(fs, jump); | 282 | luaK_code1(fs, jump, NO_JUMP); |
283 | luaK_concat(fs, exitlist, fs->pc-1); /* insert last jump in `exitlist' */ | 283 | luaK_concat(fs, exitlist, fs->pc-1); /* insert last jump in `exitlist' */ |
284 | luaK_patchlist(fs, *golist, luaK_getlabel(fs)); | 284 | luaK_patchlist(fs, *golist, luaK_getlabel(fs)); |
285 | *golist = NO_JUMP; | 285 | *golist = NO_JUMP; |
@@ -324,10 +324,11 @@ void luaK_tostack (LexState *ls, expdesc *v, int onlyone) { | |||
324 | if (ISJUMP(previous)) | 324 | if (ISJUMP(previous)) |
325 | luaK_concat(fs, &v->u.l.t, fs->pc-1); /* put `previous' in t. list */ | 325 | luaK_concat(fs, &v->u.l.t, fs->pc-1); /* put `previous' in t. list */ |
326 | else { | 326 | else { |
327 | j = code_label(fs, OP_JMP, 0); /* to jump over both pushes */ | 327 | j = code_label(fs, OP_JMP, NO_JUMP); /* to jump over both pushes */ |
328 | luaK_deltastack(fs, -1); /* next PUSHes may be skipped */ | 328 | luaK_deltastack(fs, -1); /* next PUSHes may be skipped */ |
329 | } | 329 | } |
330 | p_nil = code_label(fs, OP_PUSHNILJMP, 0); | 330 | p_nil = code_label(fs, OP_PUSHNILJMP, 0); |
331 | luaK_deltastack(fs, -1); /* next PUSH is skipped */ | ||
331 | p_1 = code_label(fs, OP_PUSHINT, 1); | 332 | p_1 = code_label(fs, OP_PUSHINT, 1); |
332 | luaK_patchlist(fs, j, luaK_getlabel(fs)); | 333 | luaK_patchlist(fs, j, luaK_getlabel(fs)); |
333 | } | 334 | } |
@@ -394,12 +395,12 @@ void luaK_posfix (LexState *ls, int op, expdesc *v1, expdesc *v2) { | |||
394 | case '/': luaK_code0(fs, OP_DIV); break; | 395 | case '/': luaK_code0(fs, OP_DIV); break; |
395 | case '^': luaK_code0(fs, OP_POW); break; | 396 | case '^': luaK_code0(fs, OP_POW); break; |
396 | case TK_CONCAT: luaK_code1(fs, OP_CONCAT, 2); break; | 397 | case TK_CONCAT: luaK_code1(fs, OP_CONCAT, 2); break; |
397 | case TK_EQ: luaK_code0(fs, OP_JMPEQ); break; | 398 | case TK_EQ: luaK_code1(fs, OP_JMPEQ, NO_JUMP); break; |
398 | case TK_NE: luaK_code0(fs, OP_JMPNE); break; | 399 | case TK_NE: luaK_code1(fs, OP_JMPNE, NO_JUMP); break; |
399 | case '>': luaK_code0(fs, OP_JMPGT); break; | 400 | case '>': luaK_code1(fs, OP_JMPGT, NO_JUMP); break; |
400 | case '<': luaK_code0(fs, OP_JMPLT); break; | 401 | case '<': luaK_code1(fs, OP_JMPLT, NO_JUMP); break; |
401 | case TK_GE: luaK_code0(fs, OP_JMPGE); break; | 402 | case TK_GE: luaK_code1(fs, OP_JMPGE, NO_JUMP); break; |
402 | case TK_LE: luaK_code0(fs, OP_JMPLE); break; | 403 | case TK_LE: luaK_code1(fs, OP_JMPLE, NO_JUMP); break; |
403 | } | 404 | } |
404 | } | 405 | } |
405 | } | 406 | } |
@@ -415,196 +416,120 @@ int luaK_code1 (FuncState *fs, OpCode o, int arg1) { | |||
415 | } | 416 | } |
416 | 417 | ||
417 | 418 | ||
419 | #define VD 100 /* flag for variable delta */ | ||
420 | |||
418 | 421 | ||
419 | int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) { | 422 | int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) { |
420 | Instruction i = previous_instruction(fs); | 423 | Instruction i = previous_instruction(fs); |
421 | int delta = 0; | 424 | int delta = luaK_opproperties[o].delta; |
422 | enum {iO, iU, iS, iAB, iP} mode; /* instruction format (or iP to optimize) */ | 425 | int optm = 0; /* 1 when there is an optimization */ |
423 | mode = iP; | ||
424 | |||
425 | switch (o) { | 426 | switch (o) { |
426 | 427 | ||
427 | case OP_CLOSURE: | 428 | case OP_CLOSURE: |
428 | delta = -arg2+1; | 429 | delta = -arg2+1; |
429 | mode = iAB; | ||
430 | break; | ||
431 | |||
432 | case OP_SETLINE: | ||
433 | mode = iU; | ||
434 | break; | ||
435 | |||
436 | case OP_CALL: | ||
437 | mode = iAB; | ||
438 | break; | ||
439 | |||
440 | case OP_PUSHINT: | ||
441 | delta = 1; | ||
442 | mode = iS; | ||
443 | break; | 430 | break; |
444 | 431 | ||
445 | case OP_SETTABLE: | 432 | case OP_SETTABLE: |
446 | delta = -arg2; | ||
447 | mode = iAB; | ||
448 | break; | ||
449 | |||
450 | case OP_SETLIST: | 433 | case OP_SETLIST: |
451 | delta = -(arg2+1); | 434 | delta = -arg2; |
452 | mode = iAB; | ||
453 | break; | 435 | break; |
454 | 436 | ||
455 | case OP_SETMAP: | 437 | case OP_SETMAP: |
456 | delta = -2*(arg1+1); | 438 | delta = -2*(arg1+1); |
457 | mode = iU; | ||
458 | break; | ||
459 | |||
460 | case OP_FORLOOP: | ||
461 | delta = -3; | ||
462 | arg1 = NO_JUMP; | ||
463 | mode = iS; | ||
464 | break; | ||
465 | |||
466 | case OP_SETLOCAL: | ||
467 | case OP_SETGLOBAL: | ||
468 | delta = -1; | ||
469 | mode = iU; | ||
470 | break; | ||
471 | |||
472 | case OP_FORPREP: | ||
473 | case OP_JMP: | ||
474 | arg1 = NO_JUMP; | ||
475 | mode = iS; | ||
476 | break; | ||
477 | |||
478 | case OP_LFORPREP: | ||
479 | delta = 3; | ||
480 | arg1 = NO_JUMP; | ||
481 | mode = iS; | ||
482 | break; | ||
483 | |||
484 | case OP_LFORLOOP: | ||
485 | delta = -4; | ||
486 | arg1 = NO_JUMP; | ||
487 | mode = iS; | ||
488 | break; | ||
489 | |||
490 | case OP_END: | ||
491 | case OP_PUSHNILJMP: | ||
492 | case OP_NOT: | ||
493 | mode = iO; | ||
494 | break; | ||
495 | |||
496 | case OP_PUSHSTRING: | ||
497 | case OP_PUSHNUM: | ||
498 | case OP_PUSHNEGNUM: | ||
499 | case OP_PUSHUPVALUE: | ||
500 | case OP_GETLOCAL: | ||
501 | case OP_GETGLOBAL: | ||
502 | case OP_PUSHSELF: | ||
503 | case OP_CREATETABLE: | ||
504 | delta = 1; | ||
505 | mode = iU; | ||
506 | break; | ||
507 | |||
508 | case OP_JMPLT: | ||
509 | case OP_JMPLE: | ||
510 | case OP_JMPGT: | ||
511 | case OP_JMPGE: | ||
512 | delta = -2; | ||
513 | arg1 = NO_JUMP; | ||
514 | mode = iS; | ||
515 | break; | ||
516 | |||
517 | case OP_MULT: | ||
518 | case OP_DIV: | ||
519 | case OP_POW: | ||
520 | delta = -1; | ||
521 | mode = iO; | ||
522 | break; | 439 | break; |
523 | 440 | ||
524 | case OP_RETURN: | 441 | case OP_RETURN: |
525 | if (GET_OPCODE(i) == OP_CALL && GETARG_B(i) == MULT_RET) { | 442 | if (GET_OPCODE(i) == OP_CALL && GETARG_B(i) == MULT_RET) { |
526 | SET_OPCODE(i, OP_TAILCALL); | 443 | SET_OPCODE(i, OP_TAILCALL); |
527 | SETARG_B(i, arg1); | 444 | SETARG_B(i, arg1); |
445 | optm = 1; | ||
528 | } | 446 | } |
529 | else mode = iU; | ||
530 | break; | 447 | break; |
531 | 448 | ||
532 | case OP_PUSHNIL: | 449 | case OP_PUSHNIL: |
533 | delta = arg1; | 450 | delta = arg1; |
534 | switch(GET_OPCODE(i)) { | 451 | switch(GET_OPCODE(i)) { |
535 | case OP_PUSHNIL: SETARG_U(i, GETARG_U(i)+arg1); break; | 452 | case OP_PUSHNIL: SETARG_U(i, GETARG_U(i)+arg1); optm = 1; break; |
536 | default: mode = iU; break; | 453 | default: break; |
537 | } | 454 | } |
538 | break; | 455 | break; |
539 | 456 | ||
540 | case OP_POP: | 457 | case OP_POP: |
541 | delta = -arg1; | 458 | delta = -arg1; |
542 | switch(GET_OPCODE(i)) { | 459 | switch(GET_OPCODE(i)) { |
543 | case OP_SETTABLE: SETARG_B(i, GETARG_B(i)+arg1); break; | 460 | case OP_SETTABLE: SETARG_B(i, GETARG_B(i)+arg1); optm = 1; break; |
544 | default: mode = iU; break; | 461 | default: break; |
545 | } | 462 | } |
546 | break; | 463 | break; |
547 | 464 | ||
548 | case OP_GETTABLE: | 465 | case OP_GETTABLE: |
549 | delta = -1; | ||
550 | switch(GET_OPCODE(i)) { | 466 | switch(GET_OPCODE(i)) { |
551 | case OP_PUSHSTRING: SET_OPCODE(i, OP_GETDOTTED); break; /* `t.x' */ | 467 | case OP_PUSHSTRING: /* `t.x' */ |
552 | case OP_GETLOCAL: SET_OPCODE(i, OP_GETINDEXED); break; /* `t[i]' */ | 468 | SET_OPCODE(i, OP_GETDOTTED); |
553 | default: mode = iO; break; | 469 | optm = 1; |
470 | break; | ||
471 | case OP_GETLOCAL: /* `t[i]' */ | ||
472 | SET_OPCODE(i, OP_GETINDEXED); | ||
473 | optm = 1; | ||
474 | break; | ||
475 | default: break; | ||
554 | } | 476 | } |
555 | break; | 477 | break; |
556 | 478 | ||
557 | case OP_ADD: | 479 | case OP_ADD: |
558 | delta = -1; | ||
559 | switch(GET_OPCODE(i)) { | 480 | switch(GET_OPCODE(i)) { |
560 | case OP_PUSHINT: SET_OPCODE(i, OP_ADDI); break; /* `a+k' */ | 481 | case OP_PUSHINT: SET_OPCODE(i, OP_ADDI); optm = 1; break; /* `a+k' */ |
561 | default: mode = iO; break; | 482 | default: break; |
562 | } | 483 | } |
563 | break; | 484 | break; |
564 | 485 | ||
565 | case OP_SUB: | 486 | case OP_SUB: |
566 | delta = -1; | ||
567 | switch(GET_OPCODE(i)) { | 487 | switch(GET_OPCODE(i)) { |
568 | case OP_PUSHINT: i = CREATE_S(OP_ADDI, -GETARG_S(i)); break; /* `a-k' */ | 488 | case OP_PUSHINT: /* `a-k' */ |
569 | default: mode = iO; break; | 489 | i = CREATE_S(OP_ADDI, -GETARG_S(i)); |
490 | optm = 1; | ||
491 | break; | ||
492 | default: break; | ||
570 | } | 493 | } |
571 | break; | 494 | break; |
572 | 495 | ||
573 | case OP_CONCAT: | 496 | case OP_CONCAT: |
574 | delta = -arg1+1; | 497 | delta = -arg1+1; |
575 | switch(GET_OPCODE(i)) { | 498 | switch(GET_OPCODE(i)) { |
576 | case OP_CONCAT: SETARG_U(i, GETARG_U(i)+1); break; /* `a..b..c' */ | 499 | case OP_CONCAT: /* `a..b..c' */ |
577 | default: mode = iU; break; | 500 | SETARG_U(i, GETARG_U(i)+1); |
501 | optm = 1; | ||
502 | break; | ||
503 | default: break; | ||
578 | } | 504 | } |
579 | break; | 505 | break; |
580 | 506 | ||
581 | case OP_MINUS: | 507 | case OP_MINUS: |
582 | switch(GET_OPCODE(i)) { | 508 | switch(GET_OPCODE(i)) { |
583 | case OP_PUSHINT: SETARG_S(i, -GETARG_S(i)); break; /* `-k' */ | 509 | case OP_PUSHINT: /* `-k' */ |
584 | case OP_PUSHNUM: SET_OPCODE(i, OP_PUSHNEGNUM); break; /* `-k' */ | 510 | SETARG_S(i, -GETARG_S(i)); |
585 | default: mode = iO; break; | 511 | optm = 1; |
512 | break; | ||
513 | case OP_PUSHNUM: /* `-k' */ | ||
514 | SET_OPCODE(i, OP_PUSHNEGNUM); | ||
515 | optm = 1; | ||
516 | break; | ||
517 | default: break; | ||
586 | } | 518 | } |
587 | break; | 519 | break; |
588 | 520 | ||
589 | case OP_JMPNE: | 521 | case OP_JMPNE: |
590 | delta = -2; | 522 | if (i == CREATE_U(OP_PUSHNIL, 1)) { /* `a~=nil' */ |
591 | if (i == CREATE_U(OP_PUSHNIL, 1)) /* `a~=nil' */ | ||
592 | i = CREATE_S(OP_JMPT, NO_JUMP); | 523 | i = CREATE_S(OP_JMPT, NO_JUMP); |
593 | else { | 524 | optm = 1; |
594 | arg1 = NO_JUMP; | ||
595 | mode = iS; | ||
596 | } | 525 | } |
597 | break; | 526 | break; |
598 | 527 | ||
599 | case OP_JMPEQ: | 528 | case OP_JMPEQ: |
600 | delta = -2; | ||
601 | if (i == CREATE_U(OP_PUSHNIL, 1)) { /* `a==nil' */ | 529 | if (i == CREATE_U(OP_PUSHNIL, 1)) { /* `a==nil' */ |
602 | i = CREATE_0(OP_NOT); | 530 | i = CREATE_0(OP_NOT); |
603 | delta = -1; /* just undo effect of previous PUSHNIL */ | 531 | delta = -1; /* just undo effect of previous PUSHNIL */ |
604 | } | 532 | optm = 1; |
605 | else { | ||
606 | arg1 = NO_JUMP; | ||
607 | mode = iS; | ||
608 | } | 533 | } |
609 | break; | 534 | break; |
610 | 535 | ||
@@ -612,11 +537,9 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) { | |||
612 | case OP_JMPF: | 537 | case OP_JMPF: |
613 | case OP_JMPONT: | 538 | case OP_JMPONT: |
614 | case OP_JMPONF: | 539 | case OP_JMPONF: |
615 | delta = -1; | ||
616 | arg1 = NO_JUMP; | ||
617 | switch (GET_OPCODE(i)) { | 540 | switch (GET_OPCODE(i)) { |
618 | case OP_NOT: i = CREATE_S(invertjump(o), NO_JUMP); break; | 541 | case OP_NOT: i = CREATE_S(invertjump(o), NO_JUMP); optm = 1; break; |
619 | default: mode = iS; break; | 542 | default: break; |
620 | } | 543 | } |
621 | break; | 544 | break; |
622 | 545 | ||
@@ -625,19 +548,23 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) { | |||
625 | case OP_TAILCALL: | 548 | case OP_TAILCALL: |
626 | case OP_ADDI: | 549 | case OP_ADDI: |
627 | LUA_INTERNALERROR(L, "instruction used only for optimizations"); | 550 | LUA_INTERNALERROR(L, "instruction used only for optimizations"); |
628 | return 0; /* to avoid warnings */ | 551 | break; |
552 | |||
553 | default: | ||
554 | LUA_ASSERT(L, delta != VD, "invalid delta"); | ||
555 | break; | ||
629 | 556 | ||
630 | } | 557 | } |
631 | luaK_deltastack(fs, delta); | 558 | luaK_deltastack(fs, delta); |
632 | switch (mode) { /* handle instruction formats */ | 559 | if (optm) { /* optimize: put instruction in place of last one */ |
560 | fs->f->code[fs->pc-1] = i; /* change previous instruction */ | ||
561 | return fs->pc-1; /* do not generate new instruction */ | ||
562 | } | ||
563 | switch ((enum Mode)luaK_opproperties[o].mode) { | ||
633 | case iO: i = CREATE_0(o); break; | 564 | case iO: i = CREATE_0(o); break; |
634 | case iU: i = CREATE_U(o, arg1); break; | 565 | case iU: i = CREATE_U(o, arg1); break; |
635 | case iS: i = CREATE_S(o, arg1); break; | 566 | case iS: i = CREATE_S(o, arg1); break; |
636 | case iAB: i = CREATE_AB(o, arg1, arg2); break; | 567 | case iAB: i = CREATE_AB(o, arg1, arg2); break; |
637 | case iP: { /* optimize: put instruction in place of last one */ | ||
638 | fs->f->code[fs->pc-1] = i; /* change previous instruction */ | ||
639 | return fs->pc-1; | ||
640 | } | ||
641 | } | 568 | } |
642 | /* actually create the new instruction */ | 569 | /* actually create the new instruction */ |
643 | luaM_growvector(fs->L, fs->f->code, fs->pc, 1, Instruction, codeEM, MAX_INT); | 570 | luaM_growvector(fs->L, fs->f->code, fs->pc, 1, Instruction, codeEM, MAX_INT); |
@@ -645,3 +572,56 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) { | |||
645 | return fs->pc++; | 572 | return fs->pc++; |
646 | } | 573 | } |
647 | 574 | ||
575 | |||
576 | const struct OpProperties luaK_opproperties[OP_SETLINE+1] = { | ||
577 | {iO, 0}, /* OP_END */ | ||
578 | {iU, 0}, /* OP_RETURN */ | ||
579 | {iAB, 0}, /* OP_CALL */ | ||
580 | {iAB, 0}, /* OP_TAILCALL */ | ||
581 | {iU, VD}, /* OP_PUSHNIL */ | ||
582 | {iU, VD}, /* OP_POP */ | ||
583 | {iS, 1}, /* OP_PUSHINT */ | ||
584 | {iU, 1}, /* OP_PUSHSTRING */ | ||
585 | {iU, 1}, /* OP_PUSHNUM */ | ||
586 | {iU, 1}, /* OP_PUSHNEGNUM */ | ||
587 | {iU, 1}, /* OP_PUSHUPVALUE */ | ||
588 | {iU, 1}, /* OP_GETLOCAL */ | ||
589 | {iU, 1}, /* OP_GETGLOBAL */ | ||
590 | {iO, -1}, /* OP_GETTABLE */ | ||
591 | {iU, 0}, /* OP_GETDOTTED */ | ||
592 | {iU, 0}, /* OP_GETINDEXED */ | ||
593 | {iU, 1}, /* OP_PUSHSELF */ | ||
594 | {iU, 1}, /* OP_CREATETABLE */ | ||
595 | {iU, -1}, /* OP_SETLOCAL */ | ||
596 | {iU, -1}, /* OP_SETGLOBAL */ | ||
597 | {iAB, VD}, /* OP_SETTABLE */ | ||
598 | {iAB, VD}, /* OP_SETLIST */ | ||
599 | {iU, VD}, /* OP_SETMAP */ | ||
600 | {iO, -1}, /* OP_ADD */ | ||
601 | {iS, 0}, /* OP_ADDI */ | ||
602 | {iO, -1}, /* OP_SUB */ | ||
603 | {iO, -1}, /* OP_MULT */ | ||
604 | {iO, -1}, /* OP_DIV */ | ||
605 | {iO, -1}, /* OP_POW */ | ||
606 | {iU, VD}, /* OP_CONCAT */ | ||
607 | {iO, 0}, /* OP_MINUS */ | ||
608 | {iO, 0}, /* OP_NOT */ | ||
609 | {iS, -2}, /* OP_JMPNE */ | ||
610 | {iS, -2}, /* OP_JMPEQ */ | ||
611 | {iS, -2}, /* OP_JMPLT */ | ||
612 | {iS, -2}, /* OP_JMPLE */ | ||
613 | {iS, -2}, /* OP_JMPGT */ | ||
614 | {iS, -2}, /* OP_JMPGE */ | ||
615 | {iS, -1}, /* OP_JMPT */ | ||
616 | {iS, -1}, /* OP_JMPF */ | ||
617 | {iS, -1}, /* OP_JMPONT */ | ||
618 | {iS, -1}, /* OP_JMPONF */ | ||
619 | {iS, 0}, /* OP_JMP */ | ||
620 | {iO, 1}, /* OP_PUSHNILJMP */ | ||
621 | {iS, 0}, /* OP_FORPREP */ | ||
622 | {iS, -3}, /* OP_FORLOOP */ | ||
623 | {iS, 3}, /* OP_LFORPREP */ | ||
624 | {iS, -4}, /* OP_LFORLOOP */ | ||
625 | {iAB, VD}, /* OP_CLOSURE */ | ||
626 | {iU, 0} /* OP_SETLINE */ | ||
627 | }; | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lcode.h,v 1.11 2000/04/07 19:35:20 roberto Exp roberto $ | 2 | ** $Id: lcode.h,v 1.12 2000/04/12 18:47:03 roberto Exp roberto $ |
3 | ** Code generator for Lua | 3 | ** Code generator for Lua |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -20,6 +20,14 @@ | |||
20 | #define NO_JUMP (-1) | 20 | #define NO_JUMP (-1) |
21 | 21 | ||
22 | 22 | ||
23 | enum Mode {iO, iU, iS, iAB}; /* instruction format */ | ||
24 | |||
25 | extern const struct OpProperties { | ||
26 | char mode; | ||
27 | signed char delta; | ||
28 | } luaK_opproperties[]; | ||
29 | |||
30 | |||
23 | void luaK_error (LexState *ls, const char *msg); | 31 | void luaK_error (LexState *ls, const char *msg); |
24 | int luaK_code0 (FuncState *fs, OpCode o); | 32 | int luaK_code0 (FuncState *fs, OpCode o); |
25 | int luaK_code1 (FuncState *fs, OpCode o, int arg1); | 33 | int luaK_code1 (FuncState *fs, OpCode o, int arg1); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lopcodes.h,v 1.60 2000/04/27 17:39:15 roberto Exp roberto $ | 2 | ** $Id: lopcodes.h,v 1.61 2000/05/15 19:48:04 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 | */ |
@@ -112,7 +112,7 @@ OP_SETLOCAL,/* L x - LOC[l]=x */ | |||
112 | OP_SETGLOBAL,/* K x - VAR[KSTR[k]]=x */ | 112 | OP_SETGLOBAL,/* K x - VAR[KSTR[k]]=x */ |
113 | OP_SETTABLE,/* A B v a_a-a_1 i t (pops b values) t[i]=v */ | 113 | OP_SETTABLE,/* A B v a_a-a_1 i t (pops b values) t[i]=v */ |
114 | 114 | ||
115 | OP_SETLIST,/* A B v_b-v_0 t t t[i+a*FPF]=v_i */ | 115 | OP_SETLIST,/* A B v_b-v_1 t t t[i+a*FPF]=v_i */ |
116 | OP_SETMAP,/* U v_u k_u - v_0 k_0 t t t[k_i]=v_i */ | 116 | OP_SETMAP,/* U v_u k_u - v_0 k_0 t t t[k_i]=v_i */ |
117 | 117 | ||
118 | OP_ADD,/* - y x x+y */ | 118 | OP_ADD,/* - y x x+y */ |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lparser.c,v 1.86 2000/05/12 18:12:04 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 1.87 2000/05/15 19:48:04 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 | */ |
@@ -626,12 +626,12 @@ static int listfields (LexState *ls) { | |||
626 | checklimit(ls, n, MAXARG_A*LFIELDS_PER_FLUSH, | 626 | checklimit(ls, n, MAXARG_A*LFIELDS_PER_FLUSH, |
627 | "items in a list initializer"); | 627 | "items in a list initializer"); |
628 | if (++mod_n == LFIELDS_PER_FLUSH) { | 628 | if (++mod_n == LFIELDS_PER_FLUSH) { |
629 | luaK_code2(fs, OP_SETLIST, n/LFIELDS_PER_FLUSH - 1, LFIELDS_PER_FLUSH-1); | 629 | luaK_code2(fs, OP_SETLIST, n/LFIELDS_PER_FLUSH - 1, LFIELDS_PER_FLUSH); |
630 | mod_n = 0; | 630 | mod_n = 0; |
631 | } | 631 | } |
632 | } | 632 | } |
633 | if (mod_n > 0) | 633 | if (mod_n > 0) |
634 | luaK_code2(fs, OP_SETLIST, n/LFIELDS_PER_FLUSH, mod_n-1); | 634 | luaK_code2(fs, OP_SETLIST, n/LFIELDS_PER_FLUSH, mod_n); |
635 | return n; | 635 | return n; |
636 | } | 636 | } |
637 | 637 | ||
@@ -911,12 +911,12 @@ static void repeatstat (LexState *ls, int line) { | |||
911 | 911 | ||
912 | static void forbody (LexState *ls, OpCode prepfor, OpCode loopfor) { | 912 | static void forbody (LexState *ls, OpCode prepfor, OpCode loopfor) { |
913 | FuncState *fs = ls->fs; | 913 | FuncState *fs = ls->fs; |
914 | int prep = luaK_code0(fs, prepfor); | 914 | int prep = luaK_code1(fs, prepfor, NO_JUMP); |
915 | int blockinit = luaK_getlabel(fs); | 915 | int blockinit = luaK_getlabel(fs); |
916 | check(ls, TK_DO); | 916 | check(ls, TK_DO); |
917 | block(ls); | 917 | block(ls); |
918 | luaK_patchlist(fs, prep, luaK_getlabel(fs)); | 918 | luaK_patchlist(fs, prep, luaK_getlabel(fs)); |
919 | luaK_patchlist(fs, luaK_code0(fs, loopfor), blockinit); | 919 | luaK_patchlist(fs, luaK_code1(fs, loopfor, NO_JUMP), blockinit); |
920 | } | 920 | } |
921 | 921 | ||
922 | 922 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltests.c,v 1.18 2000/05/10 16:33:20 roberto Exp roberto $ | 2 | ** $Id: ltests.c,v 1.19 2000/05/15 19:48:04 roberto Exp roberto $ |
3 | ** Internal Module for Debugging of the Lua Implementation | 3 | ** Internal Module for Debugging of the Lua Implementation |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -14,6 +14,7 @@ | |||
14 | 14 | ||
15 | #include "lapi.h" | 15 | #include "lapi.h" |
16 | #include "lauxlib.h" | 16 | #include "lauxlib.h" |
17 | #include "lcode.h" | ||
17 | #include "ldo.h" | 18 | #include "ldo.h" |
18 | #include "lmem.h" | 19 | #include "lmem.h" |
19 | #include "lopcodes.h" | 20 | #include "lopcodes.h" |
@@ -49,71 +50,41 @@ static void setnameval (lua_State *L, lua_Object t, const char *name, int val) { | |||
49 | */ | 50 | */ |
50 | 51 | ||
51 | 52 | ||
52 | #define O(o) sprintf(buff, "%s", o) | 53 | static const char *const instrname[OP_SETLINE+1] = { |
53 | #define U(o) sprintf(buff, "%-12s%4u", o, GETARG_U(i)) | 54 | "END", "RETURN", "CALL", "TAILCALL", "PUSHNIL", "POP", "PUSHINT", |
54 | #define S(o) sprintf(buff, "%-12s%4d", o, GETARG_S(i)) | 55 | "PUSHSTRING", "PUSHNUM", "PUSHNEGNUM", "PUSHUPVALUE", "GETLOCAL", |
55 | #define AB(o) sprintf(buff, "%-12s%4d %4d", o, GETARG_A(i), GETARG_B(i)) | 56 | "GETGLOBAL", "GETTABLE", "GETDOTTED", "GETINDEXED", "PUSHSELF", |
56 | 57 | "CREATETABLE", "SETLOCAL", "SETGLOBAL", "SETTABLE", "SETLIST", "SETMAP", | |
58 | "ADD", "ADDI", "SUB", "MULT", "DIV", "POW", "CONCAT", "MINUS", "NOT", | ||
59 | "JMPNE", "JMPEQ", "JMPLT", "JMPLE", "JMPGT", "JMPGE", "JMPT", "JMPF", | ||
60 | "JMPONT", "JMPONF", "JMP", "PUSHNILJMP", "FORPREP", "FORLOOP", "LFORPREP", | ||
61 | "LFORLOOP", "CLOSURE", "SETLINE" | ||
62 | }; | ||
57 | 63 | ||
58 | 64 | ||
59 | static int pushop (lua_State *L, Instruction i) { | 65 | static int pushop (lua_State *L, Instruction i) { |
60 | char buff[100]; | 66 | char buff[100]; |
61 | switch (GET_OPCODE(i)) { | 67 | OpCode o = GET_OPCODE(i); |
62 | case OP_END: O("END"); lua_pushstring(L, buff); return 0; | 68 | const char *name = instrname[o]; |
63 | case OP_RETURN: U("RETURN"); break; | 69 | switch ((enum Mode)luaK_opproperties[o].mode) { |
64 | case OP_CALL: AB("CALL"); break; | 70 | case iO: |
65 | case OP_TAILCALL: AB("TAILCALL"); break; | 71 | sprintf(buff, "%s", name); |
66 | case OP_PUSHNIL: U("PUSHNIL"); break; | 72 | break; |
67 | case OP_POP: U("POP"); break; | 73 | case iU: |
68 | case OP_PUSHINT: S("PUSHINT"); break; | 74 | sprintf(buff, "%-12s%4u", name, GETARG_U(i)); |
69 | case OP_PUSHSTRING: U("PUSHSTRING"); break; | 75 | break; |
70 | case OP_PUSHNUM: U("PUSHNUM"); break; | 76 | case iS: |
71 | case OP_PUSHNEGNUM: U("PUSHNEGNUM"); break; | 77 | sprintf(buff, "%-12s%4d", name, GETARG_S(i)); |
72 | case OP_PUSHUPVALUE: U("PUSHUPVALUE"); break; | 78 | break; |
73 | case OP_GETLOCAL: U("GETLOCAL"); break; | 79 | case iAB: |
74 | case OP_GETGLOBAL: U("GETGLOBAL"); break; | 80 | sprintf(buff, "%-12s%4d %4d", name, GETARG_A(i), GETARG_B(i)); |
75 | case OP_GETTABLE: O("GETTABLE"); break; | 81 | break; |
76 | case OP_GETDOTTED: U("GETDOTTED"); break; | ||
77 | case OP_GETINDEXED: U("GETINDEXED"); break; | ||
78 | case OP_PUSHSELF: U("PUSHSELF"); break; | ||
79 | case OP_CREATETABLE: U("CREATETABLE"); break; | ||
80 | case OP_SETLOCAL: U("SETLOCAL"); break; | ||
81 | case OP_SETGLOBAL: U("SETGLOBAL"); break; | ||
82 | case OP_SETTABLE: AB("SETTABLE"); break; | ||
83 | case OP_SETLIST: AB("SETLIST"); break; | ||
84 | case OP_SETMAP: U("SETMAP"); break; | ||
85 | case OP_ADD: O("ADD"); break; | ||
86 | case OP_ADDI: S("ADDI"); break; | ||
87 | case OP_SUB: O("SUB"); break; | ||
88 | case OP_MULT: O("MULT"); break; | ||
89 | case OP_DIV: O("DIV"); break; | ||
90 | case OP_POW: O("POW"); break; | ||
91 | case OP_CONCAT: U("CONCAT"); break; | ||
92 | case OP_MINUS: O("MINUS"); break; | ||
93 | case OP_NOT: O("NOT"); break; | ||
94 | case OP_JMPNE: S("JMPNE"); break; | ||
95 | case OP_JMPEQ: S("JMPEQ"); break; | ||
96 | case OP_JMPLT: S("JMPLT"); break; | ||
97 | case OP_JMPLE: S("JMPLE"); break; | ||
98 | case OP_JMPGT: S("JMPGT"); break; | ||
99 | case OP_JMPGE: S("JMPGE"); break; | ||
100 | case OP_JMPT: S("JMPT"); break; | ||
101 | case OP_JMPF: S("JMPF"); break; | ||
102 | case OP_JMPONT: S("JMPONT"); break; | ||
103 | case OP_JMPONF: S("JMPONF"); break; | ||
104 | case OP_JMP: S("JMP"); break; | ||
105 | case OP_PUSHNILJMP: O("PUSHNILJMP"); break; | ||
106 | case OP_FORPREP: S("FORPREP"); break; | ||
107 | case OP_FORLOOP: S("FORLOOP"); break; | ||
108 | case OP_LFORPREP: S("LFORPREP"); break; | ||
109 | case OP_LFORLOOP: S("LFORLOOP"); break; | ||
110 | case OP_CLOSURE: AB("CLOSURE"); break; | ||
111 | case OP_SETLINE: U("SETLINE"); break; | ||
112 | } | 82 | } |
113 | lua_pushstring(L, buff); | 83 | lua_pushstring(L, buff); |
114 | return 1; | 84 | return (o != OP_END); |
115 | } | 85 | } |
116 | 86 | ||
87 | |||
117 | static void listcode (lua_State *L) { | 88 | static void listcode (lua_State *L) { |
118 | lua_Object o = luaL_nonnullarg(L, 1); | 89 | lua_Object o = luaL_nonnullarg(L, 1); |
119 | lua_Object t = lua_createtable(L); | 90 | lua_Object t = lua_createtable(L); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 1.105 2000/05/08 19:32:53 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 1.106 2000/05/15 19:48:04 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 | */ |
@@ -470,7 +470,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
470 | 470 | ||
471 | case OP_SETLIST: { | 471 | case OP_SETLIST: { |
472 | int aux = GETARG_A(i) * LFIELDS_PER_FLUSH; | 472 | int aux = GETARG_A(i) * LFIELDS_PER_FLUSH; |
473 | int n = GETARG_B(i)+1; | 473 | int n = GETARG_B(i); |
474 | Hash *arr = avalue(top-n-1); | 474 | Hash *arr = avalue(top-n-1); |
475 | L->top = top-n; /* final value of `top' (in case of errors) */ | 475 | L->top = top-n; /* final value of `top' (in case of errors) */ |
476 | for (; n; n--) | 476 | for (; n; n--) |