Merge remote-tracking branch 'origin/lua53' into lua53

This commit is contained in:
Cloud Wu
2015-01-22 14:40:50 +08:00
15 changed files with 246 additions and 160 deletions

View File

@@ -28,6 +28,7 @@
#include "ltm.h" #include "ltm.h"
#include "lundump.h" #include "lundump.h"
#include "lvm.h" #include "lvm.h"
#include "lfunc.h"
@@ -984,6 +985,59 @@ LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
} }
static Proto * cloneproto (lua_State *L, const Proto *src) {
/* copy constants and nested proto */
int i,n;
Proto *f = luaF_newproto(L, src->sp);
n = src->sp->sizek;
f->k=luaM_newvector(L,n,TValue);
for (i=0; i<n; i++) setnilvalue(&f->k[i]);
for (i=0; i<n; i++) {
const TValue *s=&src->k[i];
TValue *o=&f->k[i];
if (ttisstring(s)) {
TString * str = luaS_newlstr(L,svalue(s),tsvalue(s)->len);
setsvalue2n(L,o,str);
} else {
setobj(L,o,s);
}
}
n = src->sp->sizep;
f->p=luaM_newvector(L,n,struct Proto *);
for (i=0; i<n; i++) f->p[i]=NULL;
for (i=0; i<n; i++) {
f->p[i]=cloneproto(L, src->p[i]);
}
return f;
}
LUA_API void lua_clonefunction (lua_State *L, void * fp) {
LClosure *cl;
LClosure *f = cast(LClosure *, fp);
lua_lock(L);
if (f->p->sp->l_G == G(L)) {
setclLvalue(L,L->top,f);
api_incr_top(L);
lua_unlock(L);
return;
}
cl = luaF_newLclosure(L,f->nupvalues);
cl->p = cloneproto(L, f->p);
setclLvalue(L,L->top,cl);
api_incr_top(L);
luaF_initupvals(L, cl);
if (f->nupvalues >= 1) { /* does it have an upvalue? */
/* get global table from registry */
Table *reg = hvalue(&G(L)->l_registry);
const TValue *gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
/* set global table as 1st upvalue of 'f' (may be LUA_ENV) */
setobj(L, f->upvals[0]->v, gt);
luaC_upvalbarrier(L, f->upvals[0]);
}
lua_unlock(L);
}
LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data, int strip) { LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data, int strip) {
int status; int status;
TValue *o; TValue *o;
@@ -1178,7 +1232,7 @@ static const char *aux_upvalue (StkId fi, int n, TValue **val,
case LUA_TLCL: { /* Lua closure */ case LUA_TLCL: { /* Lua closure */
LClosure *f = clLvalue(fi); LClosure *f = clLvalue(fi);
TString *name; TString *name;
Proto *p = f->p; SharedProto *p = f->p->sp;
if (!(1 <= n && n <= p->sizeupvalues)) return NULL; if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
*val = f->upvals[n-1]->v; *val = f->upvals[n-1]->v;
if (uv) *uv = f->upvals[n - 1]; if (uv) *uv = f->upvals[n - 1];

View File

@@ -55,7 +55,7 @@ void luaK_nil (FuncState *fs, int from, int n) {
Instruction *previous; Instruction *previous;
int l = from + n - 1; /* last register to set nil */ int l = from + n - 1; /* last register to set nil */
if (fs->pc > fs->lasttarget) { /* no jumps to current position? */ if (fs->pc > fs->lasttarget) { /* no jumps to current position? */
previous = &fs->f->code[fs->pc-1]; previous = &fs->f->sp->code[fs->pc-1];
if (GET_OPCODE(*previous) == OP_LOADNIL) { if (GET_OPCODE(*previous) == OP_LOADNIL) {
int pfrom = GETARG_A(*previous); int pfrom = GETARG_A(*previous);
int pl = pfrom + GETARG_B(*previous); int pl = pfrom + GETARG_B(*previous);
@@ -95,7 +95,7 @@ static int condjump (FuncState *fs, OpCode op, int A, int B, int C) {
static void fixjump (FuncState *fs, int pc, int dest) { static void fixjump (FuncState *fs, int pc, int dest) {
Instruction *jmp = &fs->f->code[pc]; Instruction *jmp = &fs->f->sp->code[pc];
int offset = dest-(pc+1); int offset = dest-(pc+1);
lua_assert(dest != NO_JUMP); lua_assert(dest != NO_JUMP);
if (abs(offset) > MAXARG_sBx) if (abs(offset) > MAXARG_sBx)
@@ -115,7 +115,7 @@ int luaK_getlabel (FuncState *fs) {
static int getjump (FuncState *fs, int pc) { static int getjump (FuncState *fs, int pc) {
int offset = GETARG_sBx(fs->f->code[pc]); int offset = GETARG_sBx(fs->f->sp->code[pc]);
if (offset == NO_JUMP) /* point to itself represents end of list */ if (offset == NO_JUMP) /* point to itself represents end of list */
return NO_JUMP; /* end of list */ return NO_JUMP; /* end of list */
else else
@@ -124,7 +124,7 @@ static int getjump (FuncState *fs, int pc) {
static Instruction *getjumpcontrol (FuncState *fs, int pc) { static Instruction *getjumpcontrol (FuncState *fs, int pc) {
Instruction *pi = &fs->f->code[pc]; Instruction *pi = &fs->f->sp->code[pc];
if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1)))) if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1))))
return pi-1; return pi-1;
else else
@@ -197,10 +197,10 @@ void luaK_patchclose (FuncState *fs, int list, int level) {
level++; /* argument is +1 to reserve 0 as non-op */ level++; /* argument is +1 to reserve 0 as non-op */
while (list != NO_JUMP) { while (list != NO_JUMP) {
int next = getjump(fs, list); int next = getjump(fs, list);
lua_assert(GET_OPCODE(fs->f->code[list]) == OP_JMP && lua_assert(GET_OPCODE(fs->f->sp->code[list]) == OP_JMP &&
(GETARG_A(fs->f->code[list]) == 0 || (GETARG_A(fs->f->sp->code[list]) == 0 ||
GETARG_A(fs->f->code[list]) >= level)); GETARG_A(fs->f->sp->code[list]) >= level));
SETARG_A(fs->f->code[list], level); SETARG_A(fs->f->sp->code[list], level);
list = next; list = next;
} }
} }
@@ -230,13 +230,13 @@ static int luaK_code (FuncState *fs, Instruction i) {
Proto *f = fs->f; Proto *f = fs->f;
dischargejpc(fs); /* 'pc' will change */ dischargejpc(fs); /* 'pc' will change */
/* put new instruction in code array */ /* put new instruction in code array */
luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction, luaM_growvector(fs->ls->L, f->sp->code, fs->pc, f->sp->sizecode, Instruction,
MAX_INT, "opcodes"); MAX_INT, "opcodes");
f->code[fs->pc] = i; f->sp->code[fs->pc] = i;
/* save corresponding line information */ /* save corresponding line information */
luaM_growvector(fs->ls->L, f->lineinfo, fs->pc, f->sizelineinfo, int, luaM_growvector(fs->ls->L, f->sp->lineinfo, fs->pc, f->sp->sizelineinfo, int,
MAX_INT, "opcodes"); MAX_INT, "opcodes");
f->lineinfo[fs->pc] = fs->ls->lastline; f->sp->lineinfo[fs->pc] = fs->ls->lastline;
return fs->pc++; return fs->pc++;
} }
@@ -277,10 +277,10 @@ int luaK_codek (FuncState *fs, int reg, int k) {
void luaK_checkstack (FuncState *fs, int n) { void luaK_checkstack (FuncState *fs, int n) {
int newstack = fs->freereg + n; int newstack = fs->freereg + n;
if (newstack > fs->f->maxstacksize) { if (newstack > fs->f->sp->maxstacksize) {
if (newstack >= MAXREGS) if (newstack >= MAXREGS)
luaX_syntaxerror(fs->ls, "function or expression too complex"); luaX_syntaxerror(fs->ls, "function or expression too complex");
fs->f->maxstacksize = cast_byte(newstack); fs->f->sp->maxstacksize = cast_byte(newstack);
} }
} }
@@ -322,13 +322,13 @@ static int addk (FuncState *fs, TValue *key, TValue *v) {
return k; /* reuse index */ return k; /* reuse index */
} }
/* constant not found; create a new entry */ /* constant not found; create a new entry */
oldsize = f->sizek; oldsize = f->sp->sizek;
k = fs->nk; k = fs->nk;
/* numerical value does not need GC barrier; /* numerical value does not need GC barrier;
table has no metatable, so it does not need to invalidate cache */ table has no metatable, so it does not need to invalidate cache */
setivalue(idx, k); setivalue(idx, k);
luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants"); luaM_growvector(L, f->k, k, f->sp->sizek, TValue, MAXARG_Ax, "constants");
while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); while (oldsize < f->sp->sizek) setnilvalue(&f->k[oldsize++]);
setobj(L, &f->k[k], v); setobj(L, &f->k[k], v);
fs->nk++; fs->nk++;
luaC_barrier(L, f, v); luaC_barrier(L, f, v);
@@ -933,7 +933,7 @@ void luaK_posfix (FuncState *fs, BinOpr op,
void luaK_fixline (FuncState *fs, int line) { void luaK_fixline (FuncState *fs, int line) {
fs->f->lineinfo[fs->pc - 1] = line; fs->f->sp->lineinfo[fs->pc - 1] = line;
} }

View File

@@ -40,7 +40,7 @@ typedef enum BinOpr {
typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;
#define getcode(fs,e) ((fs)->f->code[(e)->u.info]) #define getcode(fs,e) ((fs)->f->sp->code[(e)->u.info])
#define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx) #define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx)

View File

@@ -98,14 +98,14 @@ LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
static const char *upvalname (Proto *p, int uv) { static const char *upvalname (Proto *p, int uv) {
TString *s = check_exp(uv < p->sizeupvalues, p->upvalues[uv].name); TString *s = check_exp(uv < p->sizeupvalues, p->sp->upvalues[uv].name);
if (s == NULL) return "?"; if (s == NULL) return "?";
else return getstr(s); else return getstr(s);
} }
static const char *findvararg (CallInfo *ci, int n, StkId *pos) { static const char *findvararg (CallInfo *ci, int n, StkId *pos) {
int nparams = clLvalue(ci->func)->p->numparams; int nparams = clLvalue(ci->func)->p->sp->numparams;
if (n >= ci->u.l.base - ci->func - nparams) if (n >= ci->u.l.base - ci->func - nparams)
return NULL; /* no such vararg */ return NULL; /* no such vararg */
else { else {
@@ -184,7 +184,7 @@ static void funcinfo (lua_Debug *ar, Closure *cl) {
ar->what = "C"; ar->what = "C";
} }
else { else {
Proto *p = cl->l.p; SharedProto *p = cl->l.p->sp;
ar->source = p->source ? getstr(p->source) : "=?"; ar->source = p->source ? getstr(p->source) : "=?";
ar->linedefined = p->linedefined; ar->linedefined = p->linedefined;
ar->lastlinedefined = p->lastlinedefined; ar->lastlinedefined = p->lastlinedefined;
@@ -202,12 +202,12 @@ static void collectvalidlines (lua_State *L, Closure *f) {
else { else {
int i; int i;
TValue v; TValue v;
int *lineinfo = f->l.p->lineinfo; int *lineinfo = f->l.p->sp->lineinfo;
Table *t = luaH_new(L); /* new table to store active lines */ Table *t = luaH_new(L); /* new table to store active lines */
sethvalue(L, L->top, t); /* push it on stack */ sethvalue(L, L->top, t); /* push it on stack */
api_incr_top(L); api_incr_top(L);
setbvalue(&v, 1); /* boolean 'true' to be the value of all indices */ setbvalue(&v, 1); /* boolean 'true' to be the value of all indices */
for (i = 0; i < f->l.p->sizelineinfo; i++) /* for all lines with code */ for (i = 0; i < f->l.p->sp->sizelineinfo; i++) /* for all lines with code */
luaH_setint(L, t, lineinfo[i], &v); /* table[line] = true */ luaH_setint(L, t, lineinfo[i], &v); /* table[line] = true */
} }
} }
@@ -233,8 +233,8 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
ar->nparams = 0; ar->nparams = 0;
} }
else { else {
ar->isvararg = f->l.p->is_vararg; ar->isvararg = f->l.p->sp->is_vararg;
ar->nparams = f->l.p->numparams; ar->nparams = f->l.p->sp->numparams;
} }
break; break;
} }
@@ -343,7 +343,7 @@ static int findsetreg (Proto *p, int lastpc, int reg) {
int setreg = -1; /* keep last instruction that changed 'reg' */ int setreg = -1; /* keep last instruction that changed 'reg' */
int jmptarget = 0; /* any code before this address is conditional */ int jmptarget = 0; /* any code before this address is conditional */
for (pc = 0; pc < lastpc; pc++) { for (pc = 0; pc < lastpc; pc++) {
Instruction i = p->code[pc]; Instruction i = p->sp->code[pc];
OpCode op = GET_OPCODE(i); OpCode op = GET_OPCODE(i);
int a = GETARG_A(i); int a = GETARG_A(i);
switch (op) { switch (op) {
@@ -393,7 +393,7 @@ static const char *getobjname (Proto *p, int lastpc, int reg,
/* else try symbolic execution */ /* else try symbolic execution */
pc = findsetreg(p, lastpc, reg); pc = findsetreg(p, lastpc, reg);
if (pc != -1) { /* could find instruction? */ if (pc != -1) { /* could find instruction? */
Instruction i = p->code[pc]; Instruction i = p->sp->code[pc];
OpCode op = GET_OPCODE(i); OpCode op = GET_OPCODE(i);
switch (op) { switch (op) {
case OP_MOVE: { case OP_MOVE: {
@@ -419,7 +419,7 @@ static const char *getobjname (Proto *p, int lastpc, int reg,
case OP_LOADK: case OP_LOADK:
case OP_LOADKX: { case OP_LOADKX: {
int b = (op == OP_LOADK) ? GETARG_Bx(i) int b = (op == OP_LOADK) ? GETARG_Bx(i)
: GETARG_Ax(p->code[pc + 1]); : GETARG_Ax(p->sp->code[pc + 1]);
if (ttisstring(&p->k[b])) { if (ttisstring(&p->k[b])) {
*name = svalue(&p->k[b]); *name = svalue(&p->k[b]);
return "constant"; return "constant";
@@ -442,7 +442,7 @@ static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
TMS tm = (TMS)0; /* to avoid warnings */ TMS tm = (TMS)0; /* to avoid warnings */
Proto *p = ci_func(ci)->p; /* calling function */ Proto *p = ci_func(ci)->p; /* calling function */
int pc = currentpc(ci); /* calling instruction index */ int pc = currentpc(ci); /* calling instruction index */
Instruction i = p->code[pc]; /* calling instruction */ Instruction i = p->sp->code[pc]; /* calling instruction */
if (ci->callstatus & CIST_HOOKED) { /* was it called inside a hook? */ if (ci->callstatus & CIST_HOOKED) { /* was it called inside a hook? */
*name = "?"; *name = "?";
return "hook"; return "hook";
@@ -577,7 +577,7 @@ static void addinfo (lua_State *L, const char *msg) {
if (isLua(ci)) { /* is Lua code? */ if (isLua(ci)) { /* is Lua code? */
char buff[LUA_IDSIZE]; /* add file:line information */ char buff[LUA_IDSIZE]; /* add file:line information */
int line = currentline(ci); int line = currentline(ci);
TString *src = ci_func(ci)->p->source; TString *src = ci_func(ci)->p->sp->source;
if (src) if (src)
luaO_chunkid(buff, getstr(src), LUA_IDSIZE); luaO_chunkid(buff, getstr(src), LUA_IDSIZE);
else { /* no source available; use "?" instead */ else { /* no source available; use "?" instead */

View File

@@ -11,9 +11,9 @@
#include "lstate.h" #include "lstate.h"
#define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1) #define pcRel(pc, p) (cast(int, (pc) - (p)->sp->code) - 1)
#define getfuncline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : -1) #define getfuncline(f,pc) (((f)->sp->lineinfo) ? (f)->sp->lineinfo[pc] : -1)
#define resethookcount(L) (L->hookcount = L->basehookcount) #define resethookcount(L) (L->hookcount = L->basehookcount)

View File

@@ -269,7 +269,7 @@ static void callhook (lua_State *L, CallInfo *ci) {
} }
static StkId adjust_varargs (lua_State *L, Proto *p, int actual) { static StkId adjust_varargs (lua_State *L, SharedProto *p, int actual) {
int i; int i;
int nfixargs = p->numparams; int nfixargs = p->numparams;
StkId base, fixed; StkId base, fixed;
@@ -342,7 +342,7 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
} }
case LUA_TLCL: { /* Lua function: prepare its call */ case LUA_TLCL: { /* Lua function: prepare its call */
StkId base; StkId base;
Proto *p = clLvalue(func)->p; SharedProto *p = clLvalue(func)->p->sp;
n = cast_int(L->top - func) - 1; /* number of real arguments */ n = cast_int(L->top - func) - 1; /* number of real arguments */
luaD_checkstack(L, p->maxstacksize); luaD_checkstack(L, p->maxstacksize);
for (; n < p->numparams; n++) for (; n < p->numparams; n++)

View File

@@ -86,7 +86,7 @@ static void DumpString (const TString *s, DumpState *D) {
} }
static void DumpCode (const Proto *f, DumpState *D) { static void DumpCode (const SharedProto *f, DumpState *D) {
DumpInt(f->sizecode, D); DumpInt(f->sizecode, D);
DumpVector(f->code, f->sizecode, D); DumpVector(f->code, f->sizecode, D);
} }
@@ -96,7 +96,7 @@ static void DumpFunction(const Proto *f, TString *psource, DumpState *D);
static void DumpConstants (const Proto *f, DumpState *D) { static void DumpConstants (const Proto *f, DumpState *D) {
int i; int i;
int n = f->sizek; int n = f->sp->sizek;
DumpInt(n, D); DumpInt(n, D);
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
const TValue *o = &f->k[i]; const TValue *o = &f->k[i];
@@ -126,14 +126,14 @@ static void DumpConstants (const Proto *f, DumpState *D) {
static void DumpProtos (const Proto *f, DumpState *D) { static void DumpProtos (const Proto *f, DumpState *D) {
int i; int i;
int n = f->sizep; int n = f->sp->sizep;
DumpInt(n, D); DumpInt(n, D);
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
DumpFunction(f->p[i], f->source, D); DumpFunction(f->p[i], f->sp->source, D);
} }
static void DumpUpvalues (const Proto *f, DumpState *D) { static void DumpUpvalues (const SharedProto *f, DumpState *D) {
int i, n = f->sizeupvalues; int i, n = f->sizeupvalues;
DumpInt(n, D); DumpInt(n, D);
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
@@ -143,7 +143,7 @@ static void DumpUpvalues (const Proto *f, DumpState *D) {
} }
static void DumpDebug (const Proto *f, DumpState *D) { static void DumpDebug (const SharedProto *f, DumpState *D) {
int i, n; int i, n;
n = (D->strip) ? 0 : f->sizelineinfo; n = (D->strip) ? 0 : f->sizelineinfo;
DumpInt(n, D); DumpInt(n, D);
@@ -162,7 +162,8 @@ static void DumpDebug (const Proto *f, DumpState *D) {
} }
static void DumpFunction (const Proto *f, TString *psource, DumpState *D) { static void DumpFunction (const Proto *fp, TString *psource, DumpState *D) {
const SharedProto *f = fp->sp;
if (D->strip || f->source == psource) if (D->strip || f->source == psource)
DumpString(NULL, D); /* no debug info or same source as its parent */ DumpString(NULL, D); /* no debug info or same source as its parent */
else else
@@ -173,9 +174,9 @@ static void DumpFunction (const Proto *f, TString *psource, DumpState *D) {
DumpByte(f->is_vararg, D); DumpByte(f->is_vararg, D);
DumpByte(f->maxstacksize, D); DumpByte(f->maxstacksize, D);
DumpCode(f, D); DumpCode(f, D);
DumpConstants(f, D); DumpConstants(fp, D);
DumpUpvalues(f, D); DumpUpvalues(f, D);
DumpProtos(f, D); DumpProtos(fp, D);
DumpDebug(f, D); DumpDebug(f, D);
} }
@@ -207,7 +208,7 @@ int luaU_dump(lua_State *L, const Proto *f, lua_Writer w, void *data,
D.strip = strip; D.strip = strip;
D.status = 0; D.status = 0;
DumpHeader(&D); DumpHeader(&D);
DumpByte(f->sizeupvalues, &D); DumpByte(f->sp->sizeupvalues, &D);
DumpFunction(f, NULL, &D); DumpFunction(f, NULL, &D);
return D.status; return D.status;
} }

View File

@@ -96,39 +96,52 @@ void luaF_close (lua_State *L, StkId level) {
} }
Proto *luaF_newproto (lua_State *L) { Proto *luaF_newproto (lua_State *L, SharedProto *sp) {
GCObject *o = luaC_newobj(L, LUA_TPROTO, sizeof(Proto)); GCObject *o = luaC_newobj(L, LUA_TPROTO, sizeof(Proto));
Proto *f = gco2p(o); Proto *f = gco2p(o);
f->sp = NULL;
f->k = NULL; f->k = NULL;
f->sizek = 0;
f->p = NULL; f->p = NULL;
f->sizep = 0;
f->code = NULL;
f->cache = NULL; f->cache = NULL;
f->sizecode = 0; if (sp == NULL) {
f->lineinfo = NULL; sp = luaM_new(L, SharedProto);
f->sizelineinfo = 0; sp->l_G = G(L);
f->upvalues = NULL; sp->sizek = 0;
f->sizeupvalues = 0; sp->sizep = 0;
f->numparams = 0; sp->code = NULL;
f->is_vararg = 0; sp->sizecode = 0;
f->maxstacksize = 0; sp->lineinfo = NULL;
f->locvars = NULL; sp->sizelineinfo = 0;
f->sizelocvars = 0; sp->upvalues = NULL;
f->linedefined = 0; sp->sizeupvalues = 0;
f->lastlinedefined = 0; sp->numparams = 0;
f->source = NULL; sp->is_vararg = 0;
sp->maxstacksize = 0;
sp->locvars = NULL;
sp->sizelocvars = 0;
sp->linedefined = 0;
sp->lastlinedefined = 0;
sp->source = NULL;
}
f->sp = sp;
return f; return f;
} }
static void freesharedproto (lua_State *L, SharedProto *f) {
if (f == NULL || G(L) != f->l_G)
return;
luaM_freearray(L, f->code, f->sizecode);
luaM_freearray(L, f->lineinfo, f->sizelineinfo);
luaM_freearray(L, f->locvars, f->sizelocvars);
luaM_freearray(L, f->upvalues, f->sizeupvalues);
luaM_free(L, f);
}
void luaF_freeproto (lua_State *L, Proto *f) { void luaF_freeproto (lua_State *L, Proto *f) {
luaM_freearray(L, f->code, f->sizecode); luaM_freearray(L, f->p, f->sp->sizep);
luaM_freearray(L, f->p, f->sizep); luaM_freearray(L, f->k, f->sp->sizek);
luaM_freearray(L, f->k, f->sizek); freesharedproto(L, f->sp);
luaM_freearray(L, f->lineinfo, f->sizelineinfo);
luaM_freearray(L, f->locvars, f->sizelocvars);
luaM_freearray(L, f->upvalues, f->sizeupvalues);
luaM_free(L, f); luaM_free(L, f);
} }
@@ -137,8 +150,9 @@ void luaF_freeproto (lua_State *L, Proto *f) {
** Look for n-th local variable at line 'line' in function 'func'. ** Look for n-th local variable at line 'line' in function 'func'.
** Returns NULL if not found. ** Returns NULL if not found.
*/ */
const char *luaF_getlocalname (const Proto *f, int local_number, int pc) { const char *luaF_getlocalname (const Proto *fp, int local_number, int pc) {
int i; int i;
const SharedProto *f = fp->sp;
for (i = 0; i<f->sizelocvars && f->locvars[i].startpc <= pc; i++) { for (i = 0; i<f->sizelocvars && f->locvars[i].startpc <= pc; i++) {
if (pc < f->locvars[i].endpc) { /* is variable active? */ if (pc < f->locvars[i].endpc) { /* is variable active? */
local_number--; local_number--;

View File

@@ -40,7 +40,7 @@ struct UpVal {
#define upisopen(up) ((up)->v != &(up)->u.value) #define upisopen(up) ((up)->v != &(up)->u.value)
LUAI_FUNC Proto *luaF_newproto (lua_State *L); LUAI_FUNC Proto *luaF_newproto (lua_State *L, SharedProto *sp);
LUAI_FUNC CClosure *luaF_newCclosure (lua_State *L, int nelems); LUAI_FUNC CClosure *luaF_newCclosure (lua_State *L, int nelems);
LUAI_FUNC LClosure *luaF_newLclosure (lua_State *L, int nelems); LUAI_FUNC LClosure *luaF_newLclosure (lua_State *L, int nelems);
LUAI_FUNC void luaF_initupvals (lua_State *L, LClosure *cl); LUAI_FUNC void luaF_initupvals (lua_State *L, LClosure *cl);

View File

@@ -456,26 +456,32 @@ static lu_mem traversetable (global_State *g, Table *h) {
sizeof(Node) * cast(size_t, sizenode(h)); sizeof(Node) * cast(size_t, sizenode(h));
} }
static int marksharedproto (global_State *g, SharedProto *f) {
int i;
if (g != f->l_G)
return 0;
markobject(g, f->source);
for (i = 0; i < f->sizeupvalues; i++) /* mark upvalue names */
markobject(g, f->upvalues[i].name);
for (i = 0; i < f->sizelocvars; i++) /* mark local-variable names */
markobject(g, f->locvars[i].varname);
return sizeof(Instruction) * f->sizecode +
sizeof(int) * f->sizelineinfo +
sizeof(LocVar) * f->sizelocvars +
sizeof(Upvaldesc) * f->sizeupvalues;
}
static int traverseproto (global_State *g, Proto *f) { static int traverseproto (global_State *g, Proto *f) {
int i; int i;
if (f->cache && iswhite(f->cache)) if (f->cache && iswhite(f->cache))
f->cache = NULL; /* allow cache to be collected */ f->cache = NULL; /* allow cache to be collected */
markobject(g, f->source); for (i = 0; i < f->sp->sizek; i++) /* mark literals */
for (i = 0; i < f->sizek; i++) /* mark literals */
markvalue(g, &f->k[i]); markvalue(g, &f->k[i]);
for (i = 0; i < f->sizeupvalues; i++) /* mark upvalue names */ for (i = 0; i < f->sp->sizep; i++) /* mark nested protos */
markobject(g, f->upvalues[i].name);
for (i = 0; i < f->sizep; i++) /* mark nested protos */
markobject(g, f->p[i]); markobject(g, f->p[i]);
for (i = 0; i < f->sizelocvars; i++) /* mark local-variable names */ return sizeof(Proto) + sizeof(Proto *) * f->sp->sizep +
markobject(g, f->locvars[i].varname); sizeof(TValue) * f->sp->sizek +
return sizeof(Proto) + sizeof(Instruction) * f->sizecode + marksharedproto(g, f->sp);
sizeof(Proto *) * f->sizep +
sizeof(TValue) * f->sizek +
sizeof(int) * f->sizelineinfo +
sizeof(LocVar) * f->sizelocvars +
sizeof(Upvaldesc) * f->sizeupvalues;
} }

View File

@@ -392,11 +392,7 @@ typedef struct LocVar {
} LocVar; } LocVar;
/* typedef struct SharedProto {
** Function Prototypes
*/
typedef struct Proto {
CommonHeader;
lu_byte numparams; /* number of fixed parameters */ lu_byte numparams; /* number of fixed parameters */
lu_byte is_vararg; lu_byte is_vararg;
lu_byte maxstacksize; /* maximum stack used by this function */ lu_byte maxstacksize; /* maximum stack used by this function */
@@ -408,14 +404,23 @@ typedef struct Proto {
int sizelocvars; int sizelocvars;
int linedefined; int linedefined;
int lastlinedefined; int lastlinedefined;
TValue *k; /* constants used by the function */ void *l_G; /* global state belongs to */
Instruction *code; Instruction *code;
struct Proto **p; /* functions defined inside the function */
int *lineinfo; /* map from opcodes to source lines (debug information) */ int *lineinfo; /* map from opcodes to source lines (debug information) */
LocVar *locvars; /* information about local variables (debug information) */ LocVar *locvars; /* information about local variables (debug information) */
Upvaldesc *upvalues; /* upvalue information */ Upvaldesc *upvalues; /* upvalue information */
struct LClosure *cache; /* last created closure with this prototype */
TString *source; /* used for debug information */ TString *source; /* used for debug information */
} SharedProto;
/*
** Function Prototypes
*/
typedef struct Proto {
CommonHeader;
struct SharedProto *sp;
TValue *k; /* constants used by the function */
struct Proto **p; /* functions defined inside the function */
struct LClosure *cache; /* last created closure with this prototype */
GCObject *gclist; GCObject *gclist;
} Proto; } Proto;

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

View File

@@ -149,9 +149,9 @@ static const Proto* combine(lua_State* L, int n)
for (i=0; i<n; i++) for (i=0; i<n; i++)
{ {
f->p[i]=toproto(L,i-n-1); f->p[i]=toproto(L,i-n-1);
if (f->p[i]->sizeupvalues>0) f->p[i]->upvalues[0].instack=0; if (f->p[i]->sp->sizeupvalues>0) f->p[i]->sp->upvalues[0].instack=0;
} }
f->sizelineinfo=0; f->sp->sizelineinfo=0;
return f; return f;
} }
} }
@@ -282,13 +282,14 @@ static void PrintConstant(const Proto* f, int i)
} }
} }
#define UPVALNAME(x) ((f->upvalues[x].name) ? getstr(f->upvalues[x].name) : "-") #define UPVALNAME(x) ((f->sp->upvalues[x].name) ? getstr(f->sp->upvalues[x].name) : "-")
#define MYK(x) (-1-(x)) #define MYK(x) (-1-(x))
static void PrintCode(const Proto* f) static void PrintCode(const Proto* f)
{ {
const Instruction* code=f->code; const SharedProto *sp = f->sp;
int pc,n=f->sizecode; const Instruction* code=sp->code;
int pc,n=sp->sizecode;
for (pc=0; pc<n; pc++) for (pc=0; pc<n; pc++)
{ {
Instruction i=code[pc]; Instruction i=code[pc];
@@ -392,7 +393,7 @@ static void PrintCode(const Proto* f)
#define SS(x) ((x==1)?"":"s") #define SS(x) ((x==1)?"":"s")
#define S(x) (int)(x),SS(x) #define S(x) (int)(x),SS(x)
static void PrintHeader(const Proto* f) static void PrintHeader(const SharedProto* f)
{ {
const char* s=f->source ? getstr(f->source) : "=?"; const char* s=f->source ? getstr(f->source) : "=?";
if (*s=='@' || *s=='=') if (*s=='@' || *s=='=')
@@ -414,8 +415,9 @@ static void PrintHeader(const Proto* f)
static void PrintDebug(const Proto* f) static void PrintDebug(const Proto* f)
{ {
const SharedProto *sp = f->sp;
int i,n; int i,n;
n=f->sizek; n=sp->sizek;
printf("constants (%d) for %p:\n",n,VOID(f)); printf("constants (%d) for %p:\n",n,VOID(f));
for (i=0; i<n; i++) for (i=0; i<n; i++)
{ {
@@ -423,26 +425,26 @@ static void PrintDebug(const Proto* f)
PrintConstant(f,i); PrintConstant(f,i);
printf("\n"); printf("\n");
} }
n=f->sizelocvars; n=sp->sizelocvars;
printf("locals (%d) for %p:\n",n,VOID(f)); printf("locals (%d) for %p:\n",n,VOID(f));
for (i=0; i<n; i++) for (i=0; i<n; i++)
{ {
printf("\t%d\t%s\t%d\t%d\n", printf("\t%d\t%s\t%d\t%d\n",
i,getstr(f->locvars[i].varname),f->locvars[i].startpc+1,f->locvars[i].endpc+1); i,getstr(sp->locvars[i].varname),sp->locvars[i].startpc+1,sp->locvars[i].endpc+1);
} }
n=f->sizeupvalues; n=f->sp->sizeupvalues;
printf("upvalues (%d) for %p:\n",n,VOID(f)); printf("upvalues (%d) for %p:\n",n,VOID(f));
for (i=0; i<n; i++) for (i=0; i<n; i++)
{ {
printf("\t%d\t%s\t%d\t%d\n", printf("\t%d\t%s\t%d\t%d\n",
i,UPVALNAME(i),f->upvalues[i].instack,f->upvalues[i].idx); i,UPVALNAME(i),sp->upvalues[i].instack,sp->upvalues[i].idx);
} }
} }
static void PrintFunction(const Proto* f, int full) static void PrintFunction(const Proto* f, int full)
{ {
int i,n=f->sizep; int i,n=f->sp->sizep;
PrintHeader(f); PrintHeader(f->sp);
PrintCode(f); PrintCode(f);
if (full) PrintDebug(f); if (full) PrintDebug(f);
for (i=0; i<n; i++) PrintFunction(f->p[i],full); for (i=0; i<n; i++) PrintFunction(f->p[i],full);

View File

@@ -100,7 +100,7 @@ static TString *LoadString (LoadState *S) {
} }
static void LoadCode (LoadState *S, Proto *f) { static void LoadCode (LoadState *S, SharedProto *f) {
int n = LoadInt(S); int n = LoadInt(S);
f->code = luaM_newvector(S->L, n, Instruction); f->code = luaM_newvector(S->L, n, Instruction);
f->sizecode = n; f->sizecode = n;
@@ -115,7 +115,7 @@ static void LoadConstants (LoadState *S, Proto *f) {
int i; int i;
int n = LoadInt(S); int n = LoadInt(S);
f->k = luaM_newvector(S->L, n, TValue); f->k = luaM_newvector(S->L, n, TValue);
f->sizek = n; f->sp->sizek = n;
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
setnilvalue(&f->k[i]); setnilvalue(&f->k[i]);
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
@@ -149,17 +149,17 @@ static void LoadProtos (LoadState *S, Proto *f) {
int i; int i;
int n = LoadInt(S); int n = LoadInt(S);
f->p = luaM_newvector(S->L, n, Proto *); f->p = luaM_newvector(S->L, n, Proto *);
f->sizep = n; f->sp->sizep = n;
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
f->p[i] = NULL; f->p[i] = NULL;
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
f->p[i] = luaF_newproto(S->L); f->p[i] = luaF_newproto(S->L, NULL);
LoadFunction(S, f->p[i], f->source); LoadFunction(S, f->p[i], f->sp->source);
} }
} }
static void LoadUpvalues (LoadState *S, Proto *f) { static void LoadUpvalues (LoadState *S, SharedProto *f) {
int i, n; int i, n;
n = LoadInt(S); n = LoadInt(S);
f->upvalues = luaM_newvector(S->L, n, Upvaldesc); f->upvalues = luaM_newvector(S->L, n, Upvaldesc);
@@ -173,7 +173,7 @@ static void LoadUpvalues (LoadState *S, Proto *f) {
} }
static void LoadDebug (LoadState *S, Proto *f) { static void LoadDebug (LoadState *S, SharedProto *f) {
int i, n; int i, n;
n = LoadInt(S); n = LoadInt(S);
f->lineinfo = luaM_newvector(S->L, n, int); f->lineinfo = luaM_newvector(S->L, n, int);
@@ -195,7 +195,8 @@ static void LoadDebug (LoadState *S, Proto *f) {
} }
static void LoadFunction (LoadState *S, Proto *f, TString *psource) { static void LoadFunction (LoadState *S, Proto *fp, TString *psource) {
SharedProto *f = fp->sp;
f->source = LoadString(S); f->source = LoadString(S);
if (f->source == NULL) /* no source in dump? */ if (f->source == NULL) /* no source in dump? */
f->source = psource; /* reuse parent's source */ f->source = psource; /* reuse parent's source */
@@ -205,9 +206,9 @@ static void LoadFunction (LoadState *S, Proto *f, TString *psource) {
f->is_vararg = LoadByte(S); f->is_vararg = LoadByte(S);
f->maxstacksize = LoadByte(S); f->maxstacksize = LoadByte(S);
LoadCode(S, f); LoadCode(S, f);
LoadConstants(S, f); LoadConstants(S, fp);
LoadUpvalues(S, f); LoadUpvalues(S, f);
LoadProtos(S, f); LoadProtos(S, fp);
LoadDebug(S, f); LoadDebug(S, f);
} }
@@ -268,7 +269,7 @@ LClosure *luaU_undump(lua_State *L, ZIO *Z, Mbuffer *buff,
cl = luaF_newLclosure(L, LoadByte(&S)); cl = luaF_newLclosure(L, LoadByte(&S));
setclLvalue(L, L->top, cl); setclLvalue(L, L->top, cl);
incr_top(L); incr_top(L);
cl->p = luaF_newproto(L); cl->p = luaF_newproto(L, NULL);
LoadFunction(&S, cl->p, NULL); LoadFunction(&S, cl->p, NULL);
lua_assert(cl->nupvalues == cl->p->sizeupvalues); lua_assert(cl->nupvalues == cl->p->sizeupvalues);
luai_verifycode(L, buff, cl->p); luai_verifycode(L, buff, cl->p);

View File

@@ -493,8 +493,8 @@ lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y) {
static LClosure *getcached (Proto *p, UpVal **encup, StkId base) { static LClosure *getcached (Proto *p, UpVal **encup, StkId base) {
LClosure *c = p->cache; LClosure *c = p->cache;
if (c != NULL) { /* is there a cached closure? */ if (c != NULL) { /* is there a cached closure? */
int nup = p->sizeupvalues; int nup = p->sp->sizeupvalues;
Upvaldesc *uv = p->upvalues; Upvaldesc *uv = p->sp->upvalues;
int i; int i;
for (i = 0; i < nup; i++) { /* check whether it has right upvalues */ for (i = 0; i < nup; i++) { /* check whether it has right upvalues */
TValue *v = uv[i].instack ? base + uv[i].idx : encup[uv[i].idx]->v; TValue *v = uv[i].instack ? base + uv[i].idx : encup[uv[i].idx]->v;
@@ -514,8 +514,8 @@ static LClosure *getcached (Proto *p, UpVal **encup, StkId base) {
*/ */
static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base, static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base,
StkId ra) { StkId ra) {
int nup = p->sizeupvalues; int nup = p->sp->sizeupvalues;
Upvaldesc *uv = p->upvalues; Upvaldesc *uv = p->sp->upvalues;
int i; int i;
LClosure *ncl = luaF_newLclosure(L, nup); LClosure *ncl = luaF_newLclosure(L, nup);
ncl->p = p; ncl->p = p;
@@ -1012,10 +1012,10 @@ void luaV_execute (lua_State *L) {
StkId nfunc = nci->func; /* called function */ StkId nfunc = nci->func; /* called function */
StkId ofunc = oci->func; /* caller function */ StkId ofunc = oci->func; /* caller function */
/* last stack slot filled by 'precall' */ /* last stack slot filled by 'precall' */
StkId lim = nci->u.l.base + getproto(nfunc)->numparams; StkId lim = nci->u.l.base + getproto(nfunc)->sp->numparams;
int aux; int aux;
/* close all upvalues from previous call */ /* close all upvalues from previous call */
if (cl->p->sizep > 0) luaF_close(L, oci->u.l.base); if (cl->p->sp->sizep > 0) luaF_close(L, oci->u.l.base);
/* move new frame into old one */ /* move new frame into old one */
for (aux = 0; nfunc + aux < lim; aux++) for (aux = 0; nfunc + aux < lim; aux++)
setobjs2s(L, ofunc + aux, nfunc + aux); setobjs2s(L, ofunc + aux, nfunc + aux);
@@ -1032,7 +1032,7 @@ void luaV_execute (lua_State *L) {
vmcase(OP_RETURN) { vmcase(OP_RETURN) {
int b = GETARG_B(i); int b = GETARG_B(i);
if (b != 0) L->top = ra+b-1; if (b != 0) L->top = ra+b-1;
if (cl->p->sizep > 0) luaF_close(L, base); if (cl->p->sp->sizep > 0) luaF_close(L, base);
b = luaD_poscall(L, ra); b = luaD_poscall(L, ra);
if (!(ci->callstatus & CIST_REENTRY)) /* 'ci' still the called one */ if (!(ci->callstatus & CIST_REENTRY)) /* 'ci' still the called one */
return; /* external invocation: return */ return; /* external invocation: return */
@@ -1153,7 +1153,7 @@ void luaV_execute (lua_State *L) {
vmcase(OP_VARARG) { vmcase(OP_VARARG) {
int b = GETARG_B(i) - 1; int b = GETARG_B(i) - 1;
int j; int j;
int n = cast_int(base - ci->func) - cl->p->numparams - 1; int n = cast_int(base - ci->func) - cl->p->sp->numparams - 1;
if (b < 0) { /* B == 0? */ if (b < 0) { /* B == 0? */
b = n; /* get all var. arguments */ b = n; /* get all var. arguments */
Protect(luaD_checkstack(L, n)); Protect(luaD_checkstack(L, n));