Skip to content

Instantly share code, notes, and snippets.

@zethon
Last active August 29, 2020 15:24
Show Gist options
  • Save zethon/18519f3beef808868d4d9ce9d5158b39 to your computer and use it in GitHub Desktop.
Save zethon/18519f3beef808868d4d9ce9d5158b39 to your computer and use it in GitHub Desktop.
// Alternate answer to: https://stackoverflow.com/questions/63643025/lua-5-2-sandboxing-in-different-objects-with-c-api
#include <string>
#include <cassert>
#include <iostream>
#include <lua/lua.hpp>
#include <fmt/format.h>
class AwesomeThing
{
lua_State* _lua;
std::string _name;
public:
AwesomeThing(lua_State* L, const std::string& name, const std::string& luafile)
: _lua{ L },
_name{ name }
{
assert(luaL_loadfile(_lua, luafile.c_str()) == 0); // 1:chunk
const std::string code = _name + " = setmetatable({}, {__index = _G})";
luaL_dostring(_lua, code.c_str());
lua_getglobal(L, _name.c_str()); //1:chunk, 2:mt
lua_setupvalue(_lua, 1, 1); // 1:chunk
if (lua_pcall(_lua, 0, 0, 0) != 0) // 1:env
{
auto error = lua_tostring(_lua, -1);
throw std::runtime_error(error);
}
lua_settop(_lua, 0);
}
void init()
{
// call onInit from Lua
// first get the execution environment and set that
lua_getglobal(_lua, _name.c_str()); // 1:env
auto x = lua_typename(_lua, 1);
std::cout << "x:" << x << '\n';
//assert(lua_isnil(_lua, 1) == 0);
//assert(lua_istable(_lua, 1) == 1);
lua_getfield(_lua, 1, "onInit"); // 1:env, 2:func
assert(lua_isnil(_lua, 2) == 0);
assert(lua_isfunction(_lua, 2) == 1);
assert(lua_pcall(_lua, 0, LUA_MULTRET, 0) == 0); // 1:env, 2:retval
lua_settop(_lua, 0);
//// manually clear the stack to make sure we're balanced
//lua_pop(_lua, 1); // -1:env
//lua_pop(_lua, 1); // empty stack
//assert(lua_gettop(_lua) == 0);
}
};
int main()
{
lua_State* L = luaL_newstate();
luaL_openlibs(L);
AwesomeThing at1(L, "thing1", "file1.lua");
AwesomeThing at2(L, "thing2", "file2.lua");
at1.init();
at2.init();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment