예제 #1
0
LUA_API void lua_replace (lua_State *L, int idx)
{
    lua_lock(L);

    /* explicit test for incompatible code */
    if ( idx == LUA_ENVIRONINDEX && !hascallingenv( L ) )
    {
        luaG_runerror(L, "no calling environment");
    }

    api_checknelems(L, 1);
    {
        rtStack_t& rtStack = L->rtStack;

        rtStack.Lock( L );

        StkId stackTop = L->GetCurrentStackFrame().TopMutable( L, L->rtStack );

        if ( idx == LUA_ENVIRONINDEX )
        {
            Closure *func = curr_func(L);
            const TValue *val = stackTop;

            func->env = gcvalue(val);
            luaC_barrier(L, func, val);
        }
        else if ( idx == LUA_STORAGEINDEX )
        {
            const TValue *val = stackTop;

            setgcvalue( L, &L->storage, gcvalue( val ) );
            luaC_barrier( L, L, val );
        }
        else
        {
            ValueAddress o = index2adr(L, idx);
            api_checkvalidindex(L, o);

            setobj( L, o, stackTop );

            if ( idx < LUA_GLOBALSINDEX )  /* function upvalue? */
            {
                luaC_barrier(L, curr_func(L), stackTop);
            }
        }

        popstack( L, 1 );

        rtStack.Unlock( L );
    }
    lua_unlock(L);
}
예제 #2
0
LJLIB_ASM(bit_band)		LJLIB_REC(bit_nary IR_BAND)
{
#if LJ_HASFFI
  CTypeID id = 0;
  TValue *o = L->base, *top = L->top;
  int i = 0;
  do { lj_carith_check64(L, ++i, &id); } while (++o < top);
  if (id) {
    CTState *cts = ctype_cts(L);
    CType *ct = ctype_get(cts, id);
    int op = curr_func(L)->c.ffid - (int)FF_bit_bor;
    uint64_t x, y = op >= 0 ? 0 : ~(uint64_t)0;
    o = L->base;
    do {
      lj_cconv_ct_tv(cts, ct, (uint8_t *)&x, o, 0);
      if (op < 0) y &= x; else if (op == 0) y |= x; else y ^= x;
    } while (++o < top);
    return bit_result64(L, id, y);
  }
  return FFH_RETRY;
#else
  int i = 0;
  do { lj_lib_checknumber(L, ++i); } while (L->base+i < L->top);
  return FFH_RETRY;
#endif
}
예제 #3
0
파일: lj_lib.c 프로젝트: Configi/configi
int lj_lib_postreg(lua_State *L, lua_CFunction cf, int id, const char *name)
{
  GCfunc *fn = lj_lib_pushcf(L, cf, id);
  GCtab *t = tabref(curr_func(L)->c.env);  /* Reference to parent table. */
  setfuncV(L, lj_tab_setstr(L, t, lj_str_newz(L, name)), fn);
  lj_gc_anybarriert(L, t);
  setfuncV(L, L->top++, fn);
  return 1;
}
예제 #4
0
파일: lib_io.c 프로젝트: derdewey/luajit
static IOFileUD *io_file_new(lua_State *L)
{
  IOFileUD *iof = (IOFileUD *)lua_newuserdata(L, sizeof(IOFileUD));
  GCudata *ud = udataV(L->top-1);
  ud->udtype = UDTYPE_IO_FILE;
  /* NOBARRIER: The GCudata is new (marked white). */
  setgcrefr(ud->metatable, curr_func(L)->c.env);
  iof->fp = NULL;
  iof->type = IOFILE_TYPE_FILE;
  return iof;
}
예제 #5
0
LJLIB_ASM(bit_lshift)		LJLIB_REC(bit_shift IR_BSHL)
{
#if LJ_HASFFI
  CTypeID id = 0, id2 = 0;
  uint64_t x = lj_carith_check64(L, 1, &id);
  int32_t sh = (int32_t)lj_carith_check64(L, 2, &id2);
  if (id) {
    x = lj_carith_shift64(x, sh, curr_func(L)->c.ffid - (int)FF_bit_lshift);
    return bit_result64(L, id, x);
  }
  if (id2) setintV(L->base+1, sh);
  return FFH_RETRY;
#else
  lj_lib_checknumber(L, 1);
  bit_checkbit(L, 2);
  return FFH_RETRY;
#endif
}
예제 #6
0
/* Call dispatch. Used by call hooks, hot calls or when recording. */
ASMFunction LJ_FASTCALL lj_dispatch_call(lua_State *L, const BCIns *pc)
{
  GCfunc *fn = curr_func(L);
  BCOp op;
  global_State *g = G(L);
#if LJ_HASJIT
  jit_State *J = G2J(g);
#endif
  int missing = call_init(L, fn);
#if LJ_HASJIT
  J->L = L;
  if ((uintptr_t)pc & 1) {  /* Marker for hot call. */
    pc = (const BCIns *)((uintptr_t)pc & ~(uintptr_t)1);
    lj_trace_hot(J, pc);
    goto out;
  } else if (J->state != LJ_TRACE_IDLE &&
	     !(g->hookmask & (HOOK_GC|HOOK_VMEVENT))) {
    /* Record the FUNC* bytecodes, too. */
    lj_trace_ins(J, pc-1);  /* The interpreter bytecode PC is offset by 1. */
  }
#endif
  if ((g->hookmask & LUA_MASKCALL)) {
    int i;
    for (i = 0; i < missing; i++)  /* Add missing parameters. */
      setnilV(L->top++);
    callhook(L, LUA_HOOKCALL, -1);
    /* Preserve modifications of missing parameters by lua_setlocal(). */
    while (missing-- > 0 && tvisnil(L->top - 1))
      L->top--;
  }
#if LJ_HASJIT
out:
#endif
  op = bc_op(pc[-1]);  /* Get FUNC* op. */
#if LJ_HASJIT
  /* Use the non-hotcounting variants if JIT is off or while recording. */
  if ((!(J->flags & JIT_F_ON) || J->state != LJ_TRACE_IDLE) &&
      (op == BC_FUNCF || op == BC_FUNCV))
    op = (BCOp)((int)op+(int)BC_IFUNCF-(int)BC_FUNCF);
#endif
  return makeasmfunc(lj_bc_ofs[op]);  /* Return static dispatch target. */
}
예제 #7
0
/* Typecheck error for arguments. */
LJ_NOINLINE void lj_err_argtype(lua_State *L, int narg, const char *xname)
{
  const char *tname, *msg;
  if (narg <= LUA_REGISTRYINDEX) {
    if (narg >= LUA_GLOBALSINDEX) {
      tname = lj_obj_itypename[~LJ_TTAB];
    } else {
      GCfunc *fn = curr_func(L);
      int idx = LUA_GLOBALSINDEX - narg;
      if (idx <= fn->c.nupvalues)
	tname = lj_typename(&fn->c.upvalue[idx-1]);
      else
	tname = lj_obj_typename[0];
    }
  } else {
    TValue *o = narg < 0 ? L->top + narg : L->base + narg-1;
    tname = o < L->top ? lj_typename(o) : lj_obj_typename[0];
  }
  msg = lj_strfmt_pushf(L, err2msg(LJ_ERR_BADTYPE), xname, tname);
  err_argmsg(L, narg, msg);
}
예제 #8
0
/* Instruction dispatch. Used by instr/line/return hooks or when recording. */
void LJ_FASTCALL lj_dispatch_ins(lua_State *L, const BCIns *pc)
{
  GCfunc *fn = curr_func(L);
  GCproto *pt = funcproto(fn);
  void *cf = cframe_raw(L->cframe);
  const BCIns *oldpc = cframe_pc(cf);
  global_State *g = G(L);
  BCReg slots;
  setcframe_pc(cf, pc);
  slots = cur_topslot(pt, pc, cframe_multres_n(cf));
  L->top = L->base + slots;  /* Fix top. */
#if LJ_HASJIT
  {
    jit_State *J = G2J(g);
    if (J->state != LJ_TRACE_IDLE) {
      J->L = L;
      lj_trace_ins(J, pc-1);  /* The interpreter bytecode PC is offset by 1. */
    }
  }
#endif
  if ((g->hookmask & LUA_MASKCOUNT) && g->hookcount == 0) {
    g->hookcount = g->hookcstart;
    callhook(L, LUA_HOOKCOUNT, -1);
    L->top = L->base + slots;  /* Fix top again. */
  }
  if ((g->hookmask & LUA_MASKLINE)) {
    BCPos npc = proto_bcpos(pt, pc) - 1;
    BCPos opc = proto_bcpos(pt, oldpc) - 1;
    BCLine line = proto_line(pt, npc);
    if (pc <= oldpc || opc >= pt->sizebc || line != proto_line(pt, opc)) {
      callhook(L, LUA_HOOKLINE, line);
      L->top = L->base + slots;  /* Fix top again. */
    }
  }
  if ((g->hookmask & LUA_MASKRET) && bc_isret(bc_op(pc[-1])))
    callhook(L, LUA_HOOKRET, -1);
}
예제 #9
0
static int io_file_iter(lua_State *L)
{
  GCfunc *fn = curr_func(L);
  IOFileUD *iof = uddata(udataV(&fn->c.upvalue[0]));
  int n = fn->c.nupvalues - 1;
  if (iof->fp == NULL)
    lj_err_caller(L, LJ_ERR_IOCLFL);
  L->top = L->base;
  if (n) {  /* Copy upvalues with options to stack. */
    if (n > LUAI_MAXCSTACK)
      lj_err_caller(L, LJ_ERR_STKOV);
    lj_state_checkstack(L, (MSize)n);
    memcpy(L->top, &fn->c.upvalue[1], n*sizeof(TValue));
    L->top += n;
  }
  n = io_file_read(L, iof->fp, 0);
  if (ferror(iof->fp))
    lj_err_callermsg(L, strVdata(L->top-2));
  if (tvisnil(L->base) && (iof->type & IOFILE_FLAG_CLOSE)) {
    io_file_close(L, iof);  /* Return values are ignored. */
    return 0;
  }
  return n;
}
예제 #10
0
/* Instruction dispatch callback for instr/line hooks or when recording. */
void lj_dispatch_ins(lua_State *L, const BCIns *pc, uint32_t nres)
{
  GCfunc *fn = curr_func(L);
  GCproto *pt = funcproto(fn);
  BCReg slots = cur_topslot(pt, pc, nres);
  global_State *g = G(L);
  const BCIns *oldpc = cframe_Lpc(L);
  cframe_Lpc(L) = pc;
  L->top = L->base + slots;  /* Fix top. */
#if LJ_HASJIT
  {
    jit_State *J = G2J(g);
    if (J->state != LJ_TRACE_IDLE) {
      J->L = L;
      J->pc = pc-1;
      J->fn = fn;
      J->pt = pt;
      lj_trace_ins(J);
    }
  }
#endif
  if ((g->hookmask & LUA_MASKCOUNT) && g->hookcount == 0) {
    g->hookcount = g->hookcstart;
    callhook(L, LUA_HOOKCOUNT, -1);
  }
  if ((g->hookmask & LUA_MASKLINE) && pt->lineinfo) {
    BCPos npc = (BCPos)(pc - pt->bc)-1;
    BCPos opc = (BCPos)(oldpc - pt->bc)-1;
    BCLine line = pt->lineinfo[npc];
    if (npc == 0 || pc <= oldpc ||
	opc >= pt->sizebc || line != pt->lineinfo[opc]) {
      L->top = L->base + slots;  /* Fix top again after instruction hook. */
      callhook(L, LUA_HOOKLINE, line);
    }
  }
}