Пример #1
0
int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) {
  const TValue *tm;
  lua_assert(ttype(t1) == ttype(t2));
  switch (ttype(t1)) {
    case LUA_TNIL: return 1;
    case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2));
    case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2);  /* true must be 1 !! */
    case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2);
    case LUA_TUSERDATA: {
      if (uvalue(t1) == uvalue(t2)) return 1;
      tm = get_compTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable,
                         TM_EQ);
      break;  /* will try TM */
    }
    case LUA_TTABLE: {
      if (hvalue(t1) == hvalue(t2)) return 1;
      tm = get_compTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ);
      break;  /* will try TM */
    }
    default: return gcvalue(t1) == gcvalue(t2);
  }
  if (tm == NULL) return 0;  /* no TM? */
  callTMres(L, L->top, tm, t1, t2);  /* call TM */
  return !l_isfalse(L->top);
}
Пример #2
0
/* Note: 'luaV_equalval()' and 'luaO_rawequalObj()' have largely overlapping
 *       implementation.
 */
int luaV_equalval (lua_State *L, const TValue *l, const TValue *r) {
  const TValue *tm;
  lua_assert( ttype_ext(l) == ttype_ext(r) );
  switch (ttype(l)) {
    case LUA_TNIL: return 1;
#ifdef LUA_TINT
    case LUA_TINT:
#endif
    case LUA_TNUMBER: return luaO_rawequalObj(l,r);
    case LUA_TBOOLEAN: return bvalue(l) == bvalue(r);  /* true must be 1 !! */
    case LUA_TLIGHTUSERDATA: return pvalue(l) == pvalue(r);
    case LUA_TUSERDATA: {
      if (uvalue(l) == uvalue(r)) return 1;
      tm = get_compTM(L, uvalue(l)->metatable, uvalue(r)->metatable, TM_EQ);
      break;  /* will try TM */
    }
    case LUA_TTABLE: {
      if (hvalue(l) == hvalue(r)) return 1;
      tm = get_compTM(L, hvalue(l)->metatable, hvalue(r)->metatable, TM_EQ);
      break;  /* will try TM */
    }
    default: return gcvalue(l) == gcvalue(r);
  }
  if (tm == NULL) return 0;  /* no TM? */
  callTMres(L, L->top, tm, l, r);  /* call TM */
  return !l_isfalse(L->top);
}
Пример #3
0
void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) {
  int loop;
  TValue temp;
  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);
      const TValue *res = ttistable(t) ? luaH_get((Table*)h, key) : luaH_get_ro(h, key); /* do a primitive get */
      if (!ttisnil(res) ||  /* result is no nil? */
          (tm = fasttm(L, ttistable(t) ? ((Table*)h)->metatable : (Table*)luaR_getmeta(h), TM_INDEX)) == NULL) { /* or no TM? */
        setobj2s(L, val, res);
        return;
      }      
      /* else will try the tag method */
    }
    else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX)))
        luaG_typeerror(L, t, "index");
    if (ttisfunction(tm) || ttislightfunction(tm)) {
      callTMres(L, val, tm, t, key);
      return;
    }
    /* else repeat with `tm' */
    setobj(L, &temp, tm);  /* avoid pointing inside table (may rehash) */
    t = &temp;
  }
  luaG_runerror(L, "loop in gettable");
}
Пример #4
0
void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val)
{
    int loop;
    for (loop = 0; loop < MAXTAGLOOP; loop++)
    {
        const TValue *tm;
        if (ttistable(t))    /* `t' is a table? */
        {
            Table *h = hvalue(t);
            const TValue *res = luaH_get(h, key); /* do a primitive get */
            if (!ttisnil(res) ||  /* result is no nil? */
                    (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL)   /* or no TM? */
            {
                setobj2s(L, val, res);
                return;
            }
            /* else will try the tag method */
        }
        else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX)))
            luaG_typeerror(L, t, "index");
        if (ttisfunction(tm))
        {
            callTMres(L, val, tm, t, key);
            return;
        }
        t = tm;  /* else repeat with `tm' */
    }
    luaG_runerror(L, "loop in gettable");
}
Пример #5
0
static void Arith (lua_State *L, StkId ra,
                   const TObject *rb, const TObject *rc, TMS op) {
  TObject tempb, tempc;
  const TObject *b, *c;
  if ((b = luaV_tonumber(rb, &tempb)) != NULL &&
      (c = luaV_tonumber(rc, &tempc)) != NULL) {
    switch (op) {
      case TM_ADD: setnvalue(ra, nvalue(b) + nvalue(c)); break;
      case TM_SUB: setnvalue(ra, nvalue(b) - nvalue(c)); break;
      case TM_MUL: setnvalue(ra, nvalue(b) * nvalue(c)); break;
      case TM_DIV: setnvalue(ra, nvalue(b) / nvalue(c)); break;
      case TM_POW: {
        const TObject *f = luaH_getstr(hvalue(gt(L)), G(L)->tmname[TM_POW]);
        ptrdiff_t res = savestack(L, ra);
        if (!ttisfunction(f))
          luaG_runerror(L, "`__pow' (`^' operator) is not a function");
        callTMres(L, f, b, c);
        ra = restorestack(L, res);  /* previous call may change stack */
        setobjs2s(ra, L->top);
        break;
      }
      default: lua_assert(0); break;
    }
  }
  else if (!call_binTM(L, rb, rc, ra, op))
    luaG_aritherror(L, rb, rc);
}
Пример #6
0
static int call_binTM (lua_State *L, const TValue *p1, const TValue *p2,
                       StkId res, TMS event) {
  const TValue *tm = luaT_gettmbyobj(L, p1, event);  /* try first operand */
  if (ttisnil(tm))
    tm = luaT_gettmbyobj(L, p2, event);  /* try second operand */
  if (ttisnil(tm)) return 0;
  callTMres(L, res, tm, p1, p2);
  return 1;
}
Пример #7
0
static const TObject *luaV_index (lua_State *L, const TObject *t,
                                  TObject *key, int loop) {
  const TObject *tm = fasttm(L, hvalue(t)->metatable, TM_INDEX);
  if (tm == NULL) return &luaO_nilobject;  /* no TM */
  if (ttisfunction(tm)) {
    callTMres(L, tm, t, key);
    return L->top;
  }
  else return luaV_gettable(L, tm, key, loop);
}
Пример #8
0
static int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2,
                         TMS event) {
  const TValue *tm1 = luaT_gettmbyobj(L, p1, event);
  const TValue *tm2;
  if (ttisnil(tm1)) return -1;  /* no metamethod? */
  tm2 = luaT_gettmbyobj(L, p2, event);
  if (!luaO_rawequalObj(tm1, tm2))  /* different metamethods? */
    return -1;
  callTMres(L, L->top, tm1, p1, p2);
  return !l_isfalse(L->top);
}
Пример #9
0
static const TObject *luaV_getnotable (lua_State *L, const TObject *t,
                                       TObject *key, int loop) {
  const TObject *tm = luaT_gettmbyobj(L, t, TM_INDEX);
  if (ttisnil(tm))
    luaG_typeerror(L, t, "index");
  if (ttisfunction(tm)) {
    callTMres(L, tm, t, key);
    return L->top;
  }
  else return luaV_gettable(L, tm, key, loop);
}
Пример #10
0
static int call_binTM (lua_State *L, const TObject *p1, const TObject *p2,
                       StkId res, TMS event) {
  ptrdiff_t result = savestack(L, res);
  const TObject *tm = luaT_gettmbyobj(L, p1, event);  /* try first operand */
  if (ttisnil(tm))
    tm = luaT_gettmbyobj(L, p2, event);  /* try second operand */
  if (!ttisfunction(tm)) return 0;
  callTMres(L, tm, p1, p2);
  res = restorestack(L, result);  /* previous call may change stack */
  setobjs2s(res, L->top);
  return 1;
}
Пример #11
0
void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) {
  const TValue *tm;
  switch (ttype(rb)) {
    case LUA_TTABLE: {
      Table *h = hvalue(rb);
      tm = fasttm(L, h->metatable, TM_LEN);
      if (tm) break;  /* metamethod? break switch to call it */
      setnvalue(ra, cast_num(luaH_getn(h)));  /* else primitive len */
      return;
    }
    case LUA_TSTRING: {
      setnvalue(ra, cast_num(tsvalue(rb)->len));
      return;
    }
    default: {  /* try metamethod */
      tm = luaT_gettmbyobj(L, rb, TM_LEN);
      if (ttisnil(tm))  /* no metamethod? */
        luaG_typeerror(L, rb, "get length of");
      break;
    }
  }
  callTMres(L, ra, tm, rb, luaO_nilobject);
}
Пример #12
0
void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) {
  int loop;
  for (loop = 0; loop < MAXTAGLOOP; loop++) {
    const TValue *tm = 0; /* LUA-VEC -- compiler gives a warning of uninitialized value on this so we set it to 0 */
    if (ttistable(t)) {  /* `t' is a table? */
      Table *h = hvalue(t);
      const TValue *res = luaH_get(h, key); /* do a primitive get */
      if (!ttisnil(res) ||  /* result is no nil? */
          (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */
        setobj2s(L, val, res);
        return;
      }
      /* else will try the tag method */
    }
    else if (ttisvec(t)) { /* LUA-VEC -- vec[idx] operator */
      /* issue: "index" may not be the correct arg for luaG_typeerror in here */
      if (ttisnumber(key) &&   /* acessing vec by a number? */
          (nvalue(key) >= 1 && nvalue(key) <= 4)) {  /* index is between 1-4? */
        TValue res;
        setnvalue(&res, vecvalue(t)[(int)nvalue(key)-1]);
        setobj2s(L, val, &res);
        return;
      }
      else if (ttisstring(key)) {  /* acessing vec by a string? */
        if (tsvalue(key)->len == 1) {
          /* accessing by a single component, such as vec.x */
          TValue res;
          switch (*getstr(tsvalue(key))) {
            case 'x':  setnvalue(&res, vecvalue(t)[0]); break;
            case 'y':  setnvalue(&res, vecvalue(t)[1]); break;
            case 'z':  setnvalue(&res, vecvalue(t)[2]); break;
            case 'w':  setnvalue(&res, vecvalue(t)[3]); break;
            default:   luaG_typeerror(L, t, "index");
          }
          setobj2s(L, val, &res);
          return;
        }
        else if (tsvalue(key)->len <= 4) {
          /* accessing by swizzling, such as vec.xy, vec.xxyz etc. */
          TValue res;
          float v[4] = {0.0f,0.0f,0.0f,0.0f};
          int i;
          for (i = 0; i < (int)tsvalue(key)->len; ++i) {
            switch (getstr(tsvalue(key))[i]) {
              case 'x':  v[i] = vecvalue(t)[0]; break;
              case 'y':  v[i] = vecvalue(t)[1]; break;
              case 'z':  v[i] = vecvalue(t)[2]; break;
              case 'w':  v[i] = vecvalue(t)[3]; break;
              default:   luaG_typeerror(L, t, "index");
            }
          }
          setvecvalue(&res, v[0], v[1], v[2], v[3]);
          setobj2s(L, val, &res);
          return;
        }
      }
      luaG_typeerror(L, t, "index");
    }
    else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX)))
      luaG_typeerror(L, t, "index");
    if (ttisfunction(tm)) {
      callTMres(L, val, tm, t, key);
      return;
    }
    t = tm;  /* else repeat with `tm' */ 
  }
  luaG_runerror(L, "loop in gettable");
}