Skip to content

Commit b891146

Browse files
committed
add lua_clonefunction for lua 5.3
1 parent 93da2db commit b891146

15 files changed

+244
-158
lines changed

3rd/lua/lapi.c

+55-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "ltm.h"
2929
#include "lundump.h"
3030
#include "lvm.h"
31+
#include "lfunc.h"
3132

3233

3334

@@ -984,6 +985,59 @@ LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
984985
}
985986

986987

988+
static Proto * cloneproto (lua_State *L, const Proto *src) {
989+
/* copy constants and nested proto */
990+
int i,n;
991+
Proto *f = luaF_newproto(L, src->sp);
992+
n = src->sp->sizek;
993+
f->k=luaM_newvector(L,n,TValue);
994+
for (i=0; i<n; i++) setnilvalue(&f->k[i]);
995+
for (i=0; i<n; i++) {
996+
const TValue *s=&src->k[i];
997+
TValue *o=&f->k[i];
998+
if (ttisstring(s)) {
999+
TString * str = luaS_newlstr(L,svalue(s),tsvalue(s)->len);
1000+
setsvalue2n(L,o,str);
1001+
} else {
1002+
setobj(L,o,s);
1003+
}
1004+
}
1005+
n = src->sp->sizep;
1006+
f->p=luaM_newvector(L,n,struct Proto *);
1007+
for (i=0; i<n; i++) f->p[i]=NULL;
1008+
for (i=0; i<n; i++) {
1009+
f->p[i]=cloneproto(L, src->p[i]);
1010+
}
1011+
return f;
1012+
}
1013+
1014+
LUA_API void lua_clonefunction (lua_State *L, void * fp) {
1015+
LClosure *cl;
1016+
LClosure *f = cast(LClosure *, fp);
1017+
lua_lock(L);
1018+
if (f->p->sp->l_G == G(L)) {
1019+
setclLvalue(L,L->top,f);
1020+
api_incr_top(L);
1021+
lua_unlock(L);
1022+
return;
1023+
}
1024+
cl = luaF_newLclosure(L,f->nupvalues);
1025+
cl->p = cloneproto(L, f->p);
1026+
setclLvalue(L,L->top,cl);
1027+
api_incr_top(L);
1028+
luaF_initupvals(L, cl);
1029+
1030+
if (f->nupvalues >= 1) { /* does it have an upvalue? */
1031+
/* get global table from registry */
1032+
Table *reg = hvalue(&G(L)->l_registry);
1033+
const TValue *gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
1034+
/* set global table as 1st upvalue of 'f' (may be LUA_ENV) */
1035+
setobj(L, f->upvals[0]->v, gt);
1036+
luaC_upvalbarrier(L, f->upvals[0]);
1037+
}
1038+
lua_unlock(L);
1039+
}
1040+
9871041
LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data, int strip) {
9881042
int status;
9891043
TValue *o;
@@ -1178,7 +1232,7 @@ static const char *aux_upvalue (StkId fi, int n, TValue **val,
11781232
case LUA_TLCL: { /* Lua closure */
11791233
LClosure *f = clLvalue(fi);
11801234
TString *name;
1181-
Proto *p = f->p;
1235+
SharedProto *p = f->p->sp;
11821236
if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
11831237
*val = f->upvals[n-1]->v;
11841238
if (uv) *uv = f->upvals[n - 1];

3rd/lua/lcode.c

+18-18
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ void luaK_nil (FuncState *fs, int from, int n) {
5555
Instruction *previous;
5656
int l = from + n - 1; /* last register to set nil */
5757
if (fs->pc > fs->lasttarget) { /* no jumps to current position? */
58-
previous = &fs->f->code[fs->pc-1];
58+
previous = &fs->f->sp->code[fs->pc-1];
5959
if (GET_OPCODE(*previous) == OP_LOADNIL) {
6060
int pfrom = GETARG_A(*previous);
6161
int pl = pfrom + GETARG_B(*previous);
@@ -95,7 +95,7 @@ static int condjump (FuncState *fs, OpCode op, int A, int B, int C) {
9595

9696

9797
static void fixjump (FuncState *fs, int pc, int dest) {
98-
Instruction *jmp = &fs->f->code[pc];
98+
Instruction *jmp = &fs->f->sp->code[pc];
9999
int offset = dest-(pc+1);
100100
lua_assert(dest != NO_JUMP);
101101
if (abs(offset) > MAXARG_sBx)
@@ -115,7 +115,7 @@ int luaK_getlabel (FuncState *fs) {
115115

116116

117117
static int getjump (FuncState *fs, int pc) {
118-
int offset = GETARG_sBx(fs->f->code[pc]);
118+
int offset = GETARG_sBx(fs->f->sp->code[pc]);
119119
if (offset == NO_JUMP) /* point to itself represents end of list */
120120
return NO_JUMP; /* end of list */
121121
else
@@ -124,7 +124,7 @@ static int getjump (FuncState *fs, int pc) {
124124

125125

126126
static Instruction *getjumpcontrol (FuncState *fs, int pc) {
127-
Instruction *pi = &fs->f->code[pc];
127+
Instruction *pi = &fs->f->sp->code[pc];
128128
if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1))))
129129
return pi-1;
130130
else
@@ -197,10 +197,10 @@ void luaK_patchclose (FuncState *fs, int list, int level) {
197197
level++; /* argument is +1 to reserve 0 as non-op */
198198
while (list != NO_JUMP) {
199199
int next = getjump(fs, list);
200-
lua_assert(GET_OPCODE(fs->f->code[list]) == OP_JMP &&
201-
(GETARG_A(fs->f->code[list]) == 0 ||
202-
GETARG_A(fs->f->code[list]) >= level));
203-
SETARG_A(fs->f->code[list], level);
200+
lua_assert(GET_OPCODE(fs->f->sp->code[list]) == OP_JMP &&
201+
(GETARG_A(fs->f->sp->code[list]) == 0 ||
202+
GETARG_A(fs->f->sp->code[list]) >= level));
203+
SETARG_A(fs->f->sp->code[list], level);
204204
list = next;
205205
}
206206
}
@@ -230,13 +230,13 @@ static int luaK_code (FuncState *fs, Instruction i) {
230230
Proto *f = fs->f;
231231
dischargejpc(fs); /* 'pc' will change */
232232
/* put new instruction in code array */
233-
luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction,
233+
luaM_growvector(fs->ls->L, f->sp->code, fs->pc, f->sp->sizecode, Instruction,
234234
MAX_INT, "opcodes");
235-
f->code[fs->pc] = i;
235+
f->sp->code[fs->pc] = i;
236236
/* save corresponding line information */
237-
luaM_growvector(fs->ls->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
237+
luaM_growvector(fs->ls->L, f->sp->lineinfo, fs->pc, f->sp->sizelineinfo, int,
238238
MAX_INT, "opcodes");
239-
f->lineinfo[fs->pc] = fs->ls->lastline;
239+
f->sp->lineinfo[fs->pc] = fs->ls->lastline;
240240
return fs->pc++;
241241
}
242242

@@ -277,10 +277,10 @@ int luaK_codek (FuncState *fs, int reg, int k) {
277277

278278
void luaK_checkstack (FuncState *fs, int n) {
279279
int newstack = fs->freereg + n;
280-
if (newstack > fs->f->maxstacksize) {
280+
if (newstack > fs->f->sp->maxstacksize) {
281281
if (newstack >= MAXREGS)
282282
luaX_syntaxerror(fs->ls, "function or expression too complex");
283-
fs->f->maxstacksize = cast_byte(newstack);
283+
fs->f->sp->maxstacksize = cast_byte(newstack);
284284
}
285285
}
286286

@@ -322,13 +322,13 @@ static int addk (FuncState *fs, TValue *key, TValue *v) {
322322
return k; /* reuse index */
323323
}
324324
/* constant not found; create a new entry */
325-
oldsize = f->sizek;
325+
oldsize = f->sp->sizek;
326326
k = fs->nk;
327327
/* numerical value does not need GC barrier;
328328
table has no metatable, so it does not need to invalidate cache */
329329
setivalue(idx, k);
330-
luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants");
331-
while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
330+
luaM_growvector(L, f->k, k, f->sp->sizek, TValue, MAXARG_Ax, "constants");
331+
while (oldsize < f->sp->sizek) setnilvalue(&f->k[oldsize++]);
332332
setobj(L, &f->k[k], v);
333333
fs->nk++;
334334
luaC_barrier(L, f, v);
@@ -933,7 +933,7 @@ void luaK_posfix (FuncState *fs, BinOpr op,
933933

934934

935935
void luaK_fixline (FuncState *fs, int line) {
936-
fs->f->lineinfo[fs->pc - 1] = line;
936+
fs->f->sp->lineinfo[fs->pc - 1] = line;
937937
}
938938

939939

3rd/lua/lcode.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ typedef enum BinOpr {
4040
typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;
4141

4242

43-
#define getcode(fs,e) ((fs)->f->code[(e)->u.info])
43+
#define getcode(fs,e) ((fs)->f->sp->code[(e)->u.info])
4444

4545
#define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx)
4646

3rd/lua/ldebug.c

+12-12
Original file line numberDiff line numberDiff line change
@@ -98,14 +98,14 @@ LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
9898

9999

100100
static const char *upvalname (Proto *p, int uv) {
101-
TString *s = check_exp(uv < p->sizeupvalues, p->upvalues[uv].name);
101+
TString *s = check_exp(uv < p->sizeupvalues, p->sp->upvalues[uv].name);
102102
if (s == NULL) return "?";
103103
else return getstr(s);
104104
}
105105

106106

107107
static const char *findvararg (CallInfo *ci, int n, StkId *pos) {
108-
int nparams = clLvalue(ci->func)->p->numparams;
108+
int nparams = clLvalue(ci->func)->p->sp->numparams;
109109
if (n >= ci->u.l.base - ci->func - nparams)
110110
return NULL; /* no such vararg */
111111
else {
@@ -184,7 +184,7 @@ static void funcinfo (lua_Debug *ar, Closure *cl) {
184184
ar->what = "C";
185185
}
186186
else {
187-
Proto *p = cl->l.p;
187+
SharedProto *p = cl->l.p->sp;
188188
ar->source = p->source ? getstr(p->source) : "=?";
189189
ar->linedefined = p->linedefined;
190190
ar->lastlinedefined = p->lastlinedefined;
@@ -202,12 +202,12 @@ static void collectvalidlines (lua_State *L, Closure *f) {
202202
else {
203203
int i;
204204
TValue v;
205-
int *lineinfo = f->l.p->lineinfo;
205+
int *lineinfo = f->l.p->sp->lineinfo;
206206
Table *t = luaH_new(L); /* new table to store active lines */
207207
sethvalue(L, L->top, t); /* push it on stack */
208208
api_incr_top(L);
209209
setbvalue(&v, 1); /* boolean 'true' to be the value of all indices */
210-
for (i = 0; i < f->l.p->sizelineinfo; i++) /* for all lines with code */
210+
for (i = 0; i < f->l.p->sp->sizelineinfo; i++) /* for all lines with code */
211211
luaH_setint(L, t, lineinfo[i], &v); /* table[line] = true */
212212
}
213213
}
@@ -233,8 +233,8 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
233233
ar->nparams = 0;
234234
}
235235
else {
236-
ar->isvararg = f->l.p->is_vararg;
237-
ar->nparams = f->l.p->numparams;
236+
ar->isvararg = f->l.p->sp->is_vararg;
237+
ar->nparams = f->l.p->sp->numparams;
238238
}
239239
break;
240240
}
@@ -343,7 +343,7 @@ static int findsetreg (Proto *p, int lastpc, int reg) {
343343
int setreg = -1; /* keep last instruction that changed 'reg' */
344344
int jmptarget = 0; /* any code before this address is conditional */
345345
for (pc = 0; pc < lastpc; pc++) {
346-
Instruction i = p->code[pc];
346+
Instruction i = p->sp->code[pc];
347347
OpCode op = GET_OPCODE(i);
348348
int a = GETARG_A(i);
349349
switch (op) {
@@ -393,7 +393,7 @@ static const char *getobjname (Proto *p, int lastpc, int reg,
393393
/* else try symbolic execution */
394394
pc = findsetreg(p, lastpc, reg);
395395
if (pc != -1) { /* could find instruction? */
396-
Instruction i = p->code[pc];
396+
Instruction i = p->sp->code[pc];
397397
OpCode op = GET_OPCODE(i);
398398
switch (op) {
399399
case OP_MOVE: {
@@ -419,7 +419,7 @@ static const char *getobjname (Proto *p, int lastpc, int reg,
419419
case OP_LOADK:
420420
case OP_LOADKX: {
421421
int b = (op == OP_LOADK) ? GETARG_Bx(i)
422-
: GETARG_Ax(p->code[pc + 1]);
422+
: GETARG_Ax(p->sp->code[pc + 1]);
423423
if (ttisstring(&p->k[b])) {
424424
*name = svalue(&p->k[b]);
425425
return "constant";
@@ -442,7 +442,7 @@ static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
442442
TMS tm = (TMS)0; /* to avoid warnings */
443443
Proto *p = ci_func(ci)->p; /* calling function */
444444
int pc = currentpc(ci); /* calling instruction index */
445-
Instruction i = p->code[pc]; /* calling instruction */
445+
Instruction i = p->sp->code[pc]; /* calling instruction */
446446
if (ci->callstatus & CIST_HOOKED) { /* was it called inside a hook? */
447447
*name = "?";
448448
return "hook";
@@ -577,7 +577,7 @@ static void addinfo (lua_State *L, const char *msg) {
577577
if (isLua(ci)) { /* is Lua code? */
578578
char buff[LUA_IDSIZE]; /* add file:line information */
579579
int line = currentline(ci);
580-
TString *src = ci_func(ci)->p->source;
580+
TString *src = ci_func(ci)->p->sp->source;
581581
if (src)
582582
luaO_chunkid(buff, getstr(src), LUA_IDSIZE);
583583
else { /* no source available; use "?" instead */

3rd/lua/ldebug.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
#include "lstate.h"
1212

1313

14-
#define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1)
14+
#define pcRel(pc, p) (cast(int, (pc) - (p)->sp->code) - 1)
1515

16-
#define getfuncline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : -1)
16+
#define getfuncline(f,pc) (((f)->sp->lineinfo) ? (f)->sp->lineinfo[pc] : -1)
1717

1818
#define resethookcount(L) (L->hookcount = L->basehookcount)
1919

3rd/lua/ldo.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ static void callhook (lua_State *L, CallInfo *ci) {
269269
}
270270

271271

272-
static StkId adjust_varargs (lua_State *L, Proto *p, int actual) {
272+
static StkId adjust_varargs (lua_State *L, SharedProto *p, int actual) {
273273
int i;
274274
int nfixargs = p->numparams;
275275
StkId base, fixed;
@@ -342,7 +342,7 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
342342
}
343343
case LUA_TLCL: { /* Lua function: prepare its call */
344344
StkId base;
345-
Proto *p = clLvalue(func)->p;
345+
SharedProto *p = clLvalue(func)->p->sp;
346346
n = cast_int(L->top - func) - 1; /* number of real arguments */
347347
luaD_checkstack(L, p->maxstacksize);
348348
for (; n < p->numparams; n++)

3rd/lua/ldump.c

+11-10
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ static void DumpString (const TString *s, DumpState *D) {
8686
}
8787

8888

89-
static void DumpCode (const Proto *f, DumpState *D) {
89+
static void DumpCode (const SharedProto *f, DumpState *D) {
9090
DumpInt(f->sizecode, D);
9191
DumpVector(f->code, f->sizecode, D);
9292
}
@@ -96,7 +96,7 @@ static void DumpFunction(const Proto *f, TString *psource, DumpState *D);
9696

9797
static void DumpConstants (const Proto *f, DumpState *D) {
9898
int i;
99-
int n = f->sizek;
99+
int n = f->sp->sizek;
100100
DumpInt(n, D);
101101
for (i = 0; i < n; i++) {
102102
const TValue *o = &f->k[i];
@@ -126,14 +126,14 @@ static void DumpConstants (const Proto *f, DumpState *D) {
126126

127127
static void DumpProtos (const Proto *f, DumpState *D) {
128128
int i;
129-
int n = f->sizep;
129+
int n = f->sp->sizep;
130130
DumpInt(n, D);
131131
for (i = 0; i < n; i++)
132-
DumpFunction(f->p[i], f->source, D);
132+
DumpFunction(f->p[i], f->sp->source, D);
133133
}
134134

135135

136-
static void DumpUpvalues (const Proto *f, DumpState *D) {
136+
static void DumpUpvalues (const SharedProto *f, DumpState *D) {
137137
int i, n = f->sizeupvalues;
138138
DumpInt(n, D);
139139
for (i = 0; i < n; i++) {
@@ -143,7 +143,7 @@ static void DumpUpvalues (const Proto *f, DumpState *D) {
143143
}
144144

145145

146-
static void DumpDebug (const Proto *f, DumpState *D) {
146+
static void DumpDebug (const SharedProto *f, DumpState *D) {
147147
int i, n;
148148
n = (D->strip) ? 0 : f->sizelineinfo;
149149
DumpInt(n, D);
@@ -162,7 +162,8 @@ static void DumpDebug (const Proto *f, DumpState *D) {
162162
}
163163

164164

165-
static void DumpFunction (const Proto *f, TString *psource, DumpState *D) {
165+
static void DumpFunction (const Proto *fp, TString *psource, DumpState *D) {
166+
const SharedProto *f = fp->sp;
166167
if (D->strip || f->source == psource)
167168
DumpString(NULL, D); /* no debug info or same source as its parent */
168169
else
@@ -173,9 +174,9 @@ static void DumpFunction (const Proto *f, TString *psource, DumpState *D) {
173174
DumpByte(f->is_vararg, D);
174175
DumpByte(f->maxstacksize, D);
175176
DumpCode(f, D);
176-
DumpConstants(f, D);
177+
DumpConstants(fp, D);
177178
DumpUpvalues(f, D);
178-
DumpProtos(f, D);
179+
DumpProtos(fp, D);
179180
DumpDebug(f, D);
180181
}
181182

@@ -207,7 +208,7 @@ int luaU_dump(lua_State *L, const Proto *f, lua_Writer w, void *data,
207208
D.strip = strip;
208209
D.status = 0;
209210
DumpHeader(&D);
210-
DumpByte(f->sizeupvalues, &D);
211+
DumpByte(f->sp->sizeupvalues, &D);
211212
DumpFunction(f, NULL, &D);
212213
return D.status;
213214
}

0 commit comments

Comments
 (0)