Browse Source

new opcode variants.

Roberto Ierusalimschy 28 years ago
parent
commit
0dd6d1080e
3 changed files with 145 additions and 84 deletions
  1. 27 3
      lopcodes.h
  2. 63 51
      lua.stx
  3. 55 30
      lvm.c

+ 27 - 3
lopcodes.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lopcodes.h,v 1.3 1997/09/19 21:17:52 roberto Exp roberto $
+** $Id: lopcodes.h,v 1.4 1997/09/22 20:53:20 roberto Exp roberto $
 ** Opcodes for Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -29,10 +29,21 @@ PUSH2,/*		-		2.0  */
 PUSHBYTE,/*	b	-		(float)b  */
 PUSHWORD,/*	w	-		(float)w  */
 
+PUSHCONSTANT0,/*	-		CNST[0] */
+PUSHCONSTANT1,/*	-		CNST[1] */
+PUSHCONSTANT2,/*	-		CNST[2] */
+PUSHCONSTANT3,/*	-		CNST[3] */
+PUSHCONSTANT4,/*	-		CNST[4] */
+PUSHCONSTANT5,/*	-		CNST[5] */
+PUSHCONSTANT6,/*	-		CNST[6] */
+PUSHCONSTANT7,/*	-		CNST[7] */
+PUSHCONSTANT8,/*	-		CNST[8] */
+PUSHCONSTANT9,/*	-		CNST[9] */
 PUSHCONSTANTB,/*b	-		CNST[b] */
 PUSHCONSTANT,/* w	-		CNST[w] */
 
 PUSHUPVALUE0,
+PUSHUPVALUE1,
 PUSHUPVALUE,/*	b	-		Closure[b] */
 
 PUSHLOCAL0,/*		-		LOC[0]  */
@@ -47,6 +58,16 @@ PUSHLOCAL8,/*		-		LOC[8]  */
 PUSHLOCAL9,/*		-		LOC[9]  */
 PUSHLOCAL,/*	b	-		LOC[b]  */
 
+GETGLOBAL0,/*		-		VAR[CNST[0]]  */
+GETGLOBAL1,/*		-		VAR[CNST[1]]  */
+GETGLOBAL2,/*		-		VAR[CNST[2]]  */
+GETGLOBAL3,/*		-		VAR[CNST[3]]  */
+GETGLOBAL4,/*		-		VAR[CNST[4]]  */
+GETGLOBAL5,/*		-		VAR[CNST[5]]  */
+GETGLOBAL6,/*		-		VAR[CNST[6]]  */
+GETGLOBAL7,/*		-		VAR[CNST[7]]  */
+GETGLOBAL8,/*		-		VAR[CNST[8]]  */
+GETGLOBAL9,/*		-		VAR[CNST[9]]  */
 GETGLOBALB,/*	b 	-		VAR[CNST[b]]  */
 GETGLOBAL,/*	w	-		VAR[CNST[w]]  */
 
@@ -94,11 +115,14 @@ CONCOP,/*		y x		x..y  */
 MINUSOP,/*		x		-x  */
 NOTOP,/*		x		(x==nil)? 1 : nil  */
 
-ONTJMP,/*	w	x		(x!=nil)? x : -	(x!=nil)? PC+=w  */
-ONFJMP,/*	w	x		(x==nil)? x : -	(x==nil)? PC+=w  */
+/* NOTICE: all jumps are relative to the position following the opcode */
+ONTJMP,/*	b	x		(x!=nil)? x : -	(x!=nil)? PC+=b  */
+ONFJMP,/*	b	x		(x==nil)? x : -	(x==nil)? PC+=b  */
 JMP,/*		w	-		-		PC+=w  */
+UPJMPB,/*	b	-		-		PC-=b  */
 UPJMP,/*	w	-		-		PC-=w  */
 IFFJMP,/*	w	x		-		(x==nil)? PC+=w  */
+IFFUPJMPB,/*	b	x		-		(x==nil)? PC-=b  */
 IFFUPJMP,/*	w	x		-		(x==nil)? PC-=w  */
 
 CLOSUREB,/*	b	v_1...v_n	c(CNST[b]) */

+ 63 - 51
lua.stx

@@ -1,6 +1,6 @@
 %{
 /*
-** $Id: lua.stx,v 1.3 1997/09/19 21:17:52 roberto Exp roberto $
+** $Id: lua.stx,v 1.4 1997/09/22 20:53:20 roberto Exp roberto $
 ** Syntax analizer and code generator
 ** See Copyright Notice in lua.h
 */
@@ -96,15 +96,24 @@ static void code_byte (Byte c)
 
 static void code_word_at (int pc, int n)
 {
-  Word w = n;
-  if (w != n)
-    luaY_error("block too big");
+  if (n > MAX_WORD)
+    luaY_error("construction too big; unable to compile");
   currState->f->code[pc] = n&0xFF;
   currState->f->code[pc+1] = n>>8;
 }
 
+
+static void fix_jump (int pc, OpCode op, int n)
+{
+  currState->f->code[pc] = op;
+  code_word_at(pc+1, n);
+}
+
+
 static void code_word (int n)
 {
+  if (n > MAX_WORD)
+    luaY_error("construction too big; unable to compile");
   code_byte(n&0xFF);
   code_byte(n>>8);
 }
@@ -128,16 +137,25 @@ static void code_opcode (OpCode op, int delta)
 }
 
 
-static void code_opborw(OpCode opbyte, int arg, int delta)
+static void code_opb (OpCode opbyte, int arg, int delta)
 {
-  if (arg <= 255) {
-    code_opcode(opbyte, delta);
-    code_byte(arg);
-  }
-  else {
-    code_opcode(opbyte+1, delta);
-    code_word(arg);
-  }
+  code_opcode(opbyte, delta);
+  code_byte(arg);
+}
+
+static void code_opw (OpCode opbyte, int arg, int delta)
+{
+  code_opcode(opbyte, delta);
+  code_word(arg);
+}
+
+
+static void code_opborw (OpCode opbyte, int arg, int delta)
+{
+  if (arg <= 255)
+    code_opb(opbyte, arg, delta);
+  else
+    code_opw(opbyte+1, arg, delta);
 }
 
 
@@ -167,7 +185,7 @@ static void code_pop (OpCode op)
 
 static void code_constant (int c)
 {
-  code_opborw(PUSHCONSTANTB, c, 1);
+  code_oparg(PUSHCONSTANT0, PUSHCONSTANTB, c, 1);
 }
 
 
@@ -235,9 +253,8 @@ static void code_number (real f)
 
 static void flush_record (int n)
 {
-  if (n == 0) return;
-  code_opcode(SETMAP, -2*n);
-  code_byte(n);
+  if (n > 0)
+    code_opb(SETMAP, n, -2*n);
 }
 
 static void flush_list (int m, int n)
@@ -245,10 +262,8 @@ static void flush_list (int m, int n)
   if (n == 0) return;
   if (m == 0)
     code_opcode(SETLIST0, -n);
-  else if (m < 255) {
-    code_opcode(SETLIST, -n);
-    code_byte(m);
-  }
+  else if (m < 255)
+    code_opb(SETLIST, m, -n);
   else
     luaY_error("list constructor too long");
   code_byte(n);
@@ -352,8 +367,7 @@ void luaY_codedebugline (int line)
 {
   static int lastline = 0;
   if (lua_debug && line != lastline) {
-    code_neutralop(SETLINE);
-    code_word(line);
+    code_opw(SETLINE, line, 0);
     lastline = line;
   }
 }
@@ -399,13 +413,10 @@ static void adjust_mult_assign (int vars, long exps)
 
 static void code_args (int dots)
 {
-  if (!dots) {
-    code_opcode(ARGS, currState->nlocalvar);
-    code_byte(currState->nlocalvar);
-  }
+  if (!dots)
+    code_opb(ARGS, currState->nlocalvar, currState->nlocalvar);
   else {
-    code_opcode(VARARGS, currState->nlocalvar+1);
-    code_byte(currState->nlocalvar);
+    code_opb(VARARGS, currState->nlocalvar, currState->nlocalvar+1);
     add_localvar(luaS_new("arg"));
   }
 }
@@ -414,7 +425,7 @@ static void code_args (int dots)
 static void lua_pushvar (vardesc number)
 {
   if (number > 0)  /* global var */
-    code_opborw(GETGLOBALB, number-1, 1);
+    code_oparg(GETGLOBAL0, GETGLOBALB, number-1, 1);
   else if (number < 0)  /* local var */
     code_oparg(PUSHLOCAL0, PUSHLOCAL, (-number)-1, 1);
   else
@@ -456,19 +467,19 @@ static void codeIf (int thenAdd, int elseAdd)
     currState->pc -= sizeof(Word)+1;
     elseinit = currState->pc;
   }
-  else {
-    currState->f->code[elseAdd] = JMP;
-    code_word_at(elseAdd+1, currState->pc-elseinit);
-  }
-  currState->f->code[thenAdd] = IFFJMP;
-  code_word_at(thenAdd+1, elseinit-(thenAdd+sizeof(Word)+1));
+  else
+    fix_jump(elseAdd, JMP, currState->pc-(elseAdd+1));
+  fix_jump(thenAdd, IFFJMP, elseinit-(thenAdd+1));
 }
 
 
-static void code_shortcircuit (int pc, Byte jmp)
+static void code_shortcircuit (OpCode op, int pos)
 {
-  currState->f->code[pc] = jmp;
-  code_word_at(pc+1, currState->pc - (pc + sizeof(Word)+1));
+  int dist = currState->pc - (pos+1);
+  if (dist > 255)
+    luaY_error("and/or expression too long");
+  currState->f->code[pos] = op;
+  currState->f->code[pos+1] = dist;
 }
 
 
@@ -582,7 +593,7 @@ TProtoFunc *luaY_parser (ZIO *z, char *chunkname)
 %token <vReal> NUMBER
 %token <pTStr>  NAME STRING
 
-%type <vInt> PrepJump, PrepJumpPop
+%type <vInt> PrepJump, PrepJumpPop, PrepJumpSC
 %type <vLong> exprlist, exprlist1  /* if > 0, points to function return
 	counter (which has list length); if <= 0, -list lenght */
 %type <vLong> functioncall, expr  /* if != 0, points to function return
@@ -620,18 +631,15 @@ sc	 : /* empty */ | ';' ;
 stat   : IF expr1 THEN PrepJumpPop block PrepJump elsepart END
 	{ codeIf($4, $6); }
 
-       | WHILE {$<vInt>$=currState->pc;} expr1 DO PrepJumpPop block PrepJump END
+       | WHILE {$<vInt>$=currState->pc;} expr1 DO PrepJumpPop block END
        {
-         currState->f->code[$5] = IFFJMP;
-	 code_word_at($5+1, currState->pc - ($5+sizeof(Word)+1));
-         currState->f->code[$7] = UPJMP;
-	 code_word_at($7+1, currState->pc - ($<vInt>2));
+	 code_opborw(UPJMPB, currState->pc+1 - ($<vInt>2), 0);
+         fix_jump($5, IFFJMP, currState->pc - ($5+1));
        }
 
-       | REPEAT {$<vInt>$=currState->pc;} block UNTIL expr1 PrepJumpPop
+       | REPEAT {$<vInt>$=currState->pc;} block UNTIL expr1
        {
-         currState->f->code[$6] = IFFUPJMP;
-	 code_word_at($6+1, currState->pc - ($<vInt>2));
+         code_opborw(IFFUPJMPB, currState->pc+1 - ($<vInt>2), -1);
        }
 
        | varlist1 '=' exprlist1
@@ -699,6 +707,10 @@ PrepJump : /* empty */
          }
 	 ;
 
+PrepJumpSC : /* empty */
+	{ $$ = currState->pc; code_opcode(0, -1); code_byte(0); }
+	;
+
 PrepJumpPop : PrepJump	{ $$ = $1; deltastack(-1);  /* pop condition */ }
 	 ;
 
@@ -726,13 +738,13 @@ expr :  '(' expr ')'     { $$ = $2; }
      |  STRING           { code_string($1); $$ = 0; }
      |	NIL		 {code_opcode(PUSHNIL, 1); $$ = 0; }
      |  functioncall     { $$ = $1; }
-     |	expr1 AND PrepJumpPop expr1 { code_shortcircuit($3, ONFJMP); $$ = 0; }
-     |	expr1 OR PrepJumpPop expr1  { code_shortcircuit($3, ONTJMP); $$ = 0; }
      | FUNCTION { init_func(); } body { func_onstack($3); $$ = 0; }
+     |	expr1 AND PrepJumpSC expr1 { code_shortcircuit(ONFJMP, $3); $$ = 0; }
+     |	expr1 OR PrepJumpSC expr1 { code_shortcircuit(ONTJMP, $3); $$ = 0; }
      ;
 
 table :
-     { code_opcode(CREATEARRAY, 1); $<vInt>$ = currState->pc; code_word(0); }
+     { $<vInt>$ = currState->pc+1; code_opw(CREATEARRAY, 0, 1); }
        '{' fieldlist '}'
      { code_word_at($<vInt>1, $3); }
          ;

+ 55 - 30
lvm.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lvm.c,v 1.3 1997/09/19 21:17:52 roberto Exp roberto $
+** $Id: lvm.c,v 1.4 1997/09/22 20:53:20 roberto Exp roberto $
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -22,9 +22,9 @@
 #include "lvm.h"
 
 
-#define get_prevword(pc)  (*(pc-2)+(*(pc-1)<<8))
-#define get_word(pc)  (pc+=2, get_prevword(pc))
-#define skip_word(pc) {pc+=2;}
+#define skip_word(pc)	(pc+=2)
+#define get_word(pc)	(*(pc)+(*((pc)+1)<<8))
+#define next_word(pc)   (pc+=2, get_word(pc-2))
 
 
 /* Extra stack to run a function: LUA_T_LINE(1), TM calls(2), ... */
@@ -300,7 +300,7 @@ StkId luaV_execute (Closure *cl, StkId base)
         aux = *pc++; goto pushnumber;
 
       case PUSHWORD:
-        aux = get_word(pc); goto pushnumber;
+        aux = next_word(pc); goto pushnumber;
 
       case PUSH0: case PUSH1: case PUSH2:
         aux -= PUSH0;
@@ -323,10 +323,16 @@ StkId luaV_execute (Closure *cl, StkId base)
         break;
 
       case GETGLOBAL:
-        aux = get_word(pc); goto getglobal;
+        aux = next_word(pc); goto getglobal;
 
       case GETGLOBALB:
-        aux = *pc++;
+        aux = *pc++; goto getglobal;
+
+      case GETGLOBAL0: case GETGLOBAL1: case GETGLOBAL2:
+      case GETGLOBAL3: case GETGLOBAL4: case GETGLOBAL5:
+      case GETGLOBAL6: case GETGLOBAL7: case GETGLOBAL8:
+      case GETGLOBAL9:
+        aux -= GETGLOBAL0;
       getglobal:
         luaV_getglobal(luaG_findsymbol(tsvalue(&consts[aux])));
         break;
@@ -336,7 +342,7 @@ StkId luaV_execute (Closure *cl, StkId base)
        break;
 
       case PUSHSELF:
-        aux = get_word(pc); goto pushself;
+        aux = next_word(pc); goto pushself;
 
       case PUSHSELFB:
         aux = *pc++;
@@ -349,10 +355,16 @@ StkId luaV_execute (Closure *cl, StkId base)
       }
 
       case PUSHCONSTANT:
-        aux = get_word(pc); goto pushconstant;
+        aux = next_word(pc); goto pushconstant;
 
       case PUSHCONSTANTB:
-        aux = *pc++;
+        aux = *pc++; goto pushconstant;
+
+      case PUSHCONSTANT0: case PUSHCONSTANT1: case PUSHCONSTANT2:
+      case PUSHCONSTANT3: case PUSHCONSTANT4: case PUSHCONSTANT5:
+      case PUSHCONSTANT6: case PUSHCONSTANT7: case PUSHCONSTANT8:
+      case PUSHCONSTANT9:
+        aux -= PUSHCONSTANT0;
       pushconstant:
         *luaD_stack.top++ = consts[aux];
         break;
@@ -360,8 +372,8 @@ StkId luaV_execute (Closure *cl, StkId base)
       case PUSHUPVALUE:
         aux = *pc++; goto pushupvalue;
 
-      case PUSHUPVALUE0:
-        aux = 0;
+      case PUSHUPVALUE0: case PUSHUPVALUE1:
+        aux -= PUSHUPVALUE0;
       pushupvalue:
         *luaD_stack.top++ = cl->consts[aux+1];
         break;
@@ -379,7 +391,7 @@ StkId luaV_execute (Closure *cl, StkId base)
         break;
 
       case SETGLOBAL:
-        aux = get_word(pc); goto setglobal;
+        aux = next_word(pc); goto setglobal;
 
       case SETGLOBALB:
         aux = *pc++;
@@ -442,7 +454,7 @@ StkId luaV_execute (Closure *cl, StkId base)
 
       case CREATEARRAY:
         luaC_checkGC();
-        avalue(luaD_stack.top) = luaH_new(get_word(pc));
+        avalue(luaD_stack.top) = luaH_new(next_word(pc));
         ttype(luaD_stack.top) = LUA_T_ARRAY;
         luaD_stack.top++;
         break;
@@ -554,45 +566,58 @@ StkId luaV_execute (Closure *cl, StkId base)
         break;
 
       case ONTJMP:
-        skip_word(pc);
         if (ttype(luaD_stack.top-1) != LUA_T_NIL)
-          pc += get_prevword(pc);
-        else
+          pc += *pc;
+        else {
+          pc++;
           luaD_stack.top--;
+        }
         break;
 
       case ONFJMP:
-        skip_word(pc);
         if (ttype(luaD_stack.top-1) == LUA_T_NIL)
-          pc += get_prevword(pc);
-        else
+          pc += *pc;
+        else {
+          pc++;
           luaD_stack.top--;
+        }
         break;
 
       case JMP:
-        skip_word(pc);
-        pc += get_prevword(pc);
+        pc += get_word(pc);
+        break;
+
+      case UPJMPB:
+        pc -= *pc;
         break;
 
       case UPJMP:
-        skip_word(pc);
-        pc -= get_prevword(pc);
+        pc -= get_word(pc);
         break;
 
       case IFFJMP:
-        skip_word(pc);
         if (ttype(--luaD_stack.top) == LUA_T_NIL)
-          pc += get_prevword(pc);
+          pc += get_word(pc);
+        else
+          skip_word(pc);
+        break;
+
+      case IFFUPJMPB:
+        if (ttype(--luaD_stack.top) == LUA_T_NIL)
+          pc -= *pc;
+        else
+          pc++;
         break;
 
       case IFFUPJMP:
-        skip_word(pc);
         if (ttype(--luaD_stack.top) == LUA_T_NIL)
-          pc -= get_prevword(pc);
+          pc -= get_word(pc);
+        else
+          skip_word(pc);
         break;
 
       case CLOSURE:
-        aux = get_word(pc); goto closure;
+        aux = next_word(pc); goto closure;
 
       case CLOSUREB:
         aux = *pc++;
@@ -617,7 +642,7 @@ StkId luaV_execute (Closure *cl, StkId base)
         return (base + ((aux==RETCODE) ? *pc : 0));
 
       case SETLINE: {
-        int line = get_word(pc);
+        int line = next_word(pc);
         if ((luaD_stack.stack+base-1)->ttype != LUA_T_LINE) {
           /* open space for LINE value */
           luaD_openstack((luaD_stack.top-luaD_stack.stack)-base);