static void open_func (LexState *ls, FuncState *fs) { lua_State *L = ls->L; Proto *f = luaF_newproto(L); fs->f = f; fs->prev = ls->fs; /* linked list of funcstates */ fs->ls = ls; fs->L = L; ls->fs = fs; fs->pc = 0; fs->lasttarget = -1; fs->jpc = NO_JUMP; fs->freereg = 0; fs->nk = 0; fs->np = 0; fs->nlocvars = 0; fs->nactvar = 0; fs->bl = NULL; f->source = ls->source; f->maxstacksize = 2; /* registers 0/1 are always valid */ fs->h = luaH_new(L, 0, 0); /* anchor table of constants and prototype (to avoid being collected) */ sethvalue2s(L, L->top, fs->h); incr_top(L); setptvalue2s(L, L->top, f); incr_top(L); }
static void open_func (LexState *ls, FuncState *fs) { lua_State *L = ls->L; Proto *f = luaF_newproto(L); fs->f = f; fs->prev = ls->fs; /* linked list of funcstates */ fs->ls = ls; fs->L = L; ls->fs = fs; fs->pc = 0; fs->lasttarget = -1; fs->jpc = NO_JUMP; fs->freereg = 0; fs->nk = 0; fs->np = 0; #if LUA_EXT_CONTINUE fs->prohibitedloc = LUAI_MAXVARS + 1; /* nothing prohibited */ #endif /* LUA_EXT_CONTINUE */ fs->nlocvars = 0; fs->nactvar = 0; fs->bl = NULL; f->source = ls->source; #if LUA_REFCOUNT luarc_addrefstring(f->source); #endif /* LUA_REFCOUNT */ f->maxstacksize = 2; /* registers 0/1 are always valid */ fs->h = luaH_new(L, 0, 0); #if LUA_REFCOUNT luarc_addreftable(fs->h); #endif /* LUA_REFCOUNT */ /* anchor table of constants and prototype (to avoid being collected) */ sethvalue2s(L, L->top, fs->h); incr_top(L); setptvalue2s(L, L->top, f); incr_top(L); }
static const Proto* combine(lua_State* L, int n) { if (n==1) return toproto(L,-1); else { int i,pc; Proto* f=luaF_newproto(L); setptvalue2s(L,L->top,f); incr_top(L); f->source=luaS_newliteral(L,"=(" PROGNAME ")"); f->maxstacksize=1; pc=2*n+1; f->code=luaM_newvector(L,pc,Instruction); f->sizecode=pc; f->p=luaM_newvector(L,n,Proto*); f->sizep=n; pc=0; for (i=0; i<n; i++) { f->p[i]=toproto(L,i-n-1); f->code[pc++]=CREATE_ABx(OP_CLOSURE,0,i); f->code[pc++]=CREATE_ABC(OP_CALL,0,1,1); } f->code[pc++]=CREATE_ABC(OP_RETURN,0,1,0); return f; } }
static Proto * LoadFunction(LoadState * S, TString * p) { Proto* f; if(++S->L->nCcalls > LUAI_MAXCCALLS) error(S,"code too deep"); f=luaF_newproto(S->L); setptvalue2s(S->L,S->L->top,f); incr_top(S->L); f->source=LoadString(S); if(f->source==NULL) f->source=p; f->linedefined=LoadInt(S); f->lastlinedefined=LoadInt(S); f->nups=LoadByte(S); f->numparams=LoadByte(S); f->is_vararg=LoadByte(S); f->maxstacksize=LoadByte(S); LoadCode(S,f); LoadConstants(S,f); LoadDebug(S,f); IF (!luaG_checkcode(f), "bad code"); S->L->top--; S->L->nCcalls--; return f; }
static int lua_combine( lua_State* L) { int n = lua_gettop( L); /* Number of functions to combine */ if( 1 == n) { return 1; /* Only one function, nothing to combine */ } else { int i, pc = 3*n + 1; Proto* f = luaF_newproto( L); setptvalue2s( L,L->top,f); incr_top( L); f->source = luaS_newliteral( L,"=(combiner)"); f->maxstacksize = 2; f->is_vararg = VARARG_ISVARARG; f->code = luaM_newvector(L, pc, Instruction); f->sizecode = pc; f->p = luaM_newvector( L, n, Proto*); f->sizep = n; for( i = pc = 0; i < n; i ++) { int proto_idx = i-n-1; Proto *p = clvalue( L->top + proto_idx)->l.p; f->p[i] = p; f->code[pc++] = CREATE_ABx( OP_CLOSURE, 0, i); f->code[pc++] = CREATE_ABx( OP_VARARG, 1, 0); f->code[pc++] = CREATE_ABC( OP_CALL, 0, 0, 1); } f->code[pc++] = CREATE_ABC( OP_RETURN, 0, 1, 0); return 1; } }
static Proto* LoadFunction(LoadState* S) { Proto* f=luaF_newproto(S->L); setptvalue2s(S->L,S->L->top,f); incr_top(S->L); f->linedefined=LoadInt(S); f->lastlinedefined=LoadInt(S); f->numparams=LoadByte(S); f->is_vararg=LoadByte(S); f->maxstacksize=LoadByte(S); LoadCode(S,f); LoadConstants(S,f); LoadUpvalues(S,f); LoadDebug(S,f); S->L->top--; return f; }
static Proto* LoadFunction(LoadState* S, TString* p) { Proto* f=luaF_newproto(S->L); setptvalue2s(S->L,S->L->top,f); incr_top(S->L); f->source=LoadString(S); if (f->source==NULL) f->source=p; f->linedefined=LoadInt(S); f->lastlinedefined=LoadInt(S); f->nups=LoadByte(S); f->numparams=LoadByte(S); f->is_vararg=LoadByte(S); f->maxstacksize=LoadByte(S); LoadLines(S,f); LoadLocals(S,f); LoadUpvalues(S,f); LoadConstants(S,f); LoadCode(S,f); IF (!luaG_checkcode(f), "bad code"); S->L->top--; return f; }
static Proto* combine(lua_State* L, int scripts) { if (scripts==1 && preloads==0) return toproto(L,-1); else { TString *s; TValue *k; int i,pc,n; Proto* f=luaF_newproto(L); setptvalue2s(L,L->top,f); incr_top(L); f->source=luaS_newliteral(L,"=(" PROGNAME ")"); f->maxstacksize=1; pc=(2*scripts) + 1; if(preloads > 0) { pc+=(2*preloads) + 2; } f->code=luaM_newvector(L,pc,Instruction); f->sizecode=pc; n=(scripts + preloads); f->p=luaM_newvector(L,n,Proto*); f->sizep=n; pc=0; n=0; /* preload libraries. */ if (preloads > 0) { /* create constants array. */ f->k=luaM_newvector(L, (preloads + 2),TValue); f->sizek=(preloads + 2); /* make room for "local t" variable. */ f->maxstacksize=2; /* add "package" & "preload" constants. */ k=&(f->k[0]); s=luaS_newliteral(L, "package"); setsvalue2n(L,k,s); k=&(f->k[1]); s=luaS_newliteral(L, "preload"); setsvalue2n(L,k,s); /* code: local t = package.preload */ f->code[pc++]=CREATE_ABx(OP_GETGLOBAL,0,0); f->code[pc++]=CREATE_ABC(OP_GETTABLE,0,0,RKASK(1)); } /* add preload libraries to "package.preload" */ for (i=0; i < preloads; i++) { /* create constant for library name. */ k=&(f->k[i+2]); s=luaS_new(L, preload_libs[i]); setsvalue2n(L,k,s); /* code: t['name'] = function() --[[ lib code ]] end */ f->code[pc++]=CREATE_ABx(OP_CLOSURE,1,n); f->code[pc++]=CREATE_ABC(OP_SETTABLE,0,RKASK(i+2),1); f->p[n++]=toproto(L,i-preloads-1); } /* call scripts. */ for (i=0; i < scripts; i++) { /* code: (function() --[[ script code ]] end)() */ f->code[pc++]=CREATE_ABx(OP_CLOSURE,0,n); f->code[pc++]=CREATE_ABC(OP_CALL,0,1,1); f->p[n++]=toproto(L,i-scripts-1-preloads); } f->code[pc++]=CREATE_ABC(OP_RETURN,0,1,0); return f; } }
/* * If the luac command line includes multiple files or has the -f option * then luac generates a main function to reference all sub-main prototypes. * This is one of two types: * Type 0 The standard luac combination main * Type 1 A lookup wrapper that facilitates indexing into the generated protos */ static const Proto* combine(lua_State* L, int n, int type) { if (n==1 && type == 0) return toproto(L,-1); else { int i; Instruction *pc; Proto* f=luaF_newproto(L); setptvalue2s(L,L->top,f); incr_top(L); f->source=luaS_newliteral(L,"=(" PROGNAME ")"); f->p=luaM_newvector(L,n,Proto*); f->sizep=n; for (i=0; i<n; i++) f->p[i]=toproto(L,i-n-1); pc=0; if (type == 0) { /* * Type 0 is as per the standard luac, which is just a main routine which * invokes all of the compiled functions sequentially. This is fine if * they are self registering modules, but useless otherwise. */ f->numparams = 0; f->maxstacksize = 1; f->sizecode = 2*n + 1 ; f->sizek = 0; f->code = luaM_newvector(L, f->sizecode , Instruction); f->k = luaM_newvector(L,f->sizek,TValue); for (i=0, pc = f->code; i<n; i++) { *pc++ = CREATE_ABx(OP_CLOSURE,0,i); *pc++ = CREATE_ABC(OP_CALL,0,1,1); } *pc++ = CREATE_ABC(OP_RETURN,0,1,0); } else { /* * The Type 1 main() is a lookup which takes a single argument, the name to * be resolved. If this matches root name of one of the compiled files then * a closure to this file main is returned. Otherwise the Unixtime of the * compile and the list of root names is returned. */ if (n > LFIELDS_PER_FLUSH) { #define NO_MOD_ERR_(n) ": Number of modules > " #n #define NO_MOD_ERR(n) NO_MOD_ERR_(n) usage(LUA_QL("-f") NO_MOD_ERR(LFIELDS_PER_FLUSH)); } f->numparams = 1; f->maxstacksize = n + 3; f->sizecode = 5*n + 5 ; f->sizek = n + 1; f->sizelocvars = 0; f->code = luaM_newvector(L, f->sizecode , Instruction); f->k = luaM_newvector(L,f->sizek,TValue); for (i=0, pc = f->code; i<n; i++) { /* if arg1 == FnameA then return function (...) -- funcA -- end end */ setsvalue2n(L,f->k+i,corename(L, f->p[i]->source)); *pc++ = CREATE_ABC(OP_EQ,0,0,RKASK(i)); *pc++ = CREATE_ABx(OP_JMP,0,MAXARG_sBx+2); *pc++ = CREATE_ABx(OP_CLOSURE,1,i); *pc++ = CREATE_ABC(OP_RETURN,1,2,0); } setnvalue(f->k+n, (lua_Number) time(NULL)); *pc++ = CREATE_ABx(OP_LOADK,1,n); *pc++ = CREATE_ABC(OP_NEWTABLE,2,luaO_int2fb(i),0); for (i=0; i<n; i++) *pc++ = CREATE_ABx(OP_LOADK,i+3,i); *pc++ = CREATE_ABC(OP_SETLIST,2,i,1); *pc++ = CREATE_ABC(OP_RETURN,1,3,0); *pc++ = CREATE_ABC(OP_RETURN,0,1,0); } lua_assert((pc-f->code) == f->sizecode); return f; } }