示例#1
0
static void buf_grow(SBuf *sb, MSize sz)
{
  MSize osz = sbufsz(sb), len = sbuflen(sb), nsz = osz;
  char *b;
  if (nsz < LJ_MIN_SBUF) nsz = LJ_MIN_SBUF;
  while (nsz < sz) nsz += nsz;
  b = (char *)lj_mem_realloc(sbufL(sb), sbufB(sb), osz, nsz);
  setmref(sb->b, b);
  setmref(sb->p, b + len);
  setmref(sb->e, b + nsz);
}
示例#2
0
void LJ_FASTCALL lj_buf_shrink(lua_State *L, SBuf *sb)
{
  char *b = sbufB(sb);
  MSize osz = (MSize)(sbufE(sb) - b);
  if (osz > 2*LJ_MIN_SBUF) {
    MSize n = (MSize)(sbufP(sb) - b);
    b = lj_mem_realloc(L, b, osz, (osz >> 1));
    setmref(sb->b, b);
    setmref(sb->p, b + n);
    setmref(sb->e, b + (osz >> 1));
  }
示例#3
0
/* Create new hash part for table. */
static LJ_AINLINE void newhpart(lua_State *L, GCtab *t, uint32_t hbits)
{
  uint32_t hsize;
  Node *node;
  lua_assert(hbits != 0);
  if (hbits > LJ_MAX_HBITS)
    lj_err_msg(L, LJ_ERR_TABOV);
  hsize = 1u << hbits;
  node = lj_mem_newvec(L, hsize, Node);
  setmref(node->freetop, &node[hsize]);
  setmref(t->node, node);
  t->hmask = hsize-1;
}
示例#4
0
/* Find existing open upvalue for a stack slot or create a new one. */
static GCupval *func_finduv(lua_State *L, TValue *slot)
{
  global_State *g = G(L);
  GCRef *pp = &L->openupval;
  GCupval *p;
  GCupval *uv;
  /* Search the sorted list of open upvalues. */
  while (gcref(*pp) != NULL && uvval((p = gco2uv(gcref(*pp)))) >= slot) {
    lua_assert(!p->closed && uvval(p) != &p->tv);
    if (uvval(p) == slot) {  /* Found open upvalue pointing to same slot? */
      if (isdead(g, obj2gco(p)))  /* Resurrect it, if it's dead. */
	flipwhite(obj2gco(p));
      return p;
    }
    pp = &p->nextgc;
  }
  /* No matching upvalue found. Create a new one. */
  uv = lj_mem_newt(L, sizeof(GCupval), GCupval);
  newwhite(g, uv);
  uv->gct = ~LJ_TUPVAL;
  uv->closed = 0;  /* Still open. */
  setmref(uv->v, slot);  /* Pointing to the stack slot. */
  /* NOBARRIER: The GCupval is new (marked white) and open. */
  setgcrefr(uv->nextgc, *pp);  /* Insert into sorted list of open upvalues. */
  setgcref(*pp, obj2gco(uv));
  setgcref(uv->prev, obj2gco(&g->uvhead));  /* Insert into GC list, too. */
  setgcrefr(uv->next, g->uvhead.next);
  setgcref(uvnext(uv)->prev, obj2gco(uv));
  setgcref(g->uvhead.next, obj2gco(uv));
  lua_assert(uvprev(uvnext(uv)) == uv && uvnext(uvprev(uv)) == uv);
  return uv;
}
/* Throw error. Find catch frame, unwind stack and continue. */
LJ_NOINLINE void LJ_FASTCALL lj_err_throw(lua_State *L, int errcode)
{
  global_State *g = G(L);
  lj_trace_abort(g);
  g->saved_jit_base = g->jit_base;
  setmref(g->jit_base, NULL);
  L->status = 0;
#if LJ_UNWIND_EXT
  err_raise_ext(errcode);
  /*
  ** A return from this function signals a corrupt C stack that cannot be
  ** unwound. We have no choice but to call the panic function and exit.
  **
  ** Usually this is caused by a C function without unwind information.
  ** This should never happen on x64, but may happen if you've manually
  ** enabled LUAJIT_UNWIND_EXTERNAL and forgot to recompile *every*
  ** non-C++ file with -funwind-tables.
  */
  if (G(L)->panic)
    G(L)->panic(L);
#else
  {
    void *cf = err_unwind(L, NULL, errcode);
    if (cframe_unwind_ff(cf))
      lj_vm_unwind_ff(cframe_raw(cf));
    else
      lj_vm_unwind_c(cframe_raw(cf), errcode);
  }
#endif
  exit(EXIT_FAILURE);
}
示例#6
0
/* Stop profiling. */
LUA_API void luaJIT_profile_stop(lua_State *L)
{
  ProfileState *ps = &profile_state;
  global_State *g = ps->g;
  if (G(L) == g) {  /* Only stop profiler if started by this VM. */
    profile_timer_stop(ps);
    g->hookmask &= ~HOOK_PROFILE;
    lj_dispatch_update(g);
#if LJ_HASJIT
    G2J(g)->prof_mode = 0;
    lj_trace_flushall(L);
#endif
    lj_buf_free(g, &ps->sb);
    setmref(ps->sb.b, NULL);
    setmref(ps->sb.e, NULL);
    ps->g = NULL;
  }
}
示例#7
0
/* Create an empty and closed upvalue. */
static GCupval *func_emptyuv(lua_State *L)
{
  GCupval *uv = (GCupval *)lj_mem_newgco(L, sizeof(GCupval));
  uv->gct = ~LJ_TUPVAL;
  uv->closed = 1;
  setnilV(&uv->tv);
  setmref(uv->v, &uv->tv);
  return uv;
}
示例#8
0
文件: lj_lib.c 项目: Configi/configi
/* Push internal function on the stack. */
GCfunc *lj_lib_pushcc(lua_State *L, lua_CFunction f, int id, int n)
{
  GCfunc *fn;
  lua_pushcclosure(L, f, n);
  fn = funcV(L->top-1);
  fn->c.ffid = (uint8_t)id;
  setmref(fn->c.pc, &G(L)->bc_cfunc_int);
  return fn;
}
示例#9
0
static GCfunc *func_newL(lua_State *L, GCproto *pt, GCtab *env)
{
  GCfunc *fn = (GCfunc *)lj_mem_newgco(L, sizeLfunc((MSize)pt->sizeuv));
  fn->l.gct = ~LJ_TFUNC;
  fn->l.ffid = FF_LUA;
  fn->l.nupvalues = 0;  /* Set to zero until upvalues are initialized. */
  /* NOBARRIER: Really a setgcref. But the GCfunc is new (marked white). */
  setmref(fn->l.pc, proto_bc(pt));
  setgcref(fn->l.env, obj2gco(env));
  return fn;
}
示例#10
0
GCfunc *lj_func_newC(lua_State *L, MSize nelems, GCtab *env)
{
  GCfunc *fn = (GCfunc *)lj_mem_newgco(L, sizeCfunc(nelems));
  fn->c.gct = ~LJ_TFUNC;
  fn->c.ffid = FF_C;
  fn->c.nupvalues = (uint8_t)nelems;
  /* NOBARRIER: The GCfunc is new (marked white). */
  setmref(fn->c.pc, &G(L)->bc_cfunc_ext);
  setgcref(fn->c.env, obj2gco(env));
  return fn;
}
示例#11
0
/* Clear hash part of table. */
static LJ_AINLINE void clearhpart(GCtab *t)
{
  uint32_t i, hmask = t->hmask;
  Node *node = noderef(t->node);
  lua_assert(t->hmask != 0);
  for (i = 0; i <= hmask; i++) {
    Node *n = &node[i];
    setmref(n->next, NULL);
    setnilV(&n->key);
    setnilV(&n->val);
  }
}
示例#12
0
文件: lj_tab.c 项目: ssarangi/luajit
/* Create a new table. Note: the slots are not initialized (yet). */
static GCtab *newtab(lua_State *L, uint32_t asize, uint32_t hbits)
{
    GCtab *t;
    /* First try to colocate the array part. */
    if (LJ_MAX_COLOSIZE != 0 && asize > 0 && asize <= LJ_MAX_COLOSIZE) {
        lua_assert((sizeof(GCtab) & 7) == 0);
        t = (GCtab *)lj_mem_newgco(L, sizetabcolo(asize));
        t->gct = ~LJ_TTAB;
        t->nomm = (uint8_t)~0;
        t->colo = (int8_t)asize;
        setmref(t->array, (TValue *)((char *)t + sizeof(GCtab)));
        setgcrefnull(t->metatable);
        t->asize = asize;
        t->hmask = 0;
        setmref(t->node, &G(L)->nilnode);
    }
    else {  /* Otherwise separately allocate the array part. */
        t = lj_mem_newobj(L, GCtab);
        t->gct = ~LJ_TTAB;
        t->nomm = (uint8_t)~0;
        t->colo = 0;
        setmref(t->array, NULL);
        setgcrefnull(t->metatable);
        t->asize = 0;  /* In case the array allocation fails. */
        t->hmask = 0;
        setmref(t->node, &G(L)->nilnode);
        if (asize > 0) {
            if (asize > LJ_MAX_ASIZE)
                lj_err_msg(L, LJ_ERR_TABOV);
            setmref(t->array, lj_mem_newvec(L, asize, TValue));
            t->asize = asize;
        }
    }
    if (hbits)
        newhpart(L, t, hbits);
    return t;
}
示例#13
0
static GCfunc *func_newL(lua_State *L, GCproto *pt, GCtab *env)
{
  uint32_t count;
  GCfunc *fn = (GCfunc *)lj_mem_newgco(L, sizeLfunc((MSize)pt->sizeuv));
  fn->l.gct = ~LJ_TFUNC;
  fn->l.ffid = FF_LUA;
  fn->l.nupvalues = 0;  /* Set to zero until upvalues are initialized. */
  /* NOBARRIER: Really a setgcref. But the GCfunc is new (marked white). */
  setmref(fn->l.pc, proto_bc(pt));
  setgcref(fn->l.env, obj2gco(env));
  /* Saturating 3 bit counter (0..7) for created closures. */
  count = (uint32_t)pt->flags + PROTO_CLCOUNT;
  pt->flags = (uint8_t)(count - ((count >> PROTO_CLC_BITS) & PROTO_CLCOUNT));
  return fn;
}
示例#14
0
void lj_lib_register(lua_State *L, const char *libname,
		     const uint8_t *p, const lua_CFunction *cf)
{
  GCtab *env = tabref(L->env);
  GCfunc *ofn = NULL;
  int ffid = *p++;
  BCIns *bcff = &L2GG(L)->bcff[*p++];
  GCtab *tab = lib_create_table(L, libname, *p++);
  ptrdiff_t tpos = L->top - L->base;

  /* Avoid barriers further down. */
  lj_gc_anybarriert(L, tab);
  tab->nomm = 0;

  for (;;) {
    uint32_t tag = *p++;
    MSize len = tag & LIBINIT_LENMASK;
    tag &= LIBINIT_TAGMASK;
    if (tag != LIBINIT_STRING) {
      const char *name;
      MSize nuv = (MSize)(L->top - L->base - tpos);
      GCfunc *fn = lj_func_newC(L, nuv, env);
      if (nuv) {
	L->top = L->base + tpos;
	memcpy(fn->c.upvalue, L->top, sizeof(TValue)*nuv);
      }
      fn->c.ffid = (uint8_t)(ffid++);
      name = (const char *)p;
      p += len;
      if (tag == LIBINIT_CF)
	setmref(fn->c.pc, &G(L)->bc_cfunc_int);
      else
	setmref(fn->c.pc, bcff++);
      if (tag == LIBINIT_ASM_)
	fn->c.f = ofn->c.f;  /* Copy handler from previous function. */
      else
	fn->c.f = *cf++;  /* Get cf or handler from C function table. */
      if (len) {
	/* NOBARRIER: See above for common barrier. */
	setfuncV(L, lj_tab_setstr(L, tab, lj_str_new(L, name, len)), fn);
      }
      ofn = fn;
    } else {
      switch (tag | len) {
      case LIBINIT_SET:
	L->top -= 2;
	if (tvisstr(L->top+1) && strV(L->top+1)->len == 0)
	  env = tabV(L->top);
	else  /* NOBARRIER: See above for common barrier. */
	  copyTV(L, lj_tab_set(L, tab, L->top+1), L->top);
	break;
      case LIBINIT_NUMBER:
	memcpy(&L->top->n, p, sizeof(double));
	L->top++;
	p += sizeof(double);
	break;
      case LIBINIT_COPY:
	copyTV(L, L->top, L->top - *p++);
	L->top++;
	break;
      case LIBINIT_LASTCL:
	setfuncV(L, L->top++, ofn);
	break;
      case LIBINIT_FFID:
	ffid++;
	break;
      case LIBINIT_END:
	return;
      default:
	setstrV(L, L->top++, lj_str_new(L, (const char *)p, len));
	p += len;
	break;
      }
    }
  }
}