add lua_clonefunction for lua 5.3

This commit is contained in:
Cloud Wu
2015-01-22 14:13:26 +08:00
parent 93da2dbfc9
commit b891146397
15 changed files with 246 additions and 160 deletions

View File

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