Instantly share code, notes, and snippets.
Created
March 20, 2014 03:52
-
Star
(4)
4
You must be signed in to star a gist -
Fork
(0)
0
You must be signed in to fork a gist
-
Save cloudwu/9656839 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/lapi.c b/src/lapi.c | |
index d011431..a4fce7f 100644 | |
--- a/src/lapi.c | |
+++ b/src/lapi.c | |
@@ -993,6 +993,63 @@ LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data, | |
return status; | |
} | |
+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, const void * fp) { | |
+ int i; | |
+ Closure *cl; | |
+ const LClosure *f = cast(const 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->l.p = cloneproto(L, f->p); | |
+ setclLvalue(L,L->top,cl); | |
+ api_incr_top(L); | |
+ 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); | |
+ } | |
+ if (f->nupvalues == 1) { /* does it have one 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 'cl' (may be LUA_ENV) */ | |
+ setobj(L, cl->l.upvals[0]->v, gt); | |
+ luaC_barrier(L, cl->l.upvals[0], gt); | |
+ } | |
+ lua_unlock(L); | |
+} | |
LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) { | |
int status; | |
@@ -1198,7 +1255,7 @@ static const char *aux_upvalue (StkId fi, int n, TValue **val, | |
case LUA_TLCL: { /* Lua closure */ | |
LClosure *f = clLvalue(fi); | |
TString *name; | |
- Proto *p = f->p; | |
+ SharedProto *p = f->p->sp; | |
if (!(1 <= n && n <= p->sizeupvalues)) return NULL; | |
*val = f->upvals[n-1]->v; | |
if (owner) *owner = obj2gco(f->upvals[n - 1]); | |
diff --git a/src/lcode.c b/src/lcode.c | |
index 820b95c..5ba570e 100644 | |
--- a/src/lcode.c | |
+++ b/src/lcode.c | |
@@ -38,7 +38,7 @@ void luaK_nil (FuncState *fs, int from, int n) { | |
Instruction *previous; | |
int l = from + n - 1; /* last register to set nil */ | |
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) { | |
int pfrom = GETARG_A(*previous); | |
int pl = pfrom + GETARG_B(*previous); | |
@@ -78,7 +78,7 @@ static int condjump (FuncState *fs, OpCode op, int A, int B, int C) { | |
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); | |
lua_assert(dest != NO_JUMP); | |
if (abs(offset) > MAXARG_sBx) | |
@@ -98,7 +98,7 @@ int luaK_getlabel (FuncState *fs) { | |
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 */ | |
return NO_JUMP; /* end of list */ | |
else | |
@@ -107,7 +107,7 @@ static int getjump (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)))) | |
return pi-1; | |
else | |
@@ -180,10 +180,10 @@ LUAI_FUNC void luaK_patchclose (FuncState *fs, int list, int level) { | |
level++; /* argument is +1 to reserve 0 as non-op */ | |
while (list != NO_JUMP) { | |
int next = getjump(fs, list); | |
- lua_assert(GET_OPCODE(fs->f->code[list]) == OP_JMP && | |
- (GETARG_A(fs->f->code[list]) == 0 || | |
- GETARG_A(fs->f->code[list]) >= level)); | |
- SETARG_A(fs->f->code[list], level); | |
+ lua_assert(GET_OPCODE(fs->f->sp->code[list]) == OP_JMP && | |
+ (GETARG_A(fs->f->sp->code[list]) == 0 || | |
+ GETARG_A(fs->f->sp->code[list]) >= level)); | |
+ SETARG_A(fs->f->sp->code[list], level); | |
list = next; | |
} | |
} | |
@@ -210,7 +210,7 @@ void luaK_concat (FuncState *fs, int *l1, int l2) { | |
static int luaK_code (FuncState *fs, Instruction i) { | |
- Proto *f = fs->f; | |
+ SharedProto *f = fs->f->sp; | |
dischargejpc(fs); /* `pc' will change */ | |
/* put new instruction in code array */ | |
luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction, | |
@@ -260,10 +260,10 @@ int luaK_codek (FuncState *fs, int reg, int k) { | |
void luaK_checkstack (FuncState *fs, int n) { | |
int newstack = fs->freereg + n; | |
- if (newstack > fs->f->maxstacksize) { | |
+ if (newstack > fs->f->sp->maxstacksize) { | |
if (newstack >= MAXSTACK) | |
luaX_syntaxerror(fs->ls, "function or expression too complex"); | |
- fs->f->maxstacksize = cast_byte(newstack); | |
+ fs->f->sp->maxstacksize = cast_byte(newstack); | |
} | |
} | |
@@ -302,13 +302,13 @@ static int addk (FuncState *fs, TValue *key, TValue *v) { | |
go through and create a new entry for this value */ | |
} | |
/* constant not found; create a new entry */ | |
- oldsize = f->sizek; | |
+ oldsize = f->sp->sizek; | |
k = fs->nk; | |
/* numerical value does not need GC barrier; | |
table has no metatable, so it does not need to invalidate cache */ | |
setnvalue(idx, cast_num(k)); | |
- luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants"); | |
- while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); | |
+ luaM_growvector(L, f->k, k, f->sp->sizek, TValue, MAXARG_Ax, "constants"); | |
+ while (oldsize < f->sp->sizek) setnilvalue(&f->k[oldsize++]); | |
setobj(L, &f->k[k], v); | |
fs->nk++; | |
luaC_barrier(L, f, v); | |
@@ -860,7 +860,7 @@ void luaK_posfix (FuncState *fs, BinOpr op, | |
void luaK_fixline (FuncState *fs, int line) { | |
- fs->f->lineinfo[fs->pc - 1] = line; | |
+ fs->f->sp->lineinfo[fs->pc - 1] = line; | |
} | |
diff --git a/src/lcode.h b/src/lcode.h | |
index 6a1424c..5a8e0b8 100644 | |
--- a/src/lcode.h | |
+++ b/src/lcode.h | |
@@ -36,7 +36,7 @@ typedef enum BinOpr { | |
typedef enum UnOpr { OPR_MINUS, 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) | |
diff --git a/src/ldebug.c b/src/ldebug.c | |
index 20d663e..9097f67 100644 | |
--- a/src/ldebug.c | |
+++ b/src/ldebug.c | |
@@ -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) { | |
- TString *s = check_exp(uv < p->sizeupvalues, p->upvalues[uv].name); | |
+ TString *s = check_exp(uv < p->sp->sizeupvalues, p->sp->upvalues[uv].name); | |
if (s == NULL) return "?"; | |
else return getstr(s); | |
} | |
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) | |
return NULL; /* no such vararg */ | |
else { | |
@@ -183,7 +183,7 @@ static void funcinfo (lua_Debug *ar, Closure *cl) { | |
ar->what = "C"; | |
} | |
else { | |
- Proto *p = cl->l.p; | |
+ SharedProto *p = cl->l.p->sp; | |
ar->source = p->source ? getstr(p->source) : "=?"; | |
ar->linedefined = p->linedefined; | |
ar->lastlinedefined = p->lastlinedefined; | |
@@ -201,12 +201,12 @@ static void collectvalidlines (lua_State *L, Closure *f) { | |
else { | |
int i; | |
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 */ | |
sethvalue(L, L->top, t); /* push it on stack */ | |
api_incr_top(L); | |
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 */ | |
} | |
} | |
@@ -232,8 +232,8 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, | |
ar->nparams = 0; | |
} | |
else { | |
- ar->isvararg = f->l.p->is_vararg; | |
- ar->nparams = f->l.p->numparams; | |
+ ar->isvararg = f->l.p->sp->is_vararg; | |
+ ar->nparams = f->l.p->sp->numparams; | |
} | |
break; | |
} | |
@@ -342,7 +342,7 @@ static int findsetreg (Proto *p, int lastpc, int reg) { | |
int setreg = -1; /* keep last instruction that changed 'reg' */ | |
int jmptarget = 0; /* any code before this address is conditional */ | |
for (pc = 0; pc < lastpc; pc++) { | |
- Instruction i = p->code[pc]; | |
+ Instruction i = p->sp->code[pc]; | |
OpCode op = GET_OPCODE(i); | |
int a = GETARG_A(i); | |
switch (op) { | |
@@ -397,7 +397,7 @@ static const char *getobjname (Proto *p, int lastpc, int reg, | |
/* else try symbolic execution */ | |
pc = findsetreg(p, lastpc, reg); | |
if (pc != -1) { /* could find instruction? */ | |
- Instruction i = p->code[pc]; | |
+ Instruction i = p->sp->code[pc]; | |
OpCode op = GET_OPCODE(i); | |
switch (op) { | |
case OP_MOVE: { | |
@@ -423,7 +423,7 @@ static const char *getobjname (Proto *p, int lastpc, int reg, | |
case OP_LOADK: | |
case OP_LOADKX: { | |
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])) { | |
*name = svalue(&p->k[b]); | |
return "constant"; | |
@@ -446,7 +446,7 @@ static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { | |
TMS tm; | |
Proto *p = ci_func(ci)->p; /* calling function */ | |
int pc = currentpc(ci); /* calling instruction index */ | |
- Instruction i = p->code[pc]; /* calling instruction */ | |
+ Instruction i = p->sp->code[pc]; /* calling instruction */ | |
switch (GET_OPCODE(i)) { | |
case OP_CALL: | |
case OP_TAILCALL: /* get function name */ | |
@@ -559,7 +559,7 @@ static void addinfo (lua_State *L, const char *msg) { | |
if (isLua(ci)) { /* is Lua code? */ | |
char buff[LUA_IDSIZE]; /* add file:line information */ | |
int line = currentline(ci); | |
- TString *src = ci_func(ci)->p->source; | |
+ TString *src = ci_func(ci)->p->sp->source; | |
if (src) | |
luaO_chunkid(buff, getstr(src), LUA_IDSIZE); | |
else { /* no source available; use "?" instead */ | |
diff --git a/src/ldebug.h b/src/ldebug.h | |
index 6445c76..04d646d 100644 | |
--- a/src/ldebug.h | |
+++ b/src/ldebug.h | |
@@ -11,9 +11,9 @@ | |
#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] : 0) | |
+#define getfuncline(f,pc) (((f)->sp->lineinfo) ? (f)->sp->lineinfo[pc] : 0) | |
#define resethookcount(L) (L->hookcount = L->basehookcount) | |
diff --git a/src/ldo.c b/src/ldo.c | |
index e9dd5fa..ee5509f 100644 | |
--- a/src/ldo.c | |
+++ b/src/ldo.c | |
@@ -254,7 +254,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 nfixargs = p->numparams; | |
StkId base, fixed; | |
@@ -324,7 +324,7 @@ int luaD_precall (lua_State *L, StkId func, int nresults) { | |
} | |
case LUA_TLCL: { /* Lua function: prepare its call */ | |
StkId base; | |
- Proto *p = clLvalue(func)->p; | |
+ SharedProto *p = clLvalue(func)->p->sp; | |
n = cast_int(L->top - func) - 1; /* number of real arguments */ | |
luaD_checkstack(L, p->maxstacksize); | |
for (; n < p->numparams; n++) | |
diff --git a/src/ldump.c b/src/ldump.c | |
index 61fa2cd..dd232ec 100644 | |
--- a/src/ldump.c | |
+++ b/src/ldump.c | |
@@ -79,7 +79,7 @@ static void DumpFunction(const Proto* f, DumpState* D); | |
static void DumpConstants(const Proto* f, DumpState* D) | |
{ | |
- int i,n=f->sizek; | |
+ int i,n=f->sp->sizek; | |
DumpInt(n,D); | |
for (i=0; i<n; i++) | |
{ | |
@@ -101,23 +101,23 @@ static void DumpConstants(const Proto* f, DumpState* D) | |
default: lua_assert(0); | |
} | |
} | |
- n=f->sizep; | |
+ n=f->sp->sizep; | |
DumpInt(n,D); | |
for (i=0; i<n; i++) DumpFunction(f->p[i],D); | |
} | |
static void DumpUpvalues(const Proto* f, DumpState* D) | |
{ | |
- int i,n=f->sizeupvalues; | |
+ int i,n=f->sp->sizeupvalues; | |
DumpInt(n,D); | |
for (i=0; i<n; i++) | |
{ | |
- DumpChar(f->upvalues[i].instack,D); | |
- DumpChar(f->upvalues[i].idx,D); | |
+ DumpChar(f->sp->upvalues[i].instack,D); | |
+ DumpChar(f->sp->upvalues[i].idx,D); | |
} | |
} | |
-static void DumpDebug(const Proto* f, DumpState* D) | |
+static void DumpDebug(const SharedProto* f, DumpState* D) | |
{ | |
int i,n; | |
DumpString((D->strip) ? NULL : f->source,D); | |
@@ -138,15 +138,16 @@ static void DumpDebug(const Proto* f, DumpState* D) | |
static void DumpFunction(const Proto* f, DumpState* D) | |
{ | |
- DumpInt(f->linedefined,D); | |
- DumpInt(f->lastlinedefined,D); | |
- DumpChar(f->numparams,D); | |
- DumpChar(f->is_vararg,D); | |
- DumpChar(f->maxstacksize,D); | |
- DumpCode(f,D); | |
+ const SharedProto *sp = f->sp; | |
+ DumpInt(sp->linedefined,D); | |
+ DumpInt(sp->lastlinedefined,D); | |
+ DumpChar(sp->numparams,D); | |
+ DumpChar(sp->is_vararg,D); | |
+ DumpChar(sp->maxstacksize,D); | |
+ DumpCode(sp,D); | |
DumpConstants(f,D); | |
DumpUpvalues(f,D); | |
- DumpDebug(f,D); | |
+ DumpDebug(sp,D); | |
} | |
static void DumpHeader(DumpState* D) | |
diff --git a/src/lfunc.c b/src/lfunc.c | |
index e90e152..9dbb034 100644 | |
--- a/src/lfunc.c | |
+++ b/src/lfunc.c | |
@@ -107,48 +107,64 @@ void luaF_close (lua_State *L, StkId level) { | |
} | |
-Proto *luaF_newproto (lua_State *L) { | |
+Proto *luaF_newproto (lua_State *L, SharedProto *sp) { | |
Proto *f = &luaC_newobj(L, LUA_TPROTO, sizeof(Proto), NULL, 0)->p; | |
f->k = NULL; | |
- f->sizek = 0; | |
+ f->sp = NULL; | |
f->p = NULL; | |
- f->sizep = 0; | |
- f->code = NULL; | |
f->cache = NULL; | |
- f->sizecode = 0; | |
- f->lineinfo = NULL; | |
- f->sizelineinfo = 0; | |
- f->upvalues = NULL; | |
- f->sizeupvalues = 0; | |
- f->numparams = 0; | |
- f->is_vararg = 0; | |
- f->maxstacksize = 0; | |
- f->locvars = NULL; | |
- f->sizelocvars = 0; | |
- f->linedefined = 0; | |
- f->lastlinedefined = 0; | |
- f->source = NULL; | |
+ | |
+ if (sp == NULL) { | |
+ sp = luaM_new(L, SharedProto); | |
+ sp->l_G = G(L); | |
+ sp->sizek = 0; | |
+ sp->sizep = 0; | |
+ sp->code = NULL; | |
+ sp->sizecode = 0; | |
+ sp->lineinfo = NULL; | |
+ sp->sizelineinfo = 0; | |
+ sp->upvalues = NULL; | |
+ sp->sizeupvalues = 0; | |
+ sp->numparams = 0; | |
+ 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; | |
} | |
- | |
-void luaF_freeproto (lua_State *L, Proto *f) { | |
+static void | |
+luaF_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->p, f->sizep); | |
- luaM_freearray(L, f->k, f->sizek); | |
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) { | |
+ luaM_freearray(L, f->k, f->sp->sizek); | |
+ luaM_freearray(L, f->p, f->sp->sizep); | |
+ luaF_freesharedproto(L, f->sp); | |
+ luaM_free(L, f); | |
+} | |
+ | |
/* | |
** Look for n-th local variable at line `line' in function `func'. | |
** 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; | |
+ const SharedProto *f = fp->sp; | |
for (i = 0; i<f->sizelocvars && f->locvars[i].startpc <= pc; i++) { | |
if (pc < f->locvars[i].endpc) { /* is variable active? */ | |
local_number--; | |
diff --git a/src/lfunc.h b/src/lfunc.h | |
index ca0d3a3..ba31596 100644 | |
--- a/src/lfunc.h | |
+++ b/src/lfunc.h | |
@@ -18,7 +18,7 @@ | |
cast(int, sizeof(TValue *)*((n)-1))) | |
-LUAI_FUNC Proto *luaF_newproto (lua_State *L); | |
+LUAI_FUNC Proto *luaF_newproto (lua_State *L, SharedProto *sp); | |
LUAI_FUNC Closure *luaF_newCclosure (lua_State *L, int nelems); | |
LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems); | |
LUAI_FUNC UpVal *luaF_newupval (lua_State *L); | |
diff --git a/src/lgc.c b/src/lgc.c | |
index 52460dc..c0f2858 100644 | |
--- a/src/lgc.c | |
+++ b/src/lgc.c | |
@@ -453,26 +453,34 @@ static lu_mem traversetable (global_State *g, Table *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) { | |
int i; | |
if (f->cache && iswhite(obj2gco(f->cache))) | |
f->cache = NULL; /* allow cache to be collected */ | |
- markobject(g, f->source); | |
- for (i = 0; i < f->sizek; i++) /* mark literals */ | |
+ for (i = 0; i < f->sp->sizek; i++) /* mark literals */ | |
markvalue(g, &f->k[i]); | |
- for (i = 0; i < f->sizeupvalues; i++) /* mark upvalue names */ | |
- markobject(g, f->upvalues[i].name); | |
- for (i = 0; i < f->sizep; i++) /* mark nested protos */ | |
+ for (i = 0; i < f->sp->sizep; i++) /* mark nested protos */ | |
markobject(g, f->p[i]); | |
- for (i = 0; i < f->sizelocvars; i++) /* mark local-variable names */ | |
- markobject(g, f->locvars[i].varname); | |
- return sizeof(Proto) + sizeof(Instruction) * f->sizecode + | |
- sizeof(Proto *) * f->sizep + | |
- sizeof(TValue) * f->sizek + | |
- sizeof(int) * f->sizelineinfo + | |
- sizeof(LocVar) * f->sizelocvars + | |
- sizeof(Upvaldesc) * f->sizeupvalues; | |
+ return sizeof(Proto) + sizeof(Proto *) * f->sp->sizep + | |
+ sizeof(TValue) * f->sp->sizek + | |
+ marksharedproto(g, f->sp); | |
} | |
diff --git a/src/lobject.h b/src/lobject.h | |
index 3a630b9..1428725 100644 | |
--- a/src/lobject.h | |
+++ b/src/lobject.h | |
@@ -461,18 +461,12 @@ typedef struct LocVar { | |
} LocVar; | |
-/* | |
-** Function Prototypes | |
-*/ | |
-typedef struct Proto { | |
- CommonHeader; | |
- TValue *k; /* constants used by the function */ | |
+typedef struct SharedProto { | |
+ void *l_G; /* global state belongs to */ | |
Instruction *code; | |
- struct Proto **p; /* functions defined inside the function */ | |
int *lineinfo; /* map from opcodes to source lines (debug information) */ | |
LocVar *locvars; /* information about local variables (debug information) */ | |
Upvaldesc *upvalues; /* upvalue information */ | |
- union Closure *cache; /* last created closure with this prototype */ | |
TString *source; /* used for debug information */ | |
int sizeupvalues; /* size of 'upvalues' */ | |
int sizek; /* size of `k' */ | |
@@ -482,10 +476,21 @@ typedef struct Proto { | |
int sizelocvars; | |
int linedefined; | |
int lastlinedefined; | |
- GCObject *gclist; | |
lu_byte numparams; /* number of fixed parameters */ | |
lu_byte is_vararg; | |
lu_byte maxstacksize; /* maximum stack used by this function */ | |
+} SharedProto; | |
+ | |
+/* | |
+** Function Prototypes | |
+*/ | |
+typedef struct Proto { | |
+ CommonHeader; | |
+ TValue *k; /* constants used by the function */ | |
+ struct SharedProto *sp; | |
+ struct Proto **p; /* functions defined inside the function */ | |
+ union Closure *cache; /* last created closure with this prototype */ | |
+ GCObject *gclist; | |
} Proto; | |
diff --git a/src/lparser.c b/src/lparser.c | |
index 9e1a9ca..a8e37fd 100644 | |
--- a/src/lparser.c | |
+++ b/src/lparser.c | |
@@ -83,7 +83,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); | |
@@ -164,13 +164,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++; | |
} | |
@@ -198,7 +199,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]; | |
} | |
@@ -220,7 +221,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 (luaS_eqstr(up[i].name, name)) return i; | |
} | |
@@ -229,7 +230,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, | |
@@ -238,7 +240,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++; | |
} | |
@@ -500,12 +502,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; | |
} | |
@@ -526,7 +528,7 @@ static void codeclosure (LexState *ls, expdesc *v) { | |
static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) { | |
lua_State *L = ls->L; | |
- Proto *f; | |
+ SharedProto *f; | |
fs->prev = ls->fs; /* linked list of funcstates */ | |
fs->ls = ls; | |
ls->fs = fs; | |
@@ -541,7 +543,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 */ | |
fs->h = luaH_new(L); | |
@@ -556,20 +558,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; | |
/* last token read was anchored in defunct function; must re-anchor it */ | |
@@ -748,8 +751,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 */ | |
} | |
/* }====================================================================== */ | |
@@ -759,7 +762,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? */ | |
@@ -790,7 +793,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) { | |
@@ -800,7 +803,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); | |
@@ -961,7 +964,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 " LUA_QL("...") " outside a vararg function"); | |
init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0)); | |
break; | |
@@ -1605,7 +1608,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 */ | |
@@ -1623,12 +1626,12 @@ Closure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, | |
/* 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 */ | |
+ funcstate.f = cl->l.p = luaF_newproto(L, NULL); | |
+ funcstate.f->sp->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, 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 */ | |
diff --git a/src/lua.h b/src/lua.h | |
index 149a2c3..1fceb4a 100644 | |
--- a/src/lua.h | |
+++ b/src/lua.h | |
@@ -264,6 +264,7 @@ LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt, | |
LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data); | |
+LUA_API void (lua_clonefunction) (lua_State *L, const void *eL); | |
/* | |
** coroutine functions | |
diff --git a/src/luac.c b/src/luac.c | |
index 7409706..2059404 100644 | |
--- a/src/luac.c | |
+++ b/src/luac.c | |
@@ -146,9 +146,9 @@ static const Proto* combine(lua_State* L, int n) | |
for (i=0; i<n; i++) | |
{ | |
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; | |
} | |
} | |
@@ -271,13 +271,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)) | |
static void PrintCode(const Proto* f) | |
{ | |
- const Instruction* code=f->code; | |
- int pc,n=f->sizecode; | |
+ const SharedProto *sp = f->sp; | |
+ const Instruction* code=sp->code; | |
+ int pc,n=sp->sizecode; | |
for (pc=0; pc<n; pc++) | |
{ | |
Instruction i=code[pc]; | |
@@ -375,7 +376,7 @@ static void PrintCode(const Proto* f) | |
#define SS(x) ((x==1)?"":"s") | |
#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) : "=?"; | |
if (*s=='@' || *s=='=') | |
@@ -397,8 +398,9 @@ static void PrintHeader(const Proto* f) | |
static void PrintDebug(const Proto* f) | |
{ | |
+ const SharedProto *sp = f->sp; | |
int i,n; | |
- n=f->sizek; | |
+ n=sp->sizek; | |
printf("constants (%d) for %p:\n",n,VOID(f)); | |
for (i=0; i<n; i++) | |
{ | |
@@ -406,26 +408,26 @@ static void PrintDebug(const Proto* f) | |
PrintConstant(f,i); | |
printf("\n"); | |
} | |
- n=f->sizelocvars; | |
+ n=sp->sizelocvars; | |
printf("locals (%d) for %p:\n",n,VOID(f)); | |
for (i=0; i<n; i++) | |
{ | |
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=sp->sizeupvalues; | |
printf("upvalues (%d) for %p:\n",n,VOID(f)); | |
for (i=0; i<n; i++) | |
{ | |
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) | |
{ | |
- int i,n=f->sizep; | |
- PrintHeader(f); | |
+ int i,n=f->sp->sizep; | |
+ PrintHeader(f->sp); | |
PrintCode(f); | |
if (full) PrintDebug(f); | |
for (i=0; i<n; i++) PrintFunction(f->p[i],full); | |
diff --git a/src/lundump.c b/src/lundump.c | |
index 4163cb5..a404594 100644 | |
--- a/src/lundump.c | |
+++ b/src/lundump.c | |
@@ -83,7 +83,7 @@ static TString* LoadString(LoadState* S) | |
} | |
} | |
-static void LoadCode(LoadState* S, Proto* f) | |
+static void LoadCode(LoadState* S, SharedProto* f) | |
{ | |
int n=LoadInt(S); | |
f->code=luaM_newvector(S->L,n,Instruction); | |
@@ -98,7 +98,7 @@ static void LoadConstants(LoadState* S, Proto* f) | |
int i,n; | |
n=LoadInt(S); | |
f->k=luaM_newvector(S->L,n,TValue); | |
- f->sizek=n; | |
+ f->sp->sizek=n; | |
for (i=0; i<n; i++) setnilvalue(&f->k[i]); | |
for (i=0; i<n; i++) | |
{ | |
@@ -123,16 +123,16 @@ static void LoadConstants(LoadState* S, Proto* f) | |
} | |
n=LoadInt(S); | |
f->p=luaM_newvector(S->L,n,Proto*); | |
- f->sizep=n; | |
+ f->sp->sizep=n; | |
for (i=0; i<n; i++) f->p[i]=NULL; | |
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]); | |
} | |
} | |
-static void LoadUpvalues(LoadState* S, Proto* f) | |
+static void LoadUpvalues(LoadState* S, SharedProto* f) | |
{ | |
int i,n; | |
n=LoadInt(S); | |
@@ -146,7 +146,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; | |
f->source=LoadString(S); | |
@@ -170,15 +170,16 @@ static void LoadDebug(LoadState* S, Proto* f) | |
static void LoadFunction(LoadState* S, Proto* f) | |
{ | |
- f->linedefined=LoadInt(S); | |
- f->lastlinedefined=LoadInt(S); | |
- f->numparams=LoadByte(S); | |
- f->is_vararg=LoadByte(S); | |
- f->maxstacksize=LoadByte(S); | |
- LoadCode(S,f); | |
+ SharedProto *sp = f->sp; | |
+ sp->linedefined=LoadInt(S); | |
+ sp->lastlinedefined=LoadInt(S); | |
+ sp->numparams=LoadByte(S); | |
+ sp->is_vararg=LoadByte(S); | |
+ sp->maxstacksize=LoadByte(S); | |
+ LoadCode(S,sp); | |
LoadConstants(S,f); | |
- LoadUpvalues(S,f); | |
- LoadDebug(S,f); | |
+ LoadUpvalues(S,sp); | |
+ LoadDebug(S,sp); | |
} | |
/* the code below must be consistent with the code in luaU_header */ | |
@@ -219,12 +220,12 @@ Closure* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name) | |
LoadHeader(&S); | |
cl=luaF_newLclosure(L,1); | |
setclLvalue(L,L->top,cl); incr_top(L); | |
- cl->l.p=luaF_newproto(L); | |
+ cl->l.p=luaF_newproto(L, NULL); | |
LoadFunction(&S,cl->l.p); | |
- if (cl->l.p->sizeupvalues != 1) | |
+ if (cl->l.p->sp->sizeupvalues != 1) | |
{ | |
Proto* p=cl->l.p; | |
- cl=luaF_newLclosure(L,cl->l.p->sizeupvalues); | |
+ cl=luaF_newLclosure(L,cl->l.p->sp->sizeupvalues); | |
cl->l.p=p; | |
setclLvalue(L,L->top-1,cl); | |
} | |
diff --git a/src/lvm.c b/src/lvm.c | |
index 141b9fd..43019d4 100644 | |
--- a/src/lvm.c | |
+++ b/src/lvm.c | |
@@ -379,8 +379,8 @@ void luaV_arith (lua_State *L, StkId ra, const TValue *rb, | |
static Closure *getcached (Proto *p, UpVal **encup, StkId base) { | |
Closure *c = p->cache; | |
if (c != NULL) { /* is there a cached closure? */ | |
- int nup = p->sizeupvalues; | |
- Upvaldesc *uv = p->upvalues; | |
+ int nup = p->sp->sizeupvalues; | |
+ Upvaldesc *uv = p->sp->upvalues; | |
int i; | |
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; | |
@@ -400,8 +400,8 @@ static Closure *getcached (Proto *p, UpVal **encup, StkId base) { | |
*/ | |
static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base, | |
StkId ra) { | |
- int nup = p->sizeupvalues; | |
- Upvaldesc *uv = p->upvalues; | |
+ int nup = p->sp->sizeupvalues; | |
+ Upvaldesc *uv = p->sp->upvalues; | |
int i; | |
Closure *ncl = luaF_newLclosure(L, nup); | |
ncl->l.p = p; | |
@@ -733,10 +733,10 @@ void luaV_execute (lua_State *L) { | |
StkId nfunc = nci->func; /* called function */ | |
StkId ofunc = oci->func; /* caller function */ | |
/* 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; | |
/* 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 */ | |
for (aux = 0; nfunc + aux < lim; aux++) | |
setobjs2s(L, ofunc + aux, nfunc + aux); | |
@@ -752,7 +752,7 @@ void luaV_execute (lua_State *L) { | |
vmcasenb(OP_RETURN, | |
int b = GETARG_B(i); | |
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); | |
if (!(ci->callstatus & CIST_REENTRY)) /* 'ci' still the called one */ | |
return; /* external invocation: return */ | |
@@ -842,7 +842,7 @@ void luaV_execute (lua_State *L) { | |
vmcase(OP_VARARG, | |
int b = GETARG_B(i) - 1; | |
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? */ | |
b = n; /* get all var. arguments */ | |
Protect(luaD_checkstack(L, n)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment