mirror of
https://github.com/holub/mame
synced 2025-06-16 17:29:27 +03:00
Lua engine: Enable checks for debug builds, kill sol::buffer. (#9419)
This commit is contained in:
parent
0074d3ad94
commit
dd1e5b1d7a
@ -95,18 +95,6 @@ template <> struct is_container<image_interface_formats> : std::true_type { };
|
|||||||
template <> struct is_container<plugin_options_plugins> : std::true_type { };
|
template <> struct is_container<plugin_options_plugins> : std::true_type { };
|
||||||
|
|
||||||
|
|
||||||
sol::buffer *sol_lua_get(sol::types<buffer *>, lua_State *L, int index, sol::stack::record &tracking)
|
|
||||||
{
|
|
||||||
return new sol::buffer(stack::get<int>(L, index), L);
|
|
||||||
}
|
|
||||||
|
|
||||||
int sol_lua_push(sol::types<buffer *>, lua_State *L, buffer *value)
|
|
||||||
{
|
|
||||||
delete value;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct usertype_container<lua_engine::devenum<T> > : lua_engine::immutable_collection_helper<lua_engine::devenum<T>, T>
|
struct usertype_container<lua_engine::devenum<T> > : lua_engine::immutable_collection_helper<lua_engine::devenum<T>, T>
|
||||||
{
|
{
|
||||||
@ -834,7 +822,15 @@ void lua_engine::initialize()
|
|||||||
}
|
}
|
||||||
new (&file) emu_file(path, flags);
|
new (&file) emu_file(path, flags);
|
||||||
}));
|
}));
|
||||||
file_type.set("read", [](emu_file &file, sol::buffer *buff) { buff->set_len(file.read(buff->get_ptr(), buff->get_len())); return buff; });
|
file_type.set("read",
|
||||||
|
[] (emu_file &file, sol::this_state s, size_t len)
|
||||||
|
{
|
||||||
|
buffer_helper buf(s);
|
||||||
|
auto space = buf.prepare(len);
|
||||||
|
space.add(file.read(space.get(), len));
|
||||||
|
buf.push();
|
||||||
|
return sol::stack::pop<sol::object>(s);
|
||||||
|
});
|
||||||
file_type.set("write", [](emu_file &file, const std::string &data) { return file.write(data.data(), data.size()); });
|
file_type.set("write", [](emu_file &file, const std::string &data) { return file.write(data.data(), data.size()); });
|
||||||
file_type.set("puts", &emu_file::puts);
|
file_type.set("puts", &emu_file::puts);
|
||||||
file_type.set("open", static_cast<std::error_condition (emu_file::*)(std::string_view)>(&emu_file::open));
|
file_type.set("open", static_cast<std::error_condition (emu_file::*)(std::string_view)>(&emu_file::open));
|
||||||
@ -1001,16 +997,18 @@ void lua_engine::initialize()
|
|||||||
}
|
}
|
||||||
return sol::make_object(sol(), ret);
|
return sol::make_object(sol(), ret);
|
||||||
});
|
});
|
||||||
item_type.set("read_block", [](save_item &item, int offset, sol::buffer *buff) {
|
item_type.set("read_block", [](save_item &item, sol::this_state s, int offset, size_t len) {
|
||||||
if(!item.base || ((offset + buff->get_len()) > (item.size * item.count)))
|
buffer_helper buf(s);
|
||||||
|
auto space = buf.prepare(len);
|
||||||
|
if(!item.base || ((offset + len) > (item.size * item.count)))
|
||||||
{
|
{
|
||||||
buff->set_len(0);
|
space.add(0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const uint32_t blocksize = item.size * item.valcount;
|
const uint32_t blocksize = item.size * item.valcount;
|
||||||
uint32_t remaining = buff->get_len();
|
size_t remaining = len;
|
||||||
uint8_t *dest = reinterpret_cast<uint8_t *>(buff->get_ptr());
|
uint8_t *dest = reinterpret_cast<uint8_t *>(space.get());
|
||||||
while(remaining)
|
while(remaining)
|
||||||
{
|
{
|
||||||
const uint32_t blockno = offset / blocksize;
|
const uint32_t blockno = offset / blocksize;
|
||||||
@ -1022,8 +1020,10 @@ void lua_engine::initialize()
|
|||||||
remaining -= chunk;
|
remaining -= chunk;
|
||||||
dest += chunk;
|
dest += chunk;
|
||||||
}
|
}
|
||||||
|
space.add(len);
|
||||||
}
|
}
|
||||||
return buff;
|
buf.push();
|
||||||
|
return sol::stack::pop<sol::object>(s);
|
||||||
});
|
});
|
||||||
item_type.set("write", [](save_item &item, int offset, uint64_t value) {
|
item_type.set("write", [](save_item &item, int offset, uint64_t value) {
|
||||||
if(!item.base || (offset >= item.count))
|
if(!item.base || (offset >= item.count))
|
||||||
|
@ -21,7 +21,11 @@
|
|||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#ifdef MAME_DEBUG
|
||||||
|
#define SOL_ALL_SAFETIES_ON 1
|
||||||
|
#else
|
||||||
#define SOL_SAFE_USERTYPE 1
|
#define SOL_SAFE_USERTYPE 1
|
||||||
|
#endif
|
||||||
#include "sol/sol.hpp"
|
#include "sol/sol.hpp"
|
||||||
|
|
||||||
struct lua_State;
|
struct lua_State;
|
||||||
@ -30,6 +34,7 @@ class lua_engine
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// helper structures
|
// helper structures
|
||||||
|
class buffer_helper;
|
||||||
template <typename T> struct devenum;
|
template <typename T> struct devenum;
|
||||||
template <typename T> struct simple_list_wrapper;
|
template <typename T> struct simple_list_wrapper;
|
||||||
template <typename T> struct tag_object_ptr_map;
|
template <typename T> struct tag_object_ptr_map;
|
||||||
|
@ -16,10 +16,100 @@
|
|||||||
|
|
||||||
#include <lua.hpp>
|
#include <lua.hpp>
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
#include <system_error>
|
#include <system_error>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class lua_engine::buffer_helper
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
class proxy
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
buffer_helper &m_host;
|
||||||
|
char *m_space;
|
||||||
|
size_t const m_size;
|
||||||
|
|
||||||
|
public:
|
||||||
|
proxy(proxy const &) = delete;
|
||||||
|
proxy &operator=(proxy const &) = delete;
|
||||||
|
|
||||||
|
proxy(proxy &&that) : m_host(that.m_host), m_space(that.m_space), m_size(that.m_size)
|
||||||
|
{
|
||||||
|
that.m_space = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
proxy(buffer_helper &host, size_t size) : m_host(host), m_space(luaL_prepbuffsize(&host.m_buffer, size)), m_size(size)
|
||||||
|
{
|
||||||
|
m_host.m_prepared = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
~proxy()
|
||||||
|
{
|
||||||
|
if (m_space)
|
||||||
|
{
|
||||||
|
assert(m_host.m_prepared);
|
||||||
|
luaL_addsize(&m_host.m_buffer, 0U);
|
||||||
|
m_host.m_prepared = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char *get()
|
||||||
|
{
|
||||||
|
return m_space;
|
||||||
|
}
|
||||||
|
|
||||||
|
void add(size_t size)
|
||||||
|
{
|
||||||
|
assert(m_space);
|
||||||
|
assert(size <= m_size);
|
||||||
|
assert(m_host.m_prepared);
|
||||||
|
m_space = nullptr;
|
||||||
|
luaL_addsize(&m_host.m_buffer, size);
|
||||||
|
m_host.m_prepared = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
luaL_Buffer m_buffer;
|
||||||
|
bool m_valid;
|
||||||
|
bool m_prepared;
|
||||||
|
|
||||||
|
public:
|
||||||
|
buffer_helper(buffer_helper const &) = delete;
|
||||||
|
buffer_helper &operator=(buffer_helper const &) = delete;
|
||||||
|
|
||||||
|
buffer_helper(lua_State *L)
|
||||||
|
{
|
||||||
|
luaL_buffinit(L, &m_buffer);
|
||||||
|
m_valid = true;
|
||||||
|
m_prepared = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
~buffer_helper()
|
||||||
|
{
|
||||||
|
assert(!m_prepared);
|
||||||
|
if (m_valid)
|
||||||
|
luaL_pushresult(&m_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void push()
|
||||||
|
{
|
||||||
|
assert(m_valid);
|
||||||
|
assert(!m_prepared);
|
||||||
|
luaL_pushresult(&m_buffer);
|
||||||
|
m_valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
proxy prepare(size_t size)
|
||||||
|
{
|
||||||
|
assert(m_valid);
|
||||||
|
assert(!m_prepared);
|
||||||
|
return proxy(*this, size);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct lua_engine::simple_list_wrapper
|
struct lua_engine::simple_list_wrapper
|
||||||
{
|
{
|
||||||
@ -40,52 +130,9 @@ struct lua_engine::tag_object_ptr_map
|
|||||||
|
|
||||||
namespace sol {
|
namespace sol {
|
||||||
|
|
||||||
class buffer
|
// don't convert core_options to a table directly
|
||||||
{
|
|
||||||
public:
|
|
||||||
// sol does lua_settop(0), save userdata buffer in registry if necessary
|
|
||||||
buffer(int size, lua_State *L)
|
|
||||||
{
|
|
||||||
ptr = luaL_buffinitsize(L, &buff, size);
|
|
||||||
len = size;
|
|
||||||
if(buff.b != buff.initb)
|
|
||||||
{
|
|
||||||
lua_pushvalue(L, -1);
|
|
||||||
lua_setfield(L, LUA_REGISTRYINDEX, "sol::buffer_temp");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
~buffer()
|
|
||||||
{
|
|
||||||
lua_State *L = buff.L;
|
|
||||||
if(lua_getfield(L, LUA_REGISTRYINDEX, "sol::buffer_temp") != LUA_TNIL)
|
|
||||||
{
|
|
||||||
lua_pushnil(L);
|
|
||||||
lua_setfield(L, LUA_REGISTRYINDEX, "sol::buffer_temp");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
lua_pop(L, -1);
|
|
||||||
|
|
||||||
luaL_pushresultsize(&buff, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_len(int size) { len = size; }
|
|
||||||
int get_len() { return len; }
|
|
||||||
char *get_ptr() { return ptr; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
luaL_Buffer buff;
|
|
||||||
int len;
|
|
||||||
char *ptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// don't convert core_optons to a table directly
|
|
||||||
template <> struct is_container<core_options> : std::false_type { };
|
template <> struct is_container<core_options> : std::false_type { };
|
||||||
|
|
||||||
// buffer customisation
|
|
||||||
sol::buffer *sol_lua_get(sol::types<buffer *>, lua_State *L, int index, sol::stack::record &tracking);
|
|
||||||
int sol_lua_push(sol::types<buffer *>, lua_State *L, buffer *value);
|
|
||||||
|
|
||||||
|
|
||||||
// these things should be treated as containers
|
// these things should be treated as containers
|
||||||
template <typename T> struct is_container<lua_engine::devenum<T> > : std::true_type { };
|
template <typename T> struct is_container<lua_engine::devenum<T> > : std::true_type { };
|
||||||
|
Loading…
Reference in New Issue
Block a user