LUA_API void lua_settable (lua_State *L, int idx) { StkId t; lua_lock(L); api_checknelems(L, 2); t = index2addr(L, idx); luaV_settable(L, t, L->top - 2, L->top - 1); L->top -= 2; /* pop index and value */ lua_unlock(L); }
LUA_API void lua_rawseti (lua_State *L, int idx, int n) { StkId o; lua_lock(L); api_checknelems(L, 1); o = luaA_index(L, idx); api_check(L, ttistable(o)); setobj2t(luaH_setnum(L, hvalue(o), n), L->top-1); /* write barrier */ L->top--; lua_unlock(L); }
LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) { StkId t; lua_lock(L); api_checknelems(L, 1); t = index2addr(L, idx); setivalue(L->top++, n); luaV_settable(L, t, L->top - 1, L->top - 2); L->top -= 2; /* pop value and key */ lua_unlock(L); }
LUA_API void lua_setfield (lua_State *L, int idx, const char *k) { StkId t; lua_lock(L); api_checknelems(L, 1); t = index2addr(L, idx); setsvalue2s(L, L->top++, luaS_new(L, k)); luaV_settable(L, t, L->top - 1, L->top - 2); L->top -= 2; /* pop value and key */ lua_unlock(L); }
LUA_API void lua_rawset (lua_State *L, int idx) { StkId t; lua_lock(L); api_checknelems(L, 2); t = luaA_index(L, idx); api_check(L, ttistable(t)); setobj2t(luaH_set(L, hvalue(t), L->top-2), L->top-1); /* write barrier */ L->top -= 2; lua_unlock(L); }
LUA_API void lua_setglobal (lua_State *L, const char *var) { Table *reg = hvalue(&G(L)->l_registry); const TValue *gt; /* global table */ lua_lock(L); api_checknelems(L, 1); gt = luaH_getint(reg, LUA_RIDX_GLOBALS); setsvalue2s(L, L->top++, luaS_new(L, var)); luaV_settable(L, gt, L->top - 1, L->top - 2); L->top -= 2; /* pop value and key */ lua_unlock(L); }
LUA_API void lua_rawseti (lua_State *L, int idx, int n) { StkId t; lua_lock(L); api_checknelems(L, 1); t = index2addr(L, idx); api_check(L, ttistable(t), "table expected"); luaH_setint(L, hvalue(t), n, L->top - 1); luaC_barrierback(L, gcvalue(t), L->top-1); L->top--; lua_unlock(L); }
LUA_API void lua_setuservalue (lua_State *L, int idx) { StkId o; lua_lock(L); api_checknelems(L, 1); o = index2addr(L, idx); api_check(ttisfulluserdata(o), "full userdata expected"); setuservalue(L, uvalue(o), L->top - 1); luaC_barrier(L, gcvalue(o), L->top - 1); L->top--; lua_unlock(L); }
/* weet: * 将一个栈顶的n个元素拷贝到另一个栈 * */ LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) { int i; lua_lock(to); api_checknelems(from, n); from->top -= n; for (i = 0; i < n; i++) { setobj2s(to->top, from->top + i); api_incr_top(to); } lua_unlock(to); }
LUA_API void lua_arith (lua_State *L, int op) { StkId o1; /* 1st operand */ StkId o2; /* 2nd operand */ lua_lock(L); if (op != LUA_OPUNM) /* all other operations expect two operands */ api_checknelems(L, 2); else { /* for unary minus, add fake 2nd operand */ api_checknelems(L, 1); setobjs2s(L, L->top, L->top - 1); L->top++; } o1 = L->top - 2; o2 = L->top - 1; if (ttisnumber(o1) && ttisnumber(o2)) { changenvalue(o1, luaO_arith(op, nvalue(o1), nvalue(o2))); } else luaV_arith(L, o1, o1, o2, cast(TMS, op - LUA_OPADD + TM_ADD)); L->top--; lua_unlock(L); }
LUA_API void lua_rawset (lua_State *L, int idx) { StkId t; lua_lock(L); api_checknelems(L, 2); t = index2addr(L, idx); api_check(L, ttistable(t), "table expected"); setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1); invalidateTMcache(hvalue(t)); luaC_barrierback(L, gcvalue(t), L->top-1); L->top -= 2; lua_unlock(L); }
LUA_API void lua_setdefaultmetatable(lua_State *L, int type) { StkId t; lua_lock(L); api_checknelems(L, 1); t = L->top - 1; if (ttype(t) == LUA_TTABLE) { /* `t' is a table? */ sethvalue(defaultmetatypes(L, type), hvalue(t)); } L->top -= 1; lua_unlock(L); }
LUA_API void lua_replace (lua_State *L, int idx) { lua_lock(L); /* explicit test for incompatible code */ if ( idx == LUA_ENVIRONINDEX && !hascallingenv( L ) ) { luaG_runerror(L, "no calling environment"); } api_checknelems(L, 1); { rtStack_t& rtStack = L->rtStack; rtStack.Lock( L ); StkId stackTop = L->GetCurrentStackFrame().TopMutable( L, L->rtStack ); if ( idx == LUA_ENVIRONINDEX ) { Closure *func = curr_func(L); const TValue *val = stackTop; func->env = gcvalue(val); luaC_barrier(L, func, val); } else if ( idx == LUA_STORAGEINDEX ) { const TValue *val = stackTop; setgcvalue( L, &L->storage, gcvalue( val ) ); luaC_barrier( L, L, val ); } else { ValueAddress o = index2adr(L, idx); api_checkvalidindex(L, o); setobj( L, o, stackTop ); if ( idx < LUA_GLOBALSINDEX ) /* function upvalue? */ { luaC_barrier(L, curr_func(L), stackTop); } } popstack( L, 1 ); rtStack.Unlock( L ); } lua_unlock(L); }
LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) { int i; if (from == to) return; lua_lock(to); api_checknelems(from, n); api_check(from, G(from) == G(to), "moving among independent states"); api_check(from, to->ci->top - to->top >= n, "not enough elements to move"); from->top -= n; for (i = 0; i < n; i++) { setobj2s(to, to->top++, from->top + i); } lua_unlock(to); }
LUA_API void lua_rawsetp (lua_State *L, int idx, const void *p) { StkId t; TValue k; lua_lock(L); api_checknelems(L, 1); t = index2addr(L, idx); api_check(L, ttistable(t), "table expected"); setpvalue(&k, cast(void *, p)); setobj2t(L, luaH_set(L, hvalue(t), &k), L->top - 1); luaC_barrierback(L, gcvalue(t), L->top - 1); L->top--; lua_unlock(L); }
LUA_API void lua_rawseti (lua_State *L, int idx, lua_Integer n) { StkId o; Table *t; lua_lock(L); api_checknelems(L, 1); o = index2addr(L, idx); api_check(ttistable(o), "table expected"); t = hvalue(o); luaH_setint(L, t, n, L->top - 1); luaC_barrierback(L, t, L->top-1); L->top--; lua_unlock(L); }
LUA_API void lua_settable (lua_State *L, int idx) { StkId t; lua_lock(L); api_checknelems(L, 2); t = luaA_index(L, idx); luaV_settable(L, t, L->top - 2, L->top - 1); #if LUA_REFCOUNT setnilvalue(--L->top); setnilvalue(--L->top); #else !LUA_REFCOUNT L->top -= 2; /* pop index and value */ #endif LUA_REFCOUNT lua_unlock(L); }
LUA_API void lua_rawseti (lua_State *L, int idx, int n) { StkId o; lua_lock(L); api_checknelems(L, 1); o = luaA_index(L, idx); api_check(L, ttistable(o)); setobj2t(luaH_setnum(L, hvalue(o), n), L->top-1); /* write barrier */ #if LUA_REFCOUNT setnilvalue(--L->top); #else !LUA_REFCOUNT L->top--; #endif LUA_REFCOUNT lua_unlock(L); }
LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) { int i; if (from == to) return; lua_lock(to); api_checknelems(from, n); api_check(from, G(from) == G(to), "moving among independent states"); api_check(from, to->ci->top - to->top >= n, "stack overflow"); from->top -= n; for (i = 0; i < n; i++) { setobj2s(to, to->top, from->top + i); to->top++; /* stack already checked by previous 'api_check' */ } lua_unlock(to); }
/* ** t[k] = value at the top of the stack (where 'k' is a string) */ static void auxsetstr (lua_State *L, const TValue *t, const char *k) { const TValue *slot; TString *str = luaS_new(L, k); api_checknelems(L, 1); if (luaV_fastset(L, t, str, slot, luaH_getstr, L->top - 1)) L->top--; /* pop value */ else { setsvalue2s(L, L->top, str); /* push 'str' (to make it a TValue) */ api_incr_top(L); luaV_finishset(L, t, L->top - 1, L->top - 2, slot); L->top -= 2; /* pop value and key */ } lua_unlock(L); /* lock done by caller */ }
LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { Closure *cl; lua_lock(L); luaC_checkGC(L); api_checknelems(L, n); cl = luaF_newCclosure(L, n); cl->c.f = fn; L->top -= n; while (n--) setobj2n(&cl->c.upvalue[n], L->top+n); setclvalue(L->top, cl); api_incr_top(L); lua_unlock(L); }
LUA_API int lua_setfenv (lua_State *L, int idx) { StkId o; int res = 0; lua_lock(L); api_checknelems(L, 1); o = luaA_index(L, idx); L->top--; api_check(L, ttistable(L->top)); if (isLfunction(o)) { res = 1; clvalue(o)->l.g = *(L->top); } lua_unlock(L); return res; }
LUA_API void lua_rawset (lua_State *L, int idx) { StkId t; lua_lock(L); api_checknelems(L, 2); t = luaA_index(L, idx); api_check(L, ttistable(t)); setobj2t(luaH_set(L, hvalue(t), L->top-2), L->top-1); /* write barrier */ #if LUA_REFCOUNT setnilvalue(--L->top); setnilvalue(--L->top); #else !LUA_REFCOUNT L->top -= 2; #endif LUA_REFCOUNT lua_unlock(L); }
LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) { StkId t; const TValue *slot; lua_lock(L); api_checknelems(L, 1); t = index2addr(L, idx); if (luaV_fastset(L, t, n, slot, luaH_getint, L->top - 1)) L->top--; /* pop value */ else { setivalue(L->top, n); api_incr_top(L); luaV_finishset(L, t, L->top - 1, L->top - 2, slot); L->top -= 2; /* pop value and key */ } lua_unlock(L); }
LUA_API void lua_setuservalue (lua_State *L, int idx) { StkId o; lua_lock(L); api_checknelems(L, 1); o = index2addr(L, idx); api_check(L, ttisuserdata(o), "userdata expected"); if (ttisnil(L->top - 1)) uvalue(o)->env = NULL; else { api_check(L, ttistable(L->top - 1), "table expected"); uvalue(o)->env = hvalue(L->top - 1); luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1)); } L->top--; lua_unlock(L); }
LUA_API void lua_callk (lua_State *L, int nargs, int nresults, int ctx, lua_CFunction k) { StkId func; lua_lock(L); api_check(L, k == NULL || !isLua(L->ci), "cannot use continuations inside hooks"); api_checknelems(L, nargs+1); api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread"); checkresults(L, nargs, nresults); func = L->top - (nargs+1); if (k != NULL && L->nny == 0) { /* need to prepare continuation? */ L->ci->u.c.k = k; /* save continuation */ L->ci->u.c.ctx = ctx; /* save context */ luaD_call(L, func, nresults, 1); /* do the call */ } else /* no continuation or no yieldable */ luaD_call(L, func, nresults, 0); /* just do the call */ adjustresults(L, nresults); lua_unlock(L); }
LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { lua_lock(L); if (n == 0) { setfvalue(L->top, fn); } else { Closure *cl; api_checknelems(L, n); api_check(L, n <= MAXUPVAL, "upvalue index too large"); luaC_checkGC(L); cl = luaF_newCclosure(L, n); cl->c.f = fn; L->top -= n; while (n--) setobj2n(L, &cl->c.upvalue[n], L->top + n); setclCvalue(L, L->top, cl); } api_incr_top(L); lua_unlock(L); }
LUA_API int lua_setmetatable (lua_State *L, int objindex) { TValue *obj; Table *mt; lua_lock(L); api_checknelems(L, 1); obj = index2addr(L, objindex); api_checkvalidindex(L, obj); if (ttisnil(L->top - 1)) mt = NULL; else { api_check(L, ttistable(L->top - 1), "table expected"); mt = hvalue(L->top - 1); } switch (ttypenv(obj)) { case LUA_TTABLE: { hvalue(obj)->metatable = mt; if (mt) luaC_objbarrierback(L, gcvalue(obj), mt); luaC_checkfinalizer(L, gcvalue(obj), mt); break; } case LUA_TUSERDATA: { uvalue(obj)->metatable = mt; if (mt) { luaC_objbarrier(L, rawuvalue(obj), mt); luaC_checkfinalizer(L, gcvalue(obj), mt); } break; } default: { G(L)->mt[ttypenv(obj)] = mt; break; } } L->top--; lua_unlock(L); return 1; }
LUA_API int lua_setmetatable (lua_State *L, int objindex) { TObject *obj, *mt; int res = 1; lua_lock(L); api_checknelems(L, 1); obj = luaA_index(L, objindex); mt = (!ttisnil(L->top - 1)) ? L->top - 1 : defaultmeta(L); api_check(L, ttistable(mt)); switch (ttype(obj)) { case LUA_TTABLE: { #if LUA_REFCOUNT __AddRefDirect(hvalue(mt)); __ReleaseDirect(L, hvalue(obj)->metatable); #endif LUA_REFCOUNT hvalue(obj)->metatable = hvalue(mt); /* write barrier */ break; } case LUA_TUSERDATA: { #if LUA_REFCOUNT __AddRefDirect(hvalue(mt)); __ReleaseDirect(L, &uvalue(obj)->uv.metatable); #endif LUA_REFCOUNT uvalue(obj)->uv.metatable = hvalue(mt); /* write barrier */ break; } default: { res = 0; /* cannot set */ break; } } #if LUA_REFCOUNT setnilvalue(--L->top); #else !LUA_REFCOUNT L->top--; #endif LUA_REFCOUNT lua_unlock(L); return res; }