LUACLLIB_API int luaC_istype(lua_State* L, int ixo, int ixc) { int r; lua_checkstack(L, 3); int xo = lua_absindex(L, ixo); int xc = (ixc == 0)? 0 : lua_absindex(L, ixc); int tc = luaC_gettid(L, xc); if (tc == 0) return FALSE; int to = luaC_gettid(L, xo); if (to == 0) {lua_pop(L, 1); return FALSE;} if ((lua_type(L, -1) == LUA_TFUNCTION) && (lua_compare(L, -1, -2, LUA_OPEQ))) { lua_pushvalue(L, xo); lua_pushvalue(L, xc); lua_call(L, 2, 1); r = lua_toboolean(L, -1); lua_pop(L, 1); return r; } r = lua_compare(L, -1, -2, LUA_OPEQ); while ((to == 3) && (tc == 1) && (!r)) { if (!lua_getmetatable(L, -1)) break; lua_remove(L, -2); r = lua_compare(L, -1, -2, LUA_OPEQ); } lua_pop(L, 2); return r; }
// create a new T object and // push onto the Lua stack a userdata containing a pointer to T object static int new_T(lua_State *L) { if (lua_gettop(L) > 0 && lua_compare(L, 1, lua_upvalueindex(1), LUA_OPEQ)) { lua_remove(L, 1); // use classname:new(), instead of classname.new() } // do nothing if argument 1 is an instance T *obj = new T(L); // call constructor for T objects push(L, obj, true); lua_insert(L, 1); // Push self below arguments for call to init() int nresult = LunarWrapper::init(obj, L); if (nresult != 0) { const char *msg = nullptr; int err = lua_gettop(L); if (err >= 0) { msg = lua_tostring(L, err); } if (msg == nullptr) { msg = "(unknown error)"; } return luaL_error(L, "'%s' failed to initialise: %s", T::className, msg); } lua_settop(L, 1); return 1; // userdata containing pointer to T object }
/* ** Copy elements (1[f], ..., 1[e]) into (tt[t], tt[t+1], ...). Whenever ** possible, copy in increasing order, which is better for rehashing. ** "possible" means destination after original range, or smaller ** than origin, or copying to another table. */ static int tmove (lua_State *L) { lua_Integer f = luaL_checkinteger(L, 2); lua_Integer e = luaL_checkinteger(L, 3); lua_Integer t = luaL_checkinteger(L, 4); int tt = !lua_isnoneornil(L, 5) ? 5 : 1; /* destination table */ checktab(L, 1, TAB_R); checktab(L, tt, TAB_W); if (e >= f) { /* otherwise, nothing to move */ lua_Integer n, i; luaL_argcheck(L, f > 0 || e < LUA_MAXINTEGER + f, 3, "too many elements to move"); n = e - f + 1; /* number of elements to move */ luaL_argcheck(L, t <= LUA_MAXINTEGER - n + 1, 4, "destination wrap around"); if (t > e || t <= f || (tt != 1 && !lua_compare(L, 1, tt, LUA_OPEQ))) { for (i = 0; i < n; i++) { lua_geti(L, 1, f + i); lua_seti(L, tt, t + i); } } else { for (i = n - 1; i >= 0; i--) { lua_geti(L, 1, f + i); lua_seti(L, tt, t + i); } } } lua_pushvalue(L, tt); /* return destination table */ return 1; }
static void update_inner_tables_once(lua_State *L, int src, int dst, int updated) { lutro_checked_stack_begin(); assert(lua_istable(L, src)); assert(lua_istable(L, dst)); assert(lua_istable(L, updated)); src = lua_absindex(L, src); dst = lua_absindex(L, dst); updated = lua_absindex(L, updated); lua_pushnil(L); while (lua_next(L, src)) { lua_pushvalue(L, -2); lua_gettable(L, dst); if (!lua_compare(L, -2, -1, LUA_OPEQ) && lua_istable(L, -2)) { deep_update_once(L, -1, -2, updated); lua_pushvalue(L, -3); lua_pushvalue(L, -2); lua_settable(L, dst); } lua_pop(L, 2); } lutro_checked_stack_assert(0); }
// Checks that the value at the given index is a WrapperClass type and then returns a pointer to the object template<typename WrapperClass> inline typename WrapperClass::target_type * to(lua_State * L, int index) { assert(index > 0); lua_getfield(L, LUA_REGISTRYINDEX, WrapperClass::CLASS_NAME); int class_mt_index = lua_gettop(L); lua_pushnil(L); void * ptr = lua_touserdata(L, index); if(!ptr || !lua_getmetatable(L, index)) luaL_argerror(L, index, lua_pushfstring(L, "%s expected, got %s", WrapperClass::CLASS_NAME, luaL_typename(L, index))); do { lua_remove(L, lua_gettop(L) - 1); if(lua_compare(L, -1, class_mt_index, LUA_OPEQ)) { lua_pop(L, 2); return reinterpret_cast<typename WrapperClass::target_type *>(ptr); } }while(lua_getmetatable(L, -1)); luaL_argerror(L, index, lua_pushfstring(L, "%s expected, got %s", WrapperClass::CLASS_NAME, luaL_typename(L, index))); return NULL; }
int equal(lua_State * L, int idx1, int idx2) { #if LUA_VERSION_NUM < 502 return lua_equal(L, idx1, idx2); #else return lua_compare(L, idx1, idx2, LUA_OPEQ); #endif }
int lessthan(lua_State * L, int idx1, int idx2) { #if LUA_VERSION_NUM < 502 return lua_lessthan(L, idx1, idx2); #else return lua_compare(L, idx1, idx2, LUA_OPLT); #endif }
bool LuaRef::operator==(const LuaRef & ref) const { if (ref.m_lua != m_lua) return false; if (ref.m_id == m_id) return true; ref.PushCopyToStack(); PushCopyToStack(); bool return_value = lua_compare(m_lua, -1, -2, LUA_OPEQ); lua_pop(m_lua, 2); return return_value; }
static int math_max(lua_State *L) { int n = lua_gettop(L); /* number of arguments */ int imax = 1; /* index of current maximum value */ int i; luaL_argcheck(L, n >= 1, 1, "value expected"); for (i = 2; i <= n; i++) { if (lua_compare(L, imax, i, LUA_OPLT)) imax = i; } lua_pushvalue(L, imax); return 1; }
bool LuaState::Compare(int index1, int index2, LuaComparison comparison) const { #ifdef NAZARA_DEBUG if (comparison > LuaComparison_Max) { NazaraError("Lua comparison out of enum"); return false; } #endif return (lua_compare(m_state, index1, index2, s_comparisons[comparison]) != 0); }
/* {{{ ratchet_error_is() */ static int ratchet_error_is (lua_State *L) { lua_settop (L, 2); if (lua_isstring (L, 1)) { lua_pushboolean (L, lua_compare (L, 1, 2, LUA_OPEQ)); return 1; } lua_getfield (L, 1, "type"); if (!strequal (L, -1, "ratchet_error")) { lua_pop (L, 1); lua_pushboolean (L, 0); return 1; } lua_pop (L, 1); lua_getfield (L, 1, "code"); lua_pushboolean (L, lua_compare (L, -1, 2, LUA_OPEQ)); return 1; }
static int sort_comp (lua_State *L, int a, int b) { if (!lua_isnil(L, 2)) { /* function? */ int res; lua_pushvalue(L, 2); lua_pushvalue(L, a-1); /* -1 to compensate function */ lua_pushvalue(L, b-2); /* -2 to compensate function and 'a' */ lua_call(L, 2, 1); res = lua_toboolean(L, -1); lua_pop(L, 1); return res; } else /* a < b? */ return lua_compare(L, a, b, LUA_OPLT); }
/* ** Return true iff value at stack index 'a' is less than the value at ** index 'b' (according to the order of the sort). */ static int sort_comp (lua_State *L, int a, int b) { if (lua_isnil(L, 2)) /* no function? */ return lua_compare(L, a, b, LUA_OPLT); /* a < b */ else { /* function */ int res; lua_pushvalue(L, 2); /* push function */ lua_pushvalue(L, a-1); /* -1 to compensate function */ lua_pushvalue(L, b-2); /* -2 to compensate function and 'a' */ lua_call(L, 2, 1); /* call function */ res = lua_toboolean(L, -1); /* get result */ lua_pop(L, 1); /* pop result */ return res; } }
LUWRA_NS_BEGIN /// Check if two values are equal. /// /// \param state Lua state /// \param index1 Index of left-hand side value /// \param index2 Index of right-hand side value inline bool equal(State* state, int index1, int index2) { #if LUA_VERSION_NUM <= 501 return lua_equal(state, index1, index2) == 1; #else return lua_compare(state, index1, index2, LUA_OPEQ) == 1; #endif }
static void fetch_keys_from_metatable(lua_State * l, int metatable_index, const std::string & chunk, std::vector<std::string> & completion_list, bool only_functions) { metatable_index = lua_absindex(l, metatable_index); int original_height = lua_gettop(l); int recursion_count = 0; lua_pushvalue(l, metatable_index); while(true) { //First, determin whether where are stored the methods and attributes lua_pushstring(l, "__index"); lua_rawget(l, -2); // meta, meta.__index if (lua_istable(l, -1)) { fetch_keys_from_table(l, -1, chunk, completion_list, only_functions); if (lua_getmetatable(l, -1)) { // meta, meta.__index, meta^2 // Avoid the weird cases where the metatable contains itself. if (!lua_compare(l, -1, metatable_index, LUA_OPEQ) && recursion_count < COMPLETION_RECURSION_LIMIT) { recursion_count++; lua_replace(l, original_height+1); lua_pop(l, 1); continue; } else { lua_settop(l, original_height); throw RecursionLimit(); } } } else if (lua_iscfunction(l, -1)) { // Deal with the specifics of LuaObject stuff. lua_rawgeti(l, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS); lua_pushstring(l, "type"); lua_rawget(l, original_height+1); // stuff, global, type lua_rawget(l, -2); // stuff, global, methods if (lua_istable(l, -1)) fetch_keys_from_table(l, -1, chunk, completion_list, only_functions); lua_pop(l, 1); // Kick out the methods. // Do the same for the parent lua_pushstring(l, "parent"); lua_rawget(l, original_height+1); if (!lua_isnil(l, -1)) { lua_rawget(l, LUA_REGISTRYINDEX); lua_replace(l, original_height+1); lua_pop(l, 2); continue; } } break; } lua_settop(l, original_height); }
int luaCompat_isOfType(lua_State* L, const char* module, const char* type) { int result = 0; LUASTACK_SET(L); luaCompat_getType(L, -1); luaCompat_pushTypeByName(L, module, type); #if LUA_VERSION_NUM <= 501 result = (lua_equal(L, -1, -2) ? 1 : 0); #else result = (lua_compare(L, -1, -2, LUA_OPEQ) ? 1 : 0); #endif lua_pop(L, 2); LUASTACK_CLEAN(L, 0); return result; }
static LGL* get_lgl(struct lua_State *state) { if (!lua_getmetatable(state,1)) { lua_pushliteral(state, "Invalid self argument"); lua_error(state); } lua_pushvalue(state, lua_upvalueindex(1)); // Push the Solver class if (!lua_compare(state, -1, -2, LUA_OPEQ)) { lua_pushliteral(state, "Invalid self argument"); lua_error(state); } lua_pop(state, 2); LGL** lgl_ptr = lua_touserdata(state, 1); if (!lgl_ptr) { lua_pushliteral(state, "Invalid self argument"); lua_error(state); } return *lgl_ptr; }
inline int lua_equal(lua_State *L, int idx1, int idx2) { return lua_compare(L, idx1, idx2, LUA_OPEQ); }
inline int lua_lessthan(lua_State *L, int idx1, int idx2) { return lua_compare(L, idx1, idx1, LUA_OPLT); }
// takes the first term off of the lua stack and return it as an // erlang term in the state 'env'. static int terminator_toerl_core(lua_State* lua, ERL_NIF_TERM *result, ErlNifEnv* env, ErlNifResourceType* resource_type) { const int top = lua_gettop(lua); switch(lua_type(lua, top)) { case LUA_TNIL: { *result = enif_make_atom(env, "nil"); lua_pop( lua, 1); assert(lua_gettop(lua) == top-1); return 1; break; } case LUA_TNUMBER: { const lua_Number number = luaL_checknumber(lua, top); if(is_int64(number)) { *result = enif_make_int64(env, (int64_t)number); } else { *result = enif_make_double(env, (double)number); } lua_pop( lua, 1); assert(lua_gettop(lua) == top-1); return 1; break; } case LUA_TBOOLEAN: { const int truefalse = lua_toboolean(lua, top); *result = truefalse ? enif_make_atom(env, "true") : enif_make_atom(env, "false"); lua_pop( lua, 1); assert(lua_gettop(lua) == top-1); return 1; break; } case LUA_TSTRING: { // get the lua string size_t string_len; const char * lua_string = lua_tolstring (lua, top, &string_len); // make space in erlang for it ErlNifBinary binary; if(enif_alloc_binary(string_len, &binary)) { // clean it memset(binary.data, 0, binary.size); // copy it over memcpy(binary.data, lua_string, string_len); *result = enif_make_binary(env, &binary); } else { luaL_error (lua, "could not convert lua string"); } lua_pop( lua, 1); assert(lua_gettop(lua) == top-1); return 1; break; } case LUA_TTABLE: { size_t table_size = 0; int is_array = lua_is_array(lua); // table is at the top of the stack lua_pushnil(lua); // nil as the first key while (lua_next(lua, top) != 0) { ++table_size; lua_pop(lua, 1); } // make sure we can grow the stack luaL_checkstack(lua, 2, ERROR_STACK_MESSAGE); ERL_NIF_TERM *new_table = (ERL_NIF_TERM*) node_alloc(table_size * sizeof(ERL_NIF_TERM)); ERL_NIF_TERM *next_cell = new_table; // table is at the top of the stack lua_pushnil(lua); // nil as the first key while (lua_next(lua, top) != 0) { // uses 'key' (at index -2) and 'value' (at index -1) if(is_array) { // remove 'value', keeps 'key' for next iteration ERL_NIF_TERM value; terminator_toerl_core(lua, &value, env, resource_type); *next_cell = value; } else { // remove 'value', keeps 'key' for next iteration ERL_NIF_TERM tuple_value; terminator_toerl_core(lua, &tuple_value, env, resource_type); ERL_NIF_TERM tuple_key; lua_pushvalue( lua, -1); terminator_toerl_core(lua, &tuple_key, env, resource_type); *next_cell = enif_make_tuple2(env, tuple_key, tuple_value); } next_cell++; } if(NULL != new_table) { *result = enif_make_list_from_array(env, new_table, table_size); node_free(new_table); } lua_pop( lua, 1); assert(lua_gettop(lua) == top-1); return 1; break; } case LUA_TUSERDATA: { // add metatable to stack if(lua_getmetatable (lua, top)) { // put the pid metatable onto the stack // compare the two metatables luaL_getmetatable(lua, TYPE_ERL_PID); if(lua_compare(lua, -1, -2, LUA_OPEQ)) { const ErlNifPid* userdata = (const ErlNifPid*) lua_touserdata(lua, top); *result = enif_make_pid(env, userdata); lua_pop(lua, 3); assert(lua_gettop(lua) == top-1); return 1; } // pop the pid metatable lua_pop(lua, 1); // push the ref metatable luaL_getmetatable(lua, TYPE_ERL_REF); if(lua_compare(lua, -1, -2, LUA_OPEQ)) { erlref_ptr erlref = (erlref_ptr) lua_touserdata(lua, top); *result = enif_make_copy( env, erlref->reference ); lua_pop(lua, 3); assert(lua_gettop(lua) == top-1); return 1; } lua_pop(lua, 1); // pop the ref metatable luaL_getmetatable(lua, TYPE_LUA_ADDRESS); if(lua_compare(lua, -1, -2, LUA_OPEQ)) { mailbox_address_ptr address = (mailbox_address_ptr) lua_touserdata(lua, top); assert(NULL != address); state_work_ptr state_work = address->state_work; assert(NULL != state_work); void* resource; (*result) = state_make_resource( env, &resource, resource_type, state_work, WEAK_REF); assert(NULL != resource); lua_pop(lua, 3); assert(lua_gettop(lua) == top-1); return 1; } // pop the metatable lua_pop(lua, 1); } lua_pop( lua, 2); *result = enif_make_atom(env, "unknown_lua_userdata"); assert(lua_gettop(lua) == top-1); return 1; break; } case LUA_TLIGHTUSERDATA: { *result = enif_make_atom(env, "lua_lightuserdata_notsupported"); lua_pop(lua, 1); assert(lua_gettop(lua) == top-1); return 1; break; } case LUA_TTHREAD: { *result = enif_make_atom(env, "lua_thread_notsupported"); lua_pop(lua, 1); assert(lua_gettop(lua) == top-1); return 1; break; } case LUA_TFUNCTION: { *result = enif_make_atom(env, "lua_function_notsupported"); lua_pop(lua, 1); assert(lua_gettop(lua) == top-1); return 1; break; } } assert(lua_gettop(lua) == top-1); return 0; }
inline bool operator==(const stack_reference& l, const stack_reference& r) { return lua_compare(l.lua_state(), l.stack_index(), r.stack_index(), LUA_OPEQ) == 0; }
LUA_API int luanet_equal (lua_State *L, int idx1, int idx2) { return lua_compare(L,(idx1),(idx2),LUA_OPEQ); }