mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-24 20:23:06 +00:00
modify lua
This commit is contained in:
3
3rd/lua/README
Normal file
3
3rd/lua/README
Normal file
@@ -0,0 +1,3 @@
|
||||
This is a modify version of lua 5.2.3 (http://www.lua.org/ftp/lua-5.2.3.tar.gz) .
|
||||
|
||||
For detail : http://lua-users.org/lists/lua-l/2014-03/msg00489.html
|
||||
@@ -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]);
|
||||
|
||||
@@ -627,7 +627,7 @@ static int skipcomment (LoadF *lf, int *cp) {
|
||||
}
|
||||
|
||||
|
||||
LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename,
|
||||
static int luaL_loadfilex_ (lua_State *L, const char *filename,
|
||||
const char *mode) {
|
||||
LoadF lf;
|
||||
int status, readstatus;
|
||||
@@ -957,3 +957,121 @@ LUALIB_API void luaL_checkversion_ (lua_State *L, lua_Number ver) {
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
// use clonefunction
|
||||
|
||||
#define LOCK(q) while (__sync_lock_test_and_set(&(q)->lock,1)) {}
|
||||
#define UNLOCK(q) __sync_lock_release(&(q)->lock);
|
||||
|
||||
struct codecache {
|
||||
int lock;
|
||||
lua_State *L;
|
||||
};
|
||||
|
||||
static struct codecache CC = { 0 , NULL };
|
||||
|
||||
static void
|
||||
clearcache() {
|
||||
if (CC.L == NULL)
|
||||
return;
|
||||
LOCK(&CC)
|
||||
lua_close(CC.L);
|
||||
CC.L = luaL_newstate();
|
||||
UNLOCK(&CC)
|
||||
}
|
||||
|
||||
static void
|
||||
init() {
|
||||
CC.lock = 0;
|
||||
CC.L = luaL_newstate();
|
||||
}
|
||||
|
||||
static const void *
|
||||
load(const char *key) {
|
||||
if (CC.L == NULL)
|
||||
return NULL;
|
||||
LOCK(&CC)
|
||||
lua_State *L = CC.L;
|
||||
lua_pushstring(L, key);
|
||||
lua_rawget(L, LUA_REGISTRYINDEX);
|
||||
const void * result = lua_touserdata(L, -1);
|
||||
lua_pop(L, 1);
|
||||
UNLOCK(&CC)
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static const void *
|
||||
save(const char *key, const void * proto) {
|
||||
lua_State *L;
|
||||
const void * result = NULL;
|
||||
|
||||
LOCK(&CC)
|
||||
if (CC.L == NULL) {
|
||||
init();
|
||||
L = CC.L;
|
||||
} else {
|
||||
L = CC.L;
|
||||
lua_pushstring(L, key);
|
||||
lua_pushvalue(L, -1);
|
||||
lua_rawget(L, LUA_REGISTRYINDEX);
|
||||
result = lua_touserdata(L, -1); /* stack: key oldvalue */
|
||||
if (result == NULL) {
|
||||
lua_pop(L,1);
|
||||
lua_pushlightuserdata(L, (void *)proto);
|
||||
lua_rawset(L, LUA_REGISTRYINDEX);
|
||||
} else {
|
||||
lua_pop(L,2);
|
||||
}
|
||||
}
|
||||
UNLOCK(&CC)
|
||||
return result;
|
||||
}
|
||||
|
||||
LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename,
|
||||
const char *mode) {
|
||||
const void * proto = load(filename);
|
||||
if (proto) {
|
||||
lua_clonefunction(L, proto);
|
||||
return LUA_OK;
|
||||
}
|
||||
lua_State * eL = luaL_newstate();
|
||||
if (eL == NULL) {
|
||||
lua_pushliteral(L, "New state failed");
|
||||
return LUA_ERRMEM;
|
||||
}
|
||||
int err = luaL_loadfilex_(eL, filename, mode);
|
||||
if (err != LUA_OK) {
|
||||
size_t sz = 0;
|
||||
const char * msg = lua_tolstring(eL, -1, &sz);
|
||||
lua_pushlstring(L, msg, sz);
|
||||
lua_close(eL);
|
||||
return err;
|
||||
}
|
||||
proto = lua_topointer(eL, -1);
|
||||
const void * oldv = save(filename, proto);
|
||||
if (oldv) {
|
||||
lua_close(eL);
|
||||
lua_clonefunction(L, oldv);
|
||||
} else {
|
||||
lua_clonefunction(L, proto);
|
||||
/* Never close it. notice: memory leak */
|
||||
}
|
||||
return LUA_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
cache_clear(lua_State *L) {
|
||||
clearcache();
|
||||
return 0;
|
||||
}
|
||||
|
||||
LUAMOD_API int luaopen_cache(lua_State *L) {
|
||||
luaL_Reg l[] = {
|
||||
{ "clear", cache_clear },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
luaL_newlib(L,l);
|
||||
lua_getglobal(L, "loadfile");
|
||||
lua_setfield(L, -2, "loadfile");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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++)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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--;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -41,6 +41,8 @@ LUAMOD_API int (luaopen_debug) (lua_State *L);
|
||||
#define LUA_LOADLIBNAME "package"
|
||||
LUAMOD_API int (luaopen_package) (lua_State *L);
|
||||
|
||||
#define LUA_CACHELIB
|
||||
LUAMOD_API int (luaopen_cache) (lua_State *L);
|
||||
|
||||
/* open all previous libraries */
|
||||
LUALIB_API void (luaL_openlibs) (lua_State *L);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -13,6 +13,14 @@ Run these in different console
|
||||
./client 127.0.0.1 8888 # Launch a client, and try to input some words.
|
||||
```
|
||||
|
||||
## About Lua
|
||||
|
||||
Skynet push a mondified version of lua 5.2.3 to 3rd/lua , it can share proto type between lua state (http://lua-users.org/lists/lua-l/2014-03/msg00489.html) .
|
||||
|
||||
Each lua file only load once and cache it in memory during skynet start, so if you want to reflush the cache , call skynet.cache.clear() .
|
||||
|
||||
You can also use the offical lua version , edit the makefile by yourself .
|
||||
|
||||
## Blog (in Chinese)
|
||||
|
||||
* http://blog.codingnow.com/2012/09/the_design_of_skynet.html
|
||||
|
||||
@@ -105,6 +105,10 @@ main(int argc, char *argv[]) {
|
||||
}
|
||||
_init_env(L);
|
||||
|
||||
#ifdef LUA_CACHELIB
|
||||
printf("Skynet lua code cache enable\n");
|
||||
#endif
|
||||
|
||||
const char *path = optstring("lua_path","./lualib/?.lua;./lualib/?/init.lua");
|
||||
setenv("LUA_PATH",path,1);
|
||||
const char *cpath = optstring("lua_cpath","./luaclib/?.so");
|
||||
|
||||
Reference in New Issue
Block a user