浏览代码

change of code generation design (independent functions for each opcode)

Roberto Ierusalimschy 25 年之前
父节点
当前提交
d1ea38580a
共有 5 个文件被更改,包括 180 次插入188 次删除
  1. 100 123
      lcode.c
  2. 14 11
      lcode.h
  3. 6 1
      lopcodes.h
  4. 43 42
      lparser.c
  5. 17 11
      lparser.h

+ 100 - 123
lcode.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lcode.c,v 1.2 2000/03/03 12:33:59 roberto Exp roberto $
+** $Id: lcode.c,v 1.3 2000/03/03 14:58:26 roberto Exp roberto $
 ** Code generator for Lua
 ** See Copyright Notice in lua.h
 */
@@ -20,12 +20,10 @@ void luaK_error (LexState *ls, const char *msg) {
 }
 
 
-static Instruction *last_i (FuncState *fs) {
-  static Instruction dummy = SET_OPCODE(0, ENDCODE);
-  if (fs->last_pc < 0)
-    return &dummy;
-  else
-    return &fs->f->code[fs->last_pc];
+static Instruction *last_i (LexState *ls, expdesc *v) {
+  FuncState *fs = ls->fs;
+  int last_pc = (v->info != NOJUMPS) ? v->info : fs->pc-1;
+  return &fs->f->code[last_pc];
 }
 
 
@@ -37,58 +35,64 @@ int luaK_primitivecode (LexState *ls, Instruction i) {
 }
 
 
+static void luaK_minus (LexState *ls, expdesc *v) {
+  Instruction *last = last_i(ls, v);
+  switch(GET_OPCODE(*last)) {
+    case PUSHINT: *last = SETARG_S(*last, -GETARG_S(*last)); return;
+    case PUSHNUM: *last = SET_OPCODE(*last, PUSHNEGNUM); return;
+    case PUSHNEGNUM: *last = SET_OPCODE(*last, PUSHNUM); return;
+    default: luaK_primitivecode(ls, CREATE_0(MINUSOP));
+  }
+}
 
-int luaK_code (LexState *ls, Instruction i) {
-  FuncState *fs = ls->fs;
-  Instruction *last = last_i(fs);
-  switch (GET_OPCODE(i)) {
-
-    case MINUSOP:
-      switch(GET_OPCODE(*last)) {
-        case PUSHINT: *last = SETARG_S(*last, -GETARG_S(*last)); break;
-        case PUSHNUM: *last = SET_OPCODE(*last, PUSHNEGNUM); break;
-        case PUSHNEGNUM: *last = SET_OPCODE(*last, PUSHNUM); break;
-        default: fs->last_pc = luaK_primitivecode(ls, i);
-      }
-      break;
 
-    case GETTABLE:
-      switch(GET_OPCODE(*last)) {
-        case PUSHSTRING: *last = SET_OPCODE(*last, GETDOTTED); break;
-        default: fs->last_pc = luaK_primitivecode(ls, i);
-      }
-      break;
+static void luaK_gettable (LexState *ls, expdesc *v) {
+  Instruction *last = last_i(ls, v);
+  luaK_deltastack(ls, -1);
+  switch(GET_OPCODE(*last)) {
+    case PUSHSTRING: *last = SET_OPCODE(*last, GETDOTTED); break;
+    default: luaK_primitivecode(ls, CREATE_0(GETTABLE));
+  }
+}
 
-    case RETCODE:
-      switch(GET_OPCODE(*last)) {
-        case CALL:
-          *last = SET_OPCODE(*last, TAILCALL);
-          *last = SETARG_B(*last, GETARG_U(i));
-          break;
-        default: fs->last_pc = luaK_primitivecode(ls, i);
-      }
-      break;
 
-    case ADDOP:
-      switch(GET_OPCODE(*last)) {
-        case PUSHINT: *last = SET_OPCODE(*last, ADDI); break;
-        default: fs->last_pc = luaK_primitivecode(ls, i);
-      }
-      break;
+static void luaK_add (LexState *ls, expdesc *v) {
+  Instruction *last = last_i(ls, v);
+  luaK_deltastack(ls, -1);
+  switch(GET_OPCODE(*last)) {
+    case PUSHINT: *last = SET_OPCODE(*last, ADDI); break;
+    default: luaK_primitivecode(ls, CREATE_0(ADDOP));
+  }
+}
+
 
-    case SUBOP:
-      switch(GET_OPCODE(*last)) {
-        case PUSHINT:
-          *last = SET_OPCODE(*last, ADDI);
-          *last = SETARG_S(*last, -GETARG_S(*last));
-          break;
-        default: fs->last_pc = luaK_primitivecode(ls, i);
-      }
+static void luaK_sub (LexState *ls, expdesc *v) {
+  Instruction *last = last_i(ls, v);
+  luaK_deltastack(ls, -1);
+  switch(GET_OPCODE(*last)) {
+    case PUSHINT:
+      *last = SET_OPCODE(*last, ADDI);
+      *last = SETARG_S(*last, -GETARG_S(*last));
       break;
+    default: luaK_primitivecode(ls, CREATE_0(SUBOP));
+  }
+}
 
-    default: fs->last_pc = luaK_primitivecode(ls, i);
+
+void luaK_retcode (LexState *ls, int nlocals, listdesc *e) {
+  if (e->n > 0 && luaK_iscall(ls, e->info)) {
+    Instruction *last = &ls->fs->f->code[ls->fs->pc-1];
+    *last = SET_OPCODE(*last, TAILCALL);
+    *last = SETARG_B(*last, nlocals);
   }
-  return fs->last_pc;
+  else
+    luaK_U(ls, RETCODE, nlocals, 0);
+}
+
+
+int luaK_code (LexState *ls, Instruction i, int delta) {
+  luaK_deltastack(ls, delta);
+  return luaK_primitivecode(ls, i);
 }
 
 
@@ -97,7 +101,6 @@ void luaK_fixjump (LexState *ls, int pc, int dest) {
   Instruction *jmp = &fs->f->code[pc];
   /* jump is relative to position following jump instruction */
   *jmp = SETARG_S(*jmp, dest-(pc+1));
-  fs->last_pc = pc;
 }
 
 
@@ -112,38 +115,8 @@ void luaK_deltastack (LexState *ls, int delta) {
 }
 
 
-static int aux_code (LexState *ls, OpCode op, Instruction i, int delta) {
-  luaK_deltastack(ls, delta);
-  return luaK_code(ls, SET_OPCODE(i, op));
-}
-
-
-int luaK_0 (LexState *ls, OpCode op, int delta) {
-  return aux_code(ls, op, 0, delta);
-}
-
-
-int luaK_U (LexState *ls, OpCode op, int u, int delta) {
-  Instruction i = SETARG_U(0, u);
-  return aux_code(ls, op, i, delta);
-}
-
-
-int luaK_S (LexState *ls, OpCode op, int s, int delta) {
-  Instruction i = SETARG_S(0, s);
-  return aux_code(ls, op, i, delta);
-}
-
-
-int luaK_AB (LexState *ls, OpCode op, int a, int b, int delta) {
-  Instruction i = SETARG_A(0, a);
-  i = SETARG_B(i, b);
-  return aux_code(ls, op, i, delta);
-}
-
-
-int luaK_kstr (LexState *ls, int c) {
-  return luaK_U(ls, PUSHSTRING, c, 1);
+void luaK_kstr (LexState *ls, int c) {
+  luaK_U(ls, PUSHSTRING, c, 1);
 }
 
 
@@ -166,37 +139,40 @@ static int real_constant (LexState *ls, real r) {
 }
 
 
-int luaK_number (LexState *ls, real f) {
+void luaK_number (LexState *ls, real f) {
   if (f <= (real)MAXARG_S && (int)f == f)
-    return luaK_S(ls, PUSHINT, (int)f, 1);  /* f has a short integer value */
+    luaK_S(ls, PUSHINT, (int)f, 1);  /* f has a short integer value */
   else
-    return luaK_U(ls, PUSHNUM, real_constant(ls, f), 1);
+    luaK_U(ls, PUSHNUM, real_constant(ls, f), 1);
 }
 
 
-int luaK_adjuststack (LexState *ls, int n) {
+void luaK_adjuststack (LexState *ls, int n) {
   if (n > 0)
-    return luaK_U(ls, POP, n, -n);
+    luaK_U(ls, POP, n, -n);
   else if (n < 0)
-    return luaK_U(ls, PUSHNIL, (-n)-1, -n);
-  else return 0;
+    luaK_U(ls, PUSHNIL, (-n)-1, -n);
 }
 
 
-int luaK_iscall (LexState *ls, int pc) {
-  return (GET_OPCODE(ls->fs->f->code[pc]) == CALL);
+int luaK_iscall (LexState *ls, int hasjumps) {
+  if (hasjumps) return 0;   /* a call cannot have internal jumps */
+  else  /* check whether last instruction is a function call */
+    return (GET_OPCODE(ls->fs->f->code[ls->fs->pc-1]) == CALL);
 }
 
 
-void luaK_setcallreturns (LexState *ls, int pc, int nresults) {
-  if (luaK_iscall(ls, pc)) {  /* expression is a function call? */
-    Instruction *i = &ls->fs->f->code[pc];
-    int old_nresults = GETARG_B(*i);
-    if (old_nresults != MULT_RET)
-      luaK_deltastack(ls, -old_nresults);  /* pop old nresults */
-    *i = SETARG_B(*i, nresults);  /* set nresults */
-    if (nresults != MULT_RET)
-      luaK_deltastack(ls, nresults);  /* push results */
+void luaK_setcallreturns (LexState *ls, int hasjumps, int nresults) {
+  if (!hasjumps) {  /* if `hasjumps' cannot be a function call */
+    Instruction *i = &ls->fs->f->code[ls->fs->pc-1];
+    if (GET_OPCODE(*i) == CALL) {  /* expression is a function call? */
+      int old_nresults = GETARG_B(*i);
+      if (old_nresults != MULT_RET)
+        luaK_deltastack(ls, -old_nresults);  /* pop old nresults */
+      *i = SETARG_B(*i, nresults);  /* set nresults */
+      if (nresults != MULT_RET)
+        luaK_deltastack(ls, nresults);  /* push results */
+    }
   }
 }
 
@@ -209,20 +185,21 @@ static void assertglobal (LexState *ls, int index) {
 void luaK_2stack (LexState *ls, expdesc *var) {
   switch (var->k) {
     case VLOCAL:
-      var->info = luaK_U(ls, PUSHLOCAL, var->info, 1);
+      luaK_U(ls, PUSHLOCAL, var->info, 1);
       break;
     case VGLOBAL:
+      luaK_U(ls, GETGLOBAL, var->info, 1);
       assertglobal(ls, var->info);  /* make sure that there is a global */
-      var->info = luaK_U(ls, GETGLOBAL, var->info, 1);
       break;
     case VINDEXED:
-      var->info = luaK_0(ls, GETTABLE, -1);
+      luaK_gettable(ls, var);
       break;
     case VEXP:
       luaK_setcallreturns(ls, var->info, 1);  /* call must return 1 value */
-      break;
+      return;  /* does not change var->info */
   }
   var->k = VEXP;
+  var->info = NOJUMPS;
 }
 
 
@@ -246,10 +223,9 @@ void luaK_storevar (LexState *ls, const expdesc *var) {
 
 void luaK_prefix (LexState *ls, int op, expdesc *v) {
   luaK_2stack(ls, v);
-  if (op == '-')
-    v->info = luaK_0(ls, MINUSOP, 0);
-  else
-    v->info = luaK_0(ls, NOTOP, 0);
+  if (op == '-') luaK_minus(ls, v);
+  else luaK_0(ls, NOTOP, 0);
+  v->info = NOJUMPS;
 }
 
 
@@ -267,19 +243,20 @@ void luaK_posfix (LexState *ls, int op, expdesc *v1, expdesc *v2) {
   switch (op) {
     case AND:  case OR:
       luaK_fixjump(ls, v1->info, ls->fs->pc);
-      break;
-    case '+': v1->info = luaK_0(ls, ADDOP, -1); break;
-    case '-': v1->info = luaK_0(ls, SUBOP, -1); break;
-    case '*': v1->info = luaK_0(ls, MULTOP, -1); break;
-    case '/': v1->info = luaK_0(ls, DIVOP, -1); break;
-    case '^': v1->info = luaK_0(ls, POWOP, -1); break;
-    case CONC: v1->info = luaK_0(ls, CONCOP, -1); break;
-    case EQ: v1->info = luaK_0(ls, EQOP, -1); break;
-    case NE: v1->info = luaK_0(ls, NEQOP, -1); break;
-    case '>': v1->info = luaK_0(ls, GTOP, -1); break;
-    case '<': v1->info = luaK_0(ls, LTOP, -1); break;
-    case GE: v1->info = luaK_0(ls, GEOP, -1); break;
-    case LE: v1->info = luaK_0(ls, LEOP, -1); break;
+      return;  /* keep v1->info != NOJUMPS */
+    case '+': luaK_add(ls, v2); break;
+    case '-': luaK_sub(ls, v2); break;
+    case '*': luaK_0(ls, MULTOP, -1); break;
+    case '/': luaK_0(ls, DIVOP, -1); break;
+    case '^': luaK_0(ls, POWOP, -1); break;
+    case CONC: luaK_0(ls, CONCOP, -1); break;
+    case EQ: luaK_0(ls, EQOP, -1); break;
+    case NE: luaK_0(ls, NEQOP, -1); break;
+    case '>': luaK_0(ls, GTOP, -1); break;
+    case '<': luaK_0(ls, LTOP, -1); break;
+    case GE: luaK_0(ls, GEOP, -1); break;
+    case LE: luaK_0(ls, LEOP, -1); break;
   }
+  v1->info = NOJUMPS;
 }
 

+ 14 - 11
lcode.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lcode.h,v 1.1 2000/02/22 13:31:19 roberto Exp roberto $
+** $Id: lcode.h,v 1.2 2000/03/03 12:33:59 roberto Exp roberto $
 ** Code generator for Lua
 ** See Copyright Notice in lua.h
 */
@@ -13,20 +13,23 @@
 #include "lparser.h"
 
 
+#define luaK_0(ls,o,d)		luaK_code(ls, CREATE_0(o), d)
+#define luaK_U(ls,o,u,d)	luaK_code(ls, CREATE_U(o,u), d)
+#define luaK_S(ls,o,s,d)	luaK_code(ls, CREATE_S(o,s), d)
+#define luaK_AB(ls,o,a,b,d)	luaK_code(ls, CREATE_AB(o,a,b), d)
+
+
 void luaK_error (LexState *ls, const char *msg);
 int luaK_primitivecode (LexState *ls, Instruction i);
-int luaK_code (LexState *ls, Instruction i);
+int luaK_code (LexState *ls, Instruction i, int delta);
+void luaK_retcode (LexState *ls, int nlocals, listdesc *e);
 void luaK_fixjump (LexState *ls, int pc, int dest);
 void luaK_deltastack (LexState *ls, int delta);
-int luaK_0 (LexState *ls, OpCode op, int delta);
-int luaK_U (LexState *ls, OpCode op, int u, int delta);
-int luaK_S (LexState *ls, OpCode op, int s, int delta);
-int luaK_AB (LexState *ls, OpCode op, int a, int b, int delta);
-int luaK_kstr (LexState *ls, int c);
-int luaK_number (LexState *ls, real f);
-int luaK_adjuststack (LexState *ls, int n);
-int luaK_iscall (LexState *ls, int pc);
-void luaK_setcallreturns (LexState *ls, int pc, int nresults);
+void luaK_kstr (LexState *ls, int c);
+void luaK_number (LexState *ls, real f);
+void luaK_adjuststack (LexState *ls, int n);
+int luaK_iscall (LexState *ls, int hasjumps);
+void luaK_setcallreturns (LexState *ls, int hasjumps, int nresults);
 void luaK_2stack (LexState *ls, expdesc *var);
 void luaK_storevar (LexState *ls, const expdesc *var);
 void luaK_prefix (LexState *ls, int op, expdesc *v);

+ 6 - 1
lopcodes.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lopcodes.h,v 1.42 2000/03/02 12:32:53 roberto Exp roberto $
+** $Id: lopcodes.h,v 1.43 2000/03/03 14:58:26 roberto Exp roberto $
 ** Opcodes for Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -47,6 +47,11 @@
 #define SETARG_A(i,a)	(((i)&0x0000FFFFu) | ((Instruction)(a)<<16))
 #define SETARG_B(i,b)	(((i)&0xFFFF00FFu) | ((Instruction)(b)<<8))
 
+#define CREATE_0(o)	 ((Instruction)(o))
+#define CREATE_U(o,u)	 ((Instruction)(o) | (Instruction)(u)<<8)
+#define CREATE_S(o,s)	 ((Instruction)(o) | ((Instruction)(s)+EXCESS_S)<<8)
+#define CREATE_AB(o,a,b) ((Instruction)(o) | ((Instruction)(a)<<16) \
+                                           |  ((Instruction)(b)<<8))
 
 
 /*

+ 43 - 42
lparser.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lparser.c,v 1.61 2000/03/03 12:33:59 roberto Exp roberto $
+** $Id: lparser.c,v 1.62 2000/03/03 14:58:26 roberto Exp roberto $
 ** LL(1) Parser and code generator for Lua
 ** See Copyright Notice in lua.h
 */
@@ -23,15 +23,13 @@
 
 
 /*
-** Expression List descriptor:
-** tells number of expressions in the list,
-** and, if last expression is open (a function call),
-** where is the call pc index.
+** check whether arbitrary limits fit in respective opcode types
 */
-typedef struct listdesc {
-  int n;
-  int pc;  /* 0 if last expression is closed */
-} listdesc;
+#if MAXLOCALS>MAXARG_U || MAXUPVALUES>MAXARG_B || MAXVARSLH>MAXARG_B || \
+    MAXPARAMS>MAXLOCALS || MAXSTACK>MAXARG_A || LFIELDS_PER_FLUSH>MAXARG_B
+#error invalid limits
+#endif
+
 
 
 /*
@@ -51,11 +49,11 @@ typedef struct constdesc {
 /*
 ** prototypes for recursive non-terminal functions
 */
-static int body (LexState *ls, int needself, int line);
+static void body (LexState *ls, int needself, int line);
 static void chunk (LexState *ls);
-static int constructor (LexState *ls);
+static void constructor (LexState *ls);
 static void expr (LexState *ls, expdesc *v);
-static void exp1 (LexState *ls);
+static int exp1 (LexState *ls);
 
 
 static void next (LexState *ls) {
@@ -145,8 +143,8 @@ static int string_constant (LexState *ls, FuncState *fs, TaggedString *s) {
 }
 
 
-static int code_string (LexState *ls, TaggedString *s) {
-  return luaK_kstr(ls, string_constant(ls, ls->fs, s));
+static void code_string (LexState *ls, TaggedString *s) {
+  luaK_kstr(ls, string_constant(ls, ls->fs, s));
 }
 
 
@@ -249,18 +247,18 @@ static int indexupvalue (LexState *ls, TaggedString *n) {
 }
 
 
-static int pushupvalue (LexState *ls, TaggedString *n) {
+static void pushupvalue (LexState *ls, TaggedString *n) {
   if (ls->fs->prev == NULL)
     luaX_syntaxerror(ls, "cannot access upvalue in main", n->str);
   if (aux_localname(ls->fs, n) >= 0)
     luaX_syntaxerror(ls, "cannot access an upvalue in current scope", n->str);
-  return luaK_U(ls, PUSHUPVALUE, indexupvalue(ls, n), 1);
+  luaK_U(ls, PUSHUPVALUE, indexupvalue(ls, n), 1);
 }
 
 
 static void adjust_mult_assign (LexState *ls, int nvars, listdesc *d) {
   int diff = d->n - nvars;
-  if (d->n == 0 || !luaK_iscall(ls, d->pc)) {  /* list is empty or closed */
+  if (d->n == 0 || !luaK_iscall(ls, d->info)) {  /* list is empty or closed */
     /* push or pop eventual difference between list lengths */
     luaK_adjuststack(ls, diff);
   }
@@ -268,10 +266,10 @@ static void adjust_mult_assign (LexState *ls, int nvars, listdesc *d) {
     diff--;  /* do not count function call itself */
     if (diff <= 0) {  /* more variables than values? */
       /* function call must provide extra values */
-      luaK_setcallreturns(ls, d->pc, -diff);
+      luaK_setcallreturns(ls, d->info, -diff);
     }
     else {  /* more values than variables */
-      luaK_setcallreturns(ls, d->pc, 0);  /* call should provide no value */
+      luaK_setcallreturns(ls, d->info, 0);  /* call should provide no value */
       luaK_adjuststack(ls, diff);  /* pop eventual extra values */
     }
   }
@@ -308,7 +306,7 @@ static int getvarname (LexState *ls, expdesc *var) {
 }
 
 
-static int func_onstack (LexState *ls, FuncState *func) {
+static void func_onstack (LexState *ls, FuncState *func) {
   TProtoFunc *f = ls->fs->f;
   int i;
   for (i=0; i<func->nupvalues; i++)
@@ -317,7 +315,7 @@ static int func_onstack (LexState *ls, FuncState *func) {
                   constantEM, MAXARG_A);
   f->kproto[f->nkproto++] = func->f;
   luaK_deltastack(ls, 1);  /* CLOSURE puts one extra element before popping */
-  return luaK_AB(ls, CLOSURE, f->nkproto-1, func->nupvalues, -func->nupvalues);
+  luaK_AB(ls, CLOSURE, f->nkproto-1, func->nupvalues, -func->nupvalues);
 }
 
 
@@ -333,7 +331,6 @@ static void init_state (LexState *ls, FuncState *fs, TaggedString *source) {
   fs->f = f;
   f->source = source;
   fs->pc = 0;
-  fs->last_pc = -1;  /* invalid index to signal no last instruction */
   f->code = NULL;
   f->maxstacksize = 0;
   f->numparams = 0;  /* default for main chunk */
@@ -395,7 +392,7 @@ static void explist1 (LexState *ls, listdesc *d) {
   }
   luaK_2stack(ls, &v);
   luaK_setcallreturns(ls, v.info, MULT_RET);  /* default for explists */
-  d->pc = v.info;
+  d->info = v.info;
 }
 
 
@@ -412,7 +409,7 @@ static void explist (LexState *ls, listdesc *d) {
 }
 
 
-static int funcparams (LexState *ls, int slf) {
+static void funcparams (LexState *ls, int slf) {
   FuncState *fs = ls->fs;
   int slevel = fs->stacksize - slf - 1;  /* where is func in the stack */
   switch (ls->token) {
@@ -443,7 +440,7 @@ static int funcparams (LexState *ls, int slf) {
       break;
   }
   fs->stacksize = slevel;  /* call will remove func and params */
-  return luaK_AB(ls, CALL, slevel, 0, 0);
+  luaK_AB(ls, CALL, slevel, 0, 0);
 }
 
 
@@ -455,14 +452,15 @@ static void var_or_func_tail (LexState *ls, expdesc *v) {
         luaK_2stack(ls, v);  /* `v' must be on stack */
         luaK_kstr(ls, checkname(ls));
         v->k = VINDEXED;
+        v->info = NOJUMPS;
         break;
 
       case '[':  /* var_or_func_tail -> '[' exp1 ']' */
         next(ls);
         luaK_2stack(ls, v);  /* `v' must be on stack */
-        exp1(ls);
-        check(ls, ']');
         v->k = VINDEXED;
+        v->info = exp1(ls);
+        check(ls, ']');
         break;
 
       case ':': {  /* var_or_func_tail -> ':' NAME funcparams */
@@ -471,15 +469,17 @@ static void var_or_func_tail (LexState *ls, expdesc *v) {
         name = checkname(ls);
         luaK_2stack(ls, v);  /* `v' must be on stack */
         luaK_U(ls, PUSHSELF, name, 1);
+        funcparams(ls, 1);
         v->k = VEXP;
-        v->info = funcparams(ls, 1);
+        v->info = NOJUMPS;
         break;
       }
 
       case '(': case STRING: case '{':  /* var_or_func_tail -> funcparams */
         luaK_2stack(ls, v);  /* `v' must be on stack */
+        funcparams(ls, 0);
         v->k = VEXP;
-        v->info = funcparams(ls, 0);
+        v->info = NOJUMPS;
         break;
 
       default: return;  /* should be follow... */
@@ -491,8 +491,9 @@ static void var_or_func_tail (LexState *ls, expdesc *v) {
 static void var_or_func (LexState *ls, expdesc *v) {
   /* var_or_func -> ['%'] NAME var_or_func_tail */
   if (optional(ls, '%')) {  /* upvalue? */
+    pushupvalue(ls, str_checkname(ls));
     v->k = VEXP;
-    v->info = pushupvalue(ls, str_checkname(ls));
+    v->info = NOJUMPS;
   }
   else  /* variable name */
     singlevar(ls, str_checkname(ls), v, 0);
@@ -614,7 +615,7 @@ static void constructor_part (LexState *ls, constdesc *cd) {
 }
 
 
-static int constructor (LexState *ls) {
+static void constructor (LexState *ls) {
   /* constructor -> '{' constructor_part [';' constructor_part] '}' */
   int line = ls->linenumber;
   int pc = luaK_U(ls, CREATETABLE, 0, 1);
@@ -634,7 +635,6 @@ static int constructor (LexState *ls) {
   check_match(ls, '}', '{', line);
   /* set initial table size */
   ls->fs->f->code[pc] = SETARG_U(ls->fs->f->code[pc], nelems);
-  return pc;
 }
 
 /* }====================================================================== */
@@ -655,28 +655,27 @@ static void simpleexp (LexState *ls, expdesc *v) {
     case NUMBER: {  /* simpleexp -> NUMBER */
       real r = ls->seminfo.r;
       next(ls);
-      v->info = luaK_number(ls, r);
+      luaK_number(ls, r);
       break;
     }
 
     case STRING:  /* simpleexp -> STRING */
-      /* must use `seminfo' before `next' */
-      v->info = code_string(ls, ls->seminfo.ts);
+      code_string(ls, ls->seminfo.ts);  /* must use `seminfo' before `next' */
       next(ls);
       break;
 
     case NIL:  /* simpleexp -> NIL */
-      v->info = luaK_adjuststack(ls, -1);
+      luaK_adjuststack(ls, -1);
       next(ls);
       break;
 
     case '{':  /* simpleexp -> constructor */
-      v->info = constructor(ls);
+      constructor(ls);
       break;
 
     case FUNCTION:  /* simpleexp -> FUNCTION body */
       next(ls);
-      v->info = body(ls, 0, ls->linenumber);
+      body(ls, 0, ls->linenumber);
       break;
 
     case '(':  /* simpleexp -> '(' expr ')' */
@@ -694,13 +693,15 @@ static void simpleexp (LexState *ls, expdesc *v) {
       return;
   }
   v->k = VEXP;
+  v->info = NOJUMPS;
 }
 
 
-static void exp1 (LexState *ls) {
+static int exp1 (LexState *ls) {
   expdesc v;
   expr(ls, &v);
   luaK_2stack(ls, &v);
+  return v.info;
 }
 
 
@@ -1052,7 +1053,7 @@ static void parlist (LexState *ls) {
 }
 
 
-static int body (LexState *ls, int needself, int line) {
+static void body (LexState *ls, int needself, int line) {
   /* body ->  '(' parlist ')' chunk END */
   FuncState new_fs;
   init_state(ls, &new_fs, ls->fs->f->source);
@@ -1065,7 +1066,7 @@ static int body (LexState *ls, int needself, int line) {
   chunk(ls);
   check_match(ls, END, FUNCTION, line);
   close_func(ls);
-  return func_onstack(ls, &new_fs);
+  func_onstack(ls, &new_fs);
 }
 
 
@@ -1076,7 +1077,7 @@ static void ret (LexState *ls) {
     check_debugline(ls);
     next(ls);
     explist(ls, &e); 
-    luaK_U(ls, RETCODE, ls->fs->nlocalvar, 0);
+    luaK_retcode(ls, ls->fs->nlocalvar, &e);
     ls->fs->stacksize = ls->fs->nlocalvar;  /* removes all temp values */
     optional(ls, ';');
   }

+ 17 - 11
lparser.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lparser.h,v 1.7 2000/03/03 12:33:59 roberto Exp roberto $
+** $Id: lparser.h,v 1.8 2000/03/03 14:58:26 roberto Exp roberto $
 ** LL(1) Parser and code generator for Lua
 ** See Copyright Notice in lua.h
 */
@@ -8,7 +8,6 @@
 #define lparser_h
 
 #include "lobject.h"
-#include "lopcodes.h"
 #include "lzio.h"
 
 
@@ -42,21 +41,18 @@
 #endif
 
 
-#if MAXLOCALS>MAXARG_U || MAXUPVALUES>MAXARG_B || MAXVARSLH>MAXARG_B || \
-    MAXPARAMS>MAXLOCALS || MAXSTACK>MAXARG_A || LFIELDS_PER_FLUSH>MAXARG_B
-#error invalid limits
-#endif
-
-
 
 /*
 ** Expression descriptor
 */
+
+#define NOJUMPS		0
+
 typedef enum {
   VGLOBAL,  /* info is constant index of global name */
   VLOCAL,   /* info is stack index */
-  VINDEXED, /* no info (table and index are on the stack) */
-  VEXP      /* info is pc index of exp main operator */
+  VINDEXED, /* info is info of the index expression */
+  VEXP      /* info is NOJUMPS if exp has no internal jumps */
 } expkind;
 
 typedef struct expdesc {
@@ -65,12 +61,22 @@ typedef struct expdesc {
 } expdesc;
 
 
+/*
+** Expression List descriptor:
+** tells number of expressions in the list,
+** and gives the `info' of last expression.
+*/
+typedef struct listdesc {
+  int n;
+  int info;  /* 0 if last expression has no internal jumps */
+} listdesc;
+
+
 /* state needed to generate code for a given function */
 typedef struct FuncState {
   TProtoFunc *f;  /* current function header */
   struct FuncState *prev;  /* enclosing function */
   int pc;  /* next position to code */
-  int last_pc;  /* last instruction coded (for optimizations) */
   int stacksize;  /* number of values on activation register */
   int nlocalvar;  /* number of active local variables */
   int nupvalues;  /* number of upvalues */