Exemplo n.º 1
0
Arquivo: lgc.c Projeto: zapline/zlib
void GCTM (lua_State *L) {
#else
static void GCTM (lua_State *L) {
#endif /* LUA_REFCOUNT */
  global_State *g = G(L);
  GCObject *o = g->tmudata->gch.next;  /* get first element */
  Udata *udata = rawgco2u(o);
  const TValue *tm;
  /* remove udata from `tmudata' */
  if (o == g->tmudata)  /* last element? */
    g->tmudata = NULL;
  else
    g->tmudata->gch.next = udata->uv.next;
#if LUA_REFCOUNT
  udata->uv.prev = (GCObject*)&G(L)->mainthread->next;
#endif /* LUA_REFCOUNT */
  udata->uv.next = g->mainthread->next;  /* return it to `root' list */
#if LUA_REFCOUNT
  if (udata->uv.next)
    udata->uv.next->uv.prev = obj2gco(udata);
#endif /* LUA_REFCOUNT */
  g->mainthread->next = o;
  makewhite(g, o);
  tm = fasttm(L, udata->uv.metatable, TM_GC);
  if (tm != NULL) {
    lu_byte oldah = L->allowhook;
    lu_mem oldt = g->GCthreshold;
    L->allowhook = 0;  /* stop debug hooks during GC tag method */
    g->GCthreshold = 2*g->totalbytes;  /* avoid GC steps */
#if LUA_REFCOUNT
    /* We could be in the middle of a stack set, so call the __gc metamethod on
       one stack level past the current one. */
    L->top++;

	/* we're freeing this object, but fake ref count it, because GCTM actually uses it */
    udata->uv.ref++;

    L->top += 2;
    setobj2s(L, L->top - 2, tm);
    setuvalue(L, L->top - 1, udata);
    luaD_call(L, L->top - 2, 0);
    udata->uv.ref--;
    L->top--;
    setnilvalue2n(L, L->top - 1);
#else
    setobj2s(L, L->top, tm);
    setuvalue(L, L->top+1, udata);
    L->top += 2;
    luaD_call(L, L->top - 2, 0);
#endif /* LUA_REFCOUNT */
    L->allowhook = oldah;  /* restore hooks */
    g->GCthreshold = oldt;  /* restore threshold */
  }
}
Exemplo n.º 2
0
static void GCTM (lua_State *L) {
  global_State *g = G(L);
  GCObject *o = g->tmudata->gch.next;  /* get first element */
  Udata *udata = rawgco2u(o);
  const TValue *tm;
  /* remove udata from `tmudata' */
  if (o == g->tmudata)  /* last element? */
    g->tmudata = NULL;
  else
    g->tmudata->gch.next = udata->uv.next;
  udata->uv.next = g->mainthread->next;  /* return it to `root' list */
  g->mainthread->next = o;
  makewhite(g, o);
  tm = fasttm(L, udata->uv.metatable, TM_GC);
  if (tm != NULL) {
    lu_byte oldah = L->allowhook;
    lu_mem oldt = g->GCthreshold;
    L->allowhook = 0;  /* stop debug hooks during GC tag method */
    g->GCthreshold = 2*g->totalbytes;  /* avoid GC steps */
    setobj2s(L, L->top, tm);
    setuvalue(L, L->top+1, udata);
    L->top += 2;
    luaD_call(L, L->top - 2, 0);
    L->allowhook = oldah;  /* restore hooks */
    g->GCthreshold = oldt;  /* restore threshold */
  }
}
Exemplo n.º 3
0
Arquivo: lgc.c Projeto: gitrider/wxsj2
static void do1gcTM (lua_State *L, Udata *udata) {
  const TObject *tm = fasttm(L, udata->uv.metatable, TM_GC);
  if (tm != NULL) {
    setobj2s(L->top, tm);
    setuvalue(L->top+1, udata);
    L->top += 2;
    luaD_call(L, L->top - 2, 0);
  }
}
Exemplo n.º 4
0
LUA_API void lua_newuserdatabox (lua_State *L, void *ptr) {
  Udata *u;
  lua_lock(L);
  u = luaS_newudata(L, 4);
  u->uv.len = 4;  // user data box bit is set.
  *(void**)(u + 1) = ptr;
  setuvalue(L->top, u);
  api_incr_top(L);
  lua_unlock(L);
}
Exemplo n.º 5
0
void lua_unsafe_pushuserdata(lua_State *L, void *v) {
    assert(v != NULL);
    Udata *u = ((Udata*)v)-1;
    lua_lock(L);
    setuvalue(L, L->top, u);
#ifdef AM_LUA51
    L->top++;
#else
    api_incr_top(L);
#endif
    lua_unlock(L);
}
Exemplo n.º 6
0
static void freeobj (lua_State *L, GCObject *o) {
    global_State *g = G(L);
    lua_assert(is_robj(o));
    switch (o->gch.tt) {
    case LUA_TPROTO:
        luaF_freeproto(L, gco2p(o));
        break;
    case LUA_TFUNCTION:
        luaF_freeclosure(L, gco2cl(o));
        break;
    case LUA_TUPVAL:
        luaF_freeupval(L, gco2uv(o));
        break;
    case LUA_TTABLE:
        luaH_free(L, gco2h(o));
        break;
    case LUA_TTHREAD: {
        lua_assert(gco2th(o) != L && gco2th(o) != G(L)->mainthread);
        luaE_freethread(L, gco2th(o));
        break;
    }
    case LUA_TSTRING: {
        G(L)->strt.nuse--;
        luaM_freemem(L, o, sizestring(gco2ts(o)));
        break;
    }
    case LUA_TUSERDATA: {
        const Udata *udata = rawgco2u(o);
        const TValue *tm = fasttm(L, udata->uv.metatable, TM_GC);
        if (tm != NULL) {
            lu_byte oldah = L->allowhook;
            lu_mem oldt = g->GCthreshold;
            L->allowhook = 0;  /* stop debug hooks during GC tag method */
            g->GCthreshold = 2*g->totalbytes;  /* avoid GC steps */
            setobj2s(L, L->top, tm);
            setuvalue(L, L->top+1, udata);
            L->top += 2;
            luaD_call(L, L->top - 2, 0);
            L->allowhook = oldah;  /* restore hooks */
            g->GCthreshold = oldt;  /* restore threshold */
        }
        luaM_freemem(L, o, sizeudata(gco2u(o)));
        break;
    }
    default:
        lua_assert(0);
    }
}
Exemplo n.º 7
0
void luaC_callGCTM (lua_State *L) {
    lu_byte oldah = L->allowhook;
    L->allowhook = 0;  /* stop debug hooks during GC tag methods */
    L->top++;  /* reserve space to keep udata while runs its gc method */
    while (G(L)->tmudata != NULL) {
        GCObject *o = G(L)->tmudata;
        Udata *udata = gcotou(o);
        G(L)->tmudata = udata->uv.next;  /* remove udata from `tmudata' */
        udata->uv.next = G(L)->rootudata;  /* return it to `root' list */
        G(L)->rootudata = o;
        setuvalue(L->top - 1, udata);  /* keep a reference to it */
        unmark(o);
        markfinalized(udata);
        do1gcTM(L, udata);
    }
    L->top--;
    L->allowhook = oldah;  /* restore hooks */
}
Exemplo n.º 8
0
Arquivo: lgc.c Projeto: gitrider/wxsj2
void luaC_callGCTM (lua_State *L) {
  lu_byte oldah = L->allowhook;
  L->allowhook = 0;  /* stop debug hooks during GC tag methods */
  L->top++;  /* reserve space to keep udata while runs its gc method */
#if LUA_REFCOUNT
  while (G(L)->tmudata_head.next != (GCObject*)&G(L)->tmudata_tail) {
    GCObject *o = G(L)->tmudata_head.next;
    Udata *udata = gcotou(o);
    G(L)->tmudata_head.next = udata->uv.next;  /* remove udata from `tmudata' */
    udata->uv.prev = (GCObject*)&G(L)->rootudata_head;
    udata->uv.next = G(L)->rootudata_head.next;
	if (udata->uv.next)
      udata->uv.next->uv.prev = o;
    G(L)->rootudata_head.next = o;
#else !LUA_REFCOUNT
  while (G(L)->tmudata != NULL) {
    GCObject *o = G(L)->tmudata;
    Udata *udata = gcotou(o);
    G(L)->tmudata = udata->uv.next;  /* remove udata from `tmudata' */
    udata->uv.next = G(L)->rootudata;  /* return it to `root' list */
    G(L)->rootudata = o;
#endif LUA_REFCOUNT
    setuvalue(L->top - 1, udata);  /* keep a reference to it */
    unmark(o);
    markfinalized(udata);
    do1gcTM(L, udata);
  }
  L->top--;
  L->allowhook = oldah;  /* restore hooks */
}


void luaC_sweep (lua_State *L, int all) {
  if (all) all = 256;  /* larger than any mark */
#if LUA_REFCOUNT
  sweeplist(L, &G(L)->rootudata_head.next, (GCObject*)&G(L)->rootudata_tail, all);
#else !LUA_REFCOUNT
  sweeplist(L, &G(L)->rootudata, NULL, all);
#endif LUA_REFCOUNT
  sweepstrings(L, all);
#if LUA_REFCOUNT
  sweeplist(L, &G(L)->rootgc_head.next, (GCObject*)&G(L)->rootgc_tail, all);
#else !LUA_REFCOUNT
  sweeplist(L, &G(L)->rootgc, NULL, all);
#endif LUA_REFCOUNT
}


/* mark root set */
static void markroot (GCState *st, lua_State *L) {
  int i;
  global_State *g = st->g;
  markobject(st, defaultmeta(L));
  for (i = 0; i < LUA_NTYPES; i++)
  {
    markobject(st, defaultmetatypes(L, i));
  }
  markobject(st, registry(L));
  traversestack(st, g->mainthread);
  if (L != g->mainthread)  /* another thread is running? */
    markvalue(st, L);  /* cannot collect it */
  if (G(L)->userGCFunction)
  {
	st->L = g->mainthread;
    G(L)->userGCFunction(st);
  }
}