Browse Source

information about upvalues (where they come from) kept in Proto structure,
instead of sequence of pseudo-opcodes after OP_CLOSURE

Roberto Ierusalimschy 16 years ago
parent
commit
5938212748
14 changed files with 97 additions and 98 deletions
  1. 2 2
      lapi.c
  2. 3 8
      ldebug.c
  3. 3 3
      ldo.c
  4. 14 3
      ldump.c
  5. 4 5
      lfunc.c
  6. 4 4
      lgc.c
  7. 12 4
      lobject.h
  8. 1 5
      lopcodes.h
  9. 18 21
      lparser.c
  10. 2 8
      lparser.h
  11. 4 5
      ltests.c
  12. 1 8
      luaconf.h
  13. 17 6
      lundump.c
  14. 12 16
      lvm.c

+ 2 - 2
lapi.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lapi.c,v 2.90 2009/09/17 18:04:21 roberto Exp roberto $
+** $Id: lapi.c,v 2.91 2009/09/21 12:09:52 roberto Exp roberto $
 ** Lua API
 ** See Copyright Notice in lua.h
 */
@@ -1043,7 +1043,7 @@ static const char *aux_upvalue (StkId fi, int n, TValue **val) {
     Proto *p = f->l.p;
     if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
     *val = f->l.upvals[n-1]->v;
-    return getstr(p->upvalues[n-1]);
+    return getstr(p->upvalues[n-1].name);
   }
 }
 

+ 3 - 8
ldebug.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldebug.c,v 2.54 2009/09/23 20:33:05 roberto Exp roberto $
+** $Id: ldebug.c,v 2.55 2009/09/28 12:37:17 roberto Exp roberto $
 ** Debug Interface
 ** See Copyright Notice in lua.h
 */
@@ -328,7 +328,8 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int reg,
       case OP_GETUPVAL: {
         if (reg == a) {
           int u = GETARG_B(i);  /* upvalue index */
-          *name = p->upvalues ? getstr(p->upvalues[u]) : "?";
+          TString *tn = p->upvalues[u].name;
+          *name = tn ? getstr(tn) : "?";
           what = "upvalue";
         }
         break;
@@ -364,12 +365,6 @@ static const char *getobjname (lua_State *L, CallInfo *ci, int reg,
           pc += b;  /* do the jump */
         break;
       }
-      case OP_CLOSURE: {
-        int nup = p->p[GETARG_Bx(i)]->nups;
-        pc += nup;  /* do not 'execute' pseudo-instructions */
-        lua_assert(pc <= lastpc);
-        break;
-      }
       default:
         if (testAMode(op) && reg == a) what = NULL;
         break;

+ 3 - 3
ldo.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldo.c,v 2.66 2009/07/15 17:26:14 roberto Exp roberto $
+** $Id: ldo.c,v 2.67 2009/09/14 14:30:39 roberto Exp roberto $
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 */
@@ -577,10 +577,10 @@ static void f_parser (lua_State *L, void *ud) {
                                : luaY_parser(L, p->z, &p->buff, p->name);
   setptvalue2s(L, L->top, tf);
   incr_top(L);
-  cl = luaF_newLclosure(L, tf->nups, hvalue(gt(L)));
+  cl = luaF_newLclosure(L, tf->sizeupvalues, hvalue(gt(L)));
   cl->l.p = tf;
   setclvalue(L, L->top - 1, cl);
-  for (i = 0; i < tf->nups; i++)  /* initialize upvalues */
+  for (i = 0; i < tf->sizeupvalues; i++)  /* initialize upvalues */
     cl->l.upvals[i] = luaF_newupval(L);
 }
 

+ 14 - 3
ldump.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldump.c,v 2.9 2006/09/11 14:07:24 roberto Exp roberto $
+** $Id: ldump.c,v 2.10 2008/07/03 14:25:05 roberto Exp roberto $
 ** save precompiled Lua chunks
 ** See Copyright Notice in lua.h
 */
@@ -108,6 +108,17 @@ static void DumpConstants(const Proto* f, DumpState* D)
  for (i=0; i<n; i++) DumpFunction(f->p[i],f->source,D);
 }
 
+static void DumpUpvalues(const Proto* f, DumpState* D)
+{
+ int i,n=f->sizeupvalues;
+ DumpInt(n,D);
+ for (i=0; i<n; i++)
+ {
+  DumpChar(f->upvalues[i].instack, D);
+  DumpChar(f->upvalues[i].idx, D);
+ }
+}
+
 static void DumpDebug(const Proto* f, DumpState* D)
 {
  int i,n;
@@ -123,7 +134,7 @@ static void DumpDebug(const Proto* f, DumpState* D)
  }
  n= (D->strip) ? 0 : f->sizeupvalues;
  DumpInt(n,D);
- for (i=0; i<n; i++) DumpString(f->upvalues[i],D);
+ for (i=0; i<n; i++) DumpString(f->upvalues[i].name,D);
 }
 
 static void DumpFunction(const Proto* f, const TString* p, DumpState* D)
@@ -131,12 +142,12 @@ static void DumpFunction(const Proto* f, const TString* p, DumpState* D)
  DumpString((f->source==p || D->strip) ? NULL : f->source,D);
  DumpInt(f->linedefined,D);
  DumpInt(f->lastlinedefined,D);
- DumpChar(f->nups,D);
  DumpChar(f->numparams,D);
  DumpChar(f->is_vararg,D);
  DumpChar(f->maxstacksize,D);
  DumpCode(f,D);
  DumpConstants(f,D);
+ DumpUpvalues(f,D);
  DumpDebug(f,D);
 }
 

+ 4 - 5
lfunc.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lfunc.c,v 2.13 2007/02/07 17:48:52 roberto Exp roberto $
+** $Id: lfunc.c,v 2.14 2009/04/17 14:40:13 roberto Exp roberto $
 ** Auxiliary functions to manipulate prototypes and closures
 ** See Copyright Notice in lua.h
 */
@@ -121,16 +121,15 @@ Proto *luaF_newproto (lua_State *L) {
   f->sizep = 0;
   f->code = NULL;
   f->sizecode = 0;
+  f->lineinfo = NULL;
   f->sizelineinfo = 0;
-  f->sizeupvalues = 0;
-  f->nups = 0;
   f->upvalues = NULL;
+  f->sizeupvalues = 0;
   f->numparams = 0;
   f->is_vararg = 0;
   f->maxstacksize = 0;
-  f->lineinfo = NULL;
-  f->sizelocvars = 0;
   f->locvars = NULL;
+  f->sizelocvars = 0;
   f->linedefined = 0;
   f->lastlinedefined = 0;
   f->source = NULL;

+ 4 - 4
lgc.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lgc.c,v 2.55 2009/07/16 16:26:09 roberto Exp roberto $
+** $Id: lgc.c,v 2.56 2009/09/28 13:50:34 roberto Exp roberto $
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 */
@@ -349,8 +349,8 @@ static void traverseproto (global_State *g, Proto *f) {
   for (i=0; i<f->sizek; i++)  /* mark literals */
     markvalue(g, &f->k[i]);
   for (i=0; i<f->sizeupvalues; i++) {  /* mark upvalue names */
-    if (f->upvalues[i])
-      stringmark(f->upvalues[i]);
+    if (f->upvalues[i].name)
+      stringmark(f->upvalues[i].name);
   }
   for (i=0; i<f->sizep; i++)  /* mark nested protos */
     markobject(g, f->p[i]);
@@ -371,7 +371,7 @@ static void traverseclosure (global_State *g, Closure *cl) {
   }
   else {
     int i;
-    lua_assert(cl->l.nupvalues == cl->l.p->nups);
+    lua_assert(cl->l.nupvalues == cl->l.p->sizeupvalues);
     markobject(g, cl->l.p);
     for (i=0; i<cl->l.nupvalues; i++)  /* mark its upvalues */
       markobject(g, cl->l.upvals[i]);

+ 12 - 4
lobject.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lobject.h,v 2.27 2009/06/18 16:36:40 roberto Exp roberto $
+** $Id: lobject.h,v 2.28 2009/07/15 18:37:19 roberto Exp roberto $
 ** Type definitions for Lua objects
 ** See Copyright Notice in lua.h
 */
@@ -227,6 +227,15 @@ typedef union Udata {
 
 
 
+/*
+** Upvalues from a function prototype
+*/
+typedef struct Upvaldesc {
+  TString *name;  /* upvalue name (for debug information) */
+  lu_byte instack;
+  lu_byte idx;  /* index of upvalue (in stack or in outer function's list) */
+} Upvaldesc;
+
 
 /*
 ** Function Prototypes
@@ -238,9 +247,9 @@ typedef struct Proto {
   struct Proto **p;  /* functions defined inside the function */
   int *lineinfo;  /* map from opcodes to source lines */
   struct LocVar *locvars;  /* information about local variables */
-  TString **upvalues;  /* upvalue names */
+  Upvaldesc *upvalues;  /* upvalue information */
   TString  *source;
-  int sizeupvalues;
+  int sizeupvalues;  /* size of 'upvalues' */
   int sizek;  /* size of `k' */
   int sizecode;
   int sizelineinfo;
@@ -249,7 +258,6 @@ typedef struct Proto {
   int linedefined;
   int lastlinedefined;
   GCObject *gclist;
-  lu_byte nups;  /* number of upvalues */
   lu_byte numparams;
   lu_byte is_vararg;
   lu_byte maxstacksize;

+ 1 - 5
lopcodes.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lopcodes.h,v 1.129 2009/03/09 15:27:56 roberto Exp roberto $
+** $Id: lopcodes.h,v 1.130 2009/09/23 20:33:05 roberto Exp roberto $
 ** Opcodes for Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -251,10 +251,6 @@ OP_EXTRAARG/*	Ax	extra (larger) argument for previous opcode	*/
 
   (*) All `skips' (pc++) assume that next instruction is a jump.
 
-  (*) The OP_CLOSURE instruction is followed by a sequence of
-  instructions coding the upvalues: OP_MOVE A B if upvalue is local B,
-  or OP_GETUPVAL A B if upvalue is enclosing upvalue B.
-
 ===========================================================================*/
 
 

+ 18 - 21
lparser.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lparser.c,v 2.65 2009/08/10 20:41:04 roberto Exp roberto $
+** $Id: lparser.c,v 2.66 2009/09/23 20:14:00 roberto Exp roberto $
 ** Lua Parser
 ** See Copyright Notice in lua.h
 */
@@ -188,23 +188,24 @@ static int indexupvalue (FuncState *fs, TString *name, expdesc *v) {
   int i;
   Proto *f = fs->f;
   int oldsize = f->sizeupvalues;
-  for (i=0; i<f->nups; i++) {
-    if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->u.s.info) {
-      lua_assert(f->upvalues[i] == name);
+  int instk = (v->k == VLOCAL);
+  lua_assert(instk || v->k == VUPVAL);
+  for (i=0; i<fs->nups; i++) {
+    if (f->upvalues[i].instack == instk && f->upvalues[i].idx == v->u.s.info) {
+      lua_assert(f->upvalues[i].name == name);
       return i;
     }
   }
   /* new one */
-  luaY_checklimit(fs, f->nups + 1, LUAI_MAXUPVALUES, "upvalues");
-  luaM_growvector(fs->L, f->upvalues, f->nups, f->sizeupvalues,
-                  TString *, MAX_INT, "upvalues");
-  while (oldsize < f->sizeupvalues) f->upvalues[oldsize++] = NULL;
-  f->upvalues[f->nups] = name;
+  luaY_checklimit(fs, fs->nups + 1, UCHAR_MAX, "upvalues");
+  luaM_growvector(fs->L, f->upvalues, fs->nups, f->sizeupvalues,
+                  Upvaldesc, UCHAR_MAX, "upvalues");
+  while (oldsize < f->sizeupvalues) f->upvalues[oldsize++].name = NULL;
+  f->upvalues[fs->nups].name = name;
   luaC_objbarrier(fs->L, f, name);
-  lua_assert(v->k == VLOCAL || v->k == VUPVAL);
-  fs->upvalues[f->nups].k = cast_byte(v->k);
-  fs->upvalues[f->nups].info = cast_byte(v->u.s.info);
-  return f->nups++;
+  f->upvalues[fs->nups].instack = cast_byte(instk);
+  f->upvalues[fs->nups].idx = cast_byte(v->u.s.info);
+  return fs->nups++;
 }
 
 
@@ -316,17 +317,12 @@ static void pushclosure (LexState *ls, FuncState *func, expdesc *v) {
   FuncState *fs = ls->fs->prev;
   Proto *f = fs->f;
   int oldsize = f->sizep;
-  int i;
   luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *,
                   MAXARG_Bx, "functions");
   while (oldsize < f->sizep) f->p[oldsize++] = NULL;
   f->p[fs->np++] = func->f;
   luaC_objbarrier(ls->L, f, func->f);
   init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1));
-  for (i=0; i<func->f->nups; i++) {
-    OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL;
-    luaK_codeABC(fs, o, 0, func->upvalues[i].info, 0);
-  }
 }
 
 
@@ -343,6 +339,7 @@ static void open_func (LexState *ls, FuncState *fs) {
   fs->freereg = 0;
   fs->nk = 0;
   fs->np = 0;
+  fs->nups = 0;
   fs->nlocvars = 0;
   fs->nactvar = 0;
   fs->bl = NULL;
@@ -376,8 +373,8 @@ static void close_func (LexState *ls) {
   f->sizep = fs->np;
   luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar);
   f->sizelocvars = fs->nlocvars;
-  luaM_reallocvector(L, f->upvalues, f->sizeupvalues, f->nups, TString *);
-  f->sizeupvalues = f->nups;
+  luaM_reallocvector(L, f->upvalues, f->sizeupvalues, fs->nups, Upvaldesc);
+  f->sizeupvalues = fs->nups;
   lua_assert(fs->bl == NULL);
   ls->fs = fs->prev;
   L->top -= 2;  /* remove table and prototype from the stack */
@@ -402,7 +399,7 @@ Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) {
   close_func(&lexstate);
   L->top--;
   lua_assert(funcstate.prev == NULL);
-  lua_assert(funcstate.f->nups == 0);
+  lua_assert(funcstate.nups == 0);
   lua_assert(lexstate.fs == NULL);
   return funcstate.f;
 }

+ 2 - 8
lparser.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lparser.h,v 1.57 2006/03/09 18:14:31 roberto Exp roberto $
+** $Id: lparser.h,v 1.58 2008/05/08 15:44:51 roberto Exp roberto $
 ** Lua Parser
 ** See Copyright Notice in lua.h
 */
@@ -46,12 +46,6 @@ typedef struct expdesc {
 } expdesc;
 
 
-typedef struct upvaldesc {
-  lu_byte k;
-  lu_byte info;
-} upvaldesc;
-
-
 typedef struct vardesc {
   unsigned short idx;
 } vardesc;
@@ -76,7 +70,7 @@ typedef struct FuncState {
   int np;  /* number of elements in `p' */
   short nlocvars;  /* number of elements in `locvars' */
   lu_byte nactvar;  /* number of active local variables */
-  upvaldesc upvalues[LUAI_MAXUPVALUES];  /* upvalues */
+  lu_byte nups;  /* number of upvalues */
   vardesc actvar[LUAI_MAXVARS];  /* declared-variable stack */
 } FuncState;
 

+ 4 - 5
ltests.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ltests.c,v 2.71 2009/09/14 14:30:39 roberto Exp roberto $
+** $Id: ltests.c,v 2.72 2009/09/17 18:04:21 roberto Exp roberto $
 ** Internal Module for Debugging of the Lua Implementation
 ** See Copyright Notice in lua.h
 */
@@ -248,8 +248,8 @@ static void checkproto (global_State *g, Proto *f) {
       checkobjref(g, fgc, rawtsvalue(f->k+i));
   }
   for (i=0; i<f->sizeupvalues; i++) {
-    if (f->upvalues[i])
-      checkobjref(g, fgc, f->upvalues[i]);
+    if (f->upvalues[i].name)
+      checkobjref(g, fgc, f->upvalues[i].name);
   }
   for (i=0; i<f->sizep; i++) {
     if (f->p[i])
@@ -273,7 +273,7 @@ static void checkclosure (global_State *g, Closure *cl) {
   }
   else {
     int i;
-    lua_assert(cl->l.nupvalues == cl->l.p->nups);
+    lua_assert(cl->l.nupvalues == cl->l.p->sizeupvalues);
     checkobjref(g, clgc, cl->l.p);
     for (i=0; i<cl->l.nupvalues; i++) {
       if (cl->l.upvals[i]) {
@@ -493,7 +493,6 @@ static int get_limits (lua_State *L) {
   setnameval(L, "LFPF", LFIELDS_PER_FLUSH);
   setnameval(L, "MAXVARS", LUAI_MAXVARS);
   setnameval(L, "MAXSTACK", MAXSTACK);
-  setnameval(L, "MAXUPVALUES", LUAI_MAXUPVALUES);
   setnameval(L, "NUM_OPCODES", NUM_OPCODES);
   return 1;
 }

+ 1 - 8
luaconf.h

@@ -1,5 +1,5 @@
 /*
-** $Id: luaconf.h,v 1.108 2009/07/15 17:57:30 roberto Exp roberto $
+** $Id: luaconf.h,v 1.109 2009/08/25 19:58:08 roberto Exp roberto $
 ** Configuration file for Lua
 ** See Copyright Notice in lua.h
 */
@@ -461,13 +461,6 @@
 #define LUAI_MAXVARS		200
 
 
-/*
-@@ LUAI_MAXUPVALUES is the maximum number of upvalues per function
-@* (must be smaller than 250).
-*/
-#define LUAI_MAXUPVALUES	60
-
-
 /*
 @@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system.
 */

+ 17 - 6
lundump.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lundump.c,v 2.9 2008/04/07 18:44:23 roberto Exp roberto $
+** $Id: lundump.c,v 2.10 2009/04/30 17:42:21 roberto Exp roberto $
 ** load precompiled Lua chunks
 ** See Copyright Notice in lua.h
 */
@@ -133,6 +133,20 @@ static void LoadConstants(LoadState* S, Proto* f)
  for (i=0; i<n; i++) f->p[i]=LoadFunction(S,f->source);
 }
 
+static void LoadUpvalues(LoadState* S, Proto* f)
+{
+ int i,n;
+ n=LoadInt(S);
+ f->upvalues=luaM_newvector(S->L,n,Upvaldesc);
+ f->sizeupvalues=n;
+ for (i=0; i<n; i++) f->upvalues[i].name=NULL;
+ for (i=0; i<n; i++)
+ {
+  f->upvalues[i].instack=LoadChar(S);
+  f->upvalues[i].idx=LoadChar(S);
+ }
+}
+
 static void LoadDebug(LoadState* S, Proto* f)
 {
  int i,n;
@@ -151,10 +165,7 @@ static void LoadDebug(LoadState* S, Proto* f)
   f->locvars[i].endpc=LoadInt(S);
  }
  n=LoadInt(S);
- f->upvalues=luaM_newvector(S->L,n,TString*);
- f->sizeupvalues=n;
- for (i=0; i<n; i++) f->upvalues[i]=NULL;
- for (i=0; i<n; i++) f->upvalues[i]=LoadString(S);
+ for (i=0; i<n; i++) f->upvalues[i].name=LoadString(S);
 }
 
 static Proto* LoadFunction(LoadState* S, TString* p)
@@ -166,12 +177,12 @@ static Proto* LoadFunction(LoadState* S, TString* p)
  f->source=LoadString(S); if (f->source==NULL) f->source=p;
  f->linedefined=LoadInt(S);
  f->lastlinedefined=LoadInt(S);
- f->nups=LoadByte(S);
  f->numparams=LoadByte(S);
  f->is_vararg=LoadByte(S);
  f->maxstacksize=LoadByte(S);
  LoadCode(S,f);
  LoadConstants(S,f);
+ LoadUpvalues(S,f);
  LoadDebug(S,f);
  S->L->top--;
  G(S->L)->nCcalls--;

+ 12 - 16
lvm.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lvm.c,v 2.96 2009/08/07 16:17:41 roberto Exp roberto $
+** $Id: lvm.c,v 2.97 2009/09/23 20:33:05 roberto Exp roberto $
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -773,22 +773,18 @@ void luaV_execute (lua_State *L) {
         continue;
       }
       case OP_CLOSURE: {
-        Proto *p;
-        Closure *ncl;
-        int nup, j;
-        p = cl->p->p[GETARG_Bx(i)];
-        nup = p->nups;
-        ncl = luaF_newLclosure(L, nup, cl->env);
+        Proto *p = cl->p->p[GETARG_Bx(i)];  /* prototype for new closure */
+        int nup = p->sizeupvalues;
+        Closure *ncl = luaF_newLclosure(L, nup, cl->env);
+        Upvaldesc *uv = p->upvalues;
+        int j;
         ncl->l.p = p;
-        setclvalue(L, ra, ncl);
-        for (j=0; j<nup; j++) {
-          Instruction u = *ci->u.l.savedpc++;
-          if (GET_OPCODE(u) == OP_GETUPVAL)
-            ncl->l.upvals[j] = cl->upvals[GETARG_B(u)];
-          else {
-            lua_assert(GET_OPCODE(u) == OP_MOVE);
-            ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(u));
-          }
+        setclvalue(L, ra, ncl);  /* anchor new closure in stack */
+        for (j = 0; j < nup; j++) {  /* fill in upvalues */
+          if (uv[j].instack)  /* upvalue refers to local variable? */
+            ncl->l.upvals[j] = luaF_findupval(L, base + uv[j].idx);
+          else  /* get upvalue from enclosing function */
+            ncl->l.upvals[j] = cl->upvals[uv[j].idx];
         }
         Protect(luaC_checkGC(L));
         continue;