示例#1
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");
}
示例#2
0
void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
  int loop;
  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) {
          setobj2t(L, oldval, val);
          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)) {
      callTM(L, tm, t, key, val);
      return;
    }
    t = tm;  /* else repeat with `tm' */ 
  }
  luaG_runerror(L, "loop in settable");
}
示例#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");
}
示例#4
0
const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event)
{
	Table *mt;
	switch (ttype(o)) {
	case LUA_TTABLE:
		mt = hvalue(o)->metatable;
		break;
	case LUA_TROTABLE:
		mt = (Table *)luaR_getmeta(rvalue(o));
		break;
	case LUA_TUSERDATA:
		mt = uvalue(o)->metatable;
		break;
	default:
		mt = G(L)->mt[ttype(o)];
	}
	if (!mt)
		return luaO_nilobject;
	else if (luaR_isrotable(mt))
		return luaH_getstr_ro(mt, G(L)->tmname[event]);
	else
		return luaH_getstr(mt, G(L)->tmname[event]);
}