This commit is contained in:
Cloud Wu
2019-03-14 09:54:40 +08:00
parent 1d4308f33a
commit 3f38a711ad
8 changed files with 64 additions and 21 deletions

View File

@@ -1017,16 +1017,32 @@ static void cloneproto (lua_State *L, Proto *f, const Proto *src) {
/* copy constants and nested proto */
int i,n;
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_clonestring(L,tsvalue(s));
setsvalue2n(L,o,str);
} else {
setobj(L,o,s);
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;

View File

@@ -1152,6 +1152,8 @@ static int cache_mode(lua_State *L) {
return 0;
}
LUA_API void luaS_expandshr(int n);
LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename,
const char *mode) {
int level = cache_level(L);
@@ -1171,6 +1173,7 @@ LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename,
lua_pushliteral(L, "New state failed");
return LUA_ERRMEM;
}
luaS_expandshr(4096);
int err = luaL_loadfilex_(eL, filename, mode);
if (err != LUA_OK) {
size_t sz = 0;

View File

@@ -122,26 +122,33 @@ Proto *luaF_newproto (lua_State *L, SharedProto *sp) {
sp->linedefined = 0;
sp->lastlinedefined = 0;
sp->source = NULL;
sp->k = NULL;
sp->sharedk = 0;
}
f->sp = sp;
return f;
}
static void freesharedproto (lua_State *L, SharedProto *f) {
if (f == NULL || G(L) != f->l_G)
static void freesharedproto (lua_State *L, Proto *pf) {
SharedProto *f = pf->sp;
if (f == NULL)
return;
luaM_freearray(L, f->code, f->sizecode);
luaM_freearray(L, f->lineinfo, f->sizelineinfo);
luaM_freearray(L, f->locvars, f->sizelocvars);
luaM_freearray(L, f->upvalues, f->sizeupvalues);
luaM_free(L, f);
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);
luaM_freearray(L, f->k, f->sp->sizek);
freesharedproto(L, f->sp);
freesharedproto(L, f);
luaM_free(L, f);
}

View File

@@ -497,7 +497,7 @@ static int traverseproto (global_State *g, Proto *f) {
f->cache = NULL; /* allow cache to be collected */
if (f->sp == NULL)
return sizeof(Proto);
nk = (f->k == NULL) ? 0 : f->sp->sizek;
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 */
markvalue(g, &f->k[i]);

View File

@@ -404,6 +404,7 @@ typedef struct SharedProto {
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;
@@ -418,6 +419,7 @@ typedef struct SharedProto {
LocVar *locvars; /* information about local variables (debug information) */
Upvaldesc *upvalues; /* upvalue information */
TString *source; /* used for debug information */
TValue *k; /* Shared constants */
} SharedProto;
/*

View File

@@ -550,6 +550,14 @@ static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) {
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;
@@ -563,6 +571,8 @@ static void close_func (LexState *ls) {
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;

View File

@@ -397,7 +397,8 @@ internshrstr (lua_State *L, const char *str, size_t l) {
LUA_API void
luaS_expandshr(int n) {
ATOM_ADD(&SSM.n, n);
if (SSM.n < n)
ATOM_ADD(&SSM.n, n);
}
LUAI_FUNC TString *

View File

@@ -119,7 +119,9 @@ 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;
for (i = 0; i < n; i++)
setnilvalue(&f->k[i]);
for (i = 0; i < n; i++) {
@@ -139,6 +141,8 @@ 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;