Line data Source code
1 : /* 2 : ** $Id: lfunc.c,v 2.45.1.1 2017/04/19 17:39:34 roberto Exp $ 3 : ** Auxiliary functions to manipulate prototypes and closures 4 : ** See Copyright Notice in lua.h 5 : */ 6 : 7 : #define lfunc_c 8 : #define LUA_CORE 9 : 10 : #include "lprefix.h" 11 : 12 : 13 : #include <stddef.h> 14 : 15 : #include "lua.h" 16 : 17 : #include "lfunc.h" 18 : #include "lgc.h" 19 : #include "lmem.h" 20 : #include "lobject.h" 21 : #include "lstate.h" 22 : 23 : 24 : 25 96 : CClosure *luaF_newCclosure (lua_State *L, int n) { 26 96 : GCObject *o = luaC_newobj(L, LUA_TCCL, sizeCclosure(n)); 27 96 : CClosure *c = gco2ccl(o); 28 96 : c->nupvalues = cast_byte(n); 29 96 : return c; 30 : } 31 : 32 : 33 95699 : LClosure *luaF_newLclosure (lua_State *L, int n) { 34 95699 : GCObject *o = luaC_newobj(L, LUA_TLCL, sizeLclosure(n)); 35 95699 : LClosure *c = gco2lcl(o); 36 95699 : c->p = NULL; 37 95699 : c->nupvalues = cast_byte(n); 38 477140 : while (n--) c->upvals[n] = NULL; 39 95699 : return c; 40 : } 41 : 42 : /* 43 : ** fill a closure with new closed upvalues 44 : */ 45 120 : void luaF_initupvals (lua_State *L, LClosure *cl) { 46 : int i; 47 240 : for (i = 0; i < cl->nupvalues; i++) { 48 120 : UpVal *uv = luaM_new(L, UpVal); 49 120 : uv->refcount = 1; 50 120 : uv->v = &uv->u.value; /* make it closed */ 51 120 : setnilvalue(uv->v); 52 120 : cl->upvals[i] = uv; 53 : } 54 120 : } 55 : 56 : 57 379253 : UpVal *luaF_findupval (lua_State *L, StkId level) { 58 379253 : UpVal **pp = &L->openupval; 59 : UpVal *p; 60 : UpVal *uv; 61 : lua_assert(isintwups(L) || L->openupval == NULL); 62 893963 : while (*pp != NULL && (p = *pp)->v >= level) { 63 : lua_assert(upisopen(p)); 64 677190 : if (p->v == level) /* found a corresponding upvalue? */ 65 162480 : return p; /* return it */ 66 514710 : pp = &p->u.open.next; 67 : } 68 : /* not found: create a new upvalue */ 69 216773 : uv = luaM_new(L, UpVal); 70 216773 : uv->refcount = 0; 71 216773 : uv->u.open.next = *pp; /* link it to list of open upvalues */ 72 216773 : uv->u.open.touched = 1; 73 216773 : *pp = uv; 74 216773 : uv->v = level; /* current value lives in the stack */ 75 216773 : if (!isintwups(L)) { /* thread not in list of threads with upvalues? */ 76 13423 : L->twups = G(L)->twups; /* link it to the list */ 77 13423 : G(L)->twups = L; 78 : } 79 216773 : return uv; 80 : } 81 : 82 : 83 121285 : void luaF_close (lua_State *L, StkId level) { 84 : UpVal *uv; 85 338058 : while (L->openupval != NULL && (uv = L->openupval)->v >= level) { 86 : lua_assert(upisopen(uv)); 87 216773 : L->openupval = uv->u.open.next; /* remove from 'open' list */ 88 216773 : if (uv->refcount == 0) /* no references? */ 89 0 : luaM_free(L, uv); /* free upvalue */ 90 : else { 91 216773 : setobj(L, &uv->u.value, uv->v); /* move value to upvalue slot */ 92 216773 : uv->v = &uv->u.value; /* now current value lives here */ 93 216773 : luaC_upvalbarrier(L, uv); 94 : } 95 : } 96 121285 : } 97 : 98 : 99 1829 : Proto *luaF_newproto (lua_State *L) { 100 1829 : GCObject *o = luaC_newobj(L, LUA_TPROTO, sizeof(Proto)); 101 1829 : Proto *f = gco2p(o); 102 1829 : f->k = NULL; 103 1829 : f->sizek = 0; 104 1829 : f->p = NULL; 105 1829 : f->sizep = 0; 106 1829 : f->code = NULL; 107 1829 : f->cache = NULL; 108 1829 : f->sizecode = 0; 109 1829 : f->lineinfo = NULL; 110 1829 : f->sizelineinfo = 0; 111 1829 : f->upvalues = NULL; 112 1829 : f->sizeupvalues = 0; 113 1829 : f->numparams = 0; 114 1829 : f->is_vararg = 0; 115 1829 : f->maxstacksize = 0; 116 1829 : f->locvars = NULL; 117 1829 : f->sizelocvars = 0; 118 1829 : f->linedefined = 0; 119 1829 : f->lastlinedefined = 0; 120 1829 : f->source = NULL; 121 1829 : return f; 122 : } 123 : 124 : 125 928 : void luaF_freeproto (lua_State *L, Proto *f) { 126 928 : luaM_freearray(L, f->code, f->sizecode); 127 928 : luaM_freearray(L, f->p, f->sizep); 128 928 : luaM_freearray(L, f->k, f->sizek); 129 928 : luaM_freearray(L, f->lineinfo, f->sizelineinfo); 130 928 : luaM_freearray(L, f->locvars, f->sizelocvars); 131 928 : luaM_freearray(L, f->upvalues, f->sizeupvalues); 132 928 : luaM_free(L, f); 133 928 : } 134 : 135 : 136 : /* 137 : ** Look for n-th local variable at line 'line' in function 'func'. 138 : ** Returns NULL if not found. 139 : */ 140 8 : const char *luaF_getlocalname (const Proto *f, int local_number, int pc) { 141 : int i; 142 8 : for (i = 0; i<f->sizelocvars && f->locvars[i].startpc <= pc; i++) { 143 8 : if (pc < f->locvars[i].endpc) { /* is variable active? */ 144 8 : local_number--; 145 8 : if (local_number == 0) 146 8 : return getstr(f->locvars[i].varname); 147 : } 148 : } 149 0 : return NULL; /* not found */ 150 : } 151 :