diff --git a/CMakeLists.txt b/CMakeLists.txt index 4bfcce1..c04d257 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,9 +3,6 @@ project(effil) if (NOT LUA_INCLUDE_DIR OR NOT LUA_LIBRARY) find_package(Lua REQUIRED) - if( "${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}" LESS "5.2") - message(FATAL_ERROR "Wrong Lua version ${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}, use 5.2 or higher") - endif() endif() include_directories(src/cpp libs/sol/single/sol ${LUA_INCLUDE_DIR}) diff --git a/src/cpp/lua-helpers.cpp b/src/cpp/lua-helpers.cpp index a5cc08e..d1df401 100644 --- a/src/cpp/lua-helpers.cpp +++ b/src/cpp/lua-helpers.cpp @@ -26,13 +26,17 @@ int dumpMemoryWriter(lua_State*, const void* batch, size_t batchSize, void* stor return 0; } -} // namespacce +} // namespace std::string dumpFunction(const sol::function& f) { sol::state_view lua(f.lua_state()); sol::stack::push(lua, f); std::string result; +#if LUA_VERSION_NUM == 503 + int ret = lua_dump(lua, dumpMemoryWriter, &result, 0 /* not strip debug info*/); +#else int ret = lua_dump(lua, dumpMemoryWriter, &result); +#endif REQUIRE(ret == LUA_OK) << "Unable to dump Lua function: " << luaError(ret); sol::stack::remove(lua, -1, 1); return result; diff --git a/src/cpp/shared-table.cpp b/src/cpp/shared-table.cpp index 6155be0..7b9890e 100644 --- a/src/cpp/shared-table.cpp +++ b/src/cpp/shared-table.cpp @@ -208,13 +208,13 @@ sol::object SharedTable::luaLength(sol::this_state state) { DEFFINE_METAMETHOD_CALL_0("__len"); std::lock_guard g(data_->lock); size_t len = 0u; - sol::optional value; - auto iter = data_->entries.find(createStoredObject(static_cast(1))); + sol::optional value; + auto iter = data_->entries.find(createStoredObject(static_cast(1))); if (iter != data_->entries.end()) { do { ++len; ++iter; - } while ((iter != data_->entries.end()) && (value = storedObjectToDouble(iter->first)) && + } while ((iter != data_->entries.end()) && (value = storedObjectToIndexType(iter->first)) && (static_cast(value.value()) == len + 1)); } return sol::make_object(state, len); @@ -244,9 +244,9 @@ SharedTable::PairsIterator SharedTable::luaPairs(sol::this_state state) { sol::make_object(state, *this)); } -std::pair ipairsNext(sol::this_state lua, SharedTable table, sol::optional key) { +std::pair ipairsNext(sol::this_state lua, SharedTable table, sol::optional key) { size_t index = key ? key.value() + 1 : 1; - auto objKey = createStoredObject(static_cast(index)); + auto objKey = createStoredObject(static_cast(index)); sol::object value = table.get(objKey, lua); if (!value.valid()) return std::pair(sol::nil, sol::nil); diff --git a/src/cpp/stored-object.cpp b/src/cpp/stored-object.cpp index 7a8c675..2fa3d2f 100644 --- a/src/cpp/stored-object.cpp +++ b/src/cpp/stored-object.cpp @@ -138,7 +138,17 @@ StoredObject fromSolObject(const SolObject& luaObject) { case sol::type::boolean: return std::make_unique>(luaObject); case sol::type::number: - return std::make_unique>(luaObject); + { +#if LUA_VERSION_NUM == 503 + sol::stack::push(luaObject.lua_state(), luaObject); + int isInterger = lua_isinteger(luaObject.lua_state(), -1); + sol::stack::pop(luaObject.lua_state()); + if (isInterger) + return std::make_unique>(luaObject); + else +#endif // Lua5.3 + return std::make_unique>(luaObject); + } case sol::type::string: return std::make_unique>(luaObject); case sol::type::lightuserdata: @@ -177,7 +187,9 @@ StoredObject fromSolObject(const SolObject& luaObject) { StoredObject createStoredObject(bool value) { return std::make_unique>(value); } -StoredObject createStoredObject(double value) { return std::make_unique>(value); } +StoredObject createStoredObject(lua_Number value) { return std::make_unique>(value); } + +StoredObject createStoredObject(lua_Integer value) { return std::make_unique>(value); } StoredObject createStoredObject(const std::string& value) { return std::make_unique>(value); @@ -203,6 +215,8 @@ sol::optional storedObjectToBool(const StoredObject& sobj) { return getPri sol::optional storedObjectToDouble(const StoredObject& sobj) { return getPrimitiveHolderData(sobj); } +sol::optional storedObjectToIndexType(const StoredObject& sobj) { return getPrimitiveHolderData(sobj); } + sol::optional storedObjectToString(const StoredObject& sobj) { return getPrimitiveHolderData(sobj); } diff --git a/src/cpp/stored-object.h b/src/cpp/stored-object.h index 6768051..f4daa84 100644 --- a/src/cpp/stored-object.h +++ b/src/cpp/stored-object.h @@ -1,5 +1,6 @@ #pragma once +#include "utils.h" #include "garbage-collector.h" #include @@ -34,14 +35,17 @@ struct StoredObjectLess { }; StoredObject createStoredObject(bool); -StoredObject createStoredObject(double); +StoredObject createStoredObject(lua_Number); +StoredObject createStoredObject(lua_Integer); StoredObject createStoredObject(const std::string&); StoredObject createStoredObject(const char*); StoredObject createStoredObject(const sol::object&); StoredObject createStoredObject(const sol::stack_object&); + sol::optional storedObjectToBool(const StoredObject&); sol::optional storedObjectToDouble(const StoredObject&); +sol::optional storedObjectToIndexType(const StoredObject&); sol::optional storedObjectToString(const StoredObject&); } // effil diff --git a/src/cpp/utils.h b/src/cpp/utils.h index 3827e58..c4b75f9 100644 --- a/src/cpp/utils.h +++ b/src/cpp/utils.h @@ -6,6 +6,16 @@ #include +#if LUA_VERSION_NUM < 501 || LUA_VERSION_NUM > 503 +# error Unsupported Lua version +#endif + +#if LUA_VERSION_NUM == 503 +# define LUA_INDEX_TYPE lua_Integer +#else +# define LUA_INDEX_TYPE lua_Number +#endif + namespace effil { class Exception : public sol::error { diff --git a/tests/lua/bootstrap-tests.lua b/tests/lua/bootstrap-tests.lua index 96158cd..fa2a0dd 100644 --- a/tests/lua/bootstrap-tests.lua +++ b/tests/lua/bootstrap-tests.lua @@ -1,6 +1,9 @@ effil = require "effil" test = require "u-test" +local major, minor = _VERSION:match("Lua (%d).(%d)") +LUA_VERSION = major * 10 + minor + function default_tear_down() collectgarbage() effil.gc.collect() diff --git a/tests/lua/metatable.lua b/tests/lua/metatable.lua index 394d000..e500616 100644 --- a/tests/lua/metatable.lua +++ b/tests/lua/metatable.lua @@ -66,7 +66,7 @@ test.metatable.binary_op = function (metatable, metamethod, op, exp_value) testTable.was_called = false testTable.value = "left" operand.value = "right" - local left_operand, right_operand = unpack({testTable, operand}) + local left_operand, right_operand = table.unpack({testTable, operand}) test.equal(op(left_operand, right_operand), exp_value == nil and "left_right" or exp_value) test.is_true(testTable.was_called) @@ -112,6 +112,8 @@ test_unary_op("len", function(a) return #a end) test.shared_table_with_metatable.tear_down = default_tear_down +if LUA_VERSION > 51 then + test.shared_table_with_metatable.iterators = function (iterator_type) local share = effil.table() local iterator = iterator_type @@ -149,6 +151,8 @@ end test.shared_table_with_metatable.iterators("pairs") test.shared_table_with_metatable.iterators("ipairs") +end -- LUA_VERSION > 51 + test.shared_table_with_metatable.as_shared_table = function() local share = effil.table() local mt = effil.table()