Example #1
0
static int io_file_write(lua_State *L, FILE *fp, int start)
{
  cTValue *tv;
  int status = 1;
  for (tv = L->base+start; tv < L->top; tv++) {
    if (tvisstr(tv)) {
      MSize len = strV(tv)->len;
      status = status && (fwrite(strVdata(tv), 1, len, fp) == len);
    } else if (tvisint(tv)) {
      char buf[LJ_STR_INTBUF];
      char *p = lj_str_bufint(buf, intV(tv));
      size_t len = (size_t)(buf+LJ_STR_INTBUF-p);
      status = status && (fwrite(p, 1, len, fp) == len);
    } else if (tvisnum(tv)) {
      status = status && (fprintf(fp, LUA_NUMBER_FMT, numV(tv)) > 0);
    } else {
      lj_err_argt(L, (int)(tv - L->base) + 1, LUA_TSTRING);
    }
  }
  if (LJ_52 && status) {
    L->top = L->base+1;
    if (start == 0)
      setudataV(L, L->base, IOSTDF_UD(L, GCROOT_IO_OUTPUT));
    return 1;
  }
  return luaL_fileresult(L, status, NULL);
}
Example #2
0
/* Handle ctype __index/__newindex metamethods. */
static int ffi_index_meta(lua_State *L, CTState *cts, CType *ct, MMS mm)
{
  CTypeID id = ctype_typeid(cts, ct);
  cTValue *tv = lj_ctype_meta(cts, id, mm);
  TValue *base = L->base;
  if (!tv) {
    const char *s;
  err_index:
    s = strdata(lj_ctype_repr(L, id, NULL));
    if (tvisstr(L->base+1))
      lj_err_callerv(L, LJ_ERR_FFI_BADMEMBER, s, strVdata(L->base+1));
    else
      lj_err_callerv(L, LJ_ERR_FFI_BADIDX, s);
  }
  if (!tvisfunc(tv)) {
    if (mm == MM_index) {
      cTValue *o = lj_meta_tget(L, tv, base+1);
      if (o) {
	if (tvisnil(o)) goto err_index;
	copyTV(L, L->top-1, o);
	return 1;
      }
    } else {
      TValue *o = lj_meta_tset(L, tv, base+1);
      if (o) {
	copyTV(L, o, base+2);
	return 0;
      }
    }
    tv = L->top-1;
  }
  return lj_meta_tailcall(L, tv);
}
Example #3
0
static int io_file_write(lua_State *L, FILE *fp, int start)
{
  cTValue *tv;
  int status = 1;
  for (tv = L->base+start; tv < L->top; tv++) {
    if (tvisstr(tv)) {
      MSize len = strV(tv)->len;
      status = status && (fwrite(strVdata(tv), 1, len, fp) == len);
    } else if (tvisnum(tv)) {
      status = status && (fprintf(fp, LUA_NUMBER_FMT, numV(tv)) > 0);
    } else {
      lj_err_argt(L, cast_int(tv - L->base) + 1, LUA_TSTRING);
    }
  }
  return io_pushresult(L, status, NULL);
}
/* Determine mode of select() call. */
int32_t lj_ffrecord_select_mode(jit_State *J, TRef tr, TValue *tv)
{
  if (tref_isstr(tr) && *strVdata(tv) == '#') {  /* select('#', ...) */
    if (strV(tv)->len == 1) {
      emitir(IRTG(IR_EQ, IRT_STR), tr, lj_ir_kstr(J, strV(tv)));
    } else {
      TRef trptr = emitir(IRT(IR_STRREF, IRT_P32), tr, lj_ir_kint(J, 0));
      TRef trchar = emitir(IRT(IR_XLOAD, IRT_U8), trptr, IRXLOAD_READONLY);
      emitir(IRTG(IR_EQ, IRT_INT), trchar, lj_ir_kint(J, '#'));
    }
    return 0;
  } else {  /* select(n, ...) */
    int32_t start = argv2int(J, tv);
    if (start == 0) lj_trace_err(J, LJ_TRERR_BADTYPE);  /* A bit misleading. */
    return start;
  }
}
Example #5
0
void lj_vmevent_call(lua_State *L, ptrdiff_t argbase, int keeponstack)
{
  global_State *g = G(L);
  uint8_t oldmask = g->vmevmask;
  uint8_t oldh = hook_save(g);
  int status;
  g->vmevmask = 0;  /* Disable all events. */
  hook_vmevent(g);
  status = lj_vm_pcall(L, restorestack(L, argbase), 0+1+keeponstack, 0);
  if (LJ_UNLIKELY(status)) {
    /* Really shouldn't use stderr here, but where else to complain? */
    L->top--;
    fprintf(stderr, "VM handler failed: %s\n",
	    tvisstr(L->top) ? strVdata(L->top) : "?");
  }
  hook_restore(g, oldh);
  if (g->vmevmask != VMEVENT_NOCACHE)
    g->vmevmask = oldmask;  /* Restore event mask, but not if not modified. */
}
Example #6
0
static int io_file_write(lua_State *L, FILE *fp, int start)
{
  cTValue *tv;
  int status = 1;
  for (tv = L->base+start; tv < L->top; tv++) {
    if (tvisstr(tv)) {
      MSize len = strV(tv)->len;
      status = status && (fwrite(strVdata(tv), 1, len, fp) == len);
    } else if (tvisint(tv)) {
      char buf[LJ_STR_INTBUF];
      char *p = lj_str_bufint(buf, intV(tv));
      size_t len = (size_t)(buf+LJ_STR_INTBUF-p);
      status = status && (fwrite(p, 1, len, fp) == len);
    } else if (tvisnum(tv)) {
      status = status && (fprintf(fp, LUA_NUMBER_FMT, numV(tv)) > 0);
    } else {
      lj_err_argt(L, (int)(tv - L->base) + 1, LUA_TSTRING);
    }
  }
  return io_pushresult(L, status, NULL);
}
Example #7
0
static int io_file_read(lua_State *L, FILE *fp, int start)
{
  int ok, n, nargs = cast_int(L->top - L->base) - start;
  clearerr(fp);
  if (nargs == 0) {
    ok = io_file_readline(L, fp);
    n = start+1;  /* Return 1 result. */
  } else {
    /* The results plus the buffers go on top of the args. */
    luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments");
    ok = 1;
    for (n = start; nargs-- && ok; n++) {
      if (tvisstr(L->base+n)) {
	const char *p = strVdata(L->base+n);
	if (p[0] != '*')
	  lj_err_arg(L, n+1, LJ_ERR_INVOPT);
	if (p[1] == 'n')
	  ok = io_file_readnum(L, fp);
	else if (p[1] == 'l')
	  ok = io_file_readline(L, fp);
	else if (p[1] == 'a')
	  io_file_readchars(L, fp, ~((size_t)0));
	else
	  lj_err_arg(L, n+1, LJ_ERR_INVFMT);
      } else if (tvisnum(L->base+n)) {
	size_t len = (size_t)lj_lib_checkint(L, n+1);
	ok = len ? io_file_readchars(L, fp, len) : io_file_testeof(L, fp);
      } else {
	lj_err_arg(L, n+1, LJ_ERR_INVOPT);
      }
    }
  }
  if (ferror(fp))
    return io_pushresult(L, 0, NULL);
  if (!ok)
    setnilV(L->top-1);  /* Replace last result with nil. */
  return n - start;
}
Example #8
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;
}
Example #9
0
/* Helper for CAT. Coercion, iterative concat, __concat metamethod. */
TValue *lj_meta_cat(lua_State *L, TValue *top, int left)
{
  do {
    int n = 1;
    if (!(tvisstr(top-1) || tvisnumber(top-1)) || !tostring(L, top)) {
      cTValue *mo = lj_meta_lookup(L, top-1, MM_concat);
      if (tvisnil(mo)) {
	mo = lj_meta_lookup(L, top, MM_concat);
	if (tvisnil(mo)) {
	  if (tvisstr(top-1) || tvisnumber(top-1)) top++;
	  lj_err_optype(L, top-1, LJ_ERR_OPCAT);
	  return NULL;  /* unreachable */
	}
      }
      /* One of the top two elements is not a string, call __cat metamethod:
      **
      ** before:    [...][CAT stack .........................]
      **                                 top-1     top         top+1 top+2
      ** pick two:  [...][CAT stack ...] [o1]      [o2]
      ** setup mm:  [...][CAT stack ...] [cont|?]  [mo|tmtype] [o1]  [o2]
      ** in asm:    [...][CAT stack ...] [cont|PC] [mo|delta]  [o1]  [o2]
      **            ^-- func base                              ^-- mm base
      ** after mm:  [...][CAT stack ...] <--push-- [result]
      ** next step: [...][CAT stack .............]
      */
      copyTV(L, top+2, top);  /* Careful with the order of stack copies! */
      copyTV(L, top+1, top-1);
      copyTV(L, top, mo);
      setcont(top-1, lj_cont_cat);
      return top+1;  /* Trigger metamethod call. */
    } else if (strV(top)->len == 0) {  /* Shortcut. */
      (void)tostring(L, top-1);
    } else {
      /* Pick as many strings as possible from the top and concatenate them:
      **
      ** before:    [...][CAT stack ...........................]
      ** pick str:  [...][CAT stack ...] [...... strings ......]
      ** concat:    [...][CAT stack ...] [result]
      ** next step: [...][CAT stack ............]
      */
      MSize tlen = strV(top)->len;
      char *buffer;
      int i;
      for (n = 1; n <= left && tostring(L, top-n); n++) {
	MSize len = strV(top-n)->len;
	if (len >= LJ_MAX_STR - tlen)
	  lj_err_msg(L, LJ_ERR_STROV);
	tlen += len;
      }
      buffer = lj_str_needbuf(L, &G(L)->tmpbuf, tlen);
      n--;
      tlen = 0;
      for (i = n; i >= 0; i--) {
	MSize len = strV(top-i)->len;
	memcpy(buffer + tlen, strVdata(top-i), len);
	tlen += len;
      }
      setstrV(L, top-n, lj_str_new(L, buffer, tlen));
    }
    left -= n;
    top -= n;
  } while (left >= 1);
  lj_gc_check_fixtop(L);
  return NULL;
}