示例#1
0
文件: lvm.c 项目: SwadicalRag/lau
/*
** Main function for table assignment (invoking metamethods if needed).
** Compute 't[key] = val'
*/
void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
    int loop;    /* counter to avoid infinite loops */
    for (loop = 0; loop < MAXTAGLOOP; loop++) {
        const TValue *tm;
        if (ttistable(t)) {    /* 't' is a table? */
            Table *h = hvalue(t);
            TValue *oldval = cast(TValue *, luaH_get(h, key));
            /* if previous value is not nil, there must be a previous entry
                 in the table; a metamethod has no relevance */
            if (!ttisnil(oldval) ||
                 /* previous value is nil; must check the metamethod */
                 ((tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL &&
                 /* no metamethod; is there a previous entry in the table? */
                 (oldval != luaO_nilobject ||
                 /* no previous entry; must create one. (The next test is
                        always true; we only need the assignment.) */
                 (oldval = luaH_newkey(L, h, key), 1)))) {
                /* no metamethod and (now) there is an entry with given key */
                setobj2t(L, oldval, val);    /* assign new value to that entry */
                invalidateTMcache(h);
                luaC_barrierback(L, h, val);
                return;
            }
            /* else will try the metamethod */
        }
        else    /* not a table; check metamethod */
            if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
                luaG_typeerror(L, t, "index");
        /* try the metamethod */
        if (ttisfunction(tm)) {
            luaT_callTM(L, tm, t, key, val, 0);
            return;
        }
        t = tm;    /* else repeat assignment over 'tm' */
    }
示例#2
0
/*
** Main function for table assignment (invoking metamethods if needed).
** Compute 't[key] = val'
*/
void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
                     StkId val, const TValue *oldval) {
  int loop;  /* counter to avoid infinite loops */
  for (loop = 0; loop < MAXTAGLOOP; loop++) {
    const TValue *tm;
    if (oldval != NULL) {
      Table *h = hvalue(t);  /* save 't' table */
      lua_assert(ttisnil(oldval));
      /* must check the metamethod */
      if ((tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL &&
         /* no metamethod; is there a previous entry in the table? */
         (oldval != luaO_nilobject ||
         /* no previous entry; must create one. (The next test is
            always true; we only need the assignment.) */
         (oldval = luaH_newkey(L, h, key), 1))) {
        /* no metamethod and (now) there is an entry with given key */
        setobj2t(L, cast(TValue *, oldval), val);
        invalidateTMcache(h);
        luaC_barrierback(L, h, val);
        return;
      }
      /* else will try the metamethod */
    }
    else {  /* not a table; check metamethod */
      if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
        luaG_typeerror(L, t, "index");
    }
    /* try the metamethod */
    if (ttisfunction(tm)) {
      luaT_callTM(L, tm, t, key, val, 0);
      return;
    }
    t = tm;  /* else repeat assignment over 'tm' */
    if (luaV_fastset(L, t, key, oldval, luaH_get, val))
      return;  /* done */
    /* else loop */
  }
  luaG_runerror(L, "settable chain too long; possible loop");
}
示例#3
0
文件: lvm.c 项目: IamAnson/skynet
/*
** Finish a table assignment 't[key] = val'.
** If 'slot' is NULL, 't' is not a table.  Otherwise, 'slot' points
** to the entry 't[key]', or to 'luaO_nilobject' if there is no such
** entry.  (The value at 'slot' must be nil, otherwise 'luaV_fastset'
** would have done the job.)
*/
void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
                     StkId val, const TValue *slot) {
  int loop;  /* counter to avoid infinite loops */
  for (loop = 0; loop < MAXTAGLOOP; loop++) {
    const TValue *tm;  /* '__newindex' metamethod */
    if (slot != NULL) {  /* is 't' a table? */
      Table *h = hvalue(t);  /* save 't' table */
      lua_assert(ttisnil(slot));  /* old value must be nil */
      tm = fasttm(L, h->metatable, TM_NEWINDEX);  /* get metamethod */
      if (tm == NULL) {  /* no metamethod? */
        if (slot == luaO_nilobject)  /* no previous entry? */
          slot = luaH_newkey(L, h, key);  /* create one */
        /* no metamethod and (now) there is an entry with given key */
        setobj2t(L, cast(TValue *, slot), val);  /* set its new value */
        invalidateTMcache(h);
        luaC_barrierback(L, h, val);
        return;
      }
      /* else will try the metamethod */
    }
    else {  /* not a table; check metamethod */
      if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
        luaG_typeerror(L, t, "index");
    }
    /* try the metamethod */
    if (ttisfunction(tm)) {
      luaT_callTM(L, tm, t, key, val, 0);
      return;
    }
    t = tm;  /* else repeat assignment over 'tm' */
    if (luaV_fastset(L, t, key, slot, luaH_get, val))
      return;  /* done */
    /* else loop */
  }
  luaG_runerror(L, "'__newindex' chain too long; possible loop");
}