mirror of
https://github.com/mkxp-z/mkxp-z.git
synced 2025-09-10 12:02:53 +02:00
Don't make sandbox_malloc
into a coroutine
Okay, the coroutine implementation of `sandbox_malloc` is clearly
broken. It would be working if Asyncify instrumented the `memory.grow`
WebAssembly instruction, but it doesn't instrument it.
This commit reverts commit 42c4ff9497
and
also increases the default VM memory allocation from 64 MiB to 96 MiB to
account for the lack of ability to increase the memory allocation at run
time. I'll find some new way to implement increasing the memory
allocation later.
This commit is contained in:
parent
7ce7fdb3e0
commit
eeef9ff943
19 changed files with 156 additions and 318 deletions
|
@ -67,7 +67,7 @@ uint8_t *binding_base::operator*() const noexcept {
|
|||
return get();
|
||||
}
|
||||
|
||||
wasm_ptr_t binding_base::_sandbox_malloc(wasm_size_t size) {
|
||||
wasm_ptr_t binding_base::sandbox_malloc(wasm_size_t size) {
|
||||
wasm_ptr_t buf = w2c_ruby_mkxp_sandbox_malloc(&instance(), size);
|
||||
|
||||
// Verify that the entire allocated buffer is in valid memory
|
||||
|
|
|
@ -80,7 +80,7 @@ namespace mkxp_sandbox {
|
|||
struct w2c_ruby &instance() const noexcept;
|
||||
uint8_t *get() const noexcept;
|
||||
uint8_t *operator*() const noexcept;
|
||||
wasm_ptr_t _sandbox_malloc(wasm_size_t);
|
||||
wasm_ptr_t sandbox_malloc(wasm_size_t);
|
||||
void sandbox_free(wasm_ptr_t ptr);
|
||||
wasm_ptr_t rtypeddata_data(VALUE obj) const noexcept;
|
||||
void rtypeddata_dmark(wasm_ptr_t data, wasm_ptr_t ptr);
|
||||
|
|
|
@ -41,6 +41,21 @@
|
|||
return mkxp_sandbox::sb()->bind<struct alloc>()()(_klass); \
|
||||
}
|
||||
|
||||
#define SANDBOX_DEF_ALLOC_WITH_INIT(rbtype, initializer) \
|
||||
static VALUE alloc(VALUE _klass) { \
|
||||
SANDBOX_COROUTINE(alloc, \
|
||||
VALUE _obj; \
|
||||
VALUE operator()(VALUE _klass) { \
|
||||
BOOST_ASIO_CORO_REENTER (this) { \
|
||||
SANDBOX_AWAIT_AND_SET(_obj, mkxp_sandbox::rb_data_typed_object_wrap, _klass, 0, rbtype); \
|
||||
mkxp_sandbox::set_private_data(_obj, initializer); /* TODO: free when sandbox is deallocated */ \
|
||||
} \
|
||||
return _obj; \
|
||||
} \
|
||||
) \
|
||||
return mkxp_sandbox::sb()->bind<struct alloc>()()(_klass); \
|
||||
}
|
||||
|
||||
#define SANDBOX_DEF_DFREE(T) \
|
||||
static void dfree(wasm_ptr_t _buf) { \
|
||||
delete *(T **)(**mkxp_sandbox::sb() + _buf); \
|
||||
|
@ -48,46 +63,28 @@
|
|||
|
||||
#define SANDBOX_DEF_LOAD(T) \
|
||||
static VALUE load(VALUE _self, VALUE _serialized) { \
|
||||
return mkxp_sandbox::sb()->bind<struct _load_inner<T>>()()(_self, _serialized); \
|
||||
SANDBOX_COROUTINE(load, \
|
||||
struct mkxp_sandbox::_load::load_struct _data; \
|
||||
VALUE operator()(VALUE _self, VALUE _serialized) { \
|
||||
BOOST_ASIO_CORO_REENTER (this) { \
|
||||
SANDBOX_AWAIT_AND_SET(_data, mkxp_sandbox::_load::load_inner, _self, _serialized); \
|
||||
set_private_data(_data.obj, T::deserialize((const char *)(**mkxp_sandbox::sb() + _data.ptr), _data.len)); /* TODO: free when sandbox is deallocated */ \
|
||||
} \
|
||||
return _data.obj; \
|
||||
} \
|
||||
) \
|
||||
return mkxp_sandbox::sb()->bind<struct load>()()(_self, _serialized); \
|
||||
}
|
||||
|
||||
namespace mkxp_sandbox {
|
||||
// Given Ruby typed data `obj`, stores `ptr` into the private data field of `obj`.
|
||||
void set_private_data(VALUE obj, void *ptr);
|
||||
|
||||
// Given Ruby typed data `obj`, retrieves the private data field of `obj`.
|
||||
template <typename T> inline T *get_private_data(VALUE obj) {
|
||||
return *(T **)(**sb() + *(wasm_ptr_t *)(**sb() + sb()->rtypeddata_data(obj)));
|
||||
}
|
||||
|
||||
// Given Ruby typed data `obj`, stores `ptr` into the private data field of `obj`.
|
||||
SANDBOX_COROUTINE(set_private_data,
|
||||
wasm_ptr_t data;
|
||||
wasm_ptr_t buf;
|
||||
|
||||
void operator()(VALUE obj, void *ptr) {
|
||||
BOOST_ASIO_CORO_REENTER (this) {
|
||||
/* RGSS's behavior is to just leak memory if a disposable is reinitialized,
|
||||
* with the original disposable being left permanently instantiated,
|
||||
* but that's (1) bad, and (2) would currently cause memory access issues
|
||||
* when things like a sprite's src_rect inevitably get GC'd, so we're not
|
||||
* copying that. */
|
||||
|
||||
data = sb()->rtypeddata_data(obj);
|
||||
|
||||
// Free the old value if it already exists (initialize called twice?)
|
||||
if (*(wasm_ptr_t *)(**sb() + data) != 0 && *(void **)(**sb() + *(wasm_ptr_t *)(**sb() + data)) != ptr) {
|
||||
sb()->rtypeddata_dfree(obj, *(wasm_ptr_t *)(**sb() + data));
|
||||
sb()->sandbox_free(*(wasm_ptr_t *)(**sb() + data));
|
||||
*(wasm_ptr_t *)(**sb() + data) = 0;
|
||||
}
|
||||
|
||||
if (*(wasm_ptr_t *)(**sb() + data) == 0) {
|
||||
SANDBOX_AWAIT_AND_SET(buf, sandbox_malloc, sizeof(void *));
|
||||
*(void **)(**sb() + buf) = ptr;
|
||||
*(wasm_ptr_t *)(**sb() + data) = buf;
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
// Gets the length of a Ruby object.
|
||||
SANDBOX_COROUTINE(get_length,
|
||||
ID id;
|
||||
|
@ -105,23 +102,28 @@ namespace mkxp_sandbox {
|
|||
}
|
||||
)
|
||||
|
||||
// Internal-use utility coroutine for the `SANDBOX_DEF_LOAD` macro.
|
||||
template <typename T> SANDBOX_COROUTINE(_load_inner,
|
||||
VALUE obj;
|
||||
wasm_ptr_t ptr;
|
||||
wasm_size_t len;
|
||||
namespace _load {
|
||||
struct load_struct {
|
||||
VALUE obj;
|
||||
wasm_ptr_t ptr;
|
||||
wasm_size_t len;
|
||||
};
|
||||
|
||||
VALUE operator()(VALUE self, VALUE serialized) {
|
||||
BOOST_ASIO_CORO_REENTER (this) {
|
||||
SANDBOX_AWAIT_AND_SET(obj, rb_obj_alloc, self);
|
||||
SANDBOX_AWAIT_AND_SET(ptr, rb_string_value_ptr, &serialized);
|
||||
SANDBOX_AWAIT_AND_SET(len, get_length, serialized);
|
||||
SANDBOX_AWAIT(set_private_data, obj, T::deserialize((const char *)(**sb() + ptr), len)); // TODO: free when sandbox is deallocated
|
||||
// Internal-use utility coroutine for the `SANDBOX_DEF_LOAD` macro.
|
||||
SANDBOX_COROUTINE(load_inner,
|
||||
struct load_struct data;
|
||||
|
||||
struct load_struct operator()(VALUE self, VALUE serialized) {
|
||||
BOOST_ASIO_CORO_REENTER (this) {
|
||||
SANDBOX_AWAIT_AND_SET(data.obj, rb_obj_alloc, self);
|
||||
SANDBOX_AWAIT_AND_SET(data.ptr, rb_string_value_ptr, &serialized);
|
||||
SANDBOX_AWAIT_AND_SET(data.len, get_length, serialized);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// Prints the backtrace of a Ruby exception to the log.
|
||||
SANDBOX_COROUTINE(log_backtrace,
|
||||
|
|
|
@ -66,7 +66,7 @@ namespace mkxp_sandbox {
|
|||
GFX_GUARD_EXC(bitmap = new Bitmap(width, height);)
|
||||
}
|
||||
|
||||
SANDBOX_AWAIT(set_private_data, self, bitmap);
|
||||
set_private_data(self, bitmap);
|
||||
SANDBOX_AWAIT(init_props, bitmap, self);
|
||||
}
|
||||
|
||||
|
@ -96,7 +96,7 @@ namespace mkxp_sandbox {
|
|||
|
||||
SANDBOX_AWAIT(init_props, bitmap, self);
|
||||
// TODO: set font
|
||||
SANDBOX_AWAIT(set_private_data, self, bitmap);
|
||||
set_private_data(self, bitmap);
|
||||
}
|
||||
|
||||
return self;
|
||||
|
@ -138,7 +138,7 @@ namespace mkxp_sandbox {
|
|||
SANDBOX_AWAIT_AND_SET(id, rb_intern, "Rect");
|
||||
SANDBOX_AWAIT_AND_SET(klass, rb_const_get, sb()->rb_cObject(), id);
|
||||
SANDBOX_AWAIT_AND_SET(obj, rb_obj_alloc, klass);
|
||||
SANDBOX_AWAIT(set_private_data, obj, new Rect(get_private_data<Bitmap>(self)->rect()));
|
||||
set_private_data(obj, new Rect(get_private_data<Bitmap>(self)->rect()));
|
||||
}
|
||||
|
||||
return obj;
|
||||
|
@ -284,7 +284,7 @@ namespace mkxp_sandbox {
|
|||
SANDBOX_AWAIT_AND_SET(id, rb_intern, "Color");
|
||||
SANDBOX_AWAIT_AND_SET(klass, rb_const_get, sb()->rb_cObject(), id);
|
||||
SANDBOX_AWAIT_AND_SET(obj, rb_obj_alloc, klass);
|
||||
SANDBOX_AWAIT(set_private_data, obj, color);
|
||||
set_private_data(obj, color);
|
||||
}
|
||||
|
||||
return obj;
|
||||
|
@ -402,7 +402,7 @@ namespace mkxp_sandbox {
|
|||
SANDBOX_AWAIT_AND_SET(id, rb_intern, "Rect");
|
||||
SANDBOX_AWAIT_AND_SET(klass, rb_const_get, sb()->rb_cObject(), id);
|
||||
SANDBOX_AWAIT_AND_SET(obj, rb_obj_alloc, klass);
|
||||
SANDBOX_AWAIT(set_private_data, obj, new Rect(get_private_data<Bitmap>(self)->textSize((const char *)(**sb() + str))));
|
||||
set_private_data(obj, new Rect(get_private_data<Bitmap>(self)->textSize((const char *)(**sb() + str))));
|
||||
}
|
||||
|
||||
return obj;
|
||||
|
@ -416,7 +416,7 @@ namespace mkxp_sandbox {
|
|||
|
||||
void operator()() {
|
||||
BOOST_ASIO_CORO_REENTER (this) {
|
||||
SANDBOX_AWAIT_AND_SET(bitmap_type, new_rb_data_type, "Bitmap", NULL, dfree, NULL, NULL, 0, 0, 0);
|
||||
bitmap_type = sb()->rb_data_type("Bitmap", NULL, dfree, NULL, NULL, 0, 0, 0);
|
||||
SANDBOX_AWAIT_AND_SET(klass, rb_define_class, "Bitmap", sb()->rb_cObject());
|
||||
SANDBOX_AWAIT(rb_define_alloc_func, klass, alloc);
|
||||
SANDBOX_AWAIT(rb_define_method, klass, "initialize", (VALUE (*)(ANYARGS))initialize, -1);
|
||||
|
|
|
@ -33,26 +33,10 @@ namespace mkxp_sandbox {
|
|||
|
||||
SANDBOX_COROUTINE(etc_binding_init,
|
||||
SANDBOX_COROUTINE(color_binding_init,
|
||||
SANDBOX_DEF_ALLOC_WITH_INIT(color_type, new Color)
|
||||
SANDBOX_DEF_DFREE(Color)
|
||||
SANDBOX_DEF_LOAD(Color)
|
||||
|
||||
static VALUE alloc(VALUE klass) {
|
||||
SANDBOX_COROUTINE(coro,
|
||||
VALUE obj;
|
||||
|
||||
VALUE operator()(VALUE klass) {
|
||||
BOOST_ASIO_CORO_REENTER (this) {
|
||||
SANDBOX_AWAIT_AND_SET(obj, mkxp_sandbox::rb_data_typed_object_wrap, klass, 0, color_type);
|
||||
SANDBOX_AWAIT(set_private_data, obj, new Color);
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
)
|
||||
|
||||
return mkxp_sandbox::sb()->bind<struct coro>()()(klass);
|
||||
}
|
||||
|
||||
static VALUE initialize(int32_t argc, wasm_ptr_t argv, VALUE self) {
|
||||
SANDBOX_COROUTINE(coro,
|
||||
Color *color;
|
||||
|
@ -64,7 +48,7 @@ namespace mkxp_sandbox {
|
|||
VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) {
|
||||
BOOST_ASIO_CORO_REENTER (this) {
|
||||
if (argc == 0) {
|
||||
color = new Color;
|
||||
color = new Color();
|
||||
} else {
|
||||
SANDBOX_AWAIT_AND_SET(red, rb_num2dbl, ((VALUE *)(**sb() + argv))[0]);
|
||||
SANDBOX_AWAIT_AND_SET(green, rb_num2dbl, ((VALUE *)(**sb() + argv))[1]);
|
||||
|
@ -77,7 +61,7 @@ namespace mkxp_sandbox {
|
|||
}
|
||||
}
|
||||
|
||||
SANDBOX_AWAIT(set_private_data, self, color);
|
||||
set_private_data(self, color);
|
||||
}
|
||||
|
||||
return SANDBOX_NIL;
|
||||
|
@ -206,7 +190,7 @@ namespace mkxp_sandbox {
|
|||
|
||||
void operator()() {
|
||||
BOOST_ASIO_CORO_REENTER (this) {
|
||||
SANDBOX_AWAIT_AND_SET(color_type, new_rb_data_type, "Color", NULL, dfree, NULL, NULL, 0, 0, 0);
|
||||
color_type = sb()->rb_data_type("Color", NULL, dfree, NULL, NULL, 0, 0, 0);
|
||||
SANDBOX_AWAIT_AND_SET(klass, rb_define_class, "Color", sb()->rb_cObject());
|
||||
SANDBOX_AWAIT(rb_define_alloc_func, klass, alloc);
|
||||
SANDBOX_AWAIT(rb_define_singleton_method, klass, "_load", (VALUE (*)(ANYARGS))load, 1);
|
||||
|
@ -225,26 +209,10 @@ namespace mkxp_sandbox {
|
|||
)
|
||||
|
||||
SANDBOX_COROUTINE(tone_binding_init,
|
||||
SANDBOX_DEF_ALLOC_WITH_INIT(tone_type, new Tone)
|
||||
SANDBOX_DEF_DFREE(Tone)
|
||||
SANDBOX_DEF_LOAD(Tone)
|
||||
|
||||
static VALUE alloc(VALUE klass) {
|
||||
SANDBOX_COROUTINE(coro,
|
||||
VALUE obj;
|
||||
|
||||
VALUE operator()(VALUE klass) {
|
||||
BOOST_ASIO_CORO_REENTER (this) {
|
||||
SANDBOX_AWAIT_AND_SET(obj, mkxp_sandbox::rb_data_typed_object_wrap, klass, 0, tone_type);
|
||||
SANDBOX_AWAIT(set_private_data, obj, new Tone);
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
)
|
||||
|
||||
return mkxp_sandbox::sb()->bind<struct coro>()()(klass);
|
||||
}
|
||||
|
||||
static VALUE initialize(int32_t argc, wasm_ptr_t argv, VALUE self) {
|
||||
SANDBOX_COROUTINE(coro,
|
||||
Tone *tone;
|
||||
|
@ -256,7 +224,7 @@ namespace mkxp_sandbox {
|
|||
VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) {
|
||||
BOOST_ASIO_CORO_REENTER (this) {
|
||||
if (argc == 0) {
|
||||
tone = new Tone;
|
||||
tone = new Tone();
|
||||
} else {
|
||||
SANDBOX_AWAIT_AND_SET(red, rb_num2dbl, ((VALUE *)(**sb() + argv))[0]);
|
||||
SANDBOX_AWAIT_AND_SET(green, rb_num2dbl, ((VALUE *)(**sb() + argv))[1]);
|
||||
|
@ -269,7 +237,7 @@ namespace mkxp_sandbox {
|
|||
}
|
||||
}
|
||||
|
||||
SANDBOX_AWAIT(set_private_data, self, tone);
|
||||
set_private_data(self, tone);
|
||||
}
|
||||
|
||||
return SANDBOX_NIL;
|
||||
|
@ -398,7 +366,7 @@ namespace mkxp_sandbox {
|
|||
|
||||
void operator()() {
|
||||
BOOST_ASIO_CORO_REENTER (this) {
|
||||
SANDBOX_AWAIT_AND_SET(tone_type, new_rb_data_type, "Tone", NULL, dfree, NULL, NULL, 0, 0, 0);
|
||||
tone_type = sb()->rb_data_type("Tone", NULL, dfree, NULL, NULL, 0, 0, 0);
|
||||
SANDBOX_AWAIT_AND_SET(klass, rb_define_class, "Tone", sb()->rb_cObject());
|
||||
SANDBOX_AWAIT(rb_define_alloc_func, klass, alloc);
|
||||
SANDBOX_AWAIT(rb_define_singleton_method, klass, "_load", (VALUE (*)(ANYARGS))load, 1);
|
||||
|
@ -417,26 +385,10 @@ namespace mkxp_sandbox {
|
|||
)
|
||||
|
||||
SANDBOX_COROUTINE(rect_binding_init,
|
||||
SANDBOX_DEF_ALLOC_WITH_INIT(rect_type, new Rect)
|
||||
SANDBOX_DEF_DFREE(Rect)
|
||||
SANDBOX_DEF_LOAD(Rect)
|
||||
|
||||
static VALUE alloc(VALUE klass) {
|
||||
SANDBOX_COROUTINE(coro,
|
||||
VALUE obj;
|
||||
|
||||
VALUE operator()(VALUE klass) {
|
||||
BOOST_ASIO_CORO_REENTER (this) {
|
||||
SANDBOX_AWAIT_AND_SET(obj, mkxp_sandbox::rb_data_typed_object_wrap, klass, 0, rect_type);
|
||||
SANDBOX_AWAIT(set_private_data, obj, new Rect);
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
)
|
||||
|
||||
return mkxp_sandbox::sb()->bind<struct coro>()()(klass);
|
||||
}
|
||||
|
||||
static VALUE initialize(int32_t argc, wasm_ptr_t argv, VALUE self) {
|
||||
SANDBOX_COROUTINE(coro,
|
||||
Rect *rect;
|
||||
|
@ -448,7 +400,7 @@ namespace mkxp_sandbox {
|
|||
VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) {
|
||||
BOOST_ASIO_CORO_REENTER (this) {
|
||||
if (argc == 0) {
|
||||
rect = new Rect;
|
||||
rect = new Rect();
|
||||
} else {
|
||||
SANDBOX_AWAIT_AND_SET(x, rb_num2int, ((VALUE *)(**sb() + argv))[0]);
|
||||
SANDBOX_AWAIT_AND_SET(y, rb_num2int, ((VALUE *)(**sb() + argv))[1]);
|
||||
|
@ -457,7 +409,7 @@ namespace mkxp_sandbox {
|
|||
rect = new Rect(x, y, width, height);
|
||||
}
|
||||
|
||||
SANDBOX_AWAIT(set_private_data, self, rect);
|
||||
set_private_data(self, rect);
|
||||
}
|
||||
|
||||
return SANDBOX_NIL;
|
||||
|
@ -587,7 +539,7 @@ namespace mkxp_sandbox {
|
|||
|
||||
void operator()() {
|
||||
BOOST_ASIO_CORO_REENTER (this) {
|
||||
SANDBOX_AWAIT_AND_SET(rect_type, new_rb_data_type, "Rect", NULL, dfree, NULL, NULL, 0, 0, 0);
|
||||
rect_type = sb()->rb_data_type("Rect", NULL, dfree, NULL, NULL, 0, 0, 0);
|
||||
SANDBOX_AWAIT_AND_SET(klass, rb_define_class, "Rect", sb()->rb_cObject());
|
||||
SANDBOX_AWAIT(rb_define_alloc_func, klass, alloc);
|
||||
SANDBOX_AWAIT(rb_define_singleton_method, klass, "_load", (VALUE (*)(ANYARGS))load, 1);
|
||||
|
|
|
@ -41,9 +41,8 @@ namespace mkxp_sandbox {
|
|||
SANDBOX_AWAIT_AND_SET(id, rb_intern, "Color");
|
||||
SANDBOX_AWAIT_AND_SET(klass, rb_const_get, sb()->rb_cObject(), id);
|
||||
SANDBOX_AWAIT_AND_SET(obj, rb_obj_alloc, klass);
|
||||
SANDBOX_AWAIT(set_private_data, obj, new Color);
|
||||
set_private_data(obj, new Color());
|
||||
SANDBOX_AWAIT(rb_iv_set, self, "color", obj);
|
||||
SANDBOX_AWAIT_AND_SET(obj, rb_iv_get, self, "color");
|
||||
}
|
||||
|
||||
return SANDBOX_NIL;
|
||||
|
|
|
@ -62,20 +62,20 @@ namespace mkxp_sandbox {
|
|||
GFX_LOCK
|
||||
plane = new Plane(viewport);
|
||||
|
||||
SANDBOX_AWAIT(set_private_data, self, plane);
|
||||
set_private_data(self, plane);
|
||||
|
||||
plane->initDynAttribs();
|
||||
|
||||
SANDBOX_AWAIT_AND_SET(id, rb_intern, "Color");
|
||||
SANDBOX_AWAIT_AND_SET(klass, rb_const_get, sb()->rb_cObject(), id);
|
||||
SANDBOX_AWAIT_AND_SET(obj, rb_obj_alloc, klass);
|
||||
SANDBOX_AWAIT(set_private_data, obj, &plane->getColor());
|
||||
set_private_data(obj, &plane->getColor());
|
||||
SANDBOX_AWAIT(rb_iv_set, self, "color", obj);
|
||||
|
||||
SANDBOX_AWAIT_AND_SET(id, rb_intern, "Tone");
|
||||
SANDBOX_AWAIT_AND_SET(klass, rb_const_get, sb()->rb_cObject(), id);
|
||||
SANDBOX_AWAIT_AND_SET(obj, rb_obj_alloc, klass);
|
||||
SANDBOX_AWAIT(set_private_data, obj, &plane->getTone());
|
||||
set_private_data(obj, &plane->getTone());
|
||||
SANDBOX_AWAIT(rb_iv_set, self, "tone", obj);
|
||||
|
||||
GFX_UNLOCK
|
||||
|
@ -316,7 +316,7 @@ namespace mkxp_sandbox {
|
|||
|
||||
void operator()() {
|
||||
BOOST_ASIO_CORO_REENTER (this) {
|
||||
SANDBOX_AWAIT_AND_SET(plane_type, new_rb_data_type, "Plane", NULL, dfree, NULL, NULL, 0, 0, 0);
|
||||
plane_type = sb()->rb_data_type("Plane", NULL, dfree, NULL, NULL, 0, 0, 0);
|
||||
SANDBOX_AWAIT_AND_SET(klass, rb_define_class, "Plane", sb()->rb_cObject());
|
||||
SANDBOX_AWAIT(rb_define_alloc_func, klass, alloc);
|
||||
SANDBOX_AWAIT(rb_define_method, klass, "initialize", (VALUE (*)(ANYARGS))initialize, -1);
|
||||
|
|
|
@ -43,7 +43,6 @@ using namespace mkxp_sandbox;
|
|||
|
||||
usize sandbox::sandbox_malloc(usize size) {
|
||||
usize buf = w2c_ruby_mkxp_sandbox_malloc(RB, size);
|
||||
assert(w2c_ruby_asyncify_get_state(RB) == 0);
|
||||
|
||||
// Verify that the returned pointer is non-null and the entire allocated buffer is in valid memory
|
||||
usize buf_end;
|
||||
|
@ -58,7 +57,7 @@ void sandbox::sandbox_free(usize ptr) {
|
|||
w2c_ruby_mkxp_sandbox_free(RB, ptr);
|
||||
}
|
||||
|
||||
sandbox::sandbox() : ruby(new struct w2c_ruby), wasi(new wasi_t(ruby)), bindings(ruby), yielding(false), realloc_size(0) {
|
||||
sandbox::sandbox() : ruby(new struct w2c_ruby), wasi(new wasi_t(ruby)), bindings(ruby), yielding(false) {
|
||||
try {
|
||||
// Initialize the sandbox
|
||||
wasm2c_ruby_instantiate(RB, wasi.get());
|
||||
|
@ -82,8 +81,6 @@ sandbox::sandbox() : ruby(new struct w2c_ruby), wasi(new wasi_t(ruby)), bindings
|
|||
args.push_back("--yjit");
|
||||
}
|
||||
|
||||
usize state_buf = sandbox_malloc(sizeof(usize));
|
||||
|
||||
// Copy all the command-line arguments into the sandbox (sandboxed code can't access memory that's outside the sandbox!)
|
||||
usize argv_buf = sandbox_malloc(args.size() * sizeof(usize));
|
||||
for (usize i = 0; i < args.size(); ++i) {
|
||||
|
@ -101,6 +98,7 @@ sandbox::sandbox() : ruby(new struct w2c_ruby), wasi(new wasi_t(ruby)), bindings
|
|||
// Start up Ruby executable node
|
||||
bool valid;
|
||||
u32 state;
|
||||
usize state_buf = sandbox_malloc(sizeof(usize));
|
||||
AWAIT(valid = w2c_ruby_ruby_executable_node(RB, node, state_buf));
|
||||
if (valid) {
|
||||
AWAIT(state = w2c_ruby_ruby_exec_node(RB, node));
|
||||
|
@ -124,7 +122,7 @@ sandbox::sandbox() : ruby(new struct w2c_ruby), wasi(new wasi_t(ruby)), bindings
|
|||
}
|
||||
|
||||
sandbox::~sandbox() {
|
||||
if (yielding || realloc_size != 0) {
|
||||
if (yielding) {
|
||||
w2c_ruby_asyncify_stop_unwind(ruby.get());
|
||||
}
|
||||
bindings.reset(); // Destroy the bindings before destroying the runtime since the bindings destructor requires the runtime to be alive
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#ifndef MKXPZ_SANDBOX_H
|
||||
#define MKXPZ_SANDBOX_H
|
||||
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#include <boost/optional.hpp>
|
||||
#include <mkxp-sandbox-bindgen.h>
|
||||
|
@ -79,8 +78,6 @@ namespace mkxp_sandbox {
|
|||
std::unique_ptr<struct w2c_wasi__snapshot__preview1> wasi;
|
||||
boost::optional<struct mkxp_sandbox::bindings> bindings;
|
||||
bool yielding;
|
||||
size_t realloc_size;
|
||||
bool realloc_succeeded;
|
||||
usize sandbox_malloc(usize size);
|
||||
void sandbox_free(usize ptr);
|
||||
|
||||
|
@ -101,20 +98,6 @@ namespace mkxp_sandbox {
|
|||
w2c_ruby_asyncify_stop_rewind(ruby.get());
|
||||
}
|
||||
|
||||
inline void _begin_realloc(size_t size) {
|
||||
realloc_size = size;
|
||||
w2c_ruby_asyncify_start_unwind(ruby.get(), ruby->w2c_mkxp_sandbox_async_buf);
|
||||
}
|
||||
|
||||
inline bool _end_realloc() {
|
||||
w2c_ruby_asyncify_stop_rewind(ruby.get());
|
||||
return realloc_succeeded;
|
||||
}
|
||||
|
||||
inline bool _rewinding() {
|
||||
return w2c_ruby_asyncify_get_state(ruby.get()) == 2;
|
||||
}
|
||||
|
||||
// Executes the given coroutine as the top-level coroutine. Don't call this from inside of another coroutine; use `sb()->bind<T>()` instead.
|
||||
// Returns whether or not the coroutine completed execution.
|
||||
template <typename T> inline bool run() {
|
||||
|
@ -128,16 +111,7 @@ namespace mkxp_sandbox {
|
|||
frame()();
|
||||
if (yielding || frame().is_complete()) break;
|
||||
}
|
||||
if (realloc_size != 0) {
|
||||
w2c_ruby_asyncify_start_rewind(ruby.get(), ruby->w2c_mkxp_sandbox_async_buf);
|
||||
uint8_t *new_data = (uint8_t *)std::realloc(ruby->w2c_memory.data, realloc_size);
|
||||
if ((realloc_succeeded = new_data != NULL)) {
|
||||
ruby->w2c_memory.private_data = new_data;
|
||||
}
|
||||
realloc_size = 0;
|
||||
} else {
|
||||
w2c_ruby_mkxp_sandbox_yield(ruby.get());
|
||||
}
|
||||
w2c_ruby_mkxp_sandbox_yield(ruby.get());
|
||||
}
|
||||
return !yielding;
|
||||
}
|
||||
|
|
|
@ -58,25 +58,25 @@ namespace mkxp_sandbox {
|
|||
sprite = new Sprite(viewport);
|
||||
SANDBOX_AWAIT(rb_iv_set, self, "viewport", viewport_obj);
|
||||
|
||||
SANDBOX_AWAIT(set_private_data, self, sprite);
|
||||
set_private_data(self, sprite);
|
||||
sprite->initDynAttribs();
|
||||
|
||||
SANDBOX_AWAIT_AND_SET(id, rb_intern, "Rect");
|
||||
SANDBOX_AWAIT_AND_SET(klass, rb_const_get, sb()->rb_cObject(), id);
|
||||
SANDBOX_AWAIT_AND_SET(obj, rb_obj_alloc, klass);
|
||||
SANDBOX_AWAIT(set_private_data, obj, &sprite->getSrcRect());
|
||||
set_private_data(obj, &sprite->getSrcRect());
|
||||
SANDBOX_AWAIT(rb_iv_set, self, "src_rect", obj);
|
||||
|
||||
SANDBOX_AWAIT_AND_SET(id, rb_intern, "Color");
|
||||
SANDBOX_AWAIT_AND_SET(klass, rb_const_get, sb()->rb_cObject(), id);
|
||||
SANDBOX_AWAIT_AND_SET(obj, rb_obj_alloc, klass);
|
||||
SANDBOX_AWAIT(set_private_data, obj, &sprite->getColor());
|
||||
set_private_data(obj, &sprite->getColor());
|
||||
SANDBOX_AWAIT(rb_iv_set, self, "color", obj);
|
||||
|
||||
SANDBOX_AWAIT_AND_SET(id, rb_intern, "Tone");
|
||||
SANDBOX_AWAIT_AND_SET(klass, rb_const_get, sb()->rb_cObject(), id);
|
||||
SANDBOX_AWAIT_AND_SET(obj, rb_obj_alloc, klass);
|
||||
SANDBOX_AWAIT(set_private_data, obj, &sprite->getTone());
|
||||
set_private_data(obj, &sprite->getTone());
|
||||
SANDBOX_AWAIT(rb_iv_set, self, "tone", obj);
|
||||
|
||||
GFX_UNLOCK
|
||||
|
@ -460,7 +460,7 @@ namespace mkxp_sandbox {
|
|||
|
||||
void operator()() {
|
||||
BOOST_ASIO_CORO_REENTER (this) {
|
||||
SANDBOX_AWAIT_AND_SET(sprite_type, new_rb_data_type, "Sprite", NULL, dfree, NULL, NULL, 0, 0, 0);
|
||||
sprite_type = sb()->rb_data_type("Sprite", NULL, dfree, NULL, NULL, 0, 0, 0);
|
||||
SANDBOX_AWAIT_AND_SET(klass, rb_define_class, "Sprite", sb()->rb_cObject());
|
||||
SANDBOX_AWAIT(rb_define_alloc_func, klass, alloc);
|
||||
SANDBOX_AWAIT(rb_define_method, klass, "initialize", (VALUE (*)(ANYARGS))initialize, -1);
|
||||
|
|
|
@ -31,27 +31,10 @@ namespace mkxp_sandbox {
|
|||
static struct mkxp_sandbox::bindings::rb_data_type table_type;
|
||||
|
||||
SANDBOX_COROUTINE(table_binding_init,
|
||||
SANDBOX_DEF_ALLOC_WITH_INIT(table_type, new Table(0, 0, 0))
|
||||
SANDBOX_DEF_DFREE(Table)
|
||||
SANDBOX_DEF_LOAD(Table)
|
||||
|
||||
static VALUE alloc(VALUE klass) {
|
||||
SANDBOX_COROUTINE(coro,
|
||||
VALUE obj;
|
||||
|
||||
VALUE operator()(VALUE klass) {
|
||||
BOOST_ASIO_CORO_REENTER (this) {
|
||||
SANDBOX_AWAIT_AND_SET(obj, mkxp_sandbox::rb_data_typed_object_wrap, klass, 0, table_type);
|
||||
SANDBOX_AWAIT(set_private_data, obj, new Table(0, 0, 0));
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
)
|
||||
|
||||
return mkxp_sandbox::sb()->bind<struct coro>()()(klass);
|
||||
}
|
||||
|
||||
|
||||
static VALUE get(int32_t argc, wasm_ptr_t argv, VALUE self) {
|
||||
SANDBOX_COROUTINE(coro,
|
||||
Table *table;
|
||||
|
@ -128,7 +111,7 @@ namespace mkxp_sandbox {
|
|||
|
||||
void operator()() {
|
||||
BOOST_ASIO_CORO_REENTER (this) {
|
||||
SANDBOX_AWAIT_AND_SET(table_type, new_rb_data_type, "Table", NULL, dfree, NULL, NULL, 0, 0, 0);
|
||||
table_type = sb()->rb_data_type("Table", NULL, dfree, NULL, NULL, 0, 0, 0);
|
||||
SANDBOX_AWAIT_AND_SET(klass, rb_define_class, "Table", sb()->rb_cObject());
|
||||
SANDBOX_AWAIT(rb_define_alloc_func, klass, alloc);
|
||||
SANDBOX_AWAIT(rb_define_singleton_method, klass, "_load", (VALUE (*)(ANYARGS))load, 1);
|
||||
|
|
|
@ -90,7 +90,7 @@ namespace mkxp_sandbox {
|
|||
|
||||
void operator()() {
|
||||
BOOST_ASIO_CORO_REENTER (this) {
|
||||
SANDBOX_AWAIT_AND_SET(tilemap_autotiles_type, new_rb_data_type, "TilemapAutotiles", NULL, NULL, NULL, NULL, 0, 0, 0);
|
||||
tilemap_autotiles_type = sb()->rb_data_type("TilemapAutotiles", NULL, NULL, NULL, NULL, 0, 0, 0);
|
||||
SANDBOX_AWAIT_AND_SET(klass, rb_define_class, "TilemapAutotiles", sb()->rb_cObject());
|
||||
SANDBOX_AWAIT(rb_define_alloc_func, klass, alloc);
|
||||
SANDBOX_AWAIT(rb_define_method, klass, "[]", (VALUE (*)(ANYARGS))get, 1);
|
||||
|
@ -131,7 +131,7 @@ namespace mkxp_sandbox {
|
|||
GFX_LOCK
|
||||
tilemap = new Tilemap(viewport);
|
||||
|
||||
SANDBOX_AWAIT(set_private_data, self, tilemap);
|
||||
set_private_data(self, tilemap);
|
||||
|
||||
tilemap->initDynAttribs();
|
||||
|
||||
|
@ -139,25 +139,25 @@ namespace mkxp_sandbox {
|
|||
* See the comment in setPrivateData for more info. */
|
||||
SANDBOX_AWAIT_AND_SET(obj, rb_iv_get, self, "autotiles");
|
||||
if (obj != SANDBOX_NIL) {
|
||||
SANDBOX_AWAIT(set_private_data, obj, NULL);
|
||||
set_private_data(obj, NULL);
|
||||
}
|
||||
|
||||
SANDBOX_AWAIT_AND_SET(id, rb_intern, "TilemapAutotiles");
|
||||
SANDBOX_AWAIT_AND_SET(klass, rb_const_get, sb()->rb_cObject(), id);
|
||||
SANDBOX_AWAIT_AND_SET(obj, rb_obj_alloc, klass);
|
||||
SANDBOX_AWAIT(set_private_data, obj, &tilemap->getAutotiles());
|
||||
set_private_data(obj, &tilemap->getAutotiles());
|
||||
SANDBOX_AWAIT(rb_iv_set, self, "autotiles", obj);
|
||||
|
||||
SANDBOX_AWAIT_AND_SET(id, rb_intern, "Color");
|
||||
SANDBOX_AWAIT_AND_SET(klass, rb_const_get, sb()->rb_cObject(), id);
|
||||
SANDBOX_AWAIT_AND_SET(obj, rb_obj_alloc, klass);
|
||||
SANDBOX_AWAIT(set_private_data, obj, &tilemap->getColor());
|
||||
set_private_data(obj, &tilemap->getColor());
|
||||
SANDBOX_AWAIT(rb_iv_set, self, "color", obj);
|
||||
|
||||
SANDBOX_AWAIT_AND_SET(id, rb_intern, "Tone");
|
||||
SANDBOX_AWAIT_AND_SET(klass, rb_const_get, sb()->rb_cObject(), id);
|
||||
SANDBOX_AWAIT_AND_SET(obj, rb_obj_alloc, klass);
|
||||
SANDBOX_AWAIT(set_private_data, obj, &tilemap->getTone());
|
||||
set_private_data(obj, &tilemap->getTone());
|
||||
SANDBOX_AWAIT(rb_iv_set, self, "tone", obj);
|
||||
|
||||
SANDBOX_AWAIT_AND_SET(obj, rb_iv_get, self, "autotiles");
|
||||
|
@ -418,7 +418,7 @@ namespace mkxp_sandbox {
|
|||
BOOST_ASIO_CORO_REENTER (this) {
|
||||
SANDBOX_AWAIT(tilemap_autotiles_binding_init);
|
||||
|
||||
SANDBOX_AWAIT_AND_SET(tilemap_type, new_rb_data_type, "Tilemap", NULL, dfree, NULL, NULL, 0, 0, 0);
|
||||
tilemap_type = sb()->rb_data_type("Tilemap", NULL, dfree, NULL, NULL, 0, 0, 0);
|
||||
SANDBOX_AWAIT_AND_SET(klass, rb_define_class, "Tilemap", sb()->rb_cObject());
|
||||
SANDBOX_AWAIT(rb_define_alloc_func, klass, alloc);
|
||||
SANDBOX_AWAIT(rb_define_method, klass, "initialize", (VALUE (*)(ANYARGS))initialize, -1);
|
||||
|
|
|
@ -59,26 +59,26 @@ namespace mkxp_sandbox {
|
|||
viewport = new Viewport(x, y, w, h);
|
||||
}
|
||||
|
||||
SANDBOX_AWAIT(set_private_data, self, viewport);
|
||||
set_private_data(self, viewport);
|
||||
|
||||
viewport->initDynAttribs();
|
||||
|
||||
SANDBOX_AWAIT_AND_SET(id, rb_intern, "Rect");
|
||||
SANDBOX_AWAIT_AND_SET(klass, rb_const_get, sb()->rb_cObject(), id);
|
||||
SANDBOX_AWAIT_AND_SET(obj, rb_obj_alloc, klass);
|
||||
SANDBOX_AWAIT(set_private_data, obj, &viewport->getRect());
|
||||
set_private_data(obj, &viewport->getRect());
|
||||
SANDBOX_AWAIT(rb_iv_set, self, "rect", obj);
|
||||
|
||||
SANDBOX_AWAIT_AND_SET(id, rb_intern, "Color");
|
||||
SANDBOX_AWAIT_AND_SET(klass, rb_const_get, sb()->rb_cObject(), id);
|
||||
SANDBOX_AWAIT_AND_SET(obj, rb_obj_alloc, klass);
|
||||
SANDBOX_AWAIT(set_private_data, obj, &viewport->getColor());
|
||||
set_private_data(obj, &viewport->getColor());
|
||||
SANDBOX_AWAIT(rb_iv_set, self, "color", obj);
|
||||
|
||||
SANDBOX_AWAIT_AND_SET(id, rb_intern, "Tone");
|
||||
SANDBOX_AWAIT_AND_SET(klass, rb_const_get, sb()->rb_cObject(), id);
|
||||
SANDBOX_AWAIT_AND_SET(obj, rb_obj_alloc, klass);
|
||||
SANDBOX_AWAIT(set_private_data, obj, &viewport->getTone());
|
||||
set_private_data(obj, &viewport->getTone());
|
||||
SANDBOX_AWAIT(rb_iv_set, self, "tone", obj);
|
||||
|
||||
GFX_UNLOCK
|
||||
|
@ -232,7 +232,7 @@ namespace mkxp_sandbox {
|
|||
|
||||
void operator()() {
|
||||
BOOST_ASIO_CORO_REENTER (this) {
|
||||
SANDBOX_AWAIT_AND_SET(viewport_type, new_rb_data_type, "Viewport", NULL, dfree, NULL, NULL, 0, 0, 0);
|
||||
viewport_type = sb()->rb_data_type("Viewport", NULL, dfree, NULL, NULL, 0, 0, 0);
|
||||
SANDBOX_AWAIT_AND_SET(klass, rb_define_class, "Viewport", sb()->rb_cObject());
|
||||
SANDBOX_AWAIT(rb_define_alloc_func, klass, alloc);
|
||||
SANDBOX_AWAIT(rb_define_method, klass, "initialize", (VALUE (*)(ANYARGS))initialize, -1);
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
#define WASM_PAGE_SIZE ((uint64_t)65536U)
|
||||
|
||||
#define WASM_MIN_PAGES ((uint32_t)1024U) // tentative
|
||||
#define WASM_MIN_PAGES ((uint32_t)1536U)
|
||||
|
||||
extern "C" bool wasm_rt_is_initialized(void) {
|
||||
return true;
|
||||
|
@ -94,15 +94,8 @@ extern "C" uint32_t wasm_rt_grow_memory(wasm_rt_memory_t *memory, uint32_t pages
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (!mkxp_retro::sandbox.has_value()) {
|
||||
assert(new_pages <= WASM_MIN_PAGES);
|
||||
} else if (mkxp_retro::sandbox->_rewinding()) {
|
||||
if (!mkxp_retro::sandbox->_end_realloc()) {
|
||||
return -1;
|
||||
}
|
||||
} else if (new_pages > WASM_MIN_PAGES) {
|
||||
mkxp_retro::sandbox->_begin_realloc((size_t)new_size);
|
||||
return -1; // Arbitrary value that never gets read
|
||||
if (new_pages > WASM_MIN_PAGES) {
|
||||
mkxp_retro::log_printf(RETRO_LOG_ERROR, "Sandbox memory growth is not implemented yet");
|
||||
}
|
||||
|
||||
#ifdef MKXPZ_BIG_ENDIAN
|
||||
|
|
|
@ -57,25 +57,25 @@ namespace mkxp_sandbox {
|
|||
window = new Window(viewport);
|
||||
SANDBOX_AWAIT(rb_iv_set, self, "viewport", viewport_obj);
|
||||
|
||||
SANDBOX_AWAIT(set_private_data, self, window);
|
||||
set_private_data(self, window);
|
||||
window->initDynAttribs();
|
||||
|
||||
SANDBOX_AWAIT_AND_SET(id, rb_intern, "Bitmap");
|
||||
SANDBOX_AWAIT_AND_SET(klass, rb_const_get, sb()->rb_cObject(), id);
|
||||
SANDBOX_AWAIT_AND_SET(obj, rb_obj_alloc, klass);
|
||||
SANDBOX_AWAIT(set_private_data, obj, window->getWindowskin());
|
||||
set_private_data(obj, window->getWindowskin());
|
||||
SANDBOX_AWAIT(rb_iv_set, self, "windowskin", obj);
|
||||
|
||||
SANDBOX_AWAIT_AND_SET(id, rb_intern, "Bitmap");
|
||||
SANDBOX_AWAIT_AND_SET(klass, rb_const_get, sb()->rb_cObject(), id);
|
||||
SANDBOX_AWAIT_AND_SET(obj, rb_obj_alloc, klass);
|
||||
SANDBOX_AWAIT(set_private_data, obj, window->getContents());
|
||||
set_private_data(obj, window->getContents());
|
||||
SANDBOX_AWAIT(rb_iv_set, self, "contents", obj);
|
||||
|
||||
SANDBOX_AWAIT_AND_SET(id, rb_intern, "Rect");
|
||||
SANDBOX_AWAIT_AND_SET(klass, rb_const_get, sb()->rb_cObject(), id);
|
||||
SANDBOX_AWAIT_AND_SET(obj, rb_obj_alloc, klass);
|
||||
SANDBOX_AWAIT(set_private_data, obj, &window->getCursorRect());
|
||||
set_private_data(obj, &window->getCursorRect());
|
||||
SANDBOX_AWAIT(rb_iv_set, self, "cursor_rect", obj);
|
||||
|
||||
GFX_UNLOCK
|
||||
|
@ -416,7 +416,7 @@ namespace mkxp_sandbox {
|
|||
|
||||
void operator()() {
|
||||
BOOST_ASIO_CORO_REENTER (this) {
|
||||
SANDBOX_AWAIT_AND_SET(window_type, new_rb_data_type, "Window", NULL, dfree, NULL, NULL, 0, 0, 0);
|
||||
window_type = sb()->rb_data_type("Window", NULL, dfree, NULL, NULL, 0, 0, 0);
|
||||
SANDBOX_AWAIT_AND_SET(klass, rb_define_class, "Window", sb()->rb_cObject());
|
||||
SANDBOX_AWAIT(rb_define_alloc_func, klass, alloc);
|
||||
SANDBOX_AWAIT(rb_define_method, klass, "initialize", (VALUE (*)(ANYARGS))initialize, -1);
|
||||
|
|
|
@ -41,7 +41,7 @@ MKXP_SANDBOX_API void *mkxp_sandbox_fiber_arg1 = NULL;
|
|||
|
||||
/* This function should be called immediately after initializing the sandbox to perform initialization, before calling any other functions. */
|
||||
MKXP_SANDBOX_API void mkxp_sandbox_init(void) {
|
||||
void __wasm_call_ctors(void); /* Defined by wasi-libc from the WASI SDK */
|
||||
void __wasm_call_ctors(void); /* Defined by the LLVM linker */
|
||||
__wasm_call_ctors();
|
||||
|
||||
void async_buf_init(struct __rb_wasm_asyncify_jmp_buf *); /* Defined in wasm/setjmp.c in Ruby source code */
|
||||
|
|
|
@ -218,7 +218,6 @@ HEADER_START = <<~HEREDOC
|
|||
|
||||
struct rb_data_type {
|
||||
friend struct bindings;
|
||||
friend struct new_rb_data_type;
|
||||
rb_data_type();
|
||||
wasm_ptr_t get() const;
|
||||
private:
|
||||
|
@ -226,6 +225,8 @@ HEADER_START = <<~HEREDOC
|
|||
rb_data_type(wasm_ptr_t ptr);
|
||||
};
|
||||
|
||||
struct rb_data_type rb_data_type(const char *wrap_struct_name, void (*dmark)(wasm_ptr_t), void (*dfree)(wasm_ptr_t), wasm_size_t (*dsize)(wasm_ptr_t), void (*dcompact)(wasm_ptr_t), wasm_ptr_t parent, wasm_ptr_t data, wasm_size_t flags);
|
||||
|
||||
HEREDOC
|
||||
|
||||
HEADER_END = <<~HEREDOC
|
||||
|
@ -302,84 +303,58 @@ HEREDOC
|
|||
|
||||
POSTSCRIPT = <<~HEREDOC
|
||||
|
||||
sandbox_malloc::sandbox_malloc(struct binding_base &b) : bind(b) {}
|
||||
wasm_ptr_t sandbox_malloc::operator()(wasm_size_t size) {
|
||||
BOOST_ASIO_CORO_REENTER (this) {
|
||||
for (;;) {
|
||||
{
|
||||
wasm_ptr_t buf = bind._sandbox_malloc(size);
|
||||
if (w2c_#{MODULE_NAME}_asyncify_get_state(&bind.instance()) != 1) return buf;
|
||||
}
|
||||
BOOST_ASIO_CORO_YIELD;
|
||||
}
|
||||
struct bindings::rb_data_type bindings::rb_data_type(const char *wrap_struct_name, void (*dmark)(wasm_ptr_t), void (*dfree)(wasm_ptr_t), wasm_size_t (*dsize)(wasm_ptr_t), void (*dcompact)(wasm_ptr_t), wasm_ptr_t parent, wasm_ptr_t data, wasm_size_t flags) {
|
||||
wasm_ptr_t buf;
|
||||
wasm_ptr_t str;
|
||||
|
||||
buf = sandbox_malloc(9 * sizeof(wasm_ptr_t));
|
||||
if (buf == 0) {
|
||||
throw SandboxOutOfMemoryException();
|
||||
}
|
||||
str = sandbox_malloc(std::strlen(wrap_struct_name) + 1);
|
||||
if (str == 0) {
|
||||
sandbox_free(buf);
|
||||
throw SandboxOutOfMemoryException();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
std::strcpy((char *)(**this + str), wrap_struct_name);
|
||||
((wasm_ptr_t *)(**this + buf))[0] = SERIALIZE_VALUE(str);
|
||||
|
||||
new_rb_data_type::new_rb_data_type(struct binding_base &b) : bind(b), buf(0), str(0) {}
|
||||
struct bindings::rb_data_type new_rb_data_type::operator()(const char *wrap_struct_name, void (*dmark)(wasm_ptr_t), void (*dfree)(wasm_ptr_t), wasm_size_t (*dsize)(wasm_ptr_t), void (*dcompact)(wasm_ptr_t), wasm_ptr_t parent, wasm_ptr_t data, wasm_size_t flags) {
|
||||
BOOST_ASIO_CORO_REENTER (this) {
|
||||
for (;;) {
|
||||
buf = bind._sandbox_malloc(9 * sizeof(wasm_ptr_t));
|
||||
if (w2c_#{MODULE_NAME}_asyncify_get_state(&bind.instance()) != 1) break;
|
||||
BOOST_ASIO_CORO_YIELD;
|
||||
}
|
||||
if (buf == 0) {
|
||||
throw SandboxOutOfMemoryException();
|
||||
}
|
||||
((wasm_ptr_t *)(**this + buf))[1] = dmark == NULL ? 0 : SERIALIZE_VALUE(wasm_rt_push_funcref(&instance().w2c_T0, wasm_rt_funcref_t {
|
||||
.func_type = wasm2c_#{MODULE_NAME}_get_func_type(1, 0, #{FUNC_TYPE_TABLE[:ptr]}),
|
||||
.func = (wasm_rt_function_ptr_t)_sbindgen_call_#{call_type_hash([:void, [:value]])},
|
||||
.func_tailcallee = {.fn = NULL},
|
||||
.module_instance = (void *)dmark,
|
||||
}));
|
||||
|
||||
for (;;) {
|
||||
str = bind._sandbox_malloc(std::strlen(wrap_struct_name) + 1);
|
||||
if (w2c_#{MODULE_NAME}_asyncify_get_state(&bind.instance()) != 1) break;
|
||||
BOOST_ASIO_CORO_YIELD;
|
||||
}
|
||||
if (str == 0) {
|
||||
throw SandboxOutOfMemoryException();
|
||||
}
|
||||
((wasm_ptr_t *)(**this + buf))[2] = dfree == NULL ? 0 : SERIALIZE_VALUE(wasm_rt_push_funcref(&instance().w2c_T0, wasm_rt_funcref_t {
|
||||
.func_type = wasm2c_#{MODULE_NAME}_get_func_type(1, 0, #{FUNC_TYPE_TABLE[:ptr]}),
|
||||
.func = (wasm_rt_function_ptr_t)_sbindgen_call_#{call_type_hash([:void, [:value]])},
|
||||
.func_tailcallee = {.fn = NULL},
|
||||
.module_instance = (void *)dfree,
|
||||
}));
|
||||
|
||||
std::strcpy((char *)(*bind + str), wrap_struct_name);
|
||||
((wasm_ptr_t *)(*bind + buf))[0] = SERIALIZE_VALUE(str);
|
||||
((wasm_ptr_t *)(**this + buf))[3] = dsize == NULL ? 0 : SERIALIZE_VALUE(wasm_rt_push_funcref(&instance().w2c_T0, wasm_rt_funcref_t {
|
||||
.func_type = wasm2c_#{MODULE_NAME}_get_func_type(1, 0, #{FUNC_TYPE_TABLE[:ptr]}, #{FUNC_TYPE_TABLE[:size]}),
|
||||
.func = (wasm_rt_function_ptr_t)_sbindgen_call_#{call_type_hash([:size, [:value]])},
|
||||
.func_tailcallee = {.fn = NULL},
|
||||
.module_instance = (void *)dsize,
|
||||
}));
|
||||
|
||||
((wasm_ptr_t *)(*bind + buf))[1] = dmark == NULL ? 0 : SERIALIZE_VALUE(wasm_rt_push_funcref(&bind.instance().w2c_T0, wasm_rt_funcref_t {
|
||||
.func_type = wasm2c_#{MODULE_NAME}_get_func_type(1, 0, #{FUNC_TYPE_TABLE[:ptr]}),
|
||||
.func = (wasm_rt_function_ptr_t)_sbindgen_call_#{call_type_hash([:void, [:value]])},
|
||||
.func_tailcallee = {.fn = NULL},
|
||||
.module_instance = (void *)dmark,
|
||||
}));
|
||||
((wasm_ptr_t *)(**this + buf))[4] = dcompact == NULL ? 0 : SERIALIZE_VALUE(wasm_rt_push_funcref(&instance().w2c_T0, wasm_rt_funcref_t {
|
||||
.func_type = wasm2c_#{MODULE_NAME}_get_func_type(1, 0, #{FUNC_TYPE_TABLE[:ptr]}),
|
||||
.func = (wasm_rt_function_ptr_t)_sbindgen_call_#{call_type_hash([:void, [:value]])},
|
||||
.func_tailcallee = {.fn = NULL},
|
||||
.module_instance = (void *)dcompact,
|
||||
}));
|
||||
|
||||
((wasm_ptr_t *)(*bind + buf))[2] = dfree == NULL ? 0 : SERIALIZE_VALUE(wasm_rt_push_funcref(&bind.instance().w2c_T0, wasm_rt_funcref_t {
|
||||
.func_type = wasm2c_#{MODULE_NAME}_get_func_type(1, 0, #{FUNC_TYPE_TABLE[:ptr]}),
|
||||
.func = (wasm_rt_function_ptr_t)_sbindgen_call_#{call_type_hash([:void, [:value]])},
|
||||
.func_tailcallee = {.fn = NULL},
|
||||
.module_instance = (void *)dfree,
|
||||
}));
|
||||
|
||||
((wasm_ptr_t *)(*bind + buf))[3] = dsize == NULL ? 0 : SERIALIZE_VALUE(wasm_rt_push_funcref(&bind.instance().w2c_T0, wasm_rt_funcref_t {
|
||||
.func_type = wasm2c_#{MODULE_NAME}_get_func_type(1, 0, #{FUNC_TYPE_TABLE[:ptr]}, #{FUNC_TYPE_TABLE[:size]}),
|
||||
.func = (wasm_rt_function_ptr_t)_sbindgen_call_#{call_type_hash([:size, [:value]])},
|
||||
.func_tailcallee = {.fn = NULL},
|
||||
.module_instance = (void *)dsize,
|
||||
}));
|
||||
|
||||
((wasm_ptr_t *)(*bind + buf))[4] = dcompact == NULL ? 0 : SERIALIZE_VALUE(wasm_rt_push_funcref(&bind.instance().w2c_T0, wasm_rt_funcref_t {
|
||||
.func_type = wasm2c_#{MODULE_NAME}_get_func_type(1, 0, #{FUNC_TYPE_TABLE[:ptr]}),
|
||||
.func = (wasm_rt_function_ptr_t)_sbindgen_call_#{call_type_hash([:void, [:value]])},
|
||||
.func_tailcallee = {.fn = NULL},
|
||||
.module_instance = (void *)dcompact,
|
||||
}));
|
||||
|
||||
((wasm_ptr_t *)(*bind + buf))[5] = 0;
|
||||
((wasm_ptr_t *)(*bind + buf))[6] = SERIALIZE_VALUE(parent);
|
||||
((wasm_ptr_t *)(*bind + buf))[7] = SERIALIZE_VALUE(data);
|
||||
((wasm_ptr_t *)(*bind + buf))[8] = SERIALIZE_VALUE(flags);
|
||||
}
|
||||
((wasm_ptr_t *)(**this + buf))[5] = 0;
|
||||
((wasm_ptr_t *)(**this + buf))[6] = SERIALIZE_VALUE(parent);
|
||||
((wasm_ptr_t *)(**this + buf))[7] = SERIALIZE_VALUE(data);
|
||||
((wasm_ptr_t *)(**this + buf))[8] = SERIALIZE_VALUE(flags);
|
||||
|
||||
return buf;
|
||||
}
|
||||
new_rb_data_type::~new_rb_data_type() {
|
||||
if (str == 0 && buf != 0) bind.sandbox_free(buf);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -519,11 +494,7 @@ File.readlines('tags', chomp: true).each do |line|
|
|||
transformed_args.add(i)
|
||||
elsif !handler[:buf_size].nil?
|
||||
coroutine_initializer += <<~HEREDOC
|
||||
for (;;) {
|
||||
f#{i} = bind._sandbox_malloc(#{handler[:buf_size].gsub('PREV_ARG', "a#{i - 1}").gsub('ARG', "a#{i}")});
|
||||
if (w2c_#{MODULE_NAME}_asyncify_get_state(&bind.instance()) != 1) break;
|
||||
BOOST_ASIO_CORO_YIELD;
|
||||
}
|
||||
f#{i} = bind.sandbox_malloc(#{handler[:buf_size].gsub('PREV_ARG', "a#{i - 1}").gsub('ARG', "a#{i}")});
|
||||
if (f#{i} == 0) throw SandboxOutOfMemoryException();
|
||||
HEREDOC
|
||||
coroutine_initializer += handler[:serialize].gsub('PREV_ARG', "a#{i - 1}").gsub('ARG', "a#{i}").gsub('BUF', "f#{i}")
|
||||
|
@ -542,11 +513,7 @@ File.readlines('tags', chomp: true).each do |line|
|
|||
case func_name
|
||||
when 'rb_funcall'
|
||||
coroutine_initializer += <<~HEREDOC
|
||||
for (;;) {
|
||||
f#{args.length - 1} = bind._sandbox_malloc(a#{args.length - 2} * sizeof(VALUE));
|
||||
if (w2c_#{MODULE_NAME}_asyncify_get_state(&bind.instance()) != 1) break;
|
||||
BOOST_ASIO_CORO_YIELD;
|
||||
}
|
||||
f#{args.length - 1} = bind.sandbox_malloc(a#{args.length - 2} * sizeof(VALUE));
|
||||
if (f#{args.length - 1} == 0) throw SandboxOutOfMemoryException();
|
||||
std::va_list a;
|
||||
va_start(a, a#{args.length - 2});
|
||||
|
@ -566,11 +533,7 @@ File.readlines('tags', chomp: true).each do |line|
|
|||
n = 0;
|
||||
do ++n; while (va_arg(b, VALUE));
|
||||
va_end(b);
|
||||
for (;;) {
|
||||
f#{args.length - 1} = bind._sandbox_malloc(n * sizeof(VALUE));
|
||||
if (w2c_#{MODULE_NAME}_asyncify_get_state(&bind.instance()) != 1) break;
|
||||
BOOST_ASIO_CORO_YIELD;
|
||||
}
|
||||
f#{args.length - 1} = bind.sandbox_malloc(n * sizeof(VALUE));
|
||||
if (f#{args.length - 1} == 0) {
|
||||
va_end(a);
|
||||
throw SandboxOutOfMemoryException();
|
||||
|
@ -654,32 +617,7 @@ File.open('mkxp-sandbox-bindgen.h', 'w') do |file|
|
|||
for global_name in globals
|
||||
file.write(" inline VALUE #{global_name}() const noexcept { return *(VALUE *)(**this + instance().w2c_#{global_name}); }\n")
|
||||
end
|
||||
file.write(" };\n\n")
|
||||
declaration = <<~HEREDOC
|
||||
struct sandbox_malloc : boost::asio::coroutine {
|
||||
friend struct bindings::stack_frame_guard<struct sandbox_malloc>;
|
||||
BOOST_TYPE_INDEX_REGISTER_CLASS
|
||||
wasm_ptr_t operator()(wasm_size_t size);
|
||||
private:
|
||||
struct binding_base &bind;
|
||||
sandbox_malloc(struct binding_base &b);
|
||||
};
|
||||
|
||||
struct new_rb_data_type : boost::asio::coroutine {
|
||||
friend struct bindings::stack_frame_guard<struct new_rb_data_type>;
|
||||
BOOST_TYPE_INDEX_REGISTER_CLASS
|
||||
struct bindings::rb_data_type operator()(const char *wrap_struct_name, void (*dmark)(wasm_ptr_t), void (*dfree)(wasm_ptr_t), wasm_size_t (*dsize)(wasm_ptr_t), void (*dcompact)(wasm_ptr_t), wasm_ptr_t parent, wasm_ptr_t data, wasm_size_t flags);
|
||||
~new_rb_data_type();
|
||||
private:
|
||||
struct binding_base &bind;
|
||||
new_rb_data_type(struct binding_base &b);
|
||||
wasm_ptr_t buf;
|
||||
wasm_ptr_t str;
|
||||
};
|
||||
HEREDOC
|
||||
for line in declaration.split("\n")
|
||||
file.write(" #{line}".rstrip + "\n")
|
||||
end
|
||||
file.write(" };")
|
||||
for declaration in declarations
|
||||
file.write("\n\n" + declaration.split("\n").map { |line| " #{line}" }.join("\n").rstrip)
|
||||
end
|
||||
|
|
|
@ -115,8 +115,6 @@ if is_libretro
|
|||
'-DSHARED_FLUID',
|
||||
'-D_FILE_OFFSET_BITS=64',
|
||||
'-DMPG123_NO_LARGENAME',
|
||||
'-DPGL_PREFIX_TYPES',
|
||||
'-DPGL_PREFIX_GLSL',
|
||||
'-DGL_GLES_PROTOTYPES=0',
|
||||
]
|
||||
|
||||
|
@ -646,6 +644,7 @@ if is_libretro
|
|||
'src/filesystem/filesystem.cpp',
|
||||
'src/input/input-retro.cpp',
|
||||
'binding-sandbox/binding-base.cpp',
|
||||
'binding-sandbox/binding-util.cpp',
|
||||
'binding-sandbox/sandbox.cpp',
|
||||
'binding-sandbox/wasi.cpp',
|
||||
'binding-sandbox/wasm-rt.cpp',
|
||||
|
|
|
@ -257,7 +257,7 @@ static bool init_sandbox() {
|
|||
return std::calloc(1, sizeof(long));
|
||||
},
|
||||
.fread = [](void *buf, int count, void *handle) {
|
||||
assert(*(long *)handle + count < mkxp_gmgsx_sf2_len);
|
||||
assert((size_t)(*(long *)handle + count) < mkxp_gmgsx_sf2_len);
|
||||
std::memcpy(buf, mkxp_gmgsx_sf2 + *(long *)handle, count);
|
||||
*(long *)handle += count;
|
||||
return (int)FLUID_OK;
|
||||
|
|
Loading…
Add table
Reference in a new issue