COMPAT53_API int lua_compare (lua_State *L, int idx1, int idx2, int op) { int result = 0; switch (op) { case LUA_OPEQ: return lua_equal(L, idx1, idx2); case LUA_OPLT: return lua_lessthan(L, idx1, idx2); case LUA_OPLE: luaL_checkstack(L, 5, "not enough stack slots"); idx1 = lua_absindex(L, idx1); idx2 = lua_absindex(L, idx2); lua_pushvalue(L, idx1); lua_pushvalue(L, idx2); compat53_call_lua(L, (void*)compat53_compare_code, sizeof(compat53_compare_code)-1, 2, 1); result = lua_toboolean(L, -1); lua_pop(L, 1); return result; default: luaL_error(L, "invalid 'op' argument for lua_compare"); } return 0; }
/** * \brief Implementation of sol.menu.is_started(). * \param l the Lua context that is calling this function * \return number of values to return to Lua */ int LuaContext::menu_api_is_started(lua_State* l) { return LuaTools::exception_boundary_handle(l, [&] { LuaContext& lua_context = get_lua_context(l); LuaTools::check_type(l, 1, LUA_TTABLE); bool found = false; std::list<LuaMenuData>& menus = lua_context.menus; for (LuaMenuData& menu: menus) { push_ref(l, menu.ref); found = lua_equal(l, 1, -1); lua_pop(l, 1); if (found) { break; } } lua_pushboolean(l, found); return 1; }); }
/** * \brief Implementation of sol.menu.stop(). * \param l the Lua context that is calling this function * \return number of values to return to Lua */ int LuaContext::menu_api_stop(lua_State* l) { return LuaTools::exception_boundary_handle(l, [&] { LuaContext& lua_context = get_lua_context(l); LuaTools::check_type(l, 1, LUA_TTABLE); std::list<LuaMenuData>& menus = lua_context.menus; for (LuaMenuData& menu: menus) { push_ref(l, menu.ref); if (lua_equal(l, 1, -1)) { ScopedLuaRef menu_ref = menu.ref; // Don't erase it immediately since we may be iterating over menus. menu.ref.clear(); menu.context = nullptr; lua_context.menu_on_finished(menu_ref); lua_pop(l, 1); break; } lua_pop(l, 1); } return 0; }); }
static int t_find (lua_State *L) { luaL_checktype(L, 1, LUA_TTABLE); luaL_checkany(L, 2); #if 1 lua_settop(L, 3); if (!lua_find(L, 1)) { lua_pushnil(L); } #else if (!lua_isnoneornil(L, 3)) lua_pushvalue(L, 3); else lua_pushnil(L); while (lua_next(L, 1)) { if (lua_equal(L, -1, 2)) { lua_pop(L, 1); return 1; } lua_pop(L, 1); } lua_pushnil(L); #endif return 1; }
int NativeDelegate::__op_minusassignment(lua_State *L) { NativeDelegate *delegate = (NativeDelegate *)lualoom_getnativepointer(L, 1, "system.NativeDelegate"); if (!delegate) { LSError("Unable to get native delegate on += operator"); } if (!delegate->_callbackCount) { return 0; } delegate->setVM(L); delegate->getCallbacks(L); int tidx = lua_gettop(L); if (!lua_istable(L, tidx)) { LSError("Bad native delegates table"); } if (lua_isfunction(L, 2) || lua_iscfunction(L, 2)) { int idx = -1; for (int i = 0; i < delegate->_callbackCount; i++) { lua_rawgeti(L, tidx, i); if (lua_equal(L, 2, -1)) { idx = i; lua_pop(L, 1); break; } lua_pop(L, 1); } // this function was never added in the first place if (idx == -1) { return 0; } // shift the other delegates down lua_pushnumber(L, (double)idx); lua_pushnil(L); lua_settable(L, tidx); int ntable = 0; if (delegate->_callbackCount > 1) { // temp table lua_newtable(L); ntable = lua_gettop(L); int c = 0; for (int nidx = 0; nidx < delegate->_callbackCount; nidx++) { lua_pushnumber(L, (double)nidx); lua_gettable(L, tidx); if (lua_isnil(L, -1)) { lua_pop(L, 1); continue; } lua_pushnumber(L, (double)c); lua_pushvalue(L, -2); lua_settable(L, ntable); // pop lua_function lua_pop(L, 1); c++; } } // clear it delegate->_callbackCount--; // and copy from new temp table for (int nidx = 0; nidx < delegate->_callbackCount; nidx++) { lua_pushnumber(L, (double)nidx); lua_pushnumber(L, (double)nidx); lua_gettable(L, ntable); lua_settable(L, tidx); } } else { LSError("Unknown type on NativeDelegate -= operator"); } return 0; }
int32_t Serializer::writeTable(const std::string parentKey) { // Handle cycles for (const auto &table : _tblMap) { lua_rawgeti(_L, LUA_REGISTRYINDEX, table.first); if (lua_equal(_L, -1, -2)) { // Maybe a cycle... lua_pop(_L, 1); if (!writeField(parentKey, table.second)) return -1; return 1; } else lua_pop(_L, 1); } { // Store this table lua_pushvalue(_L, -1); int ref = luaL_ref(_L, LUA_REGISTRYINDEX); _tblMap[ref] = parentKey; } lua_pushnil(_L); int32_t numFields = 0; while (lua_next(_L, -2) != 0) { if (!lua_isstring(_L, -2)) { lua_pop(_L, 1); continue; } std::string val; std::string fullKey = parentKey + '['; if (lua_type(_L, -2) == LUA_TSTRING) fullKey += '"'; lua_pushvalue(_L, -2); fullKey += lua_tostring(_L, -1); lua_pop(_L, 1); if (lua_type(_L, -2) == LUA_TSTRING) fullKey += '"'; fullKey += ']'; switch (lua_type(_L, -1)) { case LUA_TTABLE: { int32_t numNewFields = writeTable(fullKey); if (numNewFields < 0) return -1; numFields += numNewFields; lua_pop(_L, 1); continue; } case LUA_TBOOLEAN: { val = lua_toboolean(_L, -1) ? "true" : "false"; break; } case LUA_TSTRING: val += '"'; // Fallthrough case LUA_TNUMBER: { val += lua_tostring(_L, -1); if (val[0] == '"') val += '"'; break; } default: { lua_pop(_L, 1); continue; } } if (!writeField(fullKey, val)) return -1; numFields++; lua_pop(_L, 1); } return numFields; }
JNIEXPORT jint JNICALL Java_m_lua_Lua_equal (JNIEnv* env, jobject thiz, jlong nativeObj, jint idx1, jint idx2) { pushJNIEnv(env, nativeObj); return (jint) lua_equal((lua_State*) nativeObj, idx1, idx2); }
static int vlclua_del_callback( lua_State *L ) { vlclua_callback_t *p_callback; bool b_found = false; vlc_object_t **pp_obj = luaL_checkudata( L, 1, "vlc_object" ); const char *psz_var = luaL_checkstring( L, 2 ); lua_settop( L, 4 ); /* makes sure that optional data arg is set */ if( !lua_isfunction( L, 3 ) ) return vlclua_error( L ); /* obj var func data */ lua_getglobal( L, "vlc" ); /* obj var func data vlc */ lua_getfield( L, -1, "callbacks" ); if( lua_isnil( L, -1 ) ) return luaL_error( L, "Couldn't find matching callback." ); /* obj var func data vlc callbacks */ lua_remove( L, -2 ); /* obj var func data callbacks */ lua_pushnil( L ); /* obj var func data callbacks index */ while( lua_next( L, -2 ) ) { /* obj var func data callbacks index value */ if( lua_isnumber( L, -2 ) ) { lua_getfield( L, -1, "private2" ); /* obj var func data callbacks index value private2 */ if( lua_equal( L, 2, -1 ) ) /* var name is equal */ { lua_pop( L, 1 ); /* obj var func data callbacks index value */ lua_getfield( L, -1, "callback" ); /* obj var func data callbacks index value callback */ if( lua_equal( L, 3, -1 ) ) /* callback function is equal */ { lua_pop( L, 1 ); /* obj var func data callbacks index value */ lua_getfield( L, -1, "data" ); /* callback data is equal */ /* obj var func data callbacks index value data */ if( lua_equal( L, 4, -1 ) ) { vlc_object_t *p_obj2; lua_pop( L, 1 ); /* obj var func data callbacks index value */ lua_getfield( L, -1, "private1" ); /* obj var func data callbacks index value private1 */ p_obj2 = (vlc_object_t*)luaL_checklightuserdata( L, -1 ); if( p_obj2 == *pp_obj ) /* object is equal */ { lua_pop( L, 1 ); /* obj var func data callbacks index value */ lua_getfield( L, -1, "private3" ); /* obj var func data callbacks index value private3 */ p_callback = (vlclua_callback_t*)luaL_checklightuserdata( L, -1 ); lua_pop( L, 2 ); /* obj var func data callbacks index */ b_found = true; break; } else { /* obj var func data callbacks index value private1 */ lua_pop( L, 1 ); /* obj var func data callbacks index value */ } } else { /* obj var func data callbacks index value data */ lua_pop( L, 1 ); /* obj var func data callbacks index value */ } } else { /* obj var func data callbacks index value callback */ lua_pop( L, 1 ); /* obj var func data callbacks index value */ } } else { /* obj var func data callbacks index value private2 */ lua_pop( L, 1 ); /* obj var func data callbacks index value */ } } /* obj var func data callbacks index value */ lua_pop( L, 1 ); /* obj var func data callbacks index */ } if( b_found == false ) /* obj var func data callbacks */ return luaL_error( L, "Couldn't find matching callback." ); /* else */ /* obj var func data callbacks index*/ var_DelCallback( *pp_obj, psz_var, vlclua_callback, p_callback ); free( p_callback ); /* obj var func data callbacks index */ lua_pushnil( L ); /* obj var func data callbacks index nil */ lua_settable( L, -3 ); /* delete the callback table entry */ /* obj var func data callbacks */ lua_pop( L, 5 ); /* <empty stack> */ return 0; }
static void set_resident (lua_State *L) { /* Get '_CLIBS' table from the registry (Lua5.2). */ lua_getfield (L, LUA_REGISTRYINDEX, "_CLIBS"); if (!lua_isnil (L, -1)) { /* Remove the very last item in they array part, which is handle to our loaded module used by _CLIBS.gctm to clean modules upon state cleanup. But before removing it, check, that it is really the handle of our module. Our module filename is passed as arg 2. */ lua_pushvalue (L, 2); lua_gettable (L, -2); lua_rawgeti (L, -2, lua_objlen (L, -2)); if (lua_equal (L, -1, -2)) { lua_pushnil (L); lua_rawseti (L, -4, lua_objlen (L, -4)); } lua_pop (L, 3); return; } else { if (lua_gettop(L) == 3) { /* Some Lua versions give us the path to the .so on the stack. Just load & leak it. */ GModule* module = g_module_open(lua_tostring(L, 2), G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL); if (module != NULL) return; } /* This hack tries to enumerate the whole registry table and find 'LOADLIB: path' library. When it detects itself, it just removes pointer to the loaded library, disallowing Lua to close it, thus leaving it resident even when the state is closed. */ /* Note: 'nil' is on the stack from lua_getfield() call above. */ while (lua_next (L, LUA_REGISTRYINDEX)) { if (lua_type (L, -2) == LUA_TSTRING) { const char *str = lua_tostring (L, -2); if (g_str_has_prefix (str, "LOADLIB: ") && strstr (str, "corelgilua5")) { /* NULL the pointer to the loaded library. */ if (lua_type (L, -1) == LUA_TUSERDATA) { gpointer *lib = lua_touserdata (L, -1); *lib = NULL; } /* Clean the stack and return. */ lua_pop (L, 2); return; } } lua_pop (L, 1); } } }
static LUA_FUNCTION(openssl_evp_encrypt) { const EVP_CIPHER* cipher = NULL; if (lua_istable(L, 1)) { if (lua_getmetatable(L, 1) && lua_equal(L, 1, -1)) { lua_pop(L, 1); lua_remove(L, 1); } else luaL_error(L, "call function with invalid state"); } cipher = get_cipher(L, 1, NULL); if (cipher) { size_t input_len = 0; const char *input = luaL_checklstring(L, 2, &input_len); size_t key_len = 0; const char *key = luaL_optlstring(L, 3, NULL, &key_len); /* can be NULL */ size_t iv_len = 0; const char *iv = luaL_optlstring(L, 4, NULL, &iv_len); /* can be NULL */ int pad = lua_isnoneornil(L, 5) ? 1 : lua_toboolean(L, 5); ENGINE *e = lua_isnoneornil(L, 6) ? NULL : CHECK_OBJECT(6, ENGINE, "openssl.engine"); EVP_CIPHER_CTX *c = EVP_CIPHER_CTX_new(); int output_len = 0; int len = 0; char *buffer = NULL; char evp_key[EVP_MAX_KEY_LENGTH] = {0}; char evp_iv[EVP_MAX_IV_LENGTH] = {0}; int ret = 0; if (key) { key_len = EVP_MAX_KEY_LENGTH > key_len ? key_len : EVP_MAX_KEY_LENGTH; memcpy(evp_key, key, key_len); } if (iv_len > 0 && iv) { iv_len = EVP_MAX_IV_LENGTH > iv_len ? iv_len : EVP_MAX_IV_LENGTH; memcpy(evp_iv, iv, iv_len); } EVP_CIPHER_CTX_init(c); ret = EVP_EncryptInit_ex(c, cipher, e, (const byte*)evp_key, iv_len > 0 ? (const byte*)evp_iv : NULL); if (ret == 1) { ret = EVP_CIPHER_CTX_set_padding(c, pad); if (ret == 1) { buffer = OPENSSL_malloc(input_len + EVP_CIPHER_CTX_block_size(c)); ret = EVP_EncryptUpdate(c, (byte*) buffer, &len, (const byte*)input, input_len); if ( ret == 1 ) { output_len += len; ret = EVP_EncryptFinal(c, (byte*)buffer + len, &len); if (ret == 1) { output_len += len; lua_pushlstring(L, buffer, output_len); } } OPENSSL_free(buffer); } } EVP_CIPHER_CTX_cleanup(c); EVP_CIPHER_CTX_free(c); return (ret == 1) ? ret : openssl_pushresult(L, ret); } else luaL_error(L, "argument #1 is not a valid cipher algorithm or openssl.evp_cipher object"); return 0; }
LUA_API int luanet_equal (lua_State *L, int idx1, int idx2) { return lua_equal(L, idx1, idx2); }
int jiveL_style_rawvalue(lua_State *L) { const char *key, *path; int pathidx; /* stack is: * 1: widget * 2: key * 3: default * 4... args */ /* Make sure we have a default value */ if (lua_gettop(L) == 2) { lua_pushnil(L); } key = lua_tostring(L, 2); /* Concatenate style paths */ lua_getfield(L, 1, "_stylePath"); if (lua_isnil(L, -1)) { lua_pop(L, 1); lua_pushcfunction(L, jiveL_style_path); lua_pushvalue(L, 1); lua_call(L, 1, 1); } pathidx = lua_gettop(L); path = lua_tostring(L, -1); /* check cache */ lua_getfield(L, LUA_REGISTRYINDEX, "jiveStyleCache"); if (lua_isnil(L, -1)) { lua_pop(L, 1); lua_newtable(L); lua_pushvalue(L, -1); lua_setfield(L, LUA_REGISTRYINDEX, "jiveStyleCache"); } lua_pushvalue(L, pathidx); // path lua_gettable(L, -2); if (lua_isnil(L, -1)) { lua_pop(L, 1); lua_newtable(L); lua_pushvalue(L, pathidx); // path lua_pushvalue(L, -2); lua_settable(L, -4); } lua_getfield(L, -1, key); if (lua_isnil(L, -1)) { lua_pop(L, 1); // find value lua_pushcfunction(L, jiveL_style_find_value); lua_pushvalue(L, 1); // widget get_jive_ui_style(L); // skin lua_pushvalue(L, pathidx); lua_pushvalue(L, 2); // key lua_call(L, 4, 1); if (lua_isnil(L, -1)) { /* use a marker for nil */ lua_pushlightuserdata(L, &STYLE_VALUE_NIL); } else { lua_pushvalue(L, -1); } lua_setfield(L, -3, key); debug_style(L, path, key); } /* nil marker */ lua_pushlightuserdata(L, &STYLE_VALUE_NIL); if (lua_equal(L, -1, -2) == 1) { lua_pushnil(L); lua_replace(L, -3); } lua_pop(L, 1); if (!lua_isnil(L, -1)) { /* return skin value */ return 1; } /* per widget skin */ if (jive_getmethod(L, 1, "getWindow")) { lua_pushvalue(L, 1); lua_call(L, 1, 1); if (!lua_isnil(L, -1)) { lua_getfield(L, -1, "skin"); if (!lua_isnil(L, -1)) { lua_pushcfunction(L, jiveL_style_find_value); lua_pushvalue(L, 1); // widget lua_pushvalue(L, -3); // skin lua_pushvalue(L, pathidx); lua_pushvalue(L, 2); // key lua_call(L, 4, 1); if (!lua_isnil(L, -1)) { debug_style(L, path, key); return 1; } lua_pop(L, 1); } } lua_pop(L, 1); } /* default value */ lua_pop(L, 1); lua_pushvalue(L, 3); return 1; }
bool isEqual( int index ) { // Get stored function lua_rawgeti(_lua, LUA_REGISTRYINDEX, _method); // Compare with parameter return lua_equal( _lua, index, -1 ) == 1; }
static void l_json_encode_value(lua_State *L, int pos, luaL_Buffer *B) { switch (lua_type(L, pos)) { case LUA_TNIL: luaL_addstring(B, "null"); break; case LUA_TNUMBER: { const char *num; lua_pushvalue(L, pos); // work on a copy of the number num = lua_tostring(L, -1); // FIXME any other special cases? if (strcmp(num, "inf") == 0) { luaL_addstring(B, "23456789012E666"); } else { luaL_addstring(B, num); } lua_pop(L, 1); break; } case LUA_TBOOLEAN: if (lua_toboolean(L, pos)) { luaL_addstring(B, "true"); } else { luaL_addstring(B, "false"); } break; case LUA_TSTRING: luaL_addchar(B, '"'); l_json_encode_string(L, pos, B); luaL_addchar(B, '"'); break; case LUA_TTABLE: { int type = 0; int arrayidx = 0; lua_pushnil(L); /* first key */ while (lua_next(L, pos) != 0) { /* push key-value pair to stack base */ lua_insert(L, 1); lua_insert(L, 1); if (type == 0) { if (lua_type(L, 1) == LUA_TNUMBER) { type = 1; /* array */ luaL_addstring(B, "[" NL); } else { type = 2; /* object */ luaL_addstring(B, "{" NL); } } else { luaL_addstring(B, "," NL); } if (type == 2) { /* output key */ l_json_encode_value(L, 1, B); luaL_addstring(B, ":"); } else { /* Bug 15329, there must be a bug in the Lua API, we don't seem to get nil array values via lua_next. This hack checks for missing array indices which we assume are nil values. The while loop is necessary in case 2 nil values are sequential. TODO: handle when final array value is nil */ arrayidx++; while (lua_tonumber(L, 1) != arrayidx) { luaL_addstring(B, "null,"); arrayidx++; } } /* output value */ l_json_encode_value(L, 2, B); /* restore key to stack top */ lua_pushvalue(L, 1); lua_remove(L, 1); /* pop value */ lua_remove(L, 1); } switch (type) { case 0: /* empty */ // we don't know if this is an array or object luaL_addstring(B, "[]"); break; case 1: /* array */ luaL_addstring(B, NL "]"); break; case 2: /* object */ luaL_addstring(B, NL "}"); break; } break; } case LUA_TUSERDATA: /* special json.null value? */ lua_getglobal(L, "json"); lua_getfield(L, -1, "null"); if (lua_equal(L, pos, -1)) { lua_pop(L, 2); luaL_addstring(B, "null"); break; } /* fall through */ case LUA_TFUNCTION: case LUA_TTHREAD: case LUA_TLIGHTUSERDATA: lua_pushstring(L, "Cannot encode function, userdata or thread to json"); lua_error(L); break; } }