patch lua_clonefunction

This commit is contained in:
Cloud Wu
2015-06-18 17:39:37 +08:00
parent 2086e13a46
commit 5d9142110e
18 changed files with 364 additions and 160 deletions

View File

@@ -79,7 +79,7 @@ static l_noret error_expected (LexState *ls, int token) {
static l_noret errorlimit (FuncState *fs, int limit, const char *what) {
lua_State *L = fs->ls->L;
const char *msg;
int line = fs->f->linedefined;
int line = fs->f->sp->linedefined;
const char *where = (line == 0)
? "main function"
: luaO_pushfstring(L, "function at line %d", line);
@@ -160,13 +160,14 @@ static void checkname (LexState *ls, expdesc *e) {
static int registerlocalvar (LexState *ls, TString *varname) {
FuncState *fs = ls->fs;
Proto *f = fs->f;
Proto *fp = fs->f;
SharedProto *f = fp->sp;
int oldsize = f->sizelocvars;
luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars,
LocVar, SHRT_MAX, "local variables");
while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL;
f->locvars[fs->nlocvars].varname = varname;
luaC_objbarrier(ls->L, f, varname);
luaC_objbarrier(ls->L, fp, varname);
return fs->nlocvars++;
}
@@ -194,7 +195,7 @@ static void new_localvarliteral_ (LexState *ls, const char *name, size_t sz) {
static LocVar *getlocvar (FuncState *fs, int i) {
int idx = fs->ls->dyd->actvar.arr[fs->firstlocal + i].idx;
lua_assert(idx < fs->nlocvars);
return &fs->f->locvars[idx];
return &fs->f->sp->locvars[idx];
}
@@ -216,7 +217,7 @@ static void removevars (FuncState *fs, int tolevel) {
static int searchupvalue (FuncState *fs, TString *name) {
int i;
Upvaldesc *up = fs->f->upvalues;
Upvaldesc *up = fs->f->sp->upvalues;
for (i = 0; i < fs->nups; i++) {
if (eqstr(up[i].name, name)) return i;
}
@@ -225,7 +226,8 @@ static int searchupvalue (FuncState *fs, TString *name) {
static int newupvalue (FuncState *fs, TString *name, expdesc *v) {
Proto *f = fs->f;
Proto *fp = fs->f;
SharedProto *f = fp->sp;
int oldsize = f->sizeupvalues;
checklimit(fs, fs->nups + 1, MAXUPVAL, "upvalues");
luaM_growvector(fs->ls->L, f->upvalues, fs->nups, f->sizeupvalues,
@@ -234,7 +236,7 @@ static int newupvalue (FuncState *fs, TString *name, expdesc *v) {
f->upvalues[fs->nups].instack = (v->k == VLOCAL);
f->upvalues[fs->nups].idx = cast_byte(v->u.info);
f->upvalues[fs->nups].name = name;
luaC_objbarrier(fs->ls->L, f, name);
luaC_objbarrier(fs->ls->L, fp, name);
return fs->nups++;
}
@@ -496,12 +498,12 @@ static Proto *addprototype (LexState *ls) {
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(L, f->p, fs->np, f->sizep, Proto *, MAXARG_Bx, "functions");
while (oldsize < f->sizep) f->p[oldsize++] = NULL;
if (fs->np >= f->sp->sizep) {
int oldsize = f->sp->sizep;
luaM_growvector(L, f->p, fs->np, f->sp->sizep, Proto *, MAXARG_Bx, "functions");
while (oldsize < f->sp->sizep) f->p[oldsize++] = NULL;
}
f->p[fs->np++] = clp = luaF_newproto(L);
f->p[fs->np++] = clp = luaF_newproto(L, NULL);
luaC_objbarrier(L, f, clp);
return clp;
}
@@ -521,7 +523,7 @@ static void codeclosure (LexState *ls, expdesc *v) {
static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) {
Proto *f;
SharedProto *f;
fs->prev = ls->fs; /* linked list of funcstates */
fs->ls = ls;
ls->fs = fs;
@@ -536,7 +538,7 @@ static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) {
fs->nactvar = 0;
fs->firstlocal = ls->dyd->actvar.n;
fs->bl = NULL;
f = fs->f;
f = fs->f->sp;
f->source = ls->source;
f->maxstacksize = 2; /* registers 0/1 are always valid */
enterblock(fs, bl, 0);
@@ -547,20 +549,21 @@ static void close_func (LexState *ls) {
lua_State *L = ls->L;
FuncState *fs = ls->fs;
Proto *f = fs->f;
SharedProto *sp = f->sp;
luaK_ret(fs, 0, 0); /* final return */
leaveblock(fs);
luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction);
f->sizecode = fs->pc;
luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int);
f->sizelineinfo = fs->pc;
luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue);
f->sizek = fs->nk;
luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *);
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, fs->nups, Upvaldesc);
f->sizeupvalues = fs->nups;
luaM_reallocvector(L, sp->code, sp->sizecode, fs->pc, Instruction);
sp->sizecode = fs->pc;
luaM_reallocvector(L, sp->lineinfo, sp->sizelineinfo, fs->pc, int);
sp->sizelineinfo = fs->pc;
luaM_reallocvector(L, f->k, sp->sizek, fs->nk, TValue);
sp->sizek = fs->nk;
luaM_reallocvector(L, f->p, sp->sizep, fs->np, Proto *);
sp->sizep = fs->np;
luaM_reallocvector(L, sp->locvars, sp->sizelocvars, fs->nlocvars, LocVar);
sp->sizelocvars = fs->nlocvars;
luaM_reallocvector(L, sp->upvalues, sp->sizeupvalues, fs->nups, Upvaldesc);
sp->sizeupvalues = fs->nups;
lua_assert(fs->bl == NULL);
ls->fs = fs->prev;
luaC_checkGC(L);
@@ -736,8 +739,8 @@ static void constructor (LexState *ls, expdesc *t) {
} while (testnext(ls, ',') || testnext(ls, ';'));
check_match(ls, '}', '{', line);
lastlistfield(fs, &cc);
SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */
SETARG_C(fs->f->code[pc], luaO_int2fb(cc.nh)); /* set initial table size */
SETARG_B(fs->f->sp->code[pc], luaO_int2fb(cc.na)); /* set initial array size */
SETARG_C(fs->f->sp->code[pc], luaO_int2fb(cc.nh)); /* set initial table size */
}
/* }====================================================================== */
@@ -747,7 +750,7 @@ static void constructor (LexState *ls, expdesc *t) {
static void parlist (LexState *ls) {
/* parlist -> [ param { ',' param } ] */
FuncState *fs = ls->fs;
Proto *f = fs->f;
SharedProto *f = fs->f->sp;
int nparams = 0;
f->is_vararg = 0;
if (ls->t.token != ')') { /* is 'parlist' not empty? */
@@ -778,7 +781,7 @@ static void body (LexState *ls, expdesc *e, int ismethod, int line) {
FuncState new_fs;
BlockCnt bl;
new_fs.f = addprototype(ls);
new_fs.f->linedefined = line;
new_fs.f->sp->linedefined = line;
open_func(ls, &new_fs, &bl);
checknext(ls, '(');
if (ismethod) {
@@ -788,7 +791,7 @@ static void body (LexState *ls, expdesc *e, int ismethod, int line) {
parlist(ls);
checknext(ls, ')');
statlist(ls);
new_fs.f->lastlinedefined = ls->linenumber;
new_fs.f->sp->lastlinedefined = ls->linenumber;
check_match(ls, TK_END, TK_FUNCTION, line);
codeclosure(ls, e);
close_func(ls);
@@ -954,7 +957,7 @@ static void simpleexp (LexState *ls, expdesc *v) {
}
case TK_DOTS: { /* vararg */
FuncState *fs = ls->fs;
check_condition(ls, fs->f->is_vararg,
check_condition(ls, fs->f->sp->is_vararg,
"cannot use '...' outside a vararg function");
init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0));
break;
@@ -1610,7 +1613,7 @@ 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 */
fs->f->sp->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 */
@@ -1630,13 +1633,13 @@ LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
lexstate.h = luaH_new(L); /* create table for scanner */
sethvalue(L, L->top, lexstate.h); /* anchor it */
incr_top(L);
funcstate.f = cl->p = luaF_newproto(L);
funcstate.f->source = luaS_new(L, name); /* create and anchor TString */
funcstate.f = cl->p = luaF_newproto(L, NULL);
funcstate.f->sp->source = luaS_new(L, name); /* create and anchor TString */
lua_assert(iswhite(funcstate.f)); /* do not need barrier here */
lexstate.buff = buff;
lexstate.dyd = dyd;
dyd->actvar.n = dyd->gt.n = dyd->label.n = 0;
luaX_setinput(L, &lexstate, z, funcstate.f->source, firstchar);
luaX_setinput(L, &lexstate, z, funcstate.f->sp->source, firstchar);
mainfunc(&lexstate, &funcstate);
lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs);
/* all scopes should be correctly finished */