mirror of https://github.com/rusefi/lua.git
no more 'Proto' objects on the stack. Protos are anchored on outer
Protos or on a Closure, which must be created before the Proto.
This commit is contained in:
parent
bb1146dc39
commit
3cadc37f47
19
ldo.c
19
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);
|
||||
}
|
||||
|
||||
|
||||
|
|
7
lfunc.c
7
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;
|
||||
|
|
4
lfunc.h
4
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);
|
||||
|
|
3
lgc.c
3
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,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)
|
||||
|
||||
|
||||
|
|
97
lparser.c
97
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 */
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
6
ltests.c
6
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},
|
||||
|
|
35
lundump.c
35
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')
|
||||
|
|
|
@ -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);
|
||||
|
|
5
lvm.c
5
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? */
|
||||
|
|
Loading…
Reference in New Issue