瀏覽代碼

no more 'Proto' objects on the stack. Protos are anchored on outer
Protos or on a Closure, which must be created before the Proto.

Roberto Ierusalimschy 13 年之前
父節點
當前提交
3cadc37f47
共有 11 個文件被更改,包括 103 次插入90 次删除
  1. 9 10
      ldo.c
  2. 3 4
      lfunc.c
  3. 2 2
      lfunc.h
  4. 1 2
      lgc.c
  5. 1 6
      lobject.h
  6. 52 45
      lparser.c
  7. 3 3
      lparser.h
  8. 3 3
      ltests.c
  9. 24 11
      lundump.c
  10. 2 2
      lundump.h
  11. 3 2
      lvm.c

+ 9 - 10
ldo.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ldo.c,v 2.102 2011/11/29 15:55:08 roberto Exp roberto $
+** $Id: ldo.c,v 2.103 2012/04/26 20:41:18 roberto Exp roberto $
 ** Stack and Call structure of Lua
 ** See Copyright Notice in lua.h
 */
@@ -626,24 +626,23 @@ static void checkmode (lua_State *L, const char *mode, const char *x) {
 
 static void f_parser (lua_State *L, void *ud) {
   int i;
-  Proto *tf;
   Closure *cl;
   struct SParser *p = cast(struct SParser *, ud);
   int c = zgetc(p->z);  /* read first character */
   if (c == LUA_SIGNATURE[0]) {
     checkmode(L, p->mode, "binary");
-    tf = luaU_undump(L, p->z, &p->buff, p->name);
+    cl = luaU_undump(L, p->z, &p->buff, p->name);
   }
   else {
     checkmode(L, p->mode, "text");
-    tf = luaY_parser(L, p->z, &p->buff, &p->dyd, p->name, c);
+    cl = luaY_parser(L, p->z, &p->buff, &p->dyd, p->name, c);
+  }
+  lua_assert(cl->l.nupvalues == cl->l.p->sizeupvalues);
+  for (i = 0; i < cl->l.nupvalues; i++) {  /* initialize upvalues */
+    UpVal *up = luaF_newupval(L);
+    cl->l.upvals[i] = up;
+    luaC_objbarrier(L, cl, up);
   }
-  setptvalue2s(L, L->top, tf);
-  incr_top(L);
-  cl = luaF_newLclosure(L, tf);
-  setclLvalue(L, L->top - 1, cl);
-  for (i = 0; i < tf->sizeupvalues; i++)  /* initialize upvalues */
-    cl->l.upvals[i] = luaF_newupval(L);
 }
 
 

+ 3 - 4
lfunc.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lfunc.c,v 2.27 2010/06/30 14:11:17 roberto Exp roberto $
+** $Id: lfunc.c,v 2.28 2012/01/20 22:05:50 roberto Exp roberto $
 ** Auxiliary functions to manipulate prototypes and closures
 ** See Copyright Notice in lua.h
 */
@@ -27,10 +27,9 @@ Closure *luaF_newCclosure (lua_State *L, int n) {
 }
 
 
-Closure *luaF_newLclosure (lua_State *L, Proto *p) {
-  int n = p->sizeupvalues;
+Closure *luaF_newLclosure (lua_State *L, int n) {
   Closure *c = &luaC_newobj(L, LUA_TLCL, sizeLclosure(n), NULL, 0)->cl;
-  c->l.p = p;
+  c->l.p = NULL;
   c->l.nupvalues = cast_byte(n);
   while (n--) c->l.upvals[n] = NULL;
   return c;

+ 2 - 2
lfunc.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lfunc.h,v 2.6 2010/06/04 13:06:15 roberto Exp roberto $
+** $Id: lfunc.h,v 2.7 2012/01/20 22:05:50 roberto Exp roberto $
 ** Auxiliary functions to manipulate prototypes and closures
 ** See Copyright Notice in lua.h
 */
@@ -20,7 +20,7 @@
 
 LUAI_FUNC Proto *luaF_newproto (lua_State *L);
 LUAI_FUNC Closure *luaF_newCclosure (lua_State *L, int nelems);
-LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, Proto *p);
+LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems);
 LUAI_FUNC UpVal *luaF_newupval (lua_State *L);
 LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level);
 LUAI_FUNC void luaF_close (lua_State *L, StkId level);

+ 1 - 2
lgc.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lgc.c,v 2.117 2012/01/20 22:05:50 roberto Exp roberto $
+** $Id: lgc.c,v 2.119 2012/01/25 21:05:40 roberto Exp roberto $
 ** Garbage Collector
 ** See Copyright Notice in lua.h
 */
@@ -489,7 +489,6 @@ static int traverseCclosure (global_State *g, CClosure *cl) {
 
 static int traverseLclosure (global_State *g, LClosure *cl) {
   int i;
-  lua_assert(cl->nupvalues == cl->p->sizeupvalues);
   markobject(g, cl->p);  /* mark its prototype */
   for (i = 0; i < cl->nupvalues; i++)  /* mark its upvalues */
     markobject(g, cl->upvals[i]);

+ 1 - 6
lobject.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lobject.h,v 2.65 2012/01/20 22:05:50 roberto Exp roberto $
+** $Id: lobject.h,v 2.68 2012/01/25 21:05:40 roberto Exp roberto $
 ** Type definitions for Lua objects
 ** See Copyright Notice in lua.h
 */
@@ -236,11 +236,6 @@ typedef struct lua_TValue TValue;
     val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TTABLE)); \
     checkliveness(G(L),io); }
 
-#define setptvalue(L,obj,x) \
-  { TValue *io=(obj); \
-    val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TPROTO)); \
-    checkliveness(G(L),io); }
-
 #define setdeadvalue(obj)	settt_(obj, LUA_TDEADKEY)
 
 

+ 52 - 45
lparser.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lparser.c,v 2.125 2012/01/23 23:05:18 roberto Exp roberto $
+** $Id: lparser.c,v 2.126 2012/04/20 19:20:05 roberto Exp roberto $
 ** Lua Parser
 ** See Copyright Notice in lua.h
 */
@@ -493,21 +493,30 @@ static void leaveblock (FuncState *fs) {
 
 
 /*
-** adds prototype being created into its parent list of prototypes
-** and codes instruction to create new closure
+** adds a new prototype into list of prototypes
 */
-static void codeclosure (LexState *ls, Proto *clp, expdesc *v) {
-  FuncState *fs = ls->fs->prev;
-  Proto *f = fs->f;  /* prototype of function creating new closure */
+static Proto *addprototype (LexState *ls) {
+  Proto *clp;
+  lua_State *L = ls->L;
+  FuncState *fs = ls->fs;
+  Proto *f = fs->f;  /* prototype of current function */
   if (fs->np >= f->sizep) {
     int oldsize = f->sizep;
-    luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *,
-                    MAXARG_Bx, "functions");
+    luaM_growvector(L, f->p, fs->np, f->sizep, Proto *, MAXARG_Bx, "functions");
     while (oldsize < f->sizep) f->p[oldsize++] = NULL;
   }
-  f->p[fs->np++] = clp;
-  luaC_objbarrier(ls->L, f, clp);
-  init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1));
+  f->p[fs->np++] = clp = luaF_newproto(L);
+  luaC_objbarrier(L, f, clp);
+  return clp;
+}
+
+
+/*
+** codes instruction to create new closure in parent function
+*/
+static void codeclosure (LexState *ls, expdesc *v) {
+  FuncState *fs = ls->fs->prev;
+  init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np - 1));
   luaK_exp2nextreg(fs, v);  /* fix it at stack top (for GC) */
 }
 
@@ -529,13 +538,9 @@ static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) {
   fs->nactvar = 0;
   fs->firstlocal = ls->dyd->actvar.n;
   fs->bl = NULL;
-  f = luaF_newproto(L);
-  fs->f = f;
+  f = fs->f;
   f->source = ls->source;
   f->maxstacksize = 2;  /* registers 0/1 are always valid */
-  /* anchor prototype (to avoid being collected) */
-  setptvalue2s(L, L->top, f);
-  incr_top(L);
   fs->h = luaH_new(L);
   /* anchor table of constants (to avoid being collected) */
   sethvalue2s(L, L->top, fs->h);
@@ -568,20 +573,6 @@ static void close_func (LexState *ls) {
   anchor_token(ls);
   L->top--;  /* pop table of constants */
   luaC_checkGC(L);
-  L->top--;  /* pop prototype (after possible collection) */
-}
-
-
-/*
-** opens the main function, which is a regular vararg function with an
-** upvalue named LUA_ENV
-*/
-static void open_mainfunc (LexState *ls, FuncState *fs, BlockCnt *bl) {
-  expdesc v;
-  open_func(ls, fs, bl);
-  fs->f->is_vararg = 1;  /* main function is always vararg */
-  init_exp(&v, VLOCAL, 0);
-  newupvalue(fs, ls->envn, &v);  /* create environment upvalue */
 }
 
 
@@ -795,8 +786,9 @@ static void body (LexState *ls, expdesc *e, int ismethod, int line) {
   /* body ->  `(' parlist `)' block END */
   FuncState new_fs;
   BlockCnt bl;
-  open_func(ls, &new_fs, &bl);
+  new_fs.f = addprototype(ls);
   new_fs.f->linedefined = line;
+  open_func(ls, &new_fs, &bl);
   checknext(ls, '(');
   if (ismethod) {
     new_localvarliteral(ls, "self");  /* create 'self' parameter */
@@ -807,7 +799,7 @@ static void body (LexState *ls, expdesc *e, int ismethod, int line) {
   statlist(ls);
   new_fs.f->lastlinedefined = ls->linenumber;
   check_match(ls, TK_END, TK_FUNCTION, line);
-  codeclosure(ls, new_fs.f, e);
+  codeclosure(ls, e);
   close_func(ls);
 }
 
@@ -1596,27 +1588,42 @@ static void statement (LexState *ls) {
 /* }====================================================================== */
 
 
-Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
-                    Dyndata *dyd, const char *name, int firstchar) {
+/*
+** compiles the main function, which is a regular vararg function with an
+** upvalue named LUA_ENV
+*/
+static void mainfunc (LexState *ls, FuncState *fs) {
+  BlockCnt bl;
+  expdesc v;
+  open_func(ls, fs, &bl);
+  fs->f->is_vararg = 1;  /* main function is always vararg */
+  init_exp(&v, VLOCAL, 0);  /* create and... */
+  newupvalue(fs, ls->envn, &v);  /* ...set environment upvalue */
+  luaX_next(ls);  /* read first token */
+  statlist(ls);  /* parse main body */
+  check(ls, TK_EOS);
+  close_func(ls);
+}
+
+
+Closure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
+                      Dyndata *dyd, const char *name, int firstchar) {
   LexState lexstate;
   FuncState funcstate;
-  BlockCnt bl;
-  TString *tname = luaS_new(L, name);
-  setsvalue2s(L, L->top, tname);  /* push name to protect it */
+  Closure *cl = luaF_newLclosure(L, 1);  /* create main closure */
+  /* anchor closure (to avoid being collected) */
+  setclLvalue(L, L->top, cl);
   incr_top(L);
+  funcstate.f = cl->l.p = luaF_newproto(L);
+  funcstate.f->source = luaS_new(L, name);  /* create and anchor TString */
   lexstate.buff = buff;
   lexstate.dyd = dyd;
   dyd->actvar.n = dyd->gt.n = dyd->label.n = 0;
-  luaX_setinput(L, &lexstate, z, tname, firstchar);
-  open_mainfunc(&lexstate, &funcstate, &bl);
-  luaX_next(&lexstate);  /* read first token */
-  statlist(&lexstate);  /* main body */
-  check(&lexstate, TK_EOS);
-  close_func(&lexstate);
-  L->top--;  /* pop name */
+  luaX_setinput(L, &lexstate, z, funcstate.f->source, firstchar);
+  mainfunc(&lexstate, &funcstate);
   lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs);
   /* all scopes should be correctly finished */
   lua_assert(dyd->actvar.n == 0 && dyd->gt.n == 0 && dyd->label.n == 0);
-  return funcstate.f;
+  return cl;  /* it's on the stack too */
 }
 

+ 3 - 3
lparser.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lparser.h,v 1.68 2011/02/23 13:13:10 roberto Exp roberto $
+** $Id: lparser.h,v 1.69 2011/07/27 18:09:01 roberto Exp roberto $
 ** Lua Parser
 ** See Copyright Notice in lua.h
 */
@@ -112,8 +112,8 @@ typedef struct FuncState {
 } FuncState;
 
 
-LUAI_FUNC Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
-                              Dyndata *dyd, const char *name, int firstchar);
+LUAI_FUNC Closure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
+                                Dyndata *dyd, const char *name, int firstchar);
 
 
 #endif

+ 3 - 3
ltests.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ltests.c,v 2.125 2012/01/20 22:05:50 roberto Exp roberto $
+** $Id: ltests.c,v 2.126 2012/01/25 21:05:40 roberto Exp roberto $
 ** Internal Module for Debugging of the Lua Implementation
 ** See Copyright Notice in lua.h
 */
@@ -278,8 +278,7 @@ static void checkCclosure (global_State *g, CClosure *cl) {
 static void checkLclosure (global_State *g, LClosure *cl) {
   GCObject *clgc = obj2gco(cl);
   int i;
-  lua_assert(cl->nupvalues == cl->p->sizeupvalues);
-  checkobjref(g, clgc, cl->p);
+  if (cl->p) checkobjref(g, clgc, cl->p);
   for (i=0; i<cl->nupvalues; i++) {
     if (cl->upvals[i]) {
       lua_assert(cl->upvals[i]->tt == LUA_TUPVAL);
@@ -855,6 +854,7 @@ static int loadlib (lua_State *L) {
     {"coroutine", luaopen_coroutine},
     {"debug", luaopen_debug},
     {"io", luaopen_io},
+    {"os", luaopen_os},
     {"math", luaopen_math},
     {"string", luaopen_string},
     {"table", luaopen_table},

+ 24 - 11
lundump.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lundump.c,v 2.20 2012/01/23 23:02:10 roberto Exp roberto $
+** $Id: lundump.c,v 2.21 2012/03/19 22:58:09 roberto Exp roberto $
 ** load precompiled Lua chunks
 ** See Copyright Notice in lua.h
 */
@@ -39,7 +39,7 @@ static l_noret error(LoadState* S, const char* why)
 #define LoadVector(S,b,n,size)	LoadMem(S,b,n,size)
 
 #if !defined(luai_verifycode)
-#define luai_verifycode(L,b,f)	(f)
+#define luai_verifycode(L,b,f)	/* empty */
 #endif
 
 static void LoadBlock(LoadState* S, void* b, size_t size)
@@ -91,7 +91,7 @@ static void LoadCode(LoadState* S, Proto* f)
  LoadVector(S,f->code,n,sizeof(Instruction));
 }
 
-static Proto* LoadFunction(LoadState* S);
+static void LoadFunction(LoadState* S, Proto* f);
 
 static void LoadConstants(LoadState* S, Proto* f)
 {
@@ -125,7 +125,11 @@ static void LoadConstants(LoadState* S, Proto* f)
  f->p=luaM_newvector(S->L,n,Proto*);
  f->sizep=n;
  for (i=0; i<n; i++) f->p[i]=NULL;
- for (i=0; i<n; i++) f->p[i]=LoadFunction(S);
+ for (i=0; i<n; i++)
+ {
+  f->p[i]=luaF_newproto(S->L);
+  LoadFunction(S,f->p[i]);
+ }
 }
 
 static void LoadUpvalues(LoadState* S, Proto* f)
@@ -164,10 +168,8 @@ static void LoadDebug(LoadState* S, Proto* f)
  for (i=0; i<n; i++) f->upvalues[i].name=LoadString(S);
 }
 
-static Proto* LoadFunction(LoadState* S)
+static void LoadFunction(LoadState* S, Proto* f)
 {
- Proto* f=luaF_newproto(S->L);
- setptvalue2s(S->L,S->L->top,f); incr_top(S->L);
  f->linedefined=LoadInt(S);
  f->lastlinedefined=LoadInt(S);
  f->numparams=LoadByte(S);
@@ -177,8 +179,6 @@ static Proto* LoadFunction(LoadState* S)
  LoadConstants(S,f);
  LoadUpvalues(S,f);
  LoadDebug(S,f);
- S->L->top--;
- return f;
 }
 
 /* the code below must be consistent with the code in luaU_header */
@@ -203,9 +203,10 @@ static void LoadHeader(LoadState* S)
 /*
 ** load precompiled chunk
 */
-Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name)
+Closure* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name)
 {
  LoadState S;
+ Closure* cl;
  if (*name=='@' || *name=='=')
   S.name=name+1;
  else if (*name==LUA_SIGNATURE[0])
@@ -216,7 +217,19 @@ Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name)
  S.Z=Z;
  S.b=buff;
  LoadHeader(&S);
- return luai_verifycode(L,buff,LoadFunction(&S));
+ cl=luaF_newLclosure(L,1);
+ setclLvalue(L,L->top,cl); incr_top(L);
+ cl->l.p=luaF_newproto(L);
+ LoadFunction(&S,cl->l.p);
+ if (cl->l.p->sizeupvalues != 1)
+ {
+  Proto* p=cl->l.p;
+  cl=luaF_newLclosure(L,cl->l.p->sizeupvalues);
+  cl->l.p=p;
+  setclLvalue(L,L->top-1,cl);
+ }
+ luai_verifycode(L,buff,cl->l.p);
+ return cl;
 }
 
 #define MYINT(s)	(s[0]-'0')

+ 2 - 2
lundump.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lundump.h,v 1.44 2011/05/06 13:35:17 lhf Exp $
+** $Id: lundump.h,v 1.38 2011/05/17 12:42:43 roberto Exp roberto $
 ** load precompiled Lua chunks
 ** See Copyright Notice in lua.h
 */
@@ -11,7 +11,7 @@
 #include "lzio.h"
 
 /* load one chunk; from lundump.c */
-LUAI_FUNC Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name);
+LUAI_FUNC Closure* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name);
 
 /* make header; from lundump.c */
 LUAI_FUNC void luaU_header (lu_byte* h);

+ 3 - 2
lvm.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lvm.c,v 2.147 2011/12/07 14:43:55 roberto Exp roberto $
+** $Id: lvm.c,v 2.149 2012/01/25 21:05:40 roberto Exp roberto $
 ** Lua virtual machine
 ** See Copyright Notice in lua.h
 */
@@ -395,7 +395,8 @@ static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base,
   int nup = p->sizeupvalues;
   Upvaldesc *uv = p->upvalues;
   int i;
-  Closure *ncl = luaF_newLclosure(L, p);
+  Closure *ncl = luaF_newLclosure(L, nup);
+  ncl->l.p = p;
   setclLvalue(L, ra, ncl);  /* anchor new closure in stack */
   for (i = 0; i < nup; i++) {  /* fill in its upvalues */
     if (uv[i].instack)  /* upvalue refers to local variable? */