Esempio n. 1
0
void vm_OP_CLOSURE(lua_State *L, LClosure *cl, int a, int bx, int pseudo_ops_offset) {
  TValue *base = L->base;
  const Instruction *pc;
  TValue *ra = base + a;
  Proto *p;
  Closure *ncl;
  int nup, j;

  p = cl->p->p[bx];
  pc=cl->p->code + pseudo_ops_offset;
  nup = p->nups;
  fixedstack(L);
  ncl = luaF_newLclosure(L, nup, cl->env);
  setclvalue(L, ra, ncl);
  ncl->l.p = p;
  for (j=0; j<nup; j++, pc++) {
    if (GET_OPCODE(*pc) == OP_GETUPVAL)
      ncl->l.upvals[j] = cl->upvals[GETARG_B(*pc)];
    else {
      lua_assert(GET_OPCODE(*pc) == OP_MOVE);
      ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(*pc));
    }
  }
  unfixedstack(L);
  luaC_checkGC(L);
}
Esempio n. 2
0
void luaV_concat (lua_State *L, int total, int last) {
  lu_mem max_sizet = MAX_SIZET;
  if (G(L)->memlimit < max_sizet) max_sizet = G(L)->memlimit;
  do {
    /* Any call which does a memory allocation may trim the stack,
       invalidating top unless the stack is fixed duri  ng the allocation */ 
    StkId top = L->base + last + 1;
    fixedstack(L);
    int n = 2;  /* number of elements handled in this pass (at least 2) */
    if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) {
      unfixedstack(L);
      if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT)) {
        /* restore 'top' pointer, since stack might have been reallocted */
        top = L->base + last + 1;
        luaG_concaterror(L, top-2, top-1);
      }
    } else if (tsvalue(top-1)->len == 0) { /* second op is empty? */
      (void)tostring(L, top - 2);  /* result is first op (as string) */
    } else {
      /* at least two string values; get as many as possible */
      size_t tl = tsvalue(top-1)->len;
      char *buffer;
      int i;
      /* collect total length */
      for (n = 1; n < total && tostring(L, top-n-1); n++) {
        size_t l = tsvalue(top-n-1)->len;
        if (l >= max_sizet - tl) luaG_runerror(L, "string length overflow");
        tl += l;
      }
      G(L)->buff.n = tl;
      buffer = luaZ_openspace(L, &G(L)->buff, tl);
      tl = 0;
      for (i=n; i>0; i--) {  /* concat all strings */
        size_t l = tsvalue(top-i)->len;
        c_memcpy(buffer+tl, svalue(top-i), l);
        tl += l;
      }
      setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl));
      luaZ_resetbuffer(&G(L)->buff);
    }
    total -= n-1;  /* got `n' strings to create 1 new */
    last -= n-1;
    unfixedstack(L);
  } while (total > 1);  /* repeat until only 1 result left */
}
Esempio n. 3
0
void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
  int loop;
  TValue temp;
  setnilvalue(L->top);
  L->top++;
  fixedstack(L);
  for (loop = 0; loop < MAXTAGLOOP; loop++) {
    const TValue *tm;
    if (ttistable(t) || ttisrotable(t)) {  /* `t' is a table? */
      void *h = ttistable(t) ? hvalue(t) : rvalue(t);
      TValue *oldval = ttistable(t) ? luaH_set(L, (Table*)h, key) : NULL; /* do a primitive set */
      if ((oldval && !ttisnil(oldval)) ||  /* result is no nil? */
          (tm = fasttm(L, ttistable(t) ? ((Table*)h)->metatable : (Table*)luaR_getmeta(h), TM_NEWINDEX)) == NULL) { /* or no TM? */
        if(oldval) {
          L->top--;
          unfixedstack(L);
          setobj2t(L, oldval, val);
          ((Table *)h)->flags = 0;
          luaC_barriert(L, (Table*)h, val);
        }
        return;
      }
      /* else will try the tag method */
    }
    else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
      luaG_typeerror(L, t, "index");
    if (ttisfunction(tm) || ttislightfunction(tm)) {
      L->top--;
      unfixedstack(L);
      callTM(L, tm, t, key, val);
      return;
    }
    /* else repeat with `tm' */
    setobj(L, &temp, tm);  /* avoid pointing inside table (may rehash) */
    t = &temp;
    setobj2s(L, L->top-1, t);  /* need to protect value from EGC. */
  }
  luaG_runerror(L, "loop in settable");
}
Esempio n. 4
0
void vm_OP_SETLIST(lua_State *L, int a, int b, int c) {
  TValue *base = L->base;
  TValue *ra = base + a;
  int last;
  Table *h;
  fixedstack(L);
  if (b == 0) {
    b = cast_int(L->top - ra) - 1;
    L->top = L->ci->top;
  }
  runtime_check(L, ttistable(ra));
  h = hvalue(ra);
  last = ((c-1)*LFIELDS_PER_FLUSH) + b;
  if (last > h->sizearray)  /* needs more space? */
    luaH_resizearray(L, h, last);  /* pre-alloc it at once */
  for (; b > 0; b--) {
    TValue *val = ra+b;
    setobj2t(L, luaH_setnum(L, h, last--), val);
    luaC_barriert(L, h, val);
  }
  unfixedstack(L);
}