mirror of
https://github.com/OpenMW/openmw.git
synced 2025-03-03 21:09:41 +00:00
Move LuaState::makeReadOnly(sol::table) out of the class because it doesn't need to access LuaState internals.
This commit is contained in:
parent
8d86d90782
commit
2f25257a3e
10 changed files with 44 additions and 41 deletions
|
@ -7,7 +7,7 @@ namespace MWLua
|
||||||
{
|
{
|
||||||
sol::table api(context.mLua->sol(), sol::create);
|
sol::table api(context.mLua->sol(), sol::create);
|
||||||
// TODO
|
// TODO
|
||||||
return context.mLua->makeReadOnly(api);
|
return LuaUtil::makeReadOnly(api);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ namespace MWLua
|
||||||
api["getControlSwitch"] = [input](const std::string& key) { return input->getControlSwitch(key); };
|
api["getControlSwitch"] = [input](const std::string& key) { return input->getControlSwitch(key); };
|
||||||
api["setControlSwitch"] = [input](const std::string& key, bool v) { input->toggleControlSwitch(key, v); };
|
api["setControlSwitch"] = [input](const std::string& key, bool v) { input->toggleControlSwitch(key, v); };
|
||||||
|
|
||||||
api["ACTION"] = context.mLua->makeReadOnly(context.mLua->sol().create_table_with(
|
api["ACTION"] = LuaUtil::makeReadOnly(context.mLua->sol().create_table_with(
|
||||||
"GameMenu", MWInput::A_GameMenu,
|
"GameMenu", MWInput::A_GameMenu,
|
||||||
"Screenshot", MWInput::A_Screenshot,
|
"Screenshot", MWInput::A_Screenshot,
|
||||||
"Inventory", MWInput::A_Inventory,
|
"Inventory", MWInput::A_Inventory,
|
||||||
|
@ -102,7 +102,7 @@ namespace MWLua
|
||||||
"ZoomOut", MWInput::A_ZoomOut
|
"ZoomOut", MWInput::A_ZoomOut
|
||||||
));
|
));
|
||||||
|
|
||||||
api["CONTROL_SWITCH"] = context.mLua->makeReadOnly(context.mLua->sol().create_table_with(
|
api["CONTROL_SWITCH"] = LuaUtil::makeReadOnly(context.mLua->sol().create_table_with(
|
||||||
"Controls", "playercontrols",
|
"Controls", "playercontrols",
|
||||||
"Fighting", "playerfighting",
|
"Fighting", "playerfighting",
|
||||||
"Jumping", "playerjumping",
|
"Jumping", "playerjumping",
|
||||||
|
@ -112,7 +112,7 @@ namespace MWLua
|
||||||
"VanityMode", "vanitymode"
|
"VanityMode", "vanitymode"
|
||||||
));
|
));
|
||||||
|
|
||||||
api["CONTROLLER_BUTTON"] = context.mLua->makeReadOnly(context.mLua->sol().create_table_with(
|
api["CONTROLLER_BUTTON"] = LuaUtil::makeReadOnly(context.mLua->sol().create_table_with(
|
||||||
"A", SDL_CONTROLLER_BUTTON_A,
|
"A", SDL_CONTROLLER_BUTTON_A,
|
||||||
"B", SDL_CONTROLLER_BUTTON_B,
|
"B", SDL_CONTROLLER_BUTTON_B,
|
||||||
"X", SDL_CONTROLLER_BUTTON_X,
|
"X", SDL_CONTROLLER_BUTTON_X,
|
||||||
|
@ -130,7 +130,7 @@ namespace MWLua
|
||||||
"DPadRight", SDL_CONTROLLER_BUTTON_DPAD_RIGHT
|
"DPadRight", SDL_CONTROLLER_BUTTON_DPAD_RIGHT
|
||||||
));
|
));
|
||||||
|
|
||||||
api["CONTROLLER_AXIS"] = context.mLua->makeReadOnly(context.mLua->sol().create_table_with(
|
api["CONTROLLER_AXIS"] = LuaUtil::makeReadOnly(context.mLua->sol().create_table_with(
|
||||||
"LeftX", SDL_CONTROLLER_AXIS_LEFTX,
|
"LeftX", SDL_CONTROLLER_AXIS_LEFTX,
|
||||||
"LeftY", SDL_CONTROLLER_AXIS_LEFTY,
|
"LeftY", SDL_CONTROLLER_AXIS_LEFTY,
|
||||||
"RightX", SDL_CONTROLLER_AXIS_RIGHTX,
|
"RightX", SDL_CONTROLLER_AXIS_RIGHTX,
|
||||||
|
@ -144,7 +144,7 @@ namespace MWLua
|
||||||
"MoveLeftRight", SDL_CONTROLLER_AXIS_MAX + MWInput::A_MoveLeftRight
|
"MoveLeftRight", SDL_CONTROLLER_AXIS_MAX + MWInput::A_MoveLeftRight
|
||||||
));
|
));
|
||||||
|
|
||||||
return context.mLua->makeReadOnly(api);
|
return LuaUtil::makeReadOnly(api);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ namespace MWLua
|
||||||
sol::table res(lua.sol(), sol::create);
|
sol::table res(lua.sol(), sol::create);
|
||||||
for (const std::string& v : values)
|
for (const std::string& v : values)
|
||||||
res[v] = v;
|
res[v] = v;
|
||||||
return lua.makeReadOnly(res);
|
return LuaUtil::makeReadOnly(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
sol::table initCorePackage(const Context& context)
|
sol::table initCorePackage(const Context& context)
|
||||||
|
@ -43,7 +43,7 @@ namespace MWLua
|
||||||
"Activator", "Armor", "Book", "Clothing", "Creature", "Door", "Ingredient",
|
"Activator", "Armor", "Book", "Clothing", "Creature", "Door", "Ingredient",
|
||||||
"Light", "Miscellaneous", "NPC", "Player", "Potion", "Static", "Weapon"
|
"Light", "Miscellaneous", "NPC", "Player", "Potion", "Static", "Weapon"
|
||||||
});
|
});
|
||||||
api["EQUIPMENT_SLOT"] = lua->makeReadOnly(lua->sol().create_table_with(
|
api["EQUIPMENT_SLOT"] = LuaUtil::makeReadOnly(lua->sol().create_table_with(
|
||||||
"Helmet", MWWorld::InventoryStore::Slot_Helmet,
|
"Helmet", MWWorld::InventoryStore::Slot_Helmet,
|
||||||
"Cuirass", MWWorld::InventoryStore::Slot_Cuirass,
|
"Cuirass", MWWorld::InventoryStore::Slot_Cuirass,
|
||||||
"Greaves", MWWorld::InventoryStore::Slot_Greaves,
|
"Greaves", MWWorld::InventoryStore::Slot_Greaves,
|
||||||
|
@ -64,7 +64,7 @@ namespace MWLua
|
||||||
"CarriedLeft", MWWorld::InventoryStore::Slot_CarriedLeft,
|
"CarriedLeft", MWWorld::InventoryStore::Slot_CarriedLeft,
|
||||||
"Ammunition", MWWorld::InventoryStore::Slot_Ammunition
|
"Ammunition", MWWorld::InventoryStore::Slot_Ammunition
|
||||||
));
|
));
|
||||||
return lua->makeReadOnly(api);
|
return LuaUtil::makeReadOnly(api);
|
||||||
}
|
}
|
||||||
|
|
||||||
sol::table initWorldPackage(const Context& context)
|
sol::table initWorldPackage(const Context& context)
|
||||||
|
@ -107,7 +107,7 @@ namespace MWLua
|
||||||
// return GObjectList{worldView->selectObjects(query, false)};
|
// return GObjectList{worldView->selectObjects(query, false)};
|
||||||
};
|
};
|
||||||
// TODO: add world.placeNewObject(recordId, cell, pos, [rot])
|
// TODO: add world.placeNewObject(recordId, cell, pos, [rot])
|
||||||
return context.mLua->makeReadOnly(api);
|
return LuaUtil::makeReadOnly(api);
|
||||||
}
|
}
|
||||||
|
|
||||||
sol::table initNearbyPackage(const Context& context)
|
sol::table initNearbyPackage(const Context& context)
|
||||||
|
@ -137,7 +137,7 @@ namespace MWLua
|
||||||
// TODO: Maybe use sqlite
|
// TODO: Maybe use sqlite
|
||||||
// return LObjectList{worldView->selectObjects(query, true)};
|
// return LObjectList{worldView->selectObjects(query, true)};
|
||||||
};
|
};
|
||||||
return context.mLua->makeReadOnly(api);
|
return LuaUtil::makeReadOnly(api);
|
||||||
}
|
}
|
||||||
|
|
||||||
sol::table initQueryPackage(const Context& context)
|
sol::table initQueryPackage(const Context& context)
|
||||||
|
@ -148,7 +148,7 @@ namespace MWLua
|
||||||
query[t] = Queries::Query(std::string(t));
|
query[t] = Queries::Query(std::string(t));
|
||||||
for (const QueryFieldGroup& group : getBasicQueryFieldGroups())
|
for (const QueryFieldGroup& group : getBasicQueryFieldGroups())
|
||||||
query[group.mName] = initFieldGroup(context, group);
|
query[group.mName] = initFieldGroup(context, group);
|
||||||
return query; // makeReadonly is applied by LuaState::addCommonPackage
|
return query; // makeReadOnly is applied by LuaState::addCommonPackage
|
||||||
}
|
}
|
||||||
|
|
||||||
sol::table initFieldGroup(const Context& context, const QueryFieldGroup& group)
|
sol::table initFieldGroup(const Context& context, const QueryFieldGroup& group)
|
||||||
|
@ -163,12 +163,12 @@ namespace MWLua
|
||||||
{
|
{
|
||||||
const std::string& name = field->path()[i];
|
const std::string& name = field->path()[i];
|
||||||
if (subgroup[name] == sol::nil)
|
if (subgroup[name] == sol::nil)
|
||||||
subgroup[name] = context.mLua->makeReadOnly(context.mLua->newTable());
|
subgroup[name] = LuaUtil::makeReadOnly(context.mLua->newTable());
|
||||||
subgroup = context.mLua->getMutableFromReadOnly(subgroup[name]);
|
subgroup = LuaUtil::getMutableFromReadOnly(subgroup[name]);
|
||||||
}
|
}
|
||||||
subgroup[field->path().back()] = field;
|
subgroup[field->path().back()] = field;
|
||||||
}
|
}
|
||||||
return context.mLua->makeReadOnly(res);
|
return LuaUtil::makeReadOnly(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,7 @@ namespace MWLua
|
||||||
else
|
else
|
||||||
return sol::make_object<float>(lua->sol(), value.getFloat());
|
return sol::make_object<float>(lua->sol(), value.getFloat());
|
||||||
};
|
};
|
||||||
return lua->makeReadOnly(config);
|
return LuaUtil::makeReadOnly(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
sol::table initGlobalSettingsPackage(const Context& context) { return initSettingsPackage(context, true, false); }
|
sol::table initGlobalSettingsPackage(const Context& context) { return initSettingsPackage(context, true, false); }
|
||||||
|
|
|
@ -12,7 +12,7 @@ namespace MWLua
|
||||||
{
|
{
|
||||||
luaManager->addUIMessage(message);
|
luaManager->addUIMessage(message);
|
||||||
};
|
};
|
||||||
return context.mLua->makeReadOnly(api);
|
return LuaUtil::makeReadOnly(api);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,7 +119,7 @@ return {
|
||||||
EXPECT_ERROR(LuaUtil::call(script["rawsetSystemLib"]), "bad argument #1 to 'rawset' (table expected, got userdata)");
|
EXPECT_ERROR(LuaUtil::call(script["rawsetSystemLib"]), "bad argument #1 to 'rawset' (table expected, got userdata)");
|
||||||
EXPECT_ERROR(LuaUtil::call(script["modifySystemLib"]), "a userdata value");
|
EXPECT_ERROR(LuaUtil::call(script["modifySystemLib"]), "a userdata value");
|
||||||
|
|
||||||
EXPECT_EQ(mLua.getMutableFromReadOnly(mLua.makeReadOnly(script)), script);
|
EXPECT_EQ(LuaUtil::getMutableFromReadOnly(LuaUtil::makeReadOnly(script)), script);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(LuaStateTest, Print)
|
TEST_F(LuaStateTest, Print)
|
||||||
|
@ -150,8 +150,8 @@ return {
|
||||||
{
|
{
|
||||||
LuaUtil::LuaState lua(mVFS.get());
|
LuaUtil::LuaState lua(mVFS.get());
|
||||||
|
|
||||||
sol::table api1 = lua.makeReadOnly(lua.sol().create_table_with("name", "api1"));
|
sol::table api1 = LuaUtil::makeReadOnly(lua.sol().create_table_with("name", "api1"));
|
||||||
sol::table api2 = lua.makeReadOnly(lua.sol().create_table_with("name", "api2"));
|
sol::table api2 = LuaUtil::makeReadOnly(lua.sol().create_table_with("name", "api2"));
|
||||||
|
|
||||||
sol::table script1 = lua.runInNewSandbox("bbb/tests.lua", "", {{"test.api", api1}});
|
sol::table script1 = lua.runInNewSandbox("bbb/tests.lua", "", {{"test.api", api1}});
|
||||||
|
|
||||||
|
|
|
@ -67,27 +67,31 @@ namespace LuaUtil
|
||||||
mSandboxEnv = sol::nil;
|
mSandboxEnv = sol::nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
sol::table LuaState::makeReadOnly(sol::table table)
|
sol::table makeReadOnly(sol::table table)
|
||||||
{
|
{
|
||||||
|
if (table == sol::nil)
|
||||||
|
return table;
|
||||||
if (table.is<sol::userdata>())
|
if (table.is<sol::userdata>())
|
||||||
return table; // it is already userdata, no sense to wrap it again
|
return table; // it is already userdata, no sense to wrap it again
|
||||||
|
|
||||||
|
lua_State* lua = table.lua_state();
|
||||||
table[sol::meta_function::index] = table;
|
table[sol::meta_function::index] = table;
|
||||||
sol::stack::push(mLua, std::move(table));
|
sol::stack::push(lua, std::move(table));
|
||||||
lua_newuserdata(mLua, 0);
|
lua_newuserdata(lua, 0);
|
||||||
lua_pushvalue(mLua, -2);
|
lua_pushvalue(lua, -2);
|
||||||
lua_setmetatable(mLua, -2);
|
lua_setmetatable(lua, -2);
|
||||||
return sol::stack::pop<sol::table>(mLua);
|
return sol::stack::pop<sol::table>(lua);
|
||||||
}
|
}
|
||||||
|
|
||||||
sol::table LuaState::getMutableFromReadOnly(const sol::userdata& ro)
|
sol::table getMutableFromReadOnly(const sol::userdata& ro)
|
||||||
{
|
{
|
||||||
sol::stack::push(mLua, ro);
|
lua_State* lua = ro.lua_state();
|
||||||
int ok = lua_getmetatable(mLua, -1);
|
sol::stack::push(lua, ro);
|
||||||
|
int ok = lua_getmetatable(lua, -1);
|
||||||
assert(ok);
|
assert(ok);
|
||||||
(void)ok;
|
(void)ok;
|
||||||
sol::table res = sol::stack::pop<sol::table>(mLua);
|
sol::table res = sol::stack::pop<sol::table>(lua);
|
||||||
lua_pop(mLua, 1);
|
lua_pop(lua, 1);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include <limits> // missing from sol/sol.hpp
|
|
||||||
#include <sol/sol.hpp>
|
#include <sol/sol.hpp>
|
||||||
|
|
||||||
#include <components/vfs/manager.hpp>
|
#include <components/vfs/manager.hpp>
|
||||||
|
@ -37,11 +36,6 @@ namespace LuaUtil
|
||||||
// A shortcut to create a new Lua table.
|
// A shortcut to create a new Lua table.
|
||||||
sol::table newTable() { return sol::table(mLua, sol::create); }
|
sol::table newTable() { return sol::table(mLua, sol::create); }
|
||||||
|
|
||||||
// Makes a table read only (when accessed from Lua) by wrapping it with an empty userdata.
|
|
||||||
// Needed to forbid any changes in common resources that can accessed from different sandboxes.
|
|
||||||
sol::table makeReadOnly(sol::table);
|
|
||||||
sol::table getMutableFromReadOnly(const sol::userdata&);
|
|
||||||
|
|
||||||
// Registers a package that will be available from every sandbox via `require(name)`.
|
// Registers a package that will be available from every sandbox via `require(name)`.
|
||||||
// The package can be either a sol::table with an API or a sol::function. If it is a function,
|
// The package can be either a sol::table with an API or a sol::function. If it is a function,
|
||||||
// it will be evaluated (once per sandbox) the first time when requested. If the package
|
// it will be evaluated (once per sandbox) the first time when requested. If the package
|
||||||
|
@ -106,6 +100,11 @@ namespace LuaUtil
|
||||||
// String representation of a Lua object. Should be used for debugging/logging purposes only.
|
// String representation of a Lua object. Should be used for debugging/logging purposes only.
|
||||||
std::string toString(const sol::object&);
|
std::string toString(const sol::object&);
|
||||||
|
|
||||||
|
// Makes a table read only (when accessed from Lua) by wrapping it with an empty userdata.
|
||||||
|
// Needed to forbid any changes in common resources that can accessed from different sandboxes.
|
||||||
|
sol::table makeReadOnly(sol::table);
|
||||||
|
sol::table getMutableFromReadOnly(const sol::userdata&);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // COMPONENTS_LUA_LUASTATE_H
|
#endif // COMPONENTS_LUA_LUASTATE_H
|
||||||
|
|
|
@ -25,7 +25,7 @@ namespace LuaUtil
|
||||||
|
|
||||||
void ScriptsContainer::addPackage(const std::string& packageName, sol::object package)
|
void ScriptsContainer::addPackage(const std::string& packageName, sol::object package)
|
||||||
{
|
{
|
||||||
API[packageName] = mLua.makeReadOnly(std::move(package));
|
API[packageName] = makeReadOnly(std::move(package));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ScriptsContainer::addNewScript(const std::string& path)
|
bool ScriptsContainer::addNewScript(const std::string& path)
|
||||||
|
@ -63,7 +63,7 @@ namespace LuaUtil
|
||||||
if (interfaceName.empty() != (publicInterface == sol::nil))
|
if (interfaceName.empty() != (publicInterface == sol::nil))
|
||||||
Log(Debug::Error) << mNamePrefix << "[" << path << "]: 'interfaceName' should always be used together with 'interface'";
|
Log(Debug::Error) << mNamePrefix << "[" << path << "]: 'interfaceName' should always be used together with 'interface'";
|
||||||
else if (!interfaceName.empty())
|
else if (!interfaceName.empty())
|
||||||
script.as<sol::table>()[INTERFACE] = mPublicInterfaces[interfaceName] = mLua.makeReadOnly(publicInterface);
|
script.as<sol::table>()[INTERFACE] = mPublicInterfaces[interfaceName] = makeReadOnly(publicInterface);
|
||||||
mScriptOrder.push_back(path);
|
mScriptOrder.push_back(path);
|
||||||
mScripts[path].mInterface = std::move(script);
|
mScripts[path].mInterface = std::move(script);
|
||||||
return true;
|
return true;
|
||||||
|
@ -329,7 +329,7 @@ namespace LuaUtil
|
||||||
mHoursTimersQueue.clear();
|
mHoursTimersQueue.clear();
|
||||||
|
|
||||||
mPublicInterfaces.clear();
|
mPublicInterfaces.clear();
|
||||||
// Assigned by mLua.makeReadOnly, but `clear` removes it, so we need to assign it again.
|
// Assigned by LuaUtil::makeReadOnly, but `clear` removes it, so we need to assign it again.
|
||||||
mPublicInterfaces[sol::meta_function::index] = mPublicInterfaces;
|
mPublicInterfaces[sol::meta_function::index] = mPublicInterfaces;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -76,7 +76,7 @@ namespace LuaUtil
|
||||||
virtual ~ScriptsContainer() {}
|
virtual ~ScriptsContainer() {}
|
||||||
|
|
||||||
// Adds package that will be available (via `require`) for all scripts in the container.
|
// Adds package that will be available (via `require`) for all scripts in the container.
|
||||||
// Automatically applies LuaState::makeReadOnly to the package.
|
// Automatically applies LuaUtil::makeReadOnly to the package.
|
||||||
void addPackage(const std::string& packageName, sol::object package);
|
void addPackage(const std::string& packageName, sol::object package);
|
||||||
|
|
||||||
// Finds a file with given path in the virtual file system, starts as a new script, and adds it to the container.
|
// Finds a file with given path in the virtual file system, starts as a new script, and adds it to the container.
|
||||||
|
|
Loading…
Reference in a new issue