mirror of
https://github.com/cloudwu/skynet.git
synced 2026-07-22 02:53:09 +00:00
rewrite SSM and clonefunction
This commit is contained in:
@@ -1013,52 +1013,11 @@ LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
|
||||
return status;
|
||||
}
|
||||
|
||||
static void cloneproto (lua_State *L, Proto *f, const Proto *src) {
|
||||
/* copy constants and nested proto */
|
||||
int i,n;
|
||||
n = src->sp->sizek;
|
||||
if (src->sp->sharedk)
|
||||
f->k = src->sp->k;
|
||||
else {
|
||||
lu_byte sharedk = 1;
|
||||
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 * sstr = tsvalue(s);
|
||||
if (ttisshrstring(s)) {
|
||||
TString * str = luaS_clonestring(L,sstr);
|
||||
setsvalue2n(L,o,str);
|
||||
if (str != sstr)
|
||||
sharedk = 0;
|
||||
} else {
|
||||
setsvalue2n(L,o,sstr);
|
||||
}
|
||||
} else {
|
||||
setobj(L,o,s);
|
||||
}
|
||||
}
|
||||
if (sharedk) {
|
||||
luaM_freearray(L, f->k, n);
|
||||
f->k = src->sp->k;
|
||||
}
|
||||
}
|
||||
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]= luaF_newproto(L, src->p[i]->sp);
|
||||
cloneproto(L, f->p[i], src->p[i]);
|
||||
}
|
||||
}
|
||||
|
||||
LUA_API void lua_clonefunction (lua_State *L, const void * fp) {
|
||||
LClosure *cl;
|
||||
LClosure *f = cast(LClosure *, fp);
|
||||
lua_lock(L);
|
||||
if (f->p->sp->l_G == G(L)) {
|
||||
if (f->p->l_G == G(L)) {
|
||||
setclLvalue(L,L->top,f);
|
||||
api_incr_top(L);
|
||||
lua_unlock(L);
|
||||
@@ -1067,8 +1026,7 @@ LUA_API void lua_clonefunction (lua_State *L, const void * fp) {
|
||||
cl = luaF_newLclosure(L,f->nupvalues);
|
||||
setclLvalue(L,L->top,cl);
|
||||
api_incr_top(L);
|
||||
cl->p = luaF_newproto(L, f->p->sp);
|
||||
cloneproto(L, cl->p, f->p);
|
||||
cl->p = f->p;
|
||||
luaF_initupvals(L, cl);
|
||||
|
||||
if (cl->nupvalues >= 1) { /* does it have an upvalue? */
|
||||
@@ -1082,6 +1040,15 @@ LUA_API void lua_clonefunction (lua_State *L, const void * fp) {
|
||||
lua_unlock(L);
|
||||
}
|
||||
|
||||
LUA_API void lua_sharefunction (lua_State *L, int index) {
|
||||
if (!lua_isfunction(L,index) || lua_iscfunction(L,index)) {
|
||||
lua_pushstring(L, "Only Lua function can share");
|
||||
lua_error(L);
|
||||
}
|
||||
LClosure *f = cast(LClosure *, lua_topointer(L, index));
|
||||
luaF_shareproto(f->p);
|
||||
}
|
||||
|
||||
LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data, int strip) {
|
||||
int status;
|
||||
TValue *o;
|
||||
@@ -1276,7 +1243,7 @@ static const char *aux_upvalue (StkId fi, int n, TValue **val,
|
||||
case LUA_TLCL: { /* Lua closure */
|
||||
LClosure *f = clLvalue(fi);
|
||||
TString *name;
|
||||
SharedProto *p = f->p->sp;
|
||||
Proto *p = f->p;
|
||||
if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
|
||||
*val = f->upvals[n-1]->v;
|
||||
if (uv) *uv = f->upvals[n - 1];
|
||||
@@ -1328,7 +1295,7 @@ static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) {
|
||||
StkId fi = index2addr(L, fidx);
|
||||
api_check(L, ttisLclosure(fi), "Lua function expected");
|
||||
f = clLvalue(fi);
|
||||
api_check(L, (1 <= n && n <= f->p->sp->sizeupvalues), "invalid upvalue index");
|
||||
api_check(L, (1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index");
|
||||
if (pf) *pf = f;
|
||||
return &f->upvals[n - 1]; /* get its upvalue pointer */
|
||||
}
|
||||
|
||||
@@ -699,9 +699,7 @@ static int skipcomment (LoadF *lf, int *cp) {
|
||||
else return 0; /* no comment */
|
||||
}
|
||||
|
||||
LUA_API void luaS_expandshr(int n);
|
||||
|
||||
static int luaL_loadfilex_ (lua_State *L, const char *filename,
|
||||
LUALIB_API int luaL_loadfilex_ (lua_State *L, const char *filename,
|
||||
const char *mode) {
|
||||
LoadF lf;
|
||||
int status, readstatus;
|
||||
@@ -725,9 +723,7 @@ static int luaL_loadfilex_ (lua_State *L, const char *filename,
|
||||
}
|
||||
if (c != EOF)
|
||||
lf.buff[lf.n++] = c; /* 'c' is the first character of the stream */
|
||||
luaS_expandshr(4096);
|
||||
status = lua_load(L, getF, &lf, lua_tostring(L, -1), mode);
|
||||
luaS_expandshr(-4096);
|
||||
readstatus = ferror(lf.f);
|
||||
if (filename) fclose(lf.f); /* close file (even in case of errors) */
|
||||
if (readstatus) {
|
||||
@@ -1181,6 +1177,7 @@ LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename,
|
||||
lua_close(eL);
|
||||
return err;
|
||||
}
|
||||
lua_sharefunction(eL, -1);
|
||||
proto = lua_topointer(eL, -1);
|
||||
const void * oldv = save(filename, proto);
|
||||
if (oldv) {
|
||||
|
||||
@@ -82,6 +82,8 @@ LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref);
|
||||
|
||||
LUALIB_API int (luaL_loadfilex) (lua_State *L, const char *filename,
|
||||
const char *mode);
|
||||
LUALIB_API int (luaL_loadfilex_) (lua_State *L, const char *filename,
|
||||
const char *mode);
|
||||
|
||||
#define luaL_loadfile(L,f) luaL_loadfilex(L,f,NULL)
|
||||
|
||||
|
||||
@@ -65,7 +65,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->sp->code[fs->pc-1];
|
||||
previous = &fs->f->code[fs->pc-1];
|
||||
if (GET_OPCODE(*previous) == OP_LOADNIL) { /* previous is LOADNIL? */
|
||||
int pfrom = GETARG_A(*previous); /* get previous range */
|
||||
int pl = pfrom + GETARG_B(*previous);
|
||||
@@ -88,7 +88,7 @@ void luaK_nil (FuncState *fs, int from, int n) {
|
||||
** a list of jumps.
|
||||
*/
|
||||
static int getjump (FuncState *fs, int pc) {
|
||||
int offset = GETARG_sBx(fs->f->sp->code[pc]);
|
||||
int offset = GETARG_sBx(fs->f->code[pc]);
|
||||
if (offset == NO_JUMP) /* point to itself represents end of list */
|
||||
return NO_JUMP; /* end of list */
|
||||
else
|
||||
@@ -101,7 +101,7 @@ static int getjump (FuncState *fs, int pc) {
|
||||
** (Jump addresses are relative in Lua)
|
||||
*/
|
||||
static void fixjump (FuncState *fs, int pc, int dest) {
|
||||
Instruction *jmp = &fs->f->sp->code[pc];
|
||||
Instruction *jmp = &fs->f->code[pc];
|
||||
int offset = dest - (pc + 1);
|
||||
lua_assert(dest != NO_JUMP);
|
||||
if (abs(offset) > MAXARG_sBx)
|
||||
@@ -177,7 +177,7 @@ int luaK_getlabel (FuncState *fs) {
|
||||
** unconditional.
|
||||
*/
|
||||
static Instruction *getjumpcontrol (FuncState *fs, int pc) {
|
||||
Instruction *pi = &fs->f->sp->code[pc];
|
||||
Instruction *pi = &fs->f->code[pc];
|
||||
if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1))))
|
||||
return pi-1;
|
||||
else
|
||||
@@ -278,10 +278,10 @@ void luaK_patchlist (FuncState *fs, int list, int target) {
|
||||
void luaK_patchclose (FuncState *fs, int list, int level) {
|
||||
level++; /* argument is +1 to reserve 0 as non-op */
|
||||
for (; list != NO_JUMP; list = getjump(fs, list)) {
|
||||
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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -294,13 +294,13 @@ static int luaK_code (FuncState *fs, Instruction i) {
|
||||
Proto *f = fs->f;
|
||||
dischargejpc(fs); /* 'pc' will change */
|
||||
/* put new instruction in code array */
|
||||
luaM_growvector(fs->ls->L, f->sp->code, fs->pc, f->sp->sizecode, Instruction,
|
||||
luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction,
|
||||
MAX_INT, "opcodes");
|
||||
f->sp->code[fs->pc] = i;
|
||||
f->code[fs->pc] = i;
|
||||
/* save corresponding line information */
|
||||
luaM_growvector(fs->ls->L, f->sp->lineinfo, fs->pc, f->sp->sizelineinfo, int,
|
||||
luaM_growvector(fs->ls->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
|
||||
MAX_INT, "opcodes");
|
||||
f->sp->lineinfo[fs->pc] = fs->ls->lastline;
|
||||
f->lineinfo[fs->pc] = fs->ls->lastline;
|
||||
return fs->pc++;
|
||||
}
|
||||
|
||||
@@ -360,11 +360,11 @@ 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->sp->maxstacksize) {
|
||||
if (newstack > fs->f->maxstacksize) {
|
||||
if (newstack >= MAXREGS)
|
||||
luaX_syntaxerror(fs->ls,
|
||||
"function or expression needs too many registers");
|
||||
fs->f->sp->maxstacksize = cast_byte(newstack);
|
||||
fs->f->maxstacksize = cast_byte(newstack);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -438,13 +438,13 @@ static int addk (FuncState *fs, TValue *key, TValue *v) {
|
||||
return k; /* reuse index */
|
||||
}
|
||||
/* constant not found; create a new entry */
|
||||
oldsize = f->sp->sizek;
|
||||
oldsize = f->sizek;
|
||||
k = fs->nk;
|
||||
/* numerical value does not need GC barrier;
|
||||
table has no metatable, so it does not need to invalidate cache */
|
||||
setivalue(idx, k);
|
||||
luaM_growvector(L, f->k, k, f->sp->sizek, TValue, MAXARG_Ax, "constants");
|
||||
while (oldsize < f->sp->sizek) setnilvalue(&f->k[oldsize++]);
|
||||
luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants");
|
||||
while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
|
||||
setobj(L, &f->k[k], v);
|
||||
fs->nk++;
|
||||
luaC_barrier(L, f, v);
|
||||
@@ -1175,7 +1175,7 @@ void luaK_posfix (FuncState *fs, BinOpr op,
|
||||
** Change line information associated with current position.
|
||||
*/
|
||||
void luaK_fixline (FuncState *fs, int line) {
|
||||
fs->f->sp->lineinfo[fs->pc - 1] = line;
|
||||
fs->f->lineinfo[fs->pc - 1] = line;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;
|
||||
|
||||
|
||||
/* get (pointer to) instruction of given 'expdesc' */
|
||||
#define getinstruction(fs,e) ((fs)->f->sp->code[(e)->u.info])
|
||||
#define getinstruction(fs,e) ((fs)->f->code[(e)->u.info])
|
||||
|
||||
#define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx)
|
||||
|
||||
|
||||
@@ -125,14 +125,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->sp->sizeupvalues, p->sp->upvalues[uv].name);
|
||||
TString *s = check_exp(uv < p->sizeupvalues, p->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->sp->numparams;
|
||||
int nparams = clLvalue(ci->func)->p->numparams;
|
||||
if (n >= cast_int(ci->u.l.base - ci->func) - nparams)
|
||||
return NULL; /* no such vararg */
|
||||
else {
|
||||
@@ -216,7 +216,7 @@ static void funcinfo (lua_Debug *ar, Closure *cl) {
|
||||
ar->what = "C";
|
||||
}
|
||||
else {
|
||||
SharedProto *p = cl->l.p->sp;
|
||||
Proto *p = cl->l.p;
|
||||
ar->source = p->source ? getstr(p->source) : "=?";
|
||||
ar->linedefined = p->linedefined;
|
||||
ar->lastlinedefined = p->lastlinedefined;
|
||||
@@ -234,12 +234,12 @@ static void collectvalidlines (lua_State *L, Closure *f) {
|
||||
else {
|
||||
int i;
|
||||
TValue v;
|
||||
int *lineinfo = f->l.p->sp->lineinfo;
|
||||
int *lineinfo = f->l.p->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->sp->sizelineinfo; i++) /* for all lines with code */
|
||||
for (i = 0; i < f->l.p->sizelineinfo; i++) /* for all lines with code */
|
||||
luaH_setint(L, t, lineinfo[i], &v); /* table[line] = true */
|
||||
}
|
||||
}
|
||||
@@ -279,8 +279,8 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
|
||||
ar->nparams = 0;
|
||||
}
|
||||
else {
|
||||
ar->isvararg = f->l.p->sp->is_vararg;
|
||||
ar->nparams = f->l.p->sp->numparams;
|
||||
ar->isvararg = f->l.p->is_vararg;
|
||||
ar->nparams = f->l.p->numparams;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -387,7 +387,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->sp->code[pc];
|
||||
Instruction i = p->code[pc];
|
||||
OpCode op = GET_OPCODE(i);
|
||||
int a = GETARG_A(i);
|
||||
switch (op) {
|
||||
@@ -437,7 +437,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->sp->code[pc];
|
||||
Instruction i = p->code[pc];
|
||||
OpCode op = GET_OPCODE(i);
|
||||
switch (op) {
|
||||
case OP_MOVE: {
|
||||
@@ -463,7 +463,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->sp->code[pc + 1]);
|
||||
: GETARG_Ax(p->code[pc + 1]);
|
||||
if (ttisstring(&p->k[b])) {
|
||||
*name = svalue(&p->k[b]);
|
||||
return "constant";
|
||||
@@ -493,7 +493,7 @@ static const char *funcnamefromcode (lua_State *L, CallInfo *ci,
|
||||
TMS tm = (TMS)0; /* (initial value avoids warnings) */
|
||||
Proto *p = ci_func(ci)->p; /* calling function */
|
||||
int pc = currentpc(ci); /* calling instruction index */
|
||||
Instruction i = p->sp->code[pc]; /* calling instruction */
|
||||
Instruction i = p->code[pc]; /* calling instruction */
|
||||
if (ci->callstatus & CIST_HOOKED) { /* was it called inside a hook? */
|
||||
*name = "?";
|
||||
return "hook";
|
||||
@@ -658,7 +658,7 @@ l_noret luaG_runerror (lua_State *L, const char *fmt, ...) {
|
||||
msg = luaO_pushvfstring(L, fmt, argp); /* format message */
|
||||
va_end(argp);
|
||||
if (isLua(ci)) /* if Lua function, add source:line information */
|
||||
luaG_addinfo(L, msg, ci_func(ci)->p->sp->source, currentline(ci));
|
||||
luaG_addinfo(L, msg, ci_func(ci)->p->source, currentline(ci));
|
||||
luaG_errormsg(L);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,9 +11,9 @@
|
||||
#include "lstate.h"
|
||||
|
||||
|
||||
#define pcRel(pc, p) (cast(int, (pc) - (p)->sp->code) - 1)
|
||||
#define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1)
|
||||
|
||||
#define getfuncline(f,pc) (((f)->sp->lineinfo) ? (f)->sp->lineinfo[pc] : -1)
|
||||
#define getfuncline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : -1)
|
||||
|
||||
#define resethookcount(L) (L->hookcount = L->basehookcount)
|
||||
|
||||
|
||||
@@ -290,7 +290,7 @@ static void callhook (lua_State *L, CallInfo *ci) {
|
||||
}
|
||||
|
||||
|
||||
static StkId adjust_varargs (lua_State *L, SharedProto *p, int actual) {
|
||||
static StkId adjust_varargs (lua_State *L, Proto *p, int actual) {
|
||||
int i;
|
||||
int nfixargs = p->numparams;
|
||||
StkId base, fixed;
|
||||
@@ -439,7 +439,7 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
|
||||
}
|
||||
case LUA_TLCL: { /* Lua function: prepare its call */
|
||||
StkId base;
|
||||
SharedProto *p = clLvalue(func)->p->sp;
|
||||
Proto *p = clLvalue(func)->p;
|
||||
int n = cast_int(L->top - func) - 1; /* number of real arguments */
|
||||
int fsize = p->maxstacksize; /* frame size */
|
||||
checkstackp(L, fsize, func);
|
||||
@@ -775,7 +775,7 @@ static void f_parser (lua_State *L, void *ud) {
|
||||
checkmode(L, p->mode, "text");
|
||||
cl = luaY_parser(L, p->z, &p->buff, &p->dyd, p->name, c);
|
||||
}
|
||||
lua_assert(cl->nupvalues == cl->p->sp->sizeupvalues);
|
||||
lua_assert(cl->nupvalues == cl->p->sizeupvalues);
|
||||
luaF_initupvals(L, cl);
|
||||
}
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ static void DumpString (const TString *s, DumpState *D) {
|
||||
}
|
||||
|
||||
|
||||
static void DumpCode (const SharedProto *f, DumpState *D) {
|
||||
static void DumpCode (const Proto *f, DumpState *D) {
|
||||
DumpInt(f->sizecode, D);
|
||||
DumpVector(f->code, f->sizecode, D);
|
||||
}
|
||||
@@ -97,7 +97,7 @@ static void DumpFunction(const Proto *f, TString *psource, DumpState *D);
|
||||
|
||||
static void DumpConstants (const Proto *f, DumpState *D) {
|
||||
int i;
|
||||
int n = f->sp->sizek;
|
||||
int n = f->sizek;
|
||||
DumpInt(n, D);
|
||||
for (i = 0; i < n; i++) {
|
||||
const TValue *o = &f->k[i];
|
||||
@@ -127,14 +127,14 @@ static void DumpConstants (const Proto *f, DumpState *D) {
|
||||
|
||||
static void DumpProtos (const Proto *f, DumpState *D) {
|
||||
int i;
|
||||
int n = f->sp->sizep;
|
||||
int n = f->sizep;
|
||||
DumpInt(n, D);
|
||||
for (i = 0; i < n; i++)
|
||||
DumpFunction(f->p[i], f->sp->source, D);
|
||||
DumpFunction(f->p[i], f->source, D);
|
||||
}
|
||||
|
||||
|
||||
static void DumpUpvalues (const SharedProto *f, DumpState *D) {
|
||||
static void DumpUpvalues (const Proto *f, DumpState *D) {
|
||||
int i, n = f->sizeupvalues;
|
||||
DumpInt(n, D);
|
||||
for (i = 0; i < n; i++) {
|
||||
@@ -144,7 +144,7 @@ static void DumpUpvalues (const SharedProto *f, DumpState *D) {
|
||||
}
|
||||
|
||||
|
||||
static void DumpDebug (const SharedProto *f, DumpState *D) {
|
||||
static void DumpDebug (const Proto *f, DumpState *D) {
|
||||
int i, n;
|
||||
n = (D->strip) ? 0 : f->sizelineinfo;
|
||||
DumpInt(n, D);
|
||||
@@ -163,8 +163,7 @@ static void DumpDebug (const SharedProto *f, DumpState *D) {
|
||||
}
|
||||
|
||||
|
||||
static void DumpFunction (const Proto *fp, TString *psource, DumpState *D) {
|
||||
const SharedProto *f = fp->sp;
|
||||
static void DumpFunction (const Proto *f, TString *psource, DumpState *D) {
|
||||
if (D->strip || f->source == psource)
|
||||
DumpString(NULL, D); /* no debug info or same source as its parent */
|
||||
else
|
||||
@@ -175,9 +174,9 @@ static void DumpFunction (const Proto *fp, TString *psource, DumpState *D) {
|
||||
DumpByte(f->is_vararg, D);
|
||||
DumpByte(f->maxstacksize, D);
|
||||
DumpCode(f, D);
|
||||
DumpConstants(fp, D);
|
||||
DumpConstants(f, D);
|
||||
DumpUpvalues(f, D);
|
||||
DumpProtos(fp, D);
|
||||
DumpProtos(f, D);
|
||||
DumpDebug(f, D);
|
||||
}
|
||||
|
||||
@@ -209,7 +208,7 @@ int luaU_dump(lua_State *L, const Proto *f, lua_Writer w, void *data,
|
||||
D.strip = strip;
|
||||
D.status = 0;
|
||||
DumpHeader(&D);
|
||||
DumpByte(f->sp->sizeupvalues, &D);
|
||||
DumpByte(f->sizeupvalues, &D);
|
||||
DumpFunction(f, NULL, &D);
|
||||
return D.status;
|
||||
}
|
||||
|
||||
@@ -96,59 +96,39 @@ void luaF_close (lua_State *L, StkId level) {
|
||||
}
|
||||
|
||||
|
||||
Proto *luaF_newproto (lua_State *L, SharedProto *sp) {
|
||||
Proto *luaF_newproto (lua_State *L) {
|
||||
GCObject *o = luaC_newobj(L, LUA_TPROTO, sizeof(Proto));
|
||||
Proto *f = gco2p(o);
|
||||
f->sp = NULL;
|
||||
f->k = NULL;
|
||||
f->sizek = 0;
|
||||
f->p = NULL;
|
||||
f->cache = 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;
|
||||
sp->k = NULL;
|
||||
sp->sharedk = 0;
|
||||
}
|
||||
f->sp = sp;
|
||||
f->sizep = 0;
|
||||
f->code = 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;
|
||||
f->l_G = G(L);
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
static void freesharedproto (lua_State *L, Proto *pf) {
|
||||
SharedProto *f = pf->sp;
|
||||
if (f == NULL)
|
||||
return;
|
||||
if (G(L) == f->l_G) {
|
||||
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_freearray(L, f->k, f->sizek);
|
||||
luaM_free(L, f);
|
||||
} else if (pf->k != f->k) {
|
||||
luaM_freearray(L, pf->k, f->sizek);
|
||||
}
|
||||
}
|
||||
|
||||
void luaF_freeproto (lua_State *L, Proto *f) {
|
||||
luaM_freearray(L, f->p, f->sp->sizep);
|
||||
freesharedproto(L, f);
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -157,9 +137,8 @@ void luaF_freeproto (lua_State *L, Proto *f) {
|
||||
** Look for n-th local variable at line 'line' in function 'func'.
|
||||
** Returns NULL if not found.
|
||||
*/
|
||||
const char *luaF_getlocalname (const Proto *fp, int local_number, int pc) {
|
||||
const char *luaF_getlocalname (const Proto *f, 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--;
|
||||
@@ -170,3 +149,21 @@ const char *luaF_getlocalname (const Proto *fp, int local_number, int pc) {
|
||||
return NULL; /* not found */
|
||||
}
|
||||
|
||||
#define MAKESHARED(x) if ((x) && (x)->tt == LUA_TLNGSTR) makeshared(x)
|
||||
|
||||
void luaF_shareproto (Proto *f) {
|
||||
int i;
|
||||
if (f == NULL)
|
||||
return;
|
||||
MAKESHARED(f->source);
|
||||
for (i = 0; i < f->sizek; i++) {
|
||||
if (ttype(&f->k[i]) == LUA_TSTRING)
|
||||
MAKESHARED(tsvalue(&f->k[i]));
|
||||
}
|
||||
for (i = 0; i < f->sizeupvalues; i++)
|
||||
MAKESHARED(f->upvalues[i].name);
|
||||
for (i = 0; i < f->sizelocvars; i++)
|
||||
MAKESHARED(f->locvars[i].varname);
|
||||
for (i = 0; i < f->sizep; i++)
|
||||
luaF_shareproto(f->p[i]);
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ struct UpVal {
|
||||
#define upisopen(up) ((up)->v != &(up)->u.value)
|
||||
|
||||
|
||||
LUAI_FUNC Proto *luaF_newproto (lua_State *L, SharedProto *sp);
|
||||
LUAI_FUNC Proto *luaF_newproto (lua_State *L);
|
||||
LUAI_FUNC CClosure *luaF_newCclosure (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);
|
||||
@@ -56,6 +56,7 @@ LUAI_FUNC void luaF_close (lua_State *L, StkId level);
|
||||
LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f);
|
||||
LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number,
|
||||
int pc);
|
||||
LUAI_FUNC void luaF_shareproto (Proto *func);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -193,6 +193,10 @@ void luaC_upvalbarrier_ (lua_State *L, UpVal *uv) {
|
||||
|
||||
void luaC_fix (lua_State *L, GCObject *o) {
|
||||
global_State *g = G(L);
|
||||
if (o->tt == LUA_TSHRSTR) {
|
||||
luaS_fix(g, gco2ts(o));
|
||||
return;
|
||||
}
|
||||
if (g->allgc != o)
|
||||
return; /* if object is not 1st in 'allgc' list, it is in global short string table */
|
||||
white2gray(o); /* they will be gray forever */
|
||||
@@ -235,20 +239,22 @@ GCObject *luaC_newobj (lua_State *L, int tt, size_t sz) {
|
||||
*/
|
||||
static void reallymarkobject (global_State *g, GCObject *o) {
|
||||
reentry:
|
||||
white2gray(o);
|
||||
switch (o->tt) {
|
||||
case LUA_TSHRSTR: {
|
||||
gray2black(o);
|
||||
g->GCmemtrav += sizelstring(gco2ts(o)->shrlen);
|
||||
luaS_mark(g, gco2ts(o));
|
||||
break;
|
||||
}
|
||||
case LUA_TLNGSTR: {
|
||||
gray2black(o);
|
||||
g->GCmemtrav += sizelstring(gco2ts(o)->u.lnglen);
|
||||
if (!isshared(o)) {
|
||||
white2gray(o);
|
||||
gray2black(o);
|
||||
g->GCmemtrav += sizelstring(gco2ts(o)->u.lnglen);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case LUA_TUSERDATA: {
|
||||
TValue uvalue;
|
||||
white2gray(o);
|
||||
markobjectN(g, gco2u(o)->metatable); /* mark its metatable */
|
||||
gray2black(o);
|
||||
g->GCmemtrav += sizeudata(gco2u(o));
|
||||
@@ -260,23 +266,31 @@ static void reallymarkobject (global_State *g, GCObject *o) {
|
||||
break;
|
||||
}
|
||||
case LUA_TLCL: {
|
||||
white2gray(o);
|
||||
linkgclist(gco2lcl(o), g->gray);
|
||||
break;
|
||||
}
|
||||
case LUA_TCCL: {
|
||||
white2gray(o);
|
||||
linkgclist(gco2ccl(o), g->gray);
|
||||
break;
|
||||
}
|
||||
case LUA_TTABLE: {
|
||||
linkgclist(gco2t(o), g->gray);
|
||||
if (!isshared(o))
|
||||
white2gray(o);
|
||||
linkgclist(gco2t(o), g->gray);
|
||||
break;
|
||||
}
|
||||
case LUA_TTHREAD: {
|
||||
white2gray(o);
|
||||
linkgclist(gco2th(o), g->gray);
|
||||
break;
|
||||
}
|
||||
case LUA_TPROTO: {
|
||||
linkgclist(gco2p(o), g->gray);
|
||||
if (!isshared(o)) {
|
||||
white2gray(o);
|
||||
linkgclist(gco2p(o), g->gray);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: lua_assert(0); break;
|
||||
@@ -471,20 +485,6 @@ static lu_mem traversetable (global_State *g, Table *h) {
|
||||
sizeof(Node) * cast(size_t, allocsizenode(h));
|
||||
}
|
||||
|
||||
static int marksharedproto (global_State *g, SharedProto *f) {
|
||||
int i;
|
||||
if (g != f->l_G)
|
||||
return 0;
|
||||
markobjectN(g, f->source);
|
||||
for (i = 0; i < f->sizeupvalues; i++) /* mark upvalue names */
|
||||
markobjectN(g, f->upvalues[i].name);
|
||||
for (i = 0; i < f->sizelocvars; i++) /* mark local-variable names */
|
||||
markobjectN(g, f->locvars[i].varname);
|
||||
return sizeof(Instruction) * f->sizecode +
|
||||
sizeof(int) * f->sizelineinfo +
|
||||
sizeof(LocVar) * f->sizelocvars +
|
||||
sizeof(Upvaldesc) * f->sizeupvalues;
|
||||
}
|
||||
|
||||
/*
|
||||
** Traverse a prototype. (While a prototype is being build, its
|
||||
@@ -492,20 +492,24 @@ static int marksharedproto (global_State *g, SharedProto *f) {
|
||||
** NULL, so the use of 'markobjectN')
|
||||
*/
|
||||
static int traverseproto (global_State *g, Proto *f) {
|
||||
int i,nk,np;
|
||||
if (f->cache && iswhite(f->cache))
|
||||
f->cache = NULL; /* allow cache to be collected */
|
||||
if (f->sp == NULL)
|
||||
return sizeof(Proto);
|
||||
nk = (f->k == f->sp->k && g != f->sp->l_G) ? 0 : f->sp->sizek;
|
||||
np = (f->p == NULL) ? 0 : f->sp->sizep;
|
||||
for (i = 0; i < nk; i++) /* mark literals */
|
||||
int i;
|
||||
if (g != f->l_G)
|
||||
return 0;
|
||||
markobjectN(g, f->source);
|
||||
for (i = 0; i < f->sizek; i++) /* mark literals */
|
||||
markvalue(g, &f->k[i]);
|
||||
for (i = 0; i < np; i++) /* mark nested protos */
|
||||
for (i = 0; i < f->sizeupvalues; i++) /* mark upvalue names */
|
||||
markobjectN(g, f->upvalues[i].name);
|
||||
for (i = 0; i < f->sizep; i++) /* mark nested protos */
|
||||
markobjectN(g, f->p[i]);
|
||||
return sizeof(Proto) + sizeof(Proto *) * np +
|
||||
sizeof(TValue) * nk +
|
||||
marksharedproto(g, f->sp);
|
||||
for (i = 0; i < f->sizelocvars; i++) /* mark local-variable names */
|
||||
markobjectN(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;
|
||||
}
|
||||
|
||||
|
||||
@@ -719,10 +723,6 @@ static void freeobj (lua_State *L, GCObject *o) {
|
||||
case LUA_TTABLE: luaH_free(L, gco2t(o)); break;
|
||||
case LUA_TTHREAD: luaE_freethread(L, gco2th(o)); break;
|
||||
case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break;
|
||||
case LUA_TSHRSTR:
|
||||
luaS_remove(L, gco2ts(o)); /* remove it from hash table */
|
||||
luaM_freemem(L, o, sizelstring(gco2ts(o)->shrlen));
|
||||
break;
|
||||
case LUA_TLNGSTR: {
|
||||
luaM_freemem(L, o, sizelstring(gco2ts(o)->u.lnglen));
|
||||
break;
|
||||
@@ -745,7 +745,7 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count);
|
||||
*/
|
||||
static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
|
||||
global_State *g = G(L);
|
||||
int ow = otherwhite(g);
|
||||
int ow = otherwhite(g) | bitmask(SHAREBIT); /* shared object never dead */
|
||||
int white = luaC_white(g); /* current white */
|
||||
while (*p != NULL && count-- > 0) {
|
||||
GCObject *curr = *p;
|
||||
@@ -783,19 +783,6 @@ static GCObject **sweeptolive (lua_State *L, GCObject **p) {
|
||||
** =======================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
** If possible, shrink string table
|
||||
*/
|
||||
static void checkSizes (lua_State *L, global_State *g) {
|
||||
if (g->gckind != KGC_EMERGENCY) {
|
||||
l_mem olddebt = g->GCdebt;
|
||||
if (g->strt.nuse < g->strt.size / 4) /* string table too big? */
|
||||
luaS_resize(L, g->strt.size / 2); /* shrink it a little */
|
||||
g->GCestimate += g->GCdebt - olddebt; /* update estimate */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static GCObject *udata2finalize (global_State *g) {
|
||||
GCObject *o = g->tobefnz; /* get first element */
|
||||
lua_assert(tofinalize(o));
|
||||
@@ -986,7 +973,6 @@ void luaC_freeallobjects (lua_State *L) {
|
||||
sweepwholelist(L, &g->finobj);
|
||||
sweepwholelist(L, &g->allgc);
|
||||
sweepwholelist(L, &g->fixedgc); /* collect fixed objects */
|
||||
lua_assert(g->strt.nuse == 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -1057,7 +1043,7 @@ static lu_mem singlestep (lua_State *L) {
|
||||
global_State *g = G(L);
|
||||
switch (g->gcstate) {
|
||||
case GCSpause: {
|
||||
g->GCmemtrav = g->strt.size * sizeof(GCObject*);
|
||||
g->GCmemtrav = 0;
|
||||
restartcollection(g);
|
||||
g->gcstate = GCSpropagate;
|
||||
return g->GCmemtrav;
|
||||
@@ -1089,7 +1075,6 @@ static lu_mem singlestep (lua_State *L) {
|
||||
}
|
||||
case GCSswpend: { /* finish sweeps */
|
||||
makewhite(g, g->mainthread); /* sweep main thread */
|
||||
checkSizes(L, g);
|
||||
g->gcstate = GCScallfin;
|
||||
return 0;
|
||||
}
|
||||
@@ -1099,6 +1084,7 @@ static lu_mem singlestep (lua_State *L) {
|
||||
return (n * GCFINALIZECOST);
|
||||
}
|
||||
else { /* emergency mode or no more finalizers */
|
||||
luaS_collect(g, 0); /* send short strings set to gc thread */
|
||||
g->gcstate = GCSpause; /* finish collection */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -79,11 +79,13 @@
|
||||
#define WHITE1BIT 1 /* object is white (type 1) */
|
||||
#define BLACKBIT 2 /* object is black */
|
||||
#define FINALIZEDBIT 3 /* object has been marked for finalization */
|
||||
#define SHAREBIT 4 /* object shared from other state */
|
||||
/* bit 7 is currently used by tests (luaL_checkmemory) */
|
||||
|
||||
#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT)
|
||||
|
||||
|
||||
/* short string is always white */
|
||||
#define iswhite(x) testbits((x)->marked, WHITEBITS)
|
||||
#define isblack(x) testbit((x)->marked, BLACKBIT)
|
||||
#define isgray(x) /* neither white nor black */ \
|
||||
@@ -91,9 +93,11 @@
|
||||
|
||||
#define tofinalize(x) testbit((x)->marked, FINALIZEDBIT)
|
||||
|
||||
#define isshared(x) testbit((x)->marked, SHAREBIT)
|
||||
#define makeshared(x) l_setbit((x)->marked, SHAREBIT)
|
||||
#define otherwhite(g) ((g)->currentwhite ^ WHITEBITS)
|
||||
#define isdeadm(ow,m) (!(((m) ^ WHITEBITS) & (ow)))
|
||||
#define isdead(g,v) isdeadm(otherwhite(g), (v)->marked)
|
||||
#define isdead(g,v) isdeadm(otherwhite(g) | bitmask(SHAREBIT), (v)->marked)
|
||||
|
||||
#define changewhite(x) ((x)->marked ^= WHITEBITS)
|
||||
#define gray2black(x) l_setbit((x)->marked, BLACKBIT)
|
||||
|
||||
@@ -307,7 +307,7 @@ typedef struct TString {
|
||||
unsigned int hash;
|
||||
union {
|
||||
size_t lnglen; /* length for long strings */
|
||||
struct TString *hnext; /* linked list for hash table */
|
||||
size_t ref; /* reference count for short strings */
|
||||
} u;
|
||||
} TString;
|
||||
|
||||
@@ -400,11 +400,15 @@ typedef struct LocVar {
|
||||
int endpc; /* first point where variable is dead */
|
||||
} LocVar;
|
||||
|
||||
typedef struct SharedProto {
|
||||
|
||||
/*
|
||||
** Function Prototypes
|
||||
*/
|
||||
typedef struct Proto {
|
||||
CommonHeader;
|
||||
lu_byte numparams; /* number of fixed parameters */
|
||||
lu_byte is_vararg;
|
||||
lu_byte maxstacksize; /* number of registers needed by this function */
|
||||
lu_byte sharedk; /* constants can be shared directly */
|
||||
int sizeupvalues; /* size of 'upvalues' */
|
||||
int sizek; /* size of 'k' */
|
||||
int sizecode;
|
||||
@@ -413,25 +417,15 @@ typedef struct SharedProto {
|
||||
int sizelocvars;
|
||||
int linedefined; /* debug information */
|
||||
int lastlinedefined; /* debug information */
|
||||
void *l_G; /* global state belongs to */
|
||||
TValue *k; /* constants used by the function */
|
||||
Instruction *code; /* opcodes */
|
||||
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 */
|
||||
TString *source; /* used for debug information */
|
||||
TValue *k; /* Shared constants */
|
||||
} 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;
|
||||
void *l_G; /* global state belongs to */
|
||||
} Proto;
|
||||
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ static l_noret error_expected (LexState *ls, int token) {
|
||||
static l_noret errorlimit (FuncState *fs, int limit, const char *what) {
|
||||
lua_State *L = fs->ls->L;
|
||||
const char *msg;
|
||||
int line = fs->f->sp->linedefined;
|
||||
int line = fs->f->linedefined;
|
||||
const char *where = (line == 0)
|
||||
? "main function"
|
||||
: luaO_pushfstring(L, "function at line %d", line);
|
||||
@@ -160,15 +160,14 @@ static void checkname (LexState *ls, expdesc *e) {
|
||||
|
||||
static int registerlocalvar (LexState *ls, TString *varname) {
|
||||
FuncState *fs = ls->fs;
|
||||
Proto *fp = fs->f;
|
||||
SharedProto *f = fp->sp;
|
||||
Proto *f = fs->f;
|
||||
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, fp, varname);
|
||||
luaC_objbarrier(ls->L, f, varname);
|
||||
return fs->nlocvars++;
|
||||
}
|
||||
|
||||
@@ -196,7 +195,7 @@ static void new_localvarliteral_ (LexState *ls, const char *name, size_t sz) {
|
||||
static LocVar *getlocvar (FuncState *fs, int i) {
|
||||
int idx = fs->ls->dyd->actvar.arr[fs->firstlocal + i].idx;
|
||||
lua_assert(idx < fs->nlocvars);
|
||||
return &fs->f->sp->locvars[idx];
|
||||
return &fs->f->locvars[idx];
|
||||
}
|
||||
|
||||
|
||||
@@ -218,7 +217,7 @@ static void removevars (FuncState *fs, int tolevel) {
|
||||
|
||||
static int searchupvalue (FuncState *fs, TString *name) {
|
||||
int i;
|
||||
Upvaldesc *up = fs->f->sp->upvalues;
|
||||
Upvaldesc *up = fs->f->upvalues;
|
||||
for (i = 0; i < fs->nups; i++) {
|
||||
if (eqstr(up[i].name, name)) return i;
|
||||
}
|
||||
@@ -227,8 +226,7 @@ static int searchupvalue (FuncState *fs, TString *name) {
|
||||
|
||||
|
||||
static int newupvalue (FuncState *fs, TString *name, expdesc *v) {
|
||||
Proto *fp = fs->f;
|
||||
SharedProto *f = fp->sp;
|
||||
Proto *f = fs->f;
|
||||
int oldsize = f->sizeupvalues;
|
||||
checklimit(fs, fs->nups + 1, MAXUPVAL, "upvalues");
|
||||
luaM_growvector(fs->ls->L, f->upvalues, fs->nups, f->sizeupvalues,
|
||||
@@ -238,7 +236,7 @@ static int newupvalue (FuncState *fs, TString *name, expdesc *v) {
|
||||
f->upvalues[fs->nups].instack = (v->k == VLOCAL);
|
||||
f->upvalues[fs->nups].idx = cast_byte(v->u.info);
|
||||
f->upvalues[fs->nups].name = name;
|
||||
luaC_objbarrier(fs->ls->L, fp, name);
|
||||
luaC_objbarrier(fs->ls->L, f, name);
|
||||
return fs->nups++;
|
||||
}
|
||||
|
||||
@@ -503,13 +501,13 @@ 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->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)
|
||||
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;
|
||||
}
|
||||
f->p[fs->np++] = clp = luaF_newproto(L, NULL);
|
||||
f->p[fs->np++] = clp = luaF_newproto(L);
|
||||
luaC_objbarrier(L, f, clp);
|
||||
return clp;
|
||||
}
|
||||
@@ -529,7 +527,7 @@ static void codeclosure (LexState *ls, expdesc *v) {
|
||||
|
||||
|
||||
static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) {
|
||||
SharedProto *f;
|
||||
Proto *f;
|
||||
fs->prev = ls->fs; /* linked list of funcstates */
|
||||
fs->ls = ls;
|
||||
ls->fs = fs;
|
||||
@@ -544,42 +542,31 @@ 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->sp;
|
||||
f = fs->f;
|
||||
f->source = ls->source;
|
||||
f->maxstacksize = 2; /* registers 0/1 are always valid */
|
||||
enterblock(fs, bl, 0);
|
||||
}
|
||||
|
||||
static lu_byte check_shortstring(const TValue *k, int sizek) {
|
||||
int i;
|
||||
for (i=0;i<sizek;i++) {
|
||||
if (ttisshrstring(&k[i]))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
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, 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->sharedk = check_shortstring(f->k, fs->nk);
|
||||
sp->k = f->k;
|
||||
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;
|
||||
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;
|
||||
lua_assert(fs->bl == NULL);
|
||||
ls->fs = fs->prev;
|
||||
luaC_checkGC(L);
|
||||
@@ -755,8 +742,8 @@ static void constructor (LexState *ls, expdesc *t) {
|
||||
} while (testnext(ls, ',') || testnext(ls, ';'));
|
||||
check_match(ls, '}', '{', line);
|
||||
lastlistfield(fs, &cc);
|
||||
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 */
|
||||
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 */
|
||||
}
|
||||
|
||||
/* }====================================================================== */
|
||||
@@ -766,7 +753,7 @@ static void constructor (LexState *ls, expdesc *t) {
|
||||
static void parlist (LexState *ls) {
|
||||
/* parlist -> [ param { ',' param } ] */
|
||||
FuncState *fs = ls->fs;
|
||||
SharedProto *f = fs->f->sp;
|
||||
Proto *f = fs->f;
|
||||
int nparams = 0;
|
||||
f->is_vararg = 0;
|
||||
if (ls->t.token != ')') { /* is 'parlist' not empty? */
|
||||
@@ -797,7 +784,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->sp->linedefined = line;
|
||||
new_fs.f->linedefined = line;
|
||||
open_func(ls, &new_fs, &bl);
|
||||
checknext(ls, '(');
|
||||
if (ismethod) {
|
||||
@@ -807,7 +794,7 @@ static void body (LexState *ls, expdesc *e, int ismethod, int line) {
|
||||
parlist(ls);
|
||||
checknext(ls, ')');
|
||||
statlist(ls);
|
||||
new_fs.f->sp->lastlinedefined = ls->linenumber;
|
||||
new_fs.f->lastlinedefined = ls->linenumber;
|
||||
check_match(ls, TK_END, TK_FUNCTION, line);
|
||||
codeclosure(ls, e);
|
||||
close_func(ls);
|
||||
@@ -973,7 +960,7 @@ static void simpleexp (LexState *ls, expdesc *v) {
|
||||
}
|
||||
case TK_DOTS: { /* vararg */
|
||||
FuncState *fs = ls->fs;
|
||||
check_condition(ls, fs->f->sp->is_vararg,
|
||||
check_condition(ls, fs->f->is_vararg,
|
||||
"cannot use '...' outside a vararg function");
|
||||
init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0));
|
||||
break;
|
||||
@@ -1609,7 +1596,7 @@ static void statement (LexState *ls) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
lua_assert(ls->fs->f->sp->maxstacksize >= ls->fs->freereg &&
|
||||
lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg &&
|
||||
ls->fs->freereg >= ls->fs->nactvar);
|
||||
ls->fs->freereg = ls->fs->nactvar; /* free registers */
|
||||
leavelevel(ls);
|
||||
@@ -1626,7 +1613,7 @@ static void mainfunc (LexState *ls, FuncState *fs) {
|
||||
BlockCnt bl;
|
||||
expdesc v;
|
||||
open_func(ls, fs, &bl);
|
||||
fs->f->sp->is_vararg = 1; /* main function is always declared vararg */
|
||||
fs->f->is_vararg = 1; /* main function is always declared vararg */
|
||||
init_exp(&v, VLOCAL, 0); /* create and... */
|
||||
newupvalue(fs, ls->envn, &v); /* ...set environment upvalue */
|
||||
luaX_next(ls); /* read first token */
|
||||
@@ -1646,13 +1633,13 @@ LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
|
||||
lexstate.h = luaH_new(L); /* create table for scanner */
|
||||
sethvalue(L, L->top, lexstate.h); /* anchor it */
|
||||
luaD_inctop(L);
|
||||
funcstate.f = cl->p = luaF_newproto(L, NULL);
|
||||
funcstate.f->sp->source = luaS_new(L, name); /* create and anchor TString */
|
||||
funcstate.f = cl->p = luaF_newproto(L);
|
||||
funcstate.f->source = luaS_new(L, name); /* create and anchor TString */
|
||||
lua_assert(iswhite(funcstate.f)); /* do not need barrier here */
|
||||
lexstate.buff = buff;
|
||||
lexstate.dyd = dyd;
|
||||
dyd->actvar.n = dyd->gt.n = dyd->label.n = 0;
|
||||
luaX_setinput(L, &lexstate, z, funcstate.f->sp->source, firstchar);
|
||||
luaX_setinput(L, &lexstate, z, funcstate.f->source, firstchar);
|
||||
mainfunc(&lexstate, &funcstate);
|
||||
lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs);
|
||||
/* all scopes should be correctly finished */
|
||||
|
||||
@@ -70,27 +70,6 @@ typedef struct LG {
|
||||
#define fromstate(L) (cast(LX *, cast(lu_byte *, (L)) - offsetof(LX, l)))
|
||||
|
||||
|
||||
/*
|
||||
** Compute an initial seed as random as possible. Rely on Address Space
|
||||
** Layout Randomization (if present) to increase randomness..
|
||||
*/
|
||||
#define addbuff(b,p,e) \
|
||||
{ size_t t = cast(size_t, e); \
|
||||
memcpy(b + p, &t, sizeof(t)); p += sizeof(t); }
|
||||
|
||||
static unsigned int makeseed (lua_State *L) {
|
||||
char buff[4 * sizeof(size_t)];
|
||||
unsigned int h = luai_makeseed();
|
||||
int p = 0;
|
||||
addbuff(buff, p, L); /* heap variable */
|
||||
addbuff(buff, p, &h); /* local variable */
|
||||
addbuff(buff, p, luaO_nilobject); /* global variable */
|
||||
addbuff(buff, p, &lua_newstate); /* public function */
|
||||
lua_assert(p == sizeof(buff));
|
||||
return luaS_hash(buff, p, h);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** set GCdebt to a new value keeping the value (totalbytes + GCdebt)
|
||||
** invariant (and avoiding underflows in 'totalbytes')
|
||||
@@ -245,7 +224,7 @@ static void close_state (lua_State *L) {
|
||||
luaC_freeallobjects(L); /* collect all objects */
|
||||
if (g->version) /* closing a fully built state? */
|
||||
luai_userstateclose(L);
|
||||
luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size);
|
||||
luaS_collect(g, 1); /* clear short strings */
|
||||
freestack(L);
|
||||
lua_assert(gettotalbytes(g) == sizeof(LG));
|
||||
(*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0); /* free main block */
|
||||
@@ -308,11 +287,8 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
|
||||
g->frealloc = f;
|
||||
g->ud = ud;
|
||||
g->mainthread = L;
|
||||
g->seed = makeseed(L);
|
||||
g->gcrunning = 0; /* no GC while building state */
|
||||
g->GCestimate = 0;
|
||||
g->strt.size = g->strt.nuse = 0;
|
||||
g->strt.hash = NULL;
|
||||
setnilvalue(&g->l_registry);
|
||||
g->panic = NULL;
|
||||
g->version = NULL;
|
||||
@@ -328,6 +304,9 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
|
||||
g->gcfinnum = 0;
|
||||
g->gcpause = LUAI_GCPAUSE;
|
||||
g->gcstepmul = LUAI_GCMUL;
|
||||
g->strsave = NULL;
|
||||
g->strmark = NULL;
|
||||
g->strfix = NULL;
|
||||
for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL;
|
||||
if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) {
|
||||
/* memory allocation error: free partial state */
|
||||
|
||||
@@ -130,6 +130,8 @@ typedef struct CallInfo {
|
||||
#define setoah(st,v) ((st) = ((st) & ~CIST_OAH) | (v))
|
||||
#define getoah(st) ((st) & CIST_OAH)
|
||||
|
||||
/* SSM (short string map) See lstring.c */
|
||||
struct ssm_ref;
|
||||
|
||||
/*
|
||||
** 'global state', shared by all threads of this state
|
||||
@@ -141,9 +143,7 @@ typedef struct global_State {
|
||||
l_mem GCdebt; /* bytes allocated not yet compensated by the collector */
|
||||
lu_mem GCmemtrav; /* memory traversed by the GC */
|
||||
lu_mem GCestimate; /* an estimate of the non-garbage memory in use */
|
||||
stringtable strt; /* hash table for strings */
|
||||
TValue l_registry;
|
||||
unsigned int seed; /* randomized seed for hashes */
|
||||
lu_byte currentwhite;
|
||||
lu_byte gcstate; /* state of garbage collector */
|
||||
lu_byte gckind; /* kind of GC running */
|
||||
@@ -169,6 +169,9 @@ typedef struct global_State {
|
||||
TString *tmname[TM_N]; /* array with tag-method names */
|
||||
struct Table *mt[LUA_NUMTAGS]; /* metatables for basic types */
|
||||
TString *strcache[STRCACHE_N][STRCACHE_M]; /* cache for strings in API */
|
||||
struct ssm_ref *strsave;
|
||||
struct ssm_ref *strmark;
|
||||
struct ssm_ref *strfix;
|
||||
} global_State;
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -36,10 +36,8 @@
|
||||
LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed);
|
||||
LUAI_FUNC unsigned int luaS_hashlongstr (TString *ts);
|
||||
LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b);
|
||||
LUAI_FUNC void luaS_resize (lua_State *L, int newsize);
|
||||
LUAI_FUNC void luaS_clearcache (global_State *g);
|
||||
LUAI_FUNC void luaS_init (lua_State *L);
|
||||
LUAI_FUNC void luaS_remove (lua_State *L, TString *ts);
|
||||
LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s);
|
||||
LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l);
|
||||
LUAI_FUNC TString *luaS_new (lua_State *L, const char *str);
|
||||
@@ -47,10 +45,26 @@ LUAI_FUNC TString *luaS_createlngstrobj (lua_State *L, size_t l);
|
||||
|
||||
#define ENABLE_SHORT_STRING_TABLE
|
||||
|
||||
LUA_API void luaS_initshr();
|
||||
LUA_API void luaS_exitshr();
|
||||
LUA_API void luaS_expandshr(int n);
|
||||
LUAI_FUNC TString *luaS_clonestring(lua_State *L, TString *);
|
||||
LUA_API int luaS_shrinfo(lua_State *L);
|
||||
struct ssm_info {
|
||||
int total;
|
||||
int longest;
|
||||
int slots;
|
||||
size_t size;
|
||||
double variance;
|
||||
};
|
||||
|
||||
struct ssm_collect {
|
||||
void *key;
|
||||
int n;
|
||||
};
|
||||
|
||||
LUA_API void luaS_initssm();
|
||||
LUA_API void luaS_exitssm();
|
||||
LUA_API void luaS_infossm(struct ssm_info *info);
|
||||
LUA_API int luaS_collectssm(struct ssm_collect *info);
|
||||
|
||||
LUAI_FUNC void luaS_mark(global_State *g, TString *s);
|
||||
LUAI_FUNC void luaS_fix(global_State *g, TString *s);
|
||||
LUAI_FUNC void luaS_collect(global_State *g, int closed);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -597,7 +597,7 @@ static int pmain (lua_State *L) {
|
||||
int main (int argc, char **argv) {
|
||||
int status, result;
|
||||
lua_State *L;
|
||||
luaS_initshr(); /* init global short string table */
|
||||
luaS_initssm();
|
||||
L = luaL_newstate(); /* create state */
|
||||
if (L == NULL) {
|
||||
l_message(argv[0], "cannot create state: not enough memory");
|
||||
@@ -610,7 +610,7 @@ int main (int argc, char **argv) {
|
||||
result = lua_toboolean(L, -1); /* get result */
|
||||
report(L, status);
|
||||
lua_close(L);
|
||||
luaS_exitshr();
|
||||
luaS_exitssm();
|
||||
return (result && status == LUA_OK) ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
@@ -233,7 +233,8 @@ LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n);
|
||||
LUA_API void (lua_pushboolean) (lua_State *L, int b);
|
||||
LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p);
|
||||
LUA_API int (lua_pushthread) (lua_State *L);
|
||||
|
||||
LUA_API void (lua_clonefunction) (lua_State *L, const void * fp);
|
||||
LUA_API void (lua_sharefunction) (lua_State *L, int index);
|
||||
|
||||
/*
|
||||
** get functions (Lua -> stack)
|
||||
@@ -282,8 +283,6 @@ 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, int strip);
|
||||
|
||||
LUA_API void (lua_clonefunction) (lua_State *L, const void *eL);
|
||||
|
||||
|
||||
/*
|
||||
** coroutine functions
|
||||
@@ -460,11 +459,6 @@ struct lua_Debug {
|
||||
|
||||
/* }====================================================================== */
|
||||
|
||||
/* Add by skynet */
|
||||
|
||||
LUA_API lua_State * skynet_sig_L;
|
||||
LUA_API void (lua_checksig_)(lua_State *L);
|
||||
#define lua_checksig(L) if (skynet_sig_L) { lua_checksig_(L); }
|
||||
|
||||
/******************************************************************************
|
||||
* Copyright (C) 1994-2018 Lua.org, PUC-Rio.
|
||||
|
||||
@@ -150,9 +150,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]->sp->sizeupvalues>0) f->p[i]->sp->upvalues[0].instack=0;
|
||||
if (f->p[i]->sizeupvalues>0) f->p[i]->upvalues[0].instack=0;
|
||||
}
|
||||
f->sp->sizelineinfo=0;
|
||||
f->sizelineinfo=0;
|
||||
return f;
|
||||
}
|
||||
}
|
||||
@@ -193,10 +193,10 @@ static int pmain(lua_State* L)
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
lua_State* L;
|
||||
luaS_initssm();
|
||||
int i=doargs(argc,argv);
|
||||
argc-=i; argv+=i;
|
||||
if (argc<=0) usage("no input files given");
|
||||
luaS_initshr();
|
||||
L=luaL_newstate();
|
||||
if (L==NULL) fatal("cannot create state: not enough memory");
|
||||
lua_pushcfunction(L,&pmain);
|
||||
@@ -204,6 +204,7 @@ int main(int argc, char* argv[])
|
||||
lua_pushlightuserdata(L,argv);
|
||||
if (lua_pcall(L,2,0,0)!=LUA_OK) fatal(lua_tostring(L,-1));
|
||||
lua_close(L);
|
||||
luaS_exitssm();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -284,13 +285,13 @@ static void PrintConstant(const Proto* f, int i)
|
||||
}
|
||||
}
|
||||
|
||||
#define UPVALNAME(x) ((f->sp->upvalues[x].name) ? getstr(f->sp->upvalues[x].name) : "-")
|
||||
#define UPVALNAME(x) ((f->upvalues[x].name) ? getstr(f->upvalues[x].name) : "-")
|
||||
#define MYK(x) (-1-(x))
|
||||
|
||||
static void PrintCode(const Proto* f)
|
||||
{
|
||||
const Instruction* code=f->sp->code;
|
||||
int pc,n=f->sp->sizecode;
|
||||
const Instruction* code=f->code;
|
||||
int pc,n=f->sizecode;
|
||||
for (pc=0; pc<n; pc++)
|
||||
{
|
||||
Instruction i=code[pc];
|
||||
@@ -395,7 +396,7 @@ static void PrintCode(const Proto* f)
|
||||
#define SS(x) ((x==1)?"":"s")
|
||||
#define S(x) (int)(x),SS(x)
|
||||
|
||||
static void PrintHeader(const SharedProto* f)
|
||||
static void PrintHeader(const Proto* f)
|
||||
{
|
||||
const char* s=f->source ? getstr(f->source) : "=?";
|
||||
if (*s=='@' || *s=='=')
|
||||
@@ -417,9 +418,8 @@ static void PrintHeader(const SharedProto* f)
|
||||
|
||||
static void PrintDebug(const Proto* f)
|
||||
{
|
||||
const SharedProto *sp = f->sp;
|
||||
int i,n;
|
||||
n=sp->sizek;
|
||||
n=f->sizek;
|
||||
printf("constants (%d) for %p:\n",n,VOID(f));
|
||||
for (i=0; i<n; i++)
|
||||
{
|
||||
@@ -427,26 +427,26 @@ static void PrintDebug(const Proto* f)
|
||||
PrintConstant(f,i);
|
||||
printf("\n");
|
||||
}
|
||||
n=sp->sizelocvars;
|
||||
n=f->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(sp->locvars[i].varname),sp->locvars[i].startpc+1,sp->locvars[i].endpc+1);
|
||||
i,getstr(f->locvars[i].varname),f->locvars[i].startpc+1,f->locvars[i].endpc+1);
|
||||
}
|
||||
n=f->sp->sizeupvalues;
|
||||
n=f->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),sp->upvalues[i].instack,sp->upvalues[i].idx);
|
||||
i,UPVALNAME(i),f->upvalues[i].instack,f->upvalues[i].idx);
|
||||
}
|
||||
}
|
||||
|
||||
static void PrintFunction(const Proto* f, int full)
|
||||
{
|
||||
int i,n=f->sp->sizep;
|
||||
PrintHeader(f->sp);
|
||||
int i,n=f->sizep;
|
||||
PrintHeader(f);
|
||||
PrintCode(f);
|
||||
if (full) PrintDebug(f);
|
||||
for (i=0; i<n; i++) PrintFunction(f->p[i],full);
|
||||
|
||||
@@ -47,8 +47,6 @@ 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);
|
||||
|
||||
@@ -104,7 +104,7 @@ static TString *LoadString (LoadState *S) {
|
||||
}
|
||||
|
||||
|
||||
static void LoadCode (LoadState *S, SharedProto *f) {
|
||||
static void LoadCode (LoadState *S, Proto *f) {
|
||||
int n = LoadInt(S);
|
||||
f->code = luaM_newvector(S->L, n, Instruction);
|
||||
f->sizecode = n;
|
||||
@@ -119,9 +119,7 @@ static void LoadConstants (LoadState *S, Proto *f) {
|
||||
int i;
|
||||
int n = LoadInt(S);
|
||||
f->k = luaM_newvector(S->L, n, TValue);
|
||||
f->sp->k = f->k;
|
||||
f->sp->sizek = n;
|
||||
f->sp->sharedk = 1;
|
||||
f->sizek = n;
|
||||
for (i = 0; i < n; i++)
|
||||
setnilvalue(&f->k[i]);
|
||||
for (i = 0; i < n; i++) {
|
||||
@@ -141,8 +139,6 @@ static void LoadConstants (LoadState *S, Proto *f) {
|
||||
setivalue(o, LoadInteger(S));
|
||||
break;
|
||||
case LUA_TSHRSTR:
|
||||
f->sp->sharedk = 0;
|
||||
//fall-through
|
||||
case LUA_TLNGSTR:
|
||||
setsvalue2n(S->L, o, LoadString(S));
|
||||
break;
|
||||
@@ -157,17 +153,17 @@ static void LoadProtos (LoadState *S, Proto *f) {
|
||||
int i;
|
||||
int n = LoadInt(S);
|
||||
f->p = luaM_newvector(S->L, n, Proto *);
|
||||
f->sp->sizep = n;
|
||||
f->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, NULL);
|
||||
LoadFunction(S, f->p[i], f->sp->source);
|
||||
f->p[i] = luaF_newproto(S->L);
|
||||
LoadFunction(S, f->p[i], f->source);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void LoadUpvalues (LoadState *S, SharedProto *f) {
|
||||
static void LoadUpvalues (LoadState *S, Proto *f) {
|
||||
int i, n;
|
||||
n = LoadInt(S);
|
||||
f->upvalues = luaM_newvector(S->L, n, Upvaldesc);
|
||||
@@ -181,7 +177,7 @@ static void LoadUpvalues (LoadState *S, SharedProto *f) {
|
||||
}
|
||||
|
||||
|
||||
static void LoadDebug (LoadState *S, SharedProto *f) {
|
||||
static void LoadDebug (LoadState *S, Proto *f) {
|
||||
int i, n;
|
||||
n = LoadInt(S);
|
||||
f->lineinfo = luaM_newvector(S->L, n, int);
|
||||
@@ -203,8 +199,7 @@ static void LoadDebug (LoadState *S, SharedProto *f) {
|
||||
}
|
||||
|
||||
|
||||
static void LoadFunction (LoadState *S, Proto *fp, TString *psource) {
|
||||
SharedProto *f = fp->sp;
|
||||
static void LoadFunction (LoadState *S, Proto *f, TString *psource) {
|
||||
f->source = LoadString(S);
|
||||
if (f->source == NULL) /* no source in dump? */
|
||||
f->source = psource; /* reuse parent's source */
|
||||
@@ -214,9 +209,9 @@ static void LoadFunction (LoadState *S, Proto *fp, TString *psource) {
|
||||
f->is_vararg = LoadByte(S);
|
||||
f->maxstacksize = LoadByte(S);
|
||||
LoadCode(S, f);
|
||||
LoadConstants(S, fp);
|
||||
LoadConstants(S, f);
|
||||
LoadUpvalues(S, f);
|
||||
LoadProtos(S, fp);
|
||||
LoadProtos(S, f);
|
||||
LoadDebug(S, f);
|
||||
}
|
||||
|
||||
@@ -275,9 +270,9 @@ LClosure *luaU_undump(lua_State *L, ZIO *Z, const char *name) {
|
||||
cl = luaF_newLclosure(L, LoadByte(&S));
|
||||
setclLvalue(L, L->top, cl);
|
||||
luaD_inctop(L);
|
||||
cl->p = luaF_newproto(L, NULL);
|
||||
cl->p = luaF_newproto(L);
|
||||
LoadFunction(&S, cl->p, NULL);
|
||||
lua_assert(cl->nupvalues == cl->p->sp->sizeupvalues);
|
||||
lua_assert(cl->nupvalues == cl->p->sizeupvalues);
|
||||
luai_verifycode(L, buff, cl->p);
|
||||
return cl;
|
||||
}
|
||||
|
||||
@@ -63,17 +63,7 @@
|
||||
|
||||
#endif
|
||||
|
||||
/* Add by skynet */
|
||||
lua_State * skynet_sig_L = NULL;
|
||||
|
||||
LUA_API void
|
||||
lua_checksig_(lua_State *L) {
|
||||
if (skynet_sig_L == G(L)->mainthread) {
|
||||
skynet_sig_L = NULL;
|
||||
lua_pushnil(L);
|
||||
lua_error(L);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Try to convert a value to a float. The float case is already handled
|
||||
@@ -612,27 +602,6 @@ lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y) {
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** check whether cached closure in prototype 'p' may be reused, that is,
|
||||
** whether there is a cached closure with the same upvalues needed by
|
||||
** new closure to be created.
|
||||
*/
|
||||
static LClosure *getcached (Proto *p, UpVal **encup, StkId base) {
|
||||
LClosure *c = p->cache;
|
||||
if (c != NULL) { /* is there a cached closure? */
|
||||
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;
|
||||
if (c->upvals[i]->v != v)
|
||||
return NULL; /* wrong upvalue; cannot reuse closure */
|
||||
}
|
||||
}
|
||||
return c; /* return cached closure (or NULL if no cached closure) */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** create a new Lua closure, push it in the stack, and initialize
|
||||
** its upvalues. Note that the closure is not cached if prototype is
|
||||
@@ -641,8 +610,8 @@ static LClosure *getcached (Proto *p, UpVal **encup, StkId base) {
|
||||
*/
|
||||
static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base,
|
||||
StkId ra) {
|
||||
int nup = p->sp->sizeupvalues;
|
||||
Upvaldesc *uv = p->sp->upvalues;
|
||||
int nup = p->sizeupvalues;
|
||||
Upvaldesc *uv = p->upvalues;
|
||||
int i;
|
||||
LClosure *ncl = luaF_newLclosure(L, nup);
|
||||
ncl->p = p;
|
||||
@@ -655,8 +624,6 @@ static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base,
|
||||
ncl->upvals[i]->refcount++;
|
||||
/* new closure is white, so we do not need a barrier here */
|
||||
}
|
||||
if (!isblack(p)) /* cache will not break GC invariant? */
|
||||
p->cache = ncl; /* save it on cache for reuse */
|
||||
}
|
||||
|
||||
|
||||
@@ -1088,7 +1055,6 @@ void luaV_execute (lua_State *L) {
|
||||
vmbreak;
|
||||
}
|
||||
vmcase(OP_JMP) {
|
||||
lua_checksig(L);
|
||||
dojump(ci, i, 0);
|
||||
vmbreak;
|
||||
}
|
||||
@@ -1141,7 +1107,6 @@ void luaV_execute (lua_State *L) {
|
||||
vmcase(OP_CALL) {
|
||||
int b = GETARG_B(i);
|
||||
int nresults = GETARG_C(i) - 1;
|
||||
lua_checksig(L);
|
||||
if (b != 0) L->top = ra+b; /* else previous instruction set top */
|
||||
if (luaD_precall(L, ra, nresults)) { /* C function? */
|
||||
if (nresults >= 0)
|
||||
@@ -1156,7 +1121,6 @@ void luaV_execute (lua_State *L) {
|
||||
}
|
||||
vmcase(OP_TAILCALL) {
|
||||
int b = GETARG_B(i);
|
||||
lua_checksig(L);
|
||||
if (b != 0) L->top = ra+b; /* else previous instruction set top */
|
||||
lua_assert(GETARG_C(i) - 1 == LUA_MULTRET);
|
||||
if (luaD_precall(L, ra, LUA_MULTRET)) { /* C function? */
|
||||
@@ -1169,10 +1133,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)->sp->numparams;
|
||||
StkId lim = nci->u.l.base + getproto(nfunc)->numparams;
|
||||
int aux;
|
||||
/* close all upvalues from previous call */
|
||||
if (cl->p->sp->sizep > 0) luaF_close(L, oci->u.l.base);
|
||||
if (cl->p->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);
|
||||
@@ -1181,14 +1145,14 @@ void luaV_execute (lua_State *L) {
|
||||
oci->u.l.savedpc = nci->u.l.savedpc;
|
||||
oci->callstatus |= CIST_TAIL; /* function was tail called */
|
||||
ci = L->ci = oci; /* remove new frame */
|
||||
lua_assert(L->top == oci->u.l.base + getproto(ofunc)->sp->maxstacksize);
|
||||
lua_assert(L->top == oci->u.l.base + getproto(ofunc)->maxstacksize);
|
||||
goto newframe; /* restart luaV_execute over new Lua function */
|
||||
}
|
||||
vmbreak;
|
||||
}
|
||||
vmcase(OP_RETURN) {
|
||||
int b = GETARG_B(i);
|
||||
if (cl->p->sp->sizep > 0) luaF_close(L, base);
|
||||
if (cl->p->sizep > 0) luaF_close(L, base);
|
||||
b = luaD_poscall(L, ci, ra, (b != 0 ? b - 1 : cast_int(L->top - ra)));
|
||||
if (ci->callstatus & CIST_FRESH) /* local 'ci' still from callee */
|
||||
return; /* external invocation: return */
|
||||
@@ -1201,7 +1165,6 @@ void luaV_execute (lua_State *L) {
|
||||
}
|
||||
}
|
||||
vmcase(OP_FORLOOP) {
|
||||
lua_checksig(L);
|
||||
if (ttisinteger(ra)) { /* integer loop? */
|
||||
lua_Integer step = ivalue(ra + 2);
|
||||
lua_Integer idx = intop(+, ivalue(ra), step); /* increment index */
|
||||
@@ -1268,7 +1231,6 @@ void luaV_execute (lua_State *L) {
|
||||
}
|
||||
vmcase(OP_TFORLOOP) {
|
||||
l_tforloop:
|
||||
lua_checksig(L);
|
||||
if (!ttisnil(ra + 1)) { /* continue loop? */
|
||||
setobjs2s(L, ra, ra + 1); /* save control variable */
|
||||
ci->u.l.savedpc += GETARG_sBx(i); /* jump back */
|
||||
@@ -1299,18 +1261,14 @@ void luaV_execute (lua_State *L) {
|
||||
}
|
||||
vmcase(OP_CLOSURE) {
|
||||
Proto *p = cl->p->p[GETARG_Bx(i)];
|
||||
LClosure *ncl = getcached(p, cl->upvals, base); /* cached closure */
|
||||
if (ncl == NULL) /* no match? */
|
||||
pushclosure(L, p, cl->upvals, base, ra); /* create a new one */
|
||||
else
|
||||
setclLvalue(L, ra, ncl); /* push cashed closure */
|
||||
pushclosure(L, p, cl->upvals, base, ra); /* create a new one */
|
||||
checkGC(L, ra + 1);
|
||||
vmbreak;
|
||||
}
|
||||
vmcase(OP_VARARG) {
|
||||
int b = GETARG_B(i) - 1; /* required results */
|
||||
int j;
|
||||
int n = cast_int(base - ci->func) - cl->p->sp->numparams - 1;
|
||||
int n = cast_int(base - ci->func) - cl->p->numparams - 1;
|
||||
if (n < 0) /* less arguments than parameters? */
|
||||
n = 0; /* no vararg arguments */
|
||||
if (b < 0) { /* B == 0? */
|
||||
|
||||
1
Makefile
1
Makefile
@@ -69,6 +69,7 @@ LUA_CLIB_SKYNET = \
|
||||
lua-stm.c \
|
||||
lua-debugchannel.c \
|
||||
lua-datasheet.c \
|
||||
lua-ssm.c \
|
||||
\
|
||||
|
||||
SKYNET_SRC = skynet_main.c skynet_handle.c skynet_module.c skynet_mq.c \
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
#include <lauxlib.h>
|
||||
|
||||
#include "malloc_hook.h"
|
||||
#include "luashrtbl.h"
|
||||
|
||||
static int
|
||||
ltotal(lua_State *L) {
|
||||
@@ -36,13 +35,6 @@ ldump(lua_State *L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
lexpandshrtbl(lua_State *L) {
|
||||
int n = luaL_checkinteger(L, 1);
|
||||
luaS_expandshr(n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
lcurrent(lua_State *L) {
|
||||
lua_pushinteger(L, malloc_current_memory());
|
||||
@@ -79,8 +71,6 @@ luaopen_skynet_memory(lua_State *L) {
|
||||
{ "dumpinfo", ldumpinfo },
|
||||
{ "dump", ldump },
|
||||
{ "info", dump_mem_lua },
|
||||
{ "ssinfo", luaS_shrinfo },
|
||||
{ "ssexpand", lexpandshrtbl },
|
||||
{ "current", lcurrent },
|
||||
{ "dumpheap", ldumpheap },
|
||||
{ "profactive", lprofactive },
|
||||
|
||||
72
lualib-src/lua-ssm.c
Normal file
72
lualib-src/lua-ssm.c
Normal file
@@ -0,0 +1,72 @@
|
||||
#define LUA_LIB
|
||||
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lstring.h"
|
||||
|
||||
static int
|
||||
linfo(lua_State *L) {
|
||||
struct ssm_info info;
|
||||
memset(&info, 0, sizeof(info));
|
||||
luaS_infossm(&info);
|
||||
lua_createtable(L, 0, 5);
|
||||
lua_pushinteger(L, info.total);
|
||||
lua_setfield(L, -2, "n");
|
||||
lua_pushinteger(L, info.longest);
|
||||
lua_setfield(L, -2, "longest");
|
||||
lua_pushinteger(L, info.slots);
|
||||
lua_setfield(L, -2, "slots");
|
||||
lua_pushinteger(L, info.size);
|
||||
lua_setfield(L, -2, "size");
|
||||
lua_pushnumber(L, info.variance);
|
||||
lua_setfield(L, -2, "variance");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
lcollect(lua_State *L) {
|
||||
int loop = lua_toboolean(L, 1);
|
||||
if (loop) {
|
||||
int n = 0;
|
||||
struct ssm_collect info;
|
||||
while (luaS_collectssm(&info)) {
|
||||
n+=info.n;
|
||||
}
|
||||
lua_pushinteger(L, n);
|
||||
return 1;
|
||||
} else {
|
||||
struct ssm_collect info;
|
||||
int again = luaS_collectssm(&info);
|
||||
if (again && lua_istable(L, 2)) {
|
||||
lua_pushinteger(L, info.n);
|
||||
lua_setfield(L, 2, "n");
|
||||
lua_pushlightuserdata(L, info.key);
|
||||
lua_setfield(L, 2, "key");
|
||||
}
|
||||
lua_pushboolean(L, again);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
LUAMOD_API int
|
||||
luaopen_skynet_ssm(lua_State *L) {
|
||||
luaL_checkversion(L);
|
||||
|
||||
luaL_Reg l[] = {
|
||||
{ "info", linfo },
|
||||
{ "collect", lcollect },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
|
||||
luaL_newlib(L,l);
|
||||
|
||||
#ifndef ENABLE_SHORT_STRING_TABLE
|
||||
lua_pushboolean(L, 1);
|
||||
lua_setfield(L, -2, "disable");
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
local skynet = require "skynet"
|
||||
local harbor = require "skynet.harbor"
|
||||
require "skynet.manager" -- import skynet.launch, ...
|
||||
local memory = require "skynet.memory"
|
||||
|
||||
skynet.start(function()
|
||||
local sharestring = tonumber(skynet.getenv "sharestring" or 4096)
|
||||
memory.ssexpand(sharestring)
|
||||
|
||||
local standalone = skynet.getenv "standalone"
|
||||
|
||||
local launcher = assert(skynet.launch("snlua","launcher"))
|
||||
skynet.name(".launcher", launcher)
|
||||
|
||||
skynet.newservice "garbagecollect"
|
||||
|
||||
local harbor_id = tonumber(skynet.getenv "harbor" or 0)
|
||||
if harbor_id == 0 then
|
||||
assert(standalone == nil)
|
||||
|
||||
@@ -155,7 +155,6 @@ function COMMAND.help()
|
||||
debug = "debug address : debug a lua service",
|
||||
signal = "signal address sig",
|
||||
cmem = "Show C memory info",
|
||||
shrtbl = "Show shared short string table info",
|
||||
ping = "ping address",
|
||||
call = "call address ...",
|
||||
trace = "trace address [proto] [on|off]",
|
||||
@@ -337,11 +336,6 @@ function COMMAND.cmem()
|
||||
return tmp
|
||||
end
|
||||
|
||||
function COMMAND.shrtbl()
|
||||
local n, total, longest, space, slots, variance = memory.ssinfo()
|
||||
return { n = n, total = total, longest = longest, space = space, slots = slots, average = n / slots, variace = variance }
|
||||
end
|
||||
|
||||
function COMMAND.ping(address)
|
||||
address = adjust_address(address)
|
||||
local ti = skynet.now()
|
||||
|
||||
@@ -6,10 +6,23 @@
|
||||
// If you use modified lua, this macro would be defined in lstring.h
|
||||
#ifndef ENABLE_SHORT_STRING_TABLE
|
||||
|
||||
static inline int luaS_shrinfo(lua_State *L) { return 0; }
|
||||
static inline void luaS_initshr() {}
|
||||
static inline void luaS_exitshr() {}
|
||||
static inline void luaS_expandshr(int n) {}
|
||||
struct ssm_info {
|
||||
int total;
|
||||
int longest;
|
||||
int slots;
|
||||
size_t size;
|
||||
double variance;
|
||||
};
|
||||
|
||||
struct ssm_collect {
|
||||
void *key;
|
||||
int n;
|
||||
};
|
||||
|
||||
static inline void luaS_initssm();
|
||||
static inline void luaS_exitssm();
|
||||
static inline void luaS_infossm(struct ssm_info *info) {}
|
||||
static inline int luaS_collectssm(struct ssm_collect *info) { return 0; }
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -126,7 +126,7 @@ main(int argc, char *argv[]) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
luaS_initshr();
|
||||
luaS_initssm();
|
||||
skynet_globalinit();
|
||||
skynet_env_init();
|
||||
|
||||
@@ -162,7 +162,7 @@ main(int argc, char *argv[]) {
|
||||
|
||||
skynet_start(&config);
|
||||
skynet_globalexit();
|
||||
luaS_exitshr();
|
||||
luaS_exitssm();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user