aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lopcodes.h9
-rw-r--r--lua.stx129
-rw-r--r--lvm.c64
3 files changed, 126 insertions, 76 deletions
diff --git a/lopcodes.h b/lopcodes.h
index e1b95122..f6bf4818 100644
--- a/lopcodes.h
+++ b/lopcodes.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lopcodes.h,v 1.4 1997/09/22 20:53:20 roberto Exp roberto $ 2** $Id: lopcodes.h,v 1.5 1997/09/24 19:43:11 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*/
@@ -76,6 +76,7 @@ GETTABLE,/* i t t[i] */
76PUSHSELFB,/* b t t t[CNST[b]] */ 76PUSHSELFB,/* b t t t[CNST[b]] */
77PUSHSELF,/* w t t t[CNST[w]] */ 77PUSHSELF,/* w t t t[CNST[w]] */
78 78
79CREATEARRAYB,/* b - newarray(size = b) */
79CREATEARRAY,/* w - newarray(size = w) */ 80CREATEARRAY,/* w - newarray(size = w) */
80 81
81SETLOCAL0,/* x - LOC[0]=x */ 82SETLOCAL0,/* x - LOC[0]=x */
@@ -118,10 +119,12 @@ NOTOP,/* x (x==nil)? 1 : nil */
118/* NOTICE: all jumps are relative to the position following the opcode */ 119/* NOTICE: all jumps are relative to the position following the opcode */
119ONTJMP,/* b x (x!=nil)? x : - (x!=nil)? PC+=b */ 120ONTJMP,/* b x (x!=nil)? x : - (x!=nil)? PC+=b */
120ONFJMP,/* b x (x==nil)? x : - (x==nil)? PC+=b */ 121ONFJMP,/* b x (x==nil)? x : - (x==nil)? PC+=b */
122JMPB,/* b - - PC+=b */
121JMP,/* w - - PC+=w */ 123JMP,/* w - - PC+=w */
122UPJMPB,/* b - - PC-=b */ 124IFFJMPB,/* b x - (x==nil)? PC+=b */
123UPJMP,/* w - - PC-=w */
124IFFJMP,/* w x - (x==nil)? PC+=w */ 125IFFJMP,/* w x - (x==nil)? PC+=w */
126IFTUPJMPB,/* b x - (x!=nil)? PC-=b */
127IFTUPJMP,/* w x - (x!=nil)? PC-=w */
125IFFUPJMPB,/* b x - (x==nil)? PC-=b */ 128IFFUPJMPB,/* b x - (x==nil)? PC-=b */
126IFFUPJMP,/* w x - (x==nil)? PC-=w */ 129IFFUPJMP,/* w x - (x==nil)? PC-=w */
127 130
diff --git a/lua.stx b/lua.stx
index 2f650f4e..8fd89517 100644
--- a/lua.stx
+++ b/lua.stx
@@ -1,6 +1,6 @@
1%{ 1%{
2/* 2/*
3** $Id: lua.stx,v 1.5 1997/09/24 19:43:11 roberto Exp roberto $ 3** $Id: lua.stx,v 1.6 1997/09/26 15:02:26 roberto Exp roberto $
4** Syntax analizer and code generator 4** Syntax analizer and code generator
5** See Copyright Notice in lua.h 5** See Copyright Notice in lua.h
6*/ 6*/
@@ -28,6 +28,9 @@ int luaY_parse (void);
28#define free luaM_free 28#define free luaM_free
29 29
30 30
31/* size of a "normal" jump instruction: OpCode + 1 byte */
32#define JMPSIZE 2
33
31/* maximum number of local variables */ 34/* maximum number of local variables */
32#define MAXLOCALS 32 35#define MAXLOCALS 32
33 36
@@ -85,11 +88,32 @@ void luaY_error (char *s)
85} 88}
86 89
87 90
88static void code_byte (Byte c) 91static void check_pc (int n)
89{ 92{
90 if (currState->pc >= currState->maxcode) 93 if (currState->pc+n > currState->maxcode)
91 currState->maxcode = luaM_growvector(&currState->f->code, 94 currState->maxcode = luaM_growvector(&currState->f->code,
92 currState->maxcode, Byte, codeEM, MAX_INT); 95 currState->maxcode, Byte, codeEM, MAX_INT);
96}
97
98
99static void movecode_up (int d, int s, int n)
100{
101 while (n--)
102 currState->f->code[d+n] = currState->f->code[s+n];
103}
104
105
106static void movecode_down (int d, int s, int n)
107{
108 int i;
109 for (i=0; i<n; i++)
110 currState->f->code[d+i] = currState->f->code[s+i];
111}
112
113
114static void code_byte (Byte c)
115{
116 check_pc(1);
93 currState->f->code[currState->pc++] = c; 117 currState->f->code[currState->pc++] = c;
94} 118}
95 119
@@ -103,19 +127,36 @@ static void code_word_at (int pc, int n)
103} 127}
104 128
105 129
106static void fix_jump (int pc, OpCode op, int n) 130static void code_word (int n)
107{ 131{
108 currState->f->code[pc] = op; 132 check_pc(2);
109 code_word_at(pc+1, n); 133 currState->pc += 2;
134 code_word_at(currState->pc-2, n);
110} 135}
111 136
112 137
113static void code_word (int n) 138static int fix_opcode (int pc, OpCode op, int n)
114{ 139{
115 if (n > MAX_WORD) 140 if (n <= 255) {
116 luaY_error("construction too big; unable to compile"); 141 currState->f->code[pc] = op;
117 code_byte(n&0xFF); 142 currState->f->code[pc+1] = n;
118 code_byte(n>>8); 143 return 0;
144 }
145 else {
146 check_pc(1); /* open space */
147 movecode_up(pc+1, pc, currState->pc-pc);
148 currState->pc++;
149 currState->f->code[pc] = op+1; /* opcode must be word variant */
150 code_word_at(pc+1, n);
151 return 1;
152 }
153}
154
155static int fix_jump (int pc, OpCode op, int n)
156{
157 n -= pc+1; /* jump is relative to position following jump opcode */
158 if (n > 255) n++; /* jump must be 1 bigger */
159 return fix_opcode(pc, op, n);
119} 160}
120 161
121 162
@@ -462,14 +503,14 @@ static int lua_codestore (int i, int left)
462 503
463static void codeIf (int thenAdd, int elseAdd) 504static void codeIf (int thenAdd, int elseAdd)
464{ 505{
465 int elseinit = elseAdd+sizeof(Word)+1; 506 int elseinit = elseAdd+JMPSIZE;
466 if (currState->pc == elseinit) { /* no else part */ 507 if (currState->pc == elseinit) { /* no else part */
467 currState->pc -= sizeof(Word)+1; 508 currState->pc -= JMPSIZE;
468 elseinit = currState->pc; 509 elseinit = currState->pc;
469 } 510 }
470 else 511 else
471 fix_jump(elseAdd, JMP, currState->pc-(elseAdd+1)); 512 elseinit += fix_jump(elseAdd, JMPB, currState->pc);
472 fix_jump(thenAdd, IFFJMP, elseinit-(thenAdd+1)); 513 fix_jump(thenAdd, IFFJMPB, elseinit);
473} 514}
474 515
475 516
@@ -593,7 +634,7 @@ TProtoFunc *luaY_parser (ZIO *z, char *chunkname)
593%token <vReal> NUMBER 634%token <vReal> NUMBER
594%token <pTStr> NAME STRING 635%token <pTStr> NAME STRING
595 636
596%type <vInt> PrepJump, PrepJumpPop, PrepJumpSC 637%type <vInt> SaveWord, cond, GetPC, SaveWordPop, SaveWordPush
597%type <vLong> exprlist, exprlist1 /* if > 0, points to function return 638%type <vLong> exprlist, exprlist1 /* if > 0, points to function return
598 counter (which has list length); if <= 0, -list lenght */ 639 counter (which has list length); if <= 0, -list lenght */
599%type <vLong> functioncall, expr /* if != 0, points to function return 640%type <vLong> functioncall, expr /* if != 0, points to function return
@@ -628,18 +669,24 @@ statlist : /* empty */
628 669
629sc : /* empty */ | ';' ; 670sc : /* empty */ | ';' ;
630 671
631stat : IF expr1 THEN PrepJumpPop block PrepJump elsepart END 672stat : IF cond THEN block SaveWord elsepart END
632 { codeIf($4, $6); } 673 { codeIf($2, $5); }
633 674
634 | WHILE {$<vInt>$=currState->pc;} expr1 DO PrepJumpPop block END 675 | WHILE GetPC cond DO block END
635 { 676 {{
636 code_opborw(UPJMPB, currState->pc+1 - ($<vInt>2), 0); 677 int expsize = $3-$2;
637 fix_jump($5, IFFJMP, currState->pc - ($5+1)); 678 int newpos = $2+JMPSIZE;
638 } 679 check_pc(expsize);
680 memcpy(&currState->f->code[currState->pc],
681 &currState->f->code[$2], expsize);
682 movecode_down($2, $3, currState->pc-$2);
683 newpos += fix_jump($2, JMPB, currState->pc-expsize);
684 code_opborw(IFTUPJMPB, currState->pc+1 - newpos, 0);
685 }}
639 686
640 | REPEAT {$<vInt>$=currState->pc;} block UNTIL expr1 687 | REPEAT GetPC block UNTIL expr1
641 { 688 {
642 code_opborw(IFFUPJMPB, currState->pc+1 - ($<vInt>2), -1); 689 code_opborw(IFFUPJMPB, currState->pc+1 - $2, -1);
643 } 690 }
644 691
645 | varlist1 '=' exprlist1 692 | varlist1 '=' exprlist1
@@ -687,8 +734,8 @@ body : '(' parlist ')' chunk END { $$ = close_func(); }
687 734
688elsepart : /* empty */ 735elsepart : /* empty */
689 | ELSE block 736 | ELSE block
690 | ELSEIF expr1 THEN PrepJumpPop block PrepJump elsepart 737 | ELSEIF cond THEN block SaveWord elsepart
691 { codeIf($4, $6); } 738 { codeIf($2, $5); }
692 ; 739 ;
693 740
694ret : /* empty */ 741ret : /* empty */
@@ -699,19 +746,19 @@ ret : /* empty */
699 } 746 }
700 ; 747 ;
701 748
702PrepJump : /* empty */ 749GetPC : /* empty */ { $$ = currState->pc; }
703 { 750 ;
704 $$ = currState->pc; 751
705 code_byte(0); /* open space */ 752SaveWord : GetPC { $$ = $1; code_word(0); /* open space */ }
706 code_word(0);
707 }
708 ; 753 ;
709 754
710PrepJumpSC : /* empty */ 755SaveWordPop : SaveWord { $$ = $1; deltastack(-1); /* pop condition */ }
711 { $$ = currState->pc; code_opcode(0, -1); code_byte(0); } 756 ;
757
758SaveWordPush : SaveWord { $$ = $1; deltastack(1); /* push a value */ }
712 ; 759 ;
713 760
714PrepJumpPop : PrepJump { $$ = $1; deltastack(-1); /* pop condition */ } 761cond : expr1 SaveWordPop { $$ = $2; }
715 ; 762 ;
716 763
717expr1 : expr { adjust_functioncall($1, 1); } 764expr1 : expr { adjust_functioncall($1, 1); }
@@ -739,14 +786,11 @@ expr : '(' expr ')' { $$ = $2; }
739 | NIL {code_opcode(PUSHNIL, 1); $$ = 0; } 786 | NIL {code_opcode(PUSHNIL, 1); $$ = 0; }
740 | functioncall { $$ = $1; } 787 | functioncall { $$ = $1; }
741 | FUNCTION { init_func(); } body { func_onstack($3); $$ = 0; } 788 | FUNCTION { init_func(); } body { func_onstack($3); $$ = 0; }
742 | expr1 AND PrepJumpSC expr1 { code_shortcircuit(ONFJMP, $3); $$ = 0; } 789 | expr1 AND SaveWordPop expr1 { code_shortcircuit(ONFJMP, $3); $$ = 0; }
743 | expr1 OR PrepJumpSC expr1 { code_shortcircuit(ONTJMP, $3); $$ = 0; } 790 | expr1 OR SaveWordPop expr1 { code_shortcircuit(ONTJMP, $3); $$ = 0; }
744 ; 791 ;
745 792
746table : 793table : '{' SaveWordPush fieldlist '}' { fix_opcode($2, CREATEARRAYB, $3); }
747 { $<vInt>$ = currState->pc+1; code_opw(CREATEARRAY, 0, 1); }
748 '{' fieldlist '}'
749 { code_word_at($<vInt>1, $3); }
750 ; 794 ;
751 795
752functioncall : funcvalue funcParams 796functioncall : funcvalue funcParams
@@ -892,3 +936,4 @@ decinit : /* empty */ { $$ = 0; }
892 ; 936 ;
893 937
894%% 938%%
939
diff --git a/lvm.c b/lvm.c
index 6051067e..5f9db8f9 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 1.5 1997/09/24 19:43:11 roberto Exp roberto $ 2** $Id: lvm.c,v 1.6 1997/09/26 15:02:26 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*/
@@ -452,8 +452,13 @@ StkId luaV_execute (Closure *cl, StkId base)
452 break; 452 break;
453 453
454 case CREATEARRAY: 454 case CREATEARRAY:
455 aux = next_word(pc); goto createarray;
456
457 case CREATEARRAYB:
458 aux = *pc++;
459 createarray:
455 luaC_checkGC(); 460 luaC_checkGC();
456 avalue(luaD_stack.top) = luaH_new(next_word(pc)); 461 avalue(luaD_stack.top) = luaH_new(aux);
457 ttype(luaD_stack.top) = LUA_T_ARRAY; 462 ttype(luaD_stack.top) = LUA_T_ARRAY;
458 luaD_stack.top++; 463 luaD_stack.top++;
459 break; 464 break;
@@ -565,54 +570,51 @@ StkId luaV_execute (Closure *cl, StkId base)
565 break; 570 break;
566 571
567 case ONTJMP: 572 case ONTJMP:
568 if (ttype(luaD_stack.top-1) != LUA_T_NIL) 573 if (ttype(luaD_stack.top-1) != LUA_T_NIL) pc += *pc;
569 pc += *pc; 574 else { pc++; luaD_stack.top--; }
570 else {
571 pc++;
572 luaD_stack.top--;
573 }
574 break; 575 break;
575 576
576 case ONFJMP: 577 case ONFJMP:
577 if (ttype(luaD_stack.top-1) == LUA_T_NIL) 578 if (ttype(luaD_stack.top-1) == LUA_T_NIL) pc += *pc;
578 pc += *pc; 579 else { pc++; luaD_stack.top--; }
579 else { 580 break;
580 pc++; 581
581 luaD_stack.top--; 582 case JMPB:
582 } 583 pc += *pc;
583 break; 584 break;
584 585
585 case JMP: 586 case JMP:
586 pc += get_word(pc); 587 pc += get_word(pc);
587 break; 588 break;
588 589
589 case UPJMPB: 590 case IFFJMPB:
590 pc -= *pc; 591 if (ttype(--luaD_stack.top) == LUA_T_NIL) pc += *pc;
592 else pc++;
591 break; 593 break;
592 594
593 case UPJMP: 595 case IFFJMP:
594 pc -= get_word(pc); 596 if (ttype(--luaD_stack.top) == LUA_T_NIL) pc += get_word(pc);
597 else skip_word(pc);
595 break; 598 break;
596 599
597 case IFFJMP: 600 case IFTUPJMPB:
598 if (ttype(--luaD_stack.top) == LUA_T_NIL) 601 if (ttype(--luaD_stack.top) != LUA_T_NIL) pc -= *pc;
599 pc += get_word(pc); 602 else pc++;
600 else 603 break;
601 skip_word(pc); 604
605 case IFTUPJMP:
606 if (ttype(--luaD_stack.top) != LUA_T_NIL) pc -= get_word(pc);
607 else skip_word(pc);
602 break; 608 break;
603 609
604 case IFFUPJMPB: 610 case IFFUPJMPB:
605 if (ttype(--luaD_stack.top) == LUA_T_NIL) 611 if (ttype(--luaD_stack.top) == LUA_T_NIL) pc -= *pc;
606 pc -= *pc; 612 else pc++;
607 else
608 pc++;
609 break; 613 break;
610 614
611 case IFFUPJMP: 615 case IFFUPJMP:
612 if (ttype(--luaD_stack.top) == LUA_T_NIL) 616 if (ttype(--luaD_stack.top) == LUA_T_NIL) pc -= get_word(pc);
613 pc -= get_word(pc); 617 else skip_word(pc);
614 else
615 skip_word(pc);
616 break; 618 break;
617 619
618 case CLOSURE: 620 case CLOSURE: