| 45 | |
| 46 | |
| 47 | UpVal *luaF_findupval (lua_State *L, StkId level) { |
| 48 | global_State *g = G(L); |
| 49 | GCObject **pp = &L->openupval; |
| 50 | UpVal *p; |
| 51 | UpVal *uv; |
| 52 | while (*pp != NULL && (p = gco2uv(*pp))->v >= level) { |
| 53 | GCObject *o = obj2gco(p); |
| 54 | lua_assert(p->v != &p->u.value); |
| 55 | lua_assert(!isold(o) || isold(obj2gco(L))); |
| 56 | if (p->v == level) { /* found a corresponding upvalue? */ |
| 57 | if (isdead(g, o)) /* is it dead? */ |
| 58 | changewhite(o); /* resurrect it */ |
| 59 | return p; |
| 60 | } |
| 61 | pp = &p->next; |
| 62 | } |
| 63 | /* not found: create a new one */ |
| 64 | uv = &luaC_newobj(L, LUA_TUPVAL, sizeof(UpVal), pp, 0)->uv; |
| 65 | uv->v = level; /* current value lives in the stack */ |
| 66 | uv->u.l.prev = &g->uvhead; /* double link it in `uvhead' list */ |
| 67 | uv->u.l.next = g->uvhead.u.l.next; |
| 68 | uv->u.l.next->u.l.prev = uv; |
| 69 | g->uvhead.u.l.next = uv; |
| 70 | lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); |
| 71 | return uv; |
| 72 | } |
| 73 | |
| 74 | |
| 75 | static void unlinkupval (UpVal *uv) { |
no test coverage detected