diff --git a/binding-sandbox/audio-binding.cpp b/binding-sandbox/audio-binding.cpp index 416eb26b..8ad7334e 100644 --- a/binding-sandbox/audio-binding.cpp +++ b/binding-sandbox/audio-binding.cpp @@ -37,15 +37,15 @@ static VALUE bgm_play(int32_t argc, wasm_ptr_t argv, VALUE self) { SANDBOX_SLOT(3) = 100; SANDBOX_SLOT(5) = false; - SANDBOX_AWAIT_S(1, rb_string_value_cstr, (VALUE *)(**sb() + argv)); + SANDBOX_AWAIT_S(1, rb_string_value_cstr, &sb()->ref(argv, 0)); if (argc >= 2) { - SANDBOX_AWAIT_S(2, rb_num2int, ((VALUE *)(**sb() + argv))[1]); + SANDBOX_AWAIT_S(2, rb_num2int, sb()->ref(argv, 1)); if (argc >= 3) { - SANDBOX_AWAIT_S(3, rb_num2int, ((VALUE *)(**sb() + argv))[2]); + SANDBOX_AWAIT_S(3, rb_num2int, sb()->ref(argv, 2)); if (argc >= 4) { - SANDBOX_AWAIT_S(0, rb_num2dbl, ((VALUE *)(**sb() + argv))[3]); + SANDBOX_AWAIT_S(0, rb_num2dbl, sb()->ref(argv, 3)); if (argc >= 5) { - SANDBOX_AWAIT_S(4, rb_num2int, ((VALUE *)(**sb() + argv))[4]); + SANDBOX_AWAIT_S(4, rb_num2int, sb()->ref(argv, 4)); SANDBOX_SLOT(5) = true; } } @@ -53,9 +53,9 @@ static VALUE bgm_play(int32_t argc, wasm_ptr_t argv, VALUE self) { } if (SANDBOX_SLOT(5)) { - mkxp_retro::audio->bgmPlay((const char *)(**sb() + SANDBOX_SLOT(1)), SANDBOX_SLOT(2), SANDBOX_SLOT(3), SANDBOX_SLOT(0), SANDBOX_SLOT(4)); + mkxp_retro::audio->bgmPlay(sb()->str(SANDBOX_SLOT(1)), SANDBOX_SLOT(2), SANDBOX_SLOT(3), SANDBOX_SLOT(0), SANDBOX_SLOT(4)); } else { - mkxp_retro::audio->bgmPlay((const char *)(**sb() + SANDBOX_SLOT(1)), SANDBOX_SLOT(2), SANDBOX_SLOT(3), SANDBOX_SLOT(0)); + mkxp_retro::audio->bgmPlay(sb()->str(SANDBOX_SLOT(1)), SANDBOX_SLOT(2), SANDBOX_SLOT(3), SANDBOX_SLOT(0)); } } @@ -78,9 +78,9 @@ static VALUE bgm_fade(int32_t argc, wasm_ptr_t argv, VALUE self) { VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) { BOOST_ASIO_CORO_REENTER (this) { SANDBOX_SLOT(1) = -127; - SANDBOX_AWAIT_S(0, rb_num2int, ((VALUE *)(**sb() + argv))[0]); + SANDBOX_AWAIT_S(0, rb_num2int, sb()->ref(argv, 0)); if (argc >= 2) { - SANDBOX_AWAIT_S(1, rb_num2int, ((VALUE *)(**sb() + argv))[1]); + SANDBOX_AWAIT_S(1, rb_num2int, sb()->ref(argv, 1)); } mkxp_retro::audio->bgmFade(SANDBOX_SLOT(0), SANDBOX_SLOT(1)); } @@ -100,7 +100,7 @@ static VALUE bgm_pos(int32_t argc, wasm_ptr_t argv, VALUE self) { BOOST_ASIO_CORO_REENTER (this) { SANDBOX_SLOT(2) = -127; if (argc >= 1) { - SANDBOX_AWAIT_S(2, rb_num2int, ((VALUE *)(**sb() + argv))[0]); + SANDBOX_AWAIT_S(2, rb_num2int, sb()->ref(argv, 0)); } SANDBOX_SLOT(0) = mkxp_retro::audio->bgmPos(SANDBOX_SLOT(2)); SANDBOX_AWAIT_S(1, rb_float_new, SANDBOX_SLOT(0)); @@ -121,7 +121,7 @@ static VALUE bgm_volume(int32_t argc, wasm_ptr_t argv, VALUE self) { BOOST_ASIO_CORO_REENTER (this) { SANDBOX_SLOT(1) = -127; if (argc >= 1) { - SANDBOX_AWAIT_S(1, rb_num2int, ((VALUE *)(**sb() + argv))[0]); + SANDBOX_AWAIT_S(1, rb_num2int, sb()->ref(argv, 0)); } SANDBOX_SLOT(2) = mkxp_retro::audio->bgmGetVolume(SANDBOX_SLOT(1)); SANDBOX_AWAIT_S(0, rb_ll2inum, SANDBOX_SLOT(2)); @@ -141,9 +141,9 @@ static VALUE bgm_set_volume(int32_t argc, wasm_ptr_t argv, VALUE self) { VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) { BOOST_ASIO_CORO_REENTER (this) { SANDBOX_SLOT(1) = -127; - SANDBOX_AWAIT_S(0, rb_num2int, ((VALUE *)(**sb() + argv))[0]); + SANDBOX_AWAIT_S(0, rb_num2int, sb()->ref(argv, 0)); if (argc >= 2) { - SANDBOX_AWAIT_S(1, rb_num2int, ((VALUE *)(**sb() + argv))[1]); + SANDBOX_AWAIT_S(1, rb_num2int, sb()->ref(argv, 1)); } mkxp_retro::audio->bgmSetVolume(SANDBOX_SLOT(0), SANDBOX_SLOT(1)); } @@ -165,18 +165,18 @@ static VALUE bgs_play(int32_t argc, wasm_ptr_t argv, VALUE self) { SANDBOX_SLOT(2) = 100; SANDBOX_SLOT(3) = 100; - SANDBOX_AWAIT_S(1, rb_string_value_cstr, (VALUE *)(**sb() + argv)); + SANDBOX_AWAIT_S(1, rb_string_value_cstr, &sb()->ref(argv, 0)); if (argc >= 2) { - SANDBOX_AWAIT_S(2, rb_num2int, ((VALUE *)(**sb() + argv))[1]); + SANDBOX_AWAIT_S(2, rb_num2int, sb()->ref(argv, 1)); if (argc >= 3) { - SANDBOX_AWAIT_S(3, rb_num2int, ((VALUE *)(**sb() + argv))[2]); + SANDBOX_AWAIT_S(3, rb_num2int, sb()->ref(argv, 2)); if (argc >= 4) { - SANDBOX_AWAIT_S(0, rb_num2dbl, ((VALUE *)(**sb() + argv))[3]); + SANDBOX_AWAIT_S(0, rb_num2dbl, sb()->ref(argv, 3)); } } } - mkxp_retro::audio->bgsPlay((const char *)(**sb() + SANDBOX_SLOT(1)), SANDBOX_SLOT(2), SANDBOX_SLOT(3), SANDBOX_SLOT(0)); + mkxp_retro::audio->bgsPlay(sb()->str(SANDBOX_SLOT(1)), SANDBOX_SLOT(2), SANDBOX_SLOT(3), SANDBOX_SLOT(0)); } return SANDBOX_NIL; @@ -234,15 +234,15 @@ static VALUE me_play(int32_t argc, wasm_ptr_t argv, VALUE self) { SANDBOX_SLOT(1) = 100; SANDBOX_SLOT(2) = 100; - SANDBOX_AWAIT_S(0, rb_string_value_cstr, (VALUE *)(**sb() + argv)); + SANDBOX_AWAIT_S(0, rb_string_value_cstr, &sb()->ref(argv, 0)); if (argc >= 2) { - SANDBOX_AWAIT_S(1, rb_num2int, ((VALUE *)(**sb() + argv))[1]); + SANDBOX_AWAIT_S(1, rb_num2int, sb()->ref(argv, 1)); if (argc >= 3) { - SANDBOX_AWAIT_S(2, rb_num2int, ((VALUE *)(**sb() + argv))[2]); + SANDBOX_AWAIT_S(2, rb_num2int, sb()->ref(argv, 2)); } } - mkxp_retro::audio->mePlay((const char *)(**sb() + SANDBOX_SLOT(0)), SANDBOX_SLOT(1), SANDBOX_SLOT(2)); + mkxp_retro::audio->mePlay(sb()->str(SANDBOX_SLOT(0)), SANDBOX_SLOT(1), SANDBOX_SLOT(2)); } return SANDBOX_NIL; @@ -283,15 +283,15 @@ static VALUE se_play(int32_t argc, wasm_ptr_t argv, VALUE self) { SANDBOX_SLOT(1) = 100; SANDBOX_SLOT(2) = 100; - SANDBOX_AWAIT_S(0, rb_string_value_cstr, (VALUE *)(**sb() + argv)); + SANDBOX_AWAIT_S(0, rb_string_value_cstr, &sb()->ref(argv, 0)); if (argc >= 2) { - SANDBOX_AWAIT_S(1, rb_num2int, ((VALUE *)(**sb() + argv))[1]); + SANDBOX_AWAIT_S(1, rb_num2int, sb()->ref(argv, 1)); if (argc >= 3) { - SANDBOX_AWAIT_S(2, rb_num2int, ((VALUE *)(**sb() + argv))[2]); + SANDBOX_AWAIT_S(2, rb_num2int, sb()->ref(argv, 2)); } } - mkxp_retro::audio->sePlay((const char *)(**sb() + SANDBOX_SLOT(0)), SANDBOX_SLOT(1), SANDBOX_SLOT(2)); + mkxp_retro::audio->sePlay(sb()->str(SANDBOX_SLOT(0)), SANDBOX_SLOT(1), SANDBOX_SLOT(2)); } return SANDBOX_NIL; diff --git a/binding-sandbox/binding-base.cpp b/binding-sandbox/binding-base.cpp index f2ca9f79..1ad0c64c 100644 --- a/binding-sandbox/binding-base.cpp +++ b/binding-sandbox/binding-base.cpp @@ -71,14 +71,6 @@ struct w2c_ruby &binding_base::instance() const noexcept { return *_instance; } -uint8_t *binding_base::get() const noexcept { - return instance().w2c_memory.data; -} - -uint8_t *binding_base::operator*() const noexcept { - return get(); -} - wasm_ptr_t binding_base::sandbox_malloc(wasm_size_t size) { wasm_ptr_t buf = w2c_ruby_mkxp_sandbox_malloc(&instance(), size); diff --git a/binding-sandbox/binding-base.h b/binding-sandbox/binding-base.h index 1d508626..5cc59440 100644 --- a/binding-sandbox/binding-base.h +++ b/binding-sandbox/binding-base.h @@ -37,20 +37,6 @@ #include #include "types.h" -#ifdef MKXPZ_BIG_ENDIAN -# define SERIALIZE_32(value) __builtin_bswap32(value) -# define SERIALIZE_64(value) __builtin_bswap64(value) -#else -# define SERIALIZE_32(value) (value) -# define SERIALIZE_64(value) (value) -#endif - -#ifdef MKXPZ_RETRO_MEMORY64 -# define SERIALIZE_VALUE(value) SERIALIZE_64(value) -#else -# define SERIALIZE_VALUE(value) SERIALIZE_32(value) -#endif - // LLVM uses a stack alignment of 16 on WebAssembly targets #define WASMSTACKALIGN 16 @@ -190,8 +176,6 @@ namespace mkxp_sandbox { binding_base(std::shared_ptr m); ~binding_base(); struct w2c_ruby &instance() const noexcept; - uint8_t *get() const noexcept; - uint8_t *operator*() const noexcept; wasm_ptr_t sandbox_malloc(wasm_size_t); void sandbox_free(wasm_ptr_t ptr); wasm_ptr_t rtypeddata_data(VALUE obj) const noexcept; @@ -200,6 +184,53 @@ namespace mkxp_sandbox { wasm_size_t rtypeddata_dsize(wasm_ptr_t data, wasm_ptr_t ptr); void rtypeddata_dcompact(wasm_ptr_t data, wasm_ptr_t ptr); + // Gets a pointer to the given address in sandbox memory. + void *ptr(wasm_ptr_t address) const noexcept { +#ifdef MKXPZ_BIG_ENDIAN + return instance().w2c_memory.data + instance().w2c_memory.size - address; +#else + return instance().w2c_memory.data + address; +#endif // MKXPZ_BIG_ENDIAN + } + + // Gets a reference to the value stored at a given address in sandbox memory. + template T &ref(wasm_ptr_t address) const noexcept { + // TODO: require T to be numeric +#ifdef MKXPZ_BIG_ENDIAN + return *(T *)(ptr(address) - sizeof(T)); +#else + return *(T *)ptr(address); +#endif // MKXPZ_BIG_ENDIAN + } + + // Gets a reference to the value stored at the given index in the array at a given address in sandbox memory. + template T &ref(wasm_ptr_t array_address, wasm_size_t array_index) const noexcept { + return ref(array_address + array_index * sizeof(T)); + } + + // Gets a string stored at a given address in sandbox memory. + // The returned string doesn't need to be freed but only lives until the next call to this function, + // so you need to store the returned string in a buffer somewhere if you need to get more than one. + const char *str(wasm_ptr_t address) { +#ifdef MKXPZ_BIG_ENDIAN + static std::string buf; + buf.clear(); + const char *s = (const char *)ptr(address); + const char *t = s; + wasm_size_t n = -1; + while (*--s) { + ++n; + } + buf.reserve(n); + while (*--t) { + buf.push_back(*t); + } + return buf.c_str(); +#else + return (const char *)ptr(address); +#endif // MKXPZ_BIG_ENDIAN + } + template struct stack_frame_guard { static_assert(std::is_base_of::value, "`T` must be a subclass of `boost::asio::coroutine`"); friend struct binding_base; @@ -215,9 +246,9 @@ namespace mkxp_sandbox { static struct fiber &init_fiber(struct binding_base &bind) { key_t key = { - *(wasm_ptr_t *)(*bind + bind.instance().w2c_mkxp_sandbox_fiber_entry_point), - *(wasm_ptr_t *)(*bind + bind.instance().w2c_mkxp_sandbox_fiber_arg0), - *(wasm_ptr_t *)(*bind + bind.instance().w2c_mkxp_sandbox_fiber_arg1), + bind.ref(bind.instance().w2c_mkxp_sandbox_fiber_entry_point), + bind.ref(bind.instance().w2c_mkxp_sandbox_fiber_arg0), + bind.ref(bind.instance().w2c_mkxp_sandbox_fiber_arg1), }; if (bind.fibers.count(key) == 0) { bind.fibers[key] = (struct fiber){.key = key}; @@ -335,8 +366,4 @@ namespace mkxp_sandbox { }; } -#undef SERIALIZE_32 -#undef SERIALIZE_64 -#undef SERIALIZE_VALUE - #endif // MKXPZ_SANDBOX_BINDING_BASE diff --git a/binding-sandbox/binding-sandbox.cpp b/binding-sandbox/binding-sandbox.cpp index 7cf656ea..4ba51c26 100644 --- a/binding-sandbox/binding-sandbox.cpp +++ b/binding-sandbox/binding-sandbox.cpp @@ -104,7 +104,7 @@ struct run_rmxp_scripts : boost::asio::coroutine { zlib_result = uncompress( sb().script_decode_buffer.data(), &buffer_len, - (unsigned char *)(**sb() + SANDBOX_SLOT(6)), + (const unsigned char *)sb()->str(SANDBOX_SLOT(6)), SANDBOX_SLOT(7) ); sb().script_decode_buffer[buffer_len] = 0; @@ -121,7 +121,7 @@ struct run_rmxp_scripts : boost::asio::coroutine { } if (zlib_result != Z_OK) { - mkxp_retro::log_printf(RETRO_LOG_ERROR, "Error decoding script %zu: '%s'\n", SANDBOX_SLOT(3), **sb() + SANDBOX_SLOT(5)); + mkxp_retro::log_printf(RETRO_LOG_ERROR, "Error decoding script %zu: '%s'\n", SANDBOX_SLOT(3), sb()->str(SANDBOX_SLOT(5))); break; } } @@ -164,7 +164,7 @@ static VALUE load_data(VALUE self, VALUE path) { VALUE operator()(VALUE path) { BOOST_ASIO_CORO_REENTER (this) { SANDBOX_AWAIT_S(0, rb_string_value_cstr, &path); - SANDBOX_AWAIT_S(1, rb_file_open, (const char *)(**sb() + SANDBOX_SLOT(0)), "rb"); + SANDBOX_AWAIT_S(1, rb_file_open, sb()->str(SANDBOX_SLOT(0)), "rb"); SANDBOX_AWAIT_S(2, rb_marshal_load, SANDBOX_SLOT(1)); SANDBOX_AWAIT(rb_io_close, SANDBOX_SLOT(1)); } diff --git a/binding-sandbox/binding-util.cpp b/binding-sandbox/binding-util.cpp index 70e1bbc0..36001470 100644 --- a/binding-sandbox/binding-util.cpp +++ b/binding-sandbox/binding-util.cpp @@ -34,15 +34,15 @@ void mkxp_sandbox::set_private_data(VALUE obj, void *ptr) { wasm_ptr_t 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)); - *(wasm_ptr_t *)(**sb() + data) = 0; + if (sb()->ref(data) != 0 && sb()->ref(sb()->ref(data)) != ptr) { + sb()->rtypeddata_dfree(obj, sb()->ref(data)); + sb()->ref(data) = 0; } - if (*(wasm_ptr_t *)(**sb() + data) == 0) { + if (sb()->ref(data) == 0) { wasm_ptr_t buf = sb()->sandbox_malloc(sizeof(void *)); - *(void **)(**sb() + buf) = ptr; - *(wasm_ptr_t *)(**sb() + data) = buf; + sb()->ref(buf) = ptr; + sb()->ref(data) = buf; } } @@ -85,6 +85,6 @@ void log_backtrace::operator()(VALUE exception) { SANDBOX_AWAIT_S(2, rb_str_new_cstr, "\n\t"); SANDBOX_AWAIT_S(1, rb_funcall, SANDBOX_SLOT(1), SANDBOX_SLOT(0), 1, SANDBOX_SLOT(2)); SANDBOX_AWAIT_S(3, rb_string_value_cstr, &SANDBOX_SLOT(1)); - mkxp_retro::log_printf(RETRO_LOG_ERROR, "%s\n", **sb() + SANDBOX_SLOT(3)); + mkxp_retro::log_printf(RETRO_LOG_ERROR, "%s\n", sb()->str(SANDBOX_SLOT(3))); } } diff --git a/binding-sandbox/binding-util.h b/binding-sandbox/binding-util.h index 3337ea44..fa3e8519 100644 --- a/binding-sandbox/binding-util.h +++ b/binding-sandbox/binding-util.h @@ -29,7 +29,7 @@ #define GFX_GUARD_EXC(exp) exp -#define SANDBOX_SLOT(slot_index) (*(typename ::mkxp_sandbox::slot_type<(slot_index), slots>::type *)(**::mkxp_sandbox::sb() + ::mkxp_sandbox::sb()->stack_pointer() + ::mkxp_sandbox::slot_offset<(slot_index), slots>::value)) +#define SANDBOX_SLOT(slot_index) (::mkxp_sandbox::sb()->ref::type>(::mkxp_sandbox::sb()->stack_pointer() + ::mkxp_sandbox::slot_offset<(slot_index), slots>::value)) #define SANDBOX_AWAIT(coroutine, ...) \ do { \ @@ -103,7 +103,7 @@ namespace mkxp_sandbox { template void dfree(wasm_ptr_t buf) { - delete *(T **)(**sb() + buf); + delete sb()->ref(buf); sb()->sandbox_free(buf); } } @@ -439,7 +439,7 @@ namespace mkxp_sandbox { // Given Ruby typed data `obj`, retrieves the private data field of `obj`. template inline T *get_private_data(VALUE obj) { - return *(T **)(**sb() + *(wasm_ptr_t *)(**sb() + sb()->rtypeddata_data(obj))); + return sb()->ref(sb()->ref(sb()->rtypeddata_data(obj))); } // Gets the length of a Ruby object. diff --git a/binding-sandbox/bitmap-binding.cpp b/binding-sandbox/bitmap-binding.cpp index 4845769b..88902758 100644 --- a/binding-sandbox/bitmap-binding.cpp +++ b/binding-sandbox/bitmap-binding.cpp @@ -58,16 +58,16 @@ static VALUE initialize(int32_t argc, wasm_ptr_t argv, VALUE self) { VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) { BOOST_ASIO_CORO_REENTER (this) { if (argc == 1) { - SANDBOX_AWAIT_S(0, rb_string_value_cstr, (VALUE *)(**sb() + argv)); + SANDBOX_AWAIT_S(0, rb_string_value_cstr, &sb()->ref(argv, 0)); } else { - SANDBOX_AWAIT_S(1, rb_num2ulong, ((VALUE *)(**sb() + argv))[0]); - SANDBOX_AWAIT_S(2, rb_num2ulong, ((VALUE *)(**sb() + argv))[1]); + SANDBOX_AWAIT_S(1, rb_num2ulong, sb()->ref(argv, 0)); + SANDBOX_AWAIT_S(2, rb_num2ulong, sb()->ref(argv, 1)); } { Bitmap *bitmap; if (argc == 1) { - GFX_GUARD_EXC(bitmap = new Bitmap((const char *)(**sb() + SANDBOX_SLOT(0)));) + GFX_GUARD_EXC(bitmap = new Bitmap(sb()->str(SANDBOX_SLOT(0)));) } else { GFX_GUARD_EXC(bitmap = new Bitmap(SANDBOX_SLOT(1), SANDBOX_SLOT(2));) } @@ -145,12 +145,12 @@ static VALUE blt(int32_t argc, wasm_ptr_t argv, VALUE self) { VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) { BOOST_ASIO_CORO_REENTER (this) { // TODO: require at least 4 arguments - SANDBOX_AWAIT_S(2, rb_num2int, ((VALUE *)(**sb() + argv))[0]); - SANDBOX_AWAIT_S(3, rb_num2int, ((VALUE *)(**sb() + argv))[1]); - SANDBOX_SLOT(0) = ((VALUE *)(**sb() + argv))[2]; - SANDBOX_SLOT(1) = ((VALUE *)(**sb() + argv))[3]; + SANDBOX_AWAIT_S(2, rb_num2int, sb()->ref(argv, 0)); + SANDBOX_AWAIT_S(3, rb_num2int, sb()->ref(argv, 1)); + SANDBOX_SLOT(0) = sb()->ref(argv, 2); + SANDBOX_SLOT(1) = sb()->ref(argv, 3); if (argc > 4) { - SANDBOX_AWAIT_S(4, rb_num2int, ((VALUE *)(**sb() + argv))[4]); + SANDBOX_AWAIT_S(4, rb_num2int, sb()->ref(argv, 4)); } Bitmap *src = get_private_data(SANDBOX_SLOT(0)); @@ -177,11 +177,11 @@ static VALUE stretch_blt(int32_t argc, wasm_ptr_t argv, VALUE self) { VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) { BOOST_ASIO_CORO_REENTER (this) { - SANDBOX_SLOT(0) = ((VALUE *)(**sb() + argv))[0]; - SANDBOX_SLOT(1) = ((VALUE *)(**sb() + argv))[1]; - SANDBOX_SLOT(2) = ((VALUE *)(**sb() + argv))[2]; + SANDBOX_SLOT(0) = sb()->ref(argv, 0); + SANDBOX_SLOT(1) = sb()->ref(argv, 1); + SANDBOX_SLOT(2) = sb()->ref(argv, 2); if (argc > 3) { - SANDBOX_AWAIT_S(3, rb_num2int, ((VALUE *)(**sb() + argv))[3]); + SANDBOX_AWAIT_S(3, rb_num2int, sb()->ref(argv, 3)); } Bitmap *src = get_private_data(SANDBOX_SLOT(1)); @@ -211,14 +211,14 @@ static VALUE fill_rect(int32_t argc, wasm_ptr_t argv, VALUE self) { BOOST_ASIO_CORO_REENTER (this) { if (argc == 2) { Bitmap *bitmap = get_private_data(self); - GFX_GUARD_EXC(bitmap->fillRect(get_private_data(((VALUE *)(**sb() + argv))[0])->toIntRect(), get_private_data(((VALUE *)(**sb() + argv))[1])->norm);) + GFX_GUARD_EXC(bitmap->fillRect(get_private_data(sb()->ref(argv, 0))->toIntRect(), get_private_data(sb()->ref(argv, 1))->norm);) } else { - SANDBOX_AWAIT_S(0, rb_num2int, ((VALUE *)(**sb() + argv))[0]); - SANDBOX_AWAIT_S(1, rb_num2int, ((VALUE *)(**sb() + argv))[1]); - SANDBOX_AWAIT_S(2, rb_num2int, ((VALUE *)(**sb() + argv))[2]); - SANDBOX_AWAIT_S(3, rb_num2int, ((VALUE *)(**sb() + argv))[3]); + SANDBOX_AWAIT_S(0, rb_num2int, sb()->ref(argv, 0)); + SANDBOX_AWAIT_S(1, rb_num2int, sb()->ref(argv, 1)); + SANDBOX_AWAIT_S(2, rb_num2int, sb()->ref(argv, 2)); + SANDBOX_AWAIT_S(3, rb_num2int, sb()->ref(argv, 3)); Bitmap *bitmap = get_private_data(self); - GFX_GUARD_EXC(bitmap->fillRect(SANDBOX_SLOT(0), SANDBOX_SLOT(1), SANDBOX_SLOT(2), SANDBOX_SLOT(3), get_private_data(((VALUE *)(**sb() + argv))[4])->norm);) + GFX_GUARD_EXC(bitmap->fillRect(SANDBOX_SLOT(0), SANDBOX_SLOT(1), SANDBOX_SLOT(2), SANDBOX_SLOT(3), get_private_data(sb()->ref(argv, 4))->norm);) } } @@ -319,33 +319,33 @@ static VALUE draw_text(int32_t argc, wasm_ptr_t argv, VALUE self) { BOOST_ASIO_CORO_REENTER (this) { if (argc == 2 || argc == 3) { if (rgssVer >= 2) { - SANDBOX_AWAIT_S(1, rb_obj_as_string, ((VALUE *)(**sb() + argv))[1]); + SANDBOX_AWAIT_S(1, rb_obj_as_string, sb()->ref(argv, 1)); SANDBOX_AWAIT_S(0, rb_string_value_cstr, &SANDBOX_SLOT(1)); } else { - SANDBOX_AWAIT_S(0, rb_string_value_cstr, (VALUE *)(**sb() + argv) + 1); + SANDBOX_AWAIT_S(0, rb_string_value_cstr, &sb()->ref(argv, 1)); } if (argc == 2) { - GFX_GUARD_EXC(get_private_data(self)->drawText(get_private_data(((VALUE *)(**sb() + argv))[0])->toIntRect(), (const char *)(**sb() + SANDBOX_SLOT(0)));); + GFX_GUARD_EXC(get_private_data(self)->drawText(get_private_data(sb()->ref(argv, 0))->toIntRect(), sb()->str(SANDBOX_SLOT(0)));); } else { - SANDBOX_AWAIT_S(2, rb_num2int, ((VALUE *)(**sb() + argv))[2]); - GFX_GUARD_EXC(get_private_data(self)->drawText(get_private_data(((VALUE *)(**sb() + argv))[0])->toIntRect(), (const char *)(**sb() + SANDBOX_SLOT(0)), SANDBOX_SLOT(2));); + SANDBOX_AWAIT_S(2, rb_num2int, sb()->ref(argv, 2)); + GFX_GUARD_EXC(get_private_data(self)->drawText(get_private_data(sb()->ref(argv, 0))->toIntRect(), sb()->str(SANDBOX_SLOT(0)), SANDBOX_SLOT(2));); } } else { - SANDBOX_AWAIT_S(3, rb_num2int, ((VALUE *)(**sb() + argv))[0]); - SANDBOX_AWAIT_S(4, rb_num2int, ((VALUE *)(**sb() + argv))[1]); - SANDBOX_AWAIT_S(5, rb_num2int, ((VALUE *)(**sb() + argv))[2]); - SANDBOX_AWAIT_S(6, rb_num2int, ((VALUE *)(**sb() + argv))[3]); + SANDBOX_AWAIT_S(3, rb_num2int, sb()->ref(argv, 0)); + SANDBOX_AWAIT_S(4, rb_num2int, sb()->ref(argv, 1)); + SANDBOX_AWAIT_S(5, rb_num2int, sb()->ref(argv, 2)); + SANDBOX_AWAIT_S(6, rb_num2int, sb()->ref(argv, 3)); if (rgssVer >= 2) { - SANDBOX_AWAIT_S(1, rb_obj_as_string, ((VALUE *)(**sb() + argv))[4]); + SANDBOX_AWAIT_S(1, rb_obj_as_string, sb()->ref(argv, 4)); SANDBOX_AWAIT_S(0, rb_string_value_cstr, &SANDBOX_SLOT(1)); } else { - SANDBOX_AWAIT_S(0, rb_string_value_cstr, (VALUE *)(**sb() + argv) + 4); + SANDBOX_AWAIT_S(0, rb_string_value_cstr, &sb()->ref(argv, 4)); } if (argc < 6) { - GFX_GUARD_EXC(get_private_data(self)->drawText(SANDBOX_SLOT(3), SANDBOX_SLOT(4), SANDBOX_SLOT(5), SANDBOX_SLOT(6), (const char *)(**sb() + SANDBOX_SLOT(0)));); + GFX_GUARD_EXC(get_private_data(self)->drawText(SANDBOX_SLOT(3), SANDBOX_SLOT(4), SANDBOX_SLOT(5), SANDBOX_SLOT(6), sb()->str(SANDBOX_SLOT(0)));); } else { - SANDBOX_AWAIT_S(2, rb_num2int, ((VALUE *)(**sb() + argv))[5]); - GFX_GUARD_EXC(get_private_data(self)->drawText(SANDBOX_SLOT(3), SANDBOX_SLOT(4), SANDBOX_SLOT(5), SANDBOX_SLOT(6), (const char *)(**sb() + SANDBOX_SLOT(0)), SANDBOX_SLOT(2));); + SANDBOX_AWAIT_S(2, rb_num2int, sb()->ref(argv, 5)); + GFX_GUARD_EXC(get_private_data(self)->drawText(SANDBOX_SLOT(3), SANDBOX_SLOT(4), SANDBOX_SLOT(5), SANDBOX_SLOT(6), sb()->str(SANDBOX_SLOT(0)), SANDBOX_SLOT(2));); } } } @@ -370,7 +370,7 @@ static VALUE text_size(VALUE self, VALUE text) { SANDBOX_AWAIT_S(0, rb_string_value_cstr, &text); } SANDBOX_AWAIT_S(1, rb_obj_alloc, rect_class); - set_private_data(SANDBOX_SLOT(1), new Rect(get_private_data(self)->textSize((const char *)(**sb() + SANDBOX_SLOT(0))))); + set_private_data(SANDBOX_SLOT(1), new Rect(get_private_data(self)->textSize(sb()->str(SANDBOX_SLOT(0))))); } return SANDBOX_SLOT(1); @@ -392,7 +392,7 @@ static VALUE get_raw_data(VALUE self) { SANDBOX_AWAIT_S(1, rb_str_new_cstr, ""); SANDBOX_AWAIT(rb_str_resize, SANDBOX_SLOT(1), size); SANDBOX_AWAIT_S(0, rb_string_value_ptr, &SANDBOX_SLOT(1)); - GFX_GUARD_EXC(bitmap->getRaw(**sb() + SANDBOX_SLOT(0), size);); + GFX_GUARD_EXC(bitmap->getRaw(sb()->ptr(SANDBOX_SLOT(0)), size);); } return SANDBOX_SLOT(1); @@ -411,7 +411,7 @@ static VALUE set_raw_data(VALUE self, VALUE value) { SANDBOX_AWAIT_S(0, rb_string_value_ptr, &value); SANDBOX_AWAIT_S(1, get_bytesize, value); Bitmap *bitmap = get_private_data(self); - GFX_GUARD_EXC(bitmap->replaceRaw(**sb() + SANDBOX_SLOT(0), SANDBOX_SLOT(1));); + GFX_GUARD_EXC(bitmap->replaceRaw(sb()->ptr(SANDBOX_SLOT(0)), SANDBOX_SLOT(1));); } return self; @@ -429,7 +429,7 @@ static VALUE to_file(VALUE self, VALUE value) { BOOST_ASIO_CORO_REENTER (this) { SANDBOX_AWAIT_S(0, rb_string_value_cstr, &value); Bitmap *bitmap = get_private_data(self); - GFX_GUARD_EXC(bitmap->saveToFile((const char *)(**sb() + SANDBOX_SLOT(0)));); + GFX_GUARD_EXC(bitmap->saveToFile(sb()->str(SANDBOX_SLOT(0)));); } return SANDBOX_NIL; @@ -449,7 +449,7 @@ static VALUE snap_to_bitmap(int32_t argc, wasm_ptr_t argv, VALUE self) { if (argc < 1) { SANDBOX_SLOT(1) = -1; } else { - SANDBOX_AWAIT_S(1, rb_num2int, ((VALUE *)(**sb() + argv))[0]); + SANDBOX_AWAIT_S(1, rb_num2int, sb()->ref(argv, 0)); } SANDBOX_AWAIT_S(0, rb_obj_alloc, bitmap_class); @@ -478,22 +478,22 @@ static VALUE gradient_fill_rect(int32_t argc, wasm_ptr_t argv, VALUE self) { BOOST_ASIO_CORO_REENTER (this) { if (argc == 3 || argc == 4) { if (argc == 4) { - SANDBOX_SLOT(4) = SANDBOX_VALUE_TO_BOOL(((VALUE *)(**sb() + argv))[3]); + SANDBOX_SLOT(4) = SANDBOX_VALUE_TO_BOOL(sb()->ref(argv, 3)); } else { SANDBOX_SLOT(4) = false; } - GFX_GUARD_EXC(get_private_data(self)->gradientFillRect(get_private_data(((VALUE *)(**sb() + argv))[0])->toIntRect(), get_private_data(((VALUE *)(**sb() + argv))[1])->norm, get_private_data(((VALUE *)(**sb() + argv))[2])->norm, SANDBOX_SLOT(4));); + GFX_GUARD_EXC(get_private_data(self)->gradientFillRect(get_private_data(sb()->ref(argv, 0))->toIntRect(), get_private_data(sb()->ref(argv, 1))->norm, get_private_data(sb()->ref(argv, 2))->norm, SANDBOX_SLOT(4));); } else { - SANDBOX_AWAIT_S(0, rb_num2int, ((VALUE *)(**sb() + argv))[0]); - SANDBOX_AWAIT_S(1, rb_num2int, ((VALUE *)(**sb() + argv))[1]); - SANDBOX_AWAIT_S(2, rb_num2int, ((VALUE *)(**sb() + argv))[2]); - SANDBOX_AWAIT_S(3, rb_num2int, ((VALUE *)(**sb() + argv))[3]); + SANDBOX_AWAIT_S(0, rb_num2int, sb()->ref(argv, 0)); + SANDBOX_AWAIT_S(1, rb_num2int, sb()->ref(argv, 1)); + SANDBOX_AWAIT_S(2, rb_num2int, sb()->ref(argv, 2)); + SANDBOX_AWAIT_S(3, rb_num2int, sb()->ref(argv, 3)); if (argc >= 7) { - SANDBOX_SLOT(4) = SANDBOX_VALUE_TO_BOOL(((VALUE *)(**sb() + argv))[6]); + SANDBOX_SLOT(4) = SANDBOX_VALUE_TO_BOOL(sb()->ref(argv, 6)); } else { SANDBOX_SLOT(4) = false; } - GFX_GUARD_EXC(get_private_data(self)->gradientFillRect(SANDBOX_SLOT(0), SANDBOX_SLOT(1), SANDBOX_SLOT(2), SANDBOX_SLOT(3), get_private_data(((VALUE *)(**sb() + argv))[4])->norm, get_private_data(((VALUE *)(**sb() + argv))[5])->norm, SANDBOX_SLOT(4));); + GFX_GUARD_EXC(get_private_data(self)->gradientFillRect(SANDBOX_SLOT(0), SANDBOX_SLOT(1), SANDBOX_SLOT(2), SANDBOX_SLOT(3), get_private_data(sb()->ref(argv, 4))->norm, get_private_data(sb()->ref(argv, 5))->norm, SANDBOX_SLOT(4));); } } @@ -511,12 +511,12 @@ static VALUE clear_rect(int32_t argc, wasm_ptr_t argv, VALUE self) { VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) { BOOST_ASIO_CORO_REENTER (this) { if (argc == 1) { - GFX_GUARD_EXC(get_private_data(self)->clearRect(get_private_data(((VALUE *)(**sb() + argv))[0])->toIntRect());); + GFX_GUARD_EXC(get_private_data(self)->clearRect(get_private_data(sb()->ref(argv, 0))->toIntRect());); } else { - SANDBOX_AWAIT_S(0, rb_num2int, ((VALUE *)(**sb() + argv))[0]); - SANDBOX_AWAIT_S(1, rb_num2int, ((VALUE *)(**sb() + argv))[1]); - SANDBOX_AWAIT_S(2, rb_num2int, ((VALUE *)(**sb() + argv))[2]); - SANDBOX_AWAIT_S(3, rb_num2int, ((VALUE *)(**sb() + argv))[3]); + SANDBOX_AWAIT_S(0, rb_num2int, sb()->ref(argv, 0)); + SANDBOX_AWAIT_S(1, rb_num2int, sb()->ref(argv, 1)); + SANDBOX_AWAIT_S(2, rb_num2int, sb()->ref(argv, 2)); + SANDBOX_AWAIT_S(3, rb_num2int, sb()->ref(argv, 3)); GFX_GUARD_EXC(get_private_data(self)->clearRect(SANDBOX_SLOT(0), SANDBOX_SLOT(1), SANDBOX_SLOT(2), SANDBOX_SLOT(3));); } } @@ -637,13 +637,13 @@ static VALUE add_frame(int32_t argc, wasm_ptr_t argv, VALUE self) { if (argc < 2) { SANDBOX_SLOT(1) = -1; } else { - SANDBOX_AWAIT_S(1, rb_num2int, ((VALUE *)(**sb() + argv))[1]); + SANDBOX_AWAIT_S(1, rb_num2int, sb()->ref(argv, 1)); if (SANDBOX_SLOT(1) < 0) { SANDBOX_SLOT(1) = 0; } } if (argc >= 1) { - Bitmap *src = get_private_data(((VALUE *)(**sb() + argv))[0]); + Bitmap *src = get_private_data(sb()->ref(argv, 0)); Bitmap *b = get_private_data(self); GFX_GUARD_EXC(SANDBOX_SLOT(1) = b->addFrame(*src, SANDBOX_SLOT(1));); } @@ -666,7 +666,7 @@ static VALUE remove_frame(int32_t argc, wasm_ptr_t argv, VALUE self) { if (argc < 2) { SANDBOX_SLOT(0) = -1; } else { - SANDBOX_AWAIT_S(0, rb_num2int, ((VALUE *)(**sb() + argv))[0]); + SANDBOX_AWAIT_S(0, rb_num2int, sb()->ref(argv, 0)); if (SANDBOX_SLOT(0) < 0) { SANDBOX_SLOT(0) = 0; } diff --git a/binding-sandbox/etc-binding.cpp b/binding-sandbox/etc-binding.cpp index dbc569fb..71641d01 100644 --- a/binding-sandbox/etc-binding.cpp +++ b/binding-sandbox/etc-binding.cpp @@ -47,13 +47,13 @@ struct color_binding_init : boost::asio::coroutine { set_private_data(self, new Color); } else { // TODO: make these optional - SANDBOX_AWAIT_S(0, rb_num2dbl, ((VALUE *)(**sb() + argv))[0]); - SANDBOX_AWAIT_S(1, rb_num2dbl, ((VALUE *)(**sb() + argv))[1]); - SANDBOX_AWAIT_S(2, rb_num2dbl, ((VALUE *)(**sb() + argv))[2]); + SANDBOX_AWAIT_S(0, rb_num2dbl, sb()->ref(argv, 0)); + SANDBOX_AWAIT_S(1, rb_num2dbl, sb()->ref(argv, 1)); + SANDBOX_AWAIT_S(2, rb_num2dbl, sb()->ref(argv, 2)); if (argc <= 3) { set_private_data(self, new Color(SANDBOX_SLOT(0), SANDBOX_SLOT(1), SANDBOX_SLOT(2))); } else { - SANDBOX_AWAIT_S(3, rb_num2dbl, ((VALUE *)(**sb() + argv))[3]); + SANDBOX_AWAIT_S(3, rb_num2dbl, sb()->ref(argv, 3)); set_private_data(self, new Color(SANDBOX_SLOT(0), SANDBOX_SLOT(1), SANDBOX_SLOT(2), SANDBOX_SLOT(3))); } } @@ -90,16 +90,16 @@ struct color_binding_init : boost::asio::coroutine { VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) { BOOST_ASIO_CORO_REENTER (this) { if (argc == 1) { - *get_private_data(self) = *get_private_data(((VALUE *)(**sb() + argv))[0]); + *get_private_data(self) = *get_private_data(sb()->ref(argv, 0)); } else { // TODO: make these optional - SANDBOX_AWAIT_S(0, rb_num2dbl, ((VALUE *)(**sb() + argv))[0]); - SANDBOX_AWAIT_S(1, rb_num2dbl, ((VALUE *)(**sb() + argv))[1]); - SANDBOX_AWAIT_S(2, rb_num2dbl, ((VALUE *)(**sb() + argv))[2]); + SANDBOX_AWAIT_S(0, rb_num2dbl, sb()->ref(argv, 0)); + SANDBOX_AWAIT_S(1, rb_num2dbl, sb()->ref(argv, 1)); + SANDBOX_AWAIT_S(2, rb_num2dbl, sb()->ref(argv, 2)); if (argc <= 3) { SANDBOX_SLOT(3) = 255; } else { - SANDBOX_AWAIT_S(3, rb_num2dbl, ((VALUE *)(**sb() + argv))[3]); + SANDBOX_AWAIT_S(3, rb_num2dbl, sb()->ref(argv, 3)); } get_private_data(self)->set(SANDBOX_SLOT(0), SANDBOX_SLOT(1), SANDBOX_SLOT(2), SANDBOX_SLOT(3)); } @@ -180,13 +180,13 @@ struct tone_binding_init : boost::asio::coroutine { set_private_data(self, new Tone); } else { // TODO: make these optional - SANDBOX_AWAIT_S(0, rb_num2dbl, ((VALUE *)(**sb() + argv))[0]); - SANDBOX_AWAIT_S(1, rb_num2dbl, ((VALUE *)(**sb() + argv))[1]); - SANDBOX_AWAIT_S(2, rb_num2dbl, ((VALUE *)(**sb() + argv))[2]); + SANDBOX_AWAIT_S(0, rb_num2dbl, sb()->ref(argv, 0)); + SANDBOX_AWAIT_S(1, rb_num2dbl, sb()->ref(argv, 1)); + SANDBOX_AWAIT_S(2, rb_num2dbl, sb()->ref(argv, 2)); if (argc <= 3) { set_private_data(self, new Tone(SANDBOX_SLOT(0), SANDBOX_SLOT(1), SANDBOX_SLOT(2))); } else { - SANDBOX_AWAIT_S(3, rb_num2dbl, ((VALUE *)(**sb() + argv))[3]); + SANDBOX_AWAIT_S(3, rb_num2dbl, sb()->ref(argv, 3)); set_private_data(self, new Tone(SANDBOX_SLOT(0), SANDBOX_SLOT(1), SANDBOX_SLOT(2), SANDBOX_SLOT(3))); } } @@ -223,16 +223,16 @@ struct tone_binding_init : boost::asio::coroutine { VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) { BOOST_ASIO_CORO_REENTER (this) { if (argc == 1) { - *get_private_data(self) = *get_private_data(((VALUE *)(**sb() + argv))[0]); + *get_private_data(self) = *get_private_data(sb()->ref(argv, 0)); } else { // TODO: make these optional - SANDBOX_AWAIT_S(0, rb_num2dbl, ((VALUE *)(**sb() + argv))[0]); - SANDBOX_AWAIT_S(1, rb_num2dbl, ((VALUE *)(**sb() + argv))[1]); - SANDBOX_AWAIT_S(2, rb_num2dbl, ((VALUE *)(**sb() + argv))[2]); + SANDBOX_AWAIT_S(0, rb_num2dbl, sb()->ref(argv, 0)); + SANDBOX_AWAIT_S(1, rb_num2dbl, sb()->ref(argv, 1)); + SANDBOX_AWAIT_S(2, rb_num2dbl, sb()->ref(argv, 2)); if (argc <= 3) { SANDBOX_SLOT(3) = 0; } else { - SANDBOX_AWAIT_S(3, rb_num2dbl, ((VALUE *)(**sb() + argv))[3]); + SANDBOX_AWAIT_S(3, rb_num2dbl, sb()->ref(argv, 3)); } get_private_data(self)->set(SANDBOX_SLOT(0), SANDBOX_SLOT(1), SANDBOX_SLOT(2), SANDBOX_SLOT(3)); } @@ -313,10 +313,10 @@ struct rect_binding_init : boost::asio::coroutine { set_private_data(self, new Rect); } else { // TODO: make these optional - SANDBOX_AWAIT_S(0, rb_num2int, ((VALUE *)(**sb() + argv))[0]); - SANDBOX_AWAIT_S(1, rb_num2int, ((VALUE *)(**sb() + argv))[1]); - SANDBOX_AWAIT_S(2, rb_num2int, ((VALUE *)(**sb() + argv))[2]); - SANDBOX_AWAIT_S(3, rb_num2int, ((VALUE *)(**sb() + argv))[3]); + SANDBOX_AWAIT_S(0, rb_num2int, sb()->ref(argv, 0)); + SANDBOX_AWAIT_S(1, rb_num2int, sb()->ref(argv, 1)); + SANDBOX_AWAIT_S(2, rb_num2int, sb()->ref(argv, 2)); + SANDBOX_AWAIT_S(3, rb_num2int, sb()->ref(argv, 3)); set_private_data(self, new Rect(SANDBOX_SLOT(0), SANDBOX_SLOT(1), SANDBOX_SLOT(2), SANDBOX_SLOT(3))); } } @@ -352,13 +352,13 @@ struct rect_binding_init : boost::asio::coroutine { VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) { BOOST_ASIO_CORO_REENTER (this) { if (argc == 1) { - *get_private_data(self) = *get_private_data(((VALUE *)(**sb() + argv))[0]); + *get_private_data(self) = *get_private_data(sb()->ref(argv, 0)); } else { // TODO: make these optional - SANDBOX_AWAIT_S(0, rb_num2int, ((VALUE *)(**sb() + argv))[0]); - SANDBOX_AWAIT_S(1, rb_num2int, ((VALUE *)(**sb() + argv))[1]); - SANDBOX_AWAIT_S(2, rb_num2int, ((VALUE *)(**sb() + argv))[2]); - SANDBOX_AWAIT_S(3, rb_num2int, ((VALUE *)(**sb() + argv))[3]); + SANDBOX_AWAIT_S(0, rb_num2int, sb()->ref(argv, 0)); + SANDBOX_AWAIT_S(1, rb_num2int, sb()->ref(argv, 1)); + SANDBOX_AWAIT_S(2, rb_num2int, sb()->ref(argv, 2)); + SANDBOX_AWAIT_S(3, rb_num2int, sb()->ref(argv, 3)); get_private_data(self)->set(SANDBOX_SLOT(0), SANDBOX_SLOT(1), SANDBOX_SLOT(2), SANDBOX_SLOT(3)); } } diff --git a/binding-sandbox/font-binding.cpp b/binding-sandbox/font-binding.cpp index 1e2db171..47d2c09a 100644 --- a/binding-sandbox/font-binding.cpp +++ b/binding-sandbox/font-binding.cpp @@ -39,7 +39,7 @@ struct collect_strings : boost::asio::coroutine { SANDBOX_AWAIT_S(3, rb_obj_is_kind_of, obj, sb()->rb_cString()); if (SANDBOX_VALUE_TO_BOOL(SANDBOX_SLOT(3))) { SANDBOX_AWAIT_S(0, rb_string_value_cstr, &obj); - out.push_back((const char *)(**sb() + SANDBOX_SLOT(0))); + out.push_back(sb()->str(SANDBOX_SLOT(0))); } else { SANDBOX_AWAIT_S(3, rb_obj_is_kind_of, obj, sb()->rb_cArray()); if (SANDBOX_VALUE_TO_BOOL(SANDBOX_SLOT(3))) { @@ -51,7 +51,7 @@ struct collect_strings : boost::asio::coroutine { SANDBOX_AWAIT_S(3, rb_obj_is_kind_of, SANDBOX_SLOT(4), sb()->rb_cString()); if (SANDBOX_VALUE_TO_BOOL(SANDBOX_SLOT(3))) { SANDBOX_AWAIT_S(0, rb_string_value_cstr, &SANDBOX_SLOT(4)); - out.push_back((const char *)(**sb() + SANDBOX_SLOT(0))); + out.push_back(sb()->str(SANDBOX_SLOT(0))); } } } @@ -70,12 +70,12 @@ static VALUE initialize(int32_t argc, wasm_ptr_t argv, VALUE self) { SANDBOX_AWAIT_S(0, rb_iv_get, font_class, "default_name"); set_private_data(self, new Font); } else if (argc == 1) { - SANDBOX_SLOT(0) = ((VALUE *)(**sb() + argv))[0]; + SANDBOX_SLOT(0) = sb()->ref(argv, 0); SANDBOX_AWAIT(collect_strings, SANDBOX_SLOT(0), sb().font_names_buffer); set_private_data(self, new Font(&sb().font_names_buffer)); } else { - SANDBOX_AWAIT_S(1, rb_num2int, ((VALUE *)(**sb() + argv))[1]); - SANDBOX_SLOT(0) = ((VALUE *)(**sb() + argv))[0]; + SANDBOX_AWAIT_S(1, rb_num2int, sb()->ref(argv, 1)); + SANDBOX_SLOT(0) = sb()->ref(argv, 0); SANDBOX_AWAIT(collect_strings, SANDBOX_SLOT(0), sb().font_names_buffer); set_private_data(self, new Font(&sb().font_names_buffer, SANDBOX_SLOT(1))); } @@ -212,7 +212,7 @@ static VALUE exist(VALUE self, VALUE value) { SANDBOX_AWAIT_S(1, rb_obj_is_kind_of, value, sb()->rb_cString()); if (SANDBOX_VALUE_TO_BOOL(SANDBOX_SLOT(1))) { SANDBOX_AWAIT_S(0, rb_string_value_cstr, &value); - return SANDBOX_BOOL_TO_VALUE(Font::doesExist((const char *)(**sb() + SANDBOX_SLOT(0)))); + return SANDBOX_BOOL_TO_VALUE(Font::doesExist(sb()->str(SANDBOX_SLOT(0)))); } else { return SANDBOX_BOOL_TO_VALUE(Font::doesExist(nullptr)); } diff --git a/binding-sandbox/graphics-binding.cpp b/binding-sandbox/graphics-binding.cpp index 34cc72c5..a4859a34 100644 --- a/binding-sandbox/graphics-binding.cpp +++ b/binding-sandbox/graphics-binding.cpp @@ -84,14 +84,14 @@ static VALUE transition(int32_t argc, wasm_ptr_t argv, VALUE self) { } if (argc >= 1) { - SANDBOX_AWAIT_S(1, rb_num2int, ((VALUE *)(**sb() + argv))[0]); + SANDBOX_AWAIT_S(1, rb_num2int, sb()->ref(argv, 0)); if (argc >= 2) { - SANDBOX_AWAIT_S(0, rb_string_value_cstr, &((VALUE *)(**sb() + argv))[1]); - if (*(const char *)(**sb() + SANDBOX_SLOT(0))) { - sb().trans_map = new Bitmap((const char *)(**sb() + SANDBOX_SLOT(0))); + SANDBOX_AWAIT_S(0, rb_string_value_cstr, &sb()->ref(argv, 1)); + if (*sb()->str(SANDBOX_SLOT(0))) { + sb().trans_map = new Bitmap(sb()->str(SANDBOX_SLOT(0))); } if (argc >= 3) { - SANDBOX_AWAIT_S(2, rb_num2int, ((VALUE *)(**sb() + argv))[2]); + SANDBOX_AWAIT_S(2, rb_num2int, sb()->ref(argv, 2)); } } } @@ -135,7 +135,7 @@ static VALUE screenshot(VALUE self, VALUE value) { VALUE operator()(VALUE self, VALUE value) { BOOST_ASIO_CORO_REENTER (this) { SANDBOX_AWAIT_S(0, rb_string_value_cstr, &value); - GFX_GUARD_EXC(shState->graphics().screenshot((const char *)(**sb() + SANDBOX_SLOT(0)));); + GFX_GUARD_EXC(shState->graphics().screenshot(sb()->str(SANDBOX_SLOT(0)));); } return SANDBOX_NIL; @@ -287,11 +287,11 @@ static VALUE resize_window(int32_t argc, wasm_ptr_t argv, VALUE self) { VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) { BOOST_ASIO_CORO_REENTER (this) { // TODO: require at least 2 arguments - SANDBOX_AWAIT_S(0, rb_num2int, ((VALUE *)(**sb() + argv))[0]); - SANDBOX_AWAIT_S(1, rb_num2int, ((VALUE *)(**sb() + argv))[1]); + SANDBOX_AWAIT_S(0, rb_num2int, sb()->ref(argv, 0)); + SANDBOX_AWAIT_S(1, rb_num2int, sb()->ref(argv, 1)); GFX_LOCK; if (argc >= 3) { - shState->graphics().resizeWindow(SANDBOX_SLOT(0), SANDBOX_SLOT(1), SANDBOX_VALUE_TO_BOOL(((VALUE *)(**sb() + argv))[2])); + shState->graphics().resizeWindow(SANDBOX_SLOT(0), SANDBOX_SLOT(1), SANDBOX_VALUE_TO_BOOL(sb()->ref(argv, 2))); } else { shState->graphics().resizeWindow(SANDBOX_SLOT(0), SANDBOX_SLOT(1)); } @@ -319,15 +319,15 @@ static VALUE play_movie(int32_t argc, wasm_ptr_t argv, VALUE self) { VALUE operator()(int32_t argc, wasm_ptr_t argv, VALUE self) { BOOST_ASIO_CORO_REENTER (this) { // TODO: require at least 1 argument - SANDBOX_AWAIT_S(0, rb_string_value_cstr, &((VALUE *)(**sb() + argv))[0]); + SANDBOX_AWAIT_S(0, rb_string_value_cstr, &sb()->ref(argv, 0)); if (argc >= 2) { - SANDBOX_AWAIT_S(1, rb_num2int, ((VALUE *)(**sb() + argv))[1]); + SANDBOX_AWAIT_S(1, rb_num2int, sb()->ref(argv, 1)); } else { SANDBOX_SLOT(1) = 100; } - SANDBOX_SLOT(2) = argc >= 3 ? SANDBOX_VALUE_TO_BOOL(((VALUE *)(**sb() + argv))[2]) : false; + SANDBOX_SLOT(2) = argc >= 3 ? SANDBOX_VALUE_TO_BOOL(sb()->ref(argv, 2)) : false; - GFX_GUARD_EXC(sb().set_movie(shState->graphics().playMovie((const char *)(**sb() + SANDBOX_SLOT(0)), SANDBOX_SLOT(1), SANDBOX_SLOT(2)));); + GFX_GUARD_EXC(sb().set_movie(shState->graphics().playMovie(sb()->str(SANDBOX_SLOT(0)), SANDBOX_SLOT(1), SANDBOX_SLOT(2)));); while (sb().get_movie_from_main_thread() != nullptr) { SANDBOX_YIELD; GFX_GUARD_EXC(sb().set_movie(shState->graphics().playMovie(sb().get_movie_from_main_thread()));); diff --git a/binding-sandbox/input-binding.cpp b/binding-sandbox/input-binding.cpp index 56f29a86..a6096ed1 100644 --- a/binding-sandbox/input-binding.cpp +++ b/binding-sandbox/input-binding.cpp @@ -589,7 +589,7 @@ static VALUE set_clipboard(VALUE self, VALUE value) { VALUE operator()(VALUE self, VALUE value) { BOOST_ASIO_CORO_REENTER (this) { SANDBOX_AWAIT_S(0, rb_string_value_cstr, &value); - mkxp_retro::input->setClipboardText((const char *)(**sb() + SANDBOX_SLOT(0))); + mkxp_retro::input->setClipboardText(sb()->str(SANDBOX_SLOT(0))); } return value; diff --git a/binding-sandbox/sandbox.cpp b/binding-sandbox/sandbox.cpp index f79a9088..462e7846 100644 --- a/binding-sandbox/sandbox.cpp +++ b/binding-sandbox/sandbox.cpp @@ -152,7 +152,7 @@ void sandbox::set_movie(Movie *new_movie) { const char *sandbox::getcwd() { if (w2c_ruby_mkxp_sandbox_getcwd(ruby.get())) { - return (const char *)(**bindings + ruby->w2c_mkxp_sandbox_cwd); + return bindings->str(ruby->w2c_mkxp_sandbox_cwd); } else { return "/game"; } diff --git a/binding-sandbox/serializable-binding.h b/binding-sandbox/serializable-binding.h index 547cc96b..4aef8b87 100644 --- a/binding-sandbox/serializable-binding.h +++ b/binding-sandbox/serializable-binding.h @@ -34,7 +34,7 @@ namespace mkxp_sandbox { SANDBOX_AWAIT_S(2, rb_obj_alloc, klass); SANDBOX_AWAIT_S(0, rb_string_value_ptr, &src); SANDBOX_AWAIT_S(1, get_bytesize, src); - set_private_data(SANDBOX_SLOT(2), C::deserialize((const char *)(**sb() + SANDBOX_SLOT(0)), SANDBOX_SLOT(1))); /* TODO: free when sandbox is deallocated */ + set_private_data(SANDBOX_SLOT(2), C::deserialize((const char *)sb()->ptr(SANDBOX_SLOT(0)), SANDBOX_SLOT(1))); /* TODO: free when sandbox is deallocated */ } return SANDBOX_SLOT(2); @@ -54,7 +54,7 @@ namespace mkxp_sandbox { SANDBOX_AWAIT_S(2, rb_str_new_cstr, ""); SANDBOX_AWAIT(rb_str_resize, SANDBOX_SLOT(2), SANDBOX_SLOT(1)); SANDBOX_AWAIT_S(0, rb_string_value_ptr, &SANDBOX_SLOT(2)); - get_private_data(self)->serialize((char *)(**sb() + SANDBOX_SLOT(0))); + get_private_data(self)->serialize((char *)sb()->ptr(SANDBOX_SLOT(0))); } return SANDBOX_SLOT(2); diff --git a/binding-sandbox/table-binding.cpp b/binding-sandbox/table-binding.cpp index 255d931c..18acfb16 100644 --- a/binding-sandbox/table-binding.cpp +++ b/binding-sandbox/table-binding.cpp @@ -39,13 +39,13 @@ static VALUE initialize(int32_t argc, wasm_ptr_t argv, VALUE self) { SANDBOX_SLOT(1) = SANDBOX_SLOT(2) = 1; // TODO: throw error if too many or too few arguments - SANDBOX_AWAIT_S(0, rb_num2int, ((VALUE *)(**sb() + argv))[0]); + SANDBOX_AWAIT_S(0, rb_num2int, sb()->ref(argv, 0)); SANDBOX_SLOT(0) = std::max(SANDBOX_SLOT(0), (int32_t)0); if (argc >= 2) { - SANDBOX_AWAIT_S(1, rb_num2int, ((VALUE *)(**sb() + argv))[1]); + SANDBOX_AWAIT_S(1, rb_num2int, sb()->ref(argv, 1)); SANDBOX_SLOT(1) = std::max(SANDBOX_SLOT(1), (int32_t)0); if (argc >= 3) { - SANDBOX_AWAIT_S(2, rb_num2int, ((VALUE *)(**sb() + argv))[2]); + SANDBOX_AWAIT_S(2, rb_num2int, sb()->ref(argv, 2)); SANDBOX_SLOT(2) = std::max(SANDBOX_SLOT(2), (int32_t)0); } } @@ -92,13 +92,13 @@ static VALUE resize(int32_t argc, wasm_ptr_t argv, VALUE self) { SANDBOX_SLOT(1) = SANDBOX_SLOT(2) = 1; // TODO: throw error if too many or too few arguments - SANDBOX_AWAIT_S(0, rb_num2int, ((VALUE *)(**sb() + argv))[0]); + SANDBOX_AWAIT_S(0, rb_num2int, sb()->ref(argv, 0)); SANDBOX_SLOT(0) = std::max(SANDBOX_SLOT(0), (int32_t)0); if (argc >= 2) { - SANDBOX_AWAIT_S(1, rb_num2int, ((VALUE *)(**sb() + argv))[1]); + SANDBOX_AWAIT_S(1, rb_num2int, sb()->ref(argv, 1)); SANDBOX_SLOT(1) = std::max(SANDBOX_SLOT(1), (int32_t)0); if (argc >= 3) { - SANDBOX_AWAIT_S(2, rb_num2int, ((VALUE *)(**sb() + argv))[2]); + SANDBOX_AWAIT_S(2, rb_num2int, sb()->ref(argv, 2)); SANDBOX_SLOT(2) = std::max(SANDBOX_SLOT(2), (int32_t)0); } } @@ -133,11 +133,11 @@ static VALUE get(int32_t argc, wasm_ptr_t argv, VALUE self) { BOOST_ASIO_CORO_REENTER (this) { SANDBOX_SLOT(2) = SANDBOX_SLOT(3) = 0; - SANDBOX_AWAIT_S(1, rb_num2int, ((VALUE *)(**sb() + argv))[0]); + SANDBOX_AWAIT_S(1, rb_num2int, sb()->ref(argv, 0)); if (argc >= 2) { - SANDBOX_AWAIT_S(2, rb_num2int, ((VALUE *)(**sb() + argv))[1]); + SANDBOX_AWAIT_S(2, rb_num2int, sb()->ref(argv, 1)); if (argc >= 3) { - SANDBOX_AWAIT_S(3, rb_num2int, ((VALUE *)(**sb() + argv))[2]); + SANDBOX_AWAIT_S(3, rb_num2int, sb()->ref(argv, 2)); // TODO: throw error if too many arguments } } @@ -166,18 +166,18 @@ static VALUE set(int32_t argc, wasm_ptr_t argv, VALUE self) { // TODO: throw error if too few arguments - SANDBOX_AWAIT_S(0, rb_num2int, ((VALUE *)(**sb() + argv))[0]); + SANDBOX_AWAIT_S(0, rb_num2int, sb()->ref(argv, 0)); if (argc >= 3) { - SANDBOX_AWAIT_S(1, rb_num2int, ((VALUE *)(**sb() + argv))[1]); + SANDBOX_AWAIT_S(1, rb_num2int, sb()->ref(argv, 1)); if (argc >= 4) { - SANDBOX_AWAIT_S(2, rb_num2int, ((VALUE *)(**sb() + argv))[2]); + SANDBOX_AWAIT_S(2, rb_num2int, sb()->ref(argv, 2)); } } - SANDBOX_AWAIT_S(3, rb_num2int, ((VALUE *)(**sb() + argv))[std::min(argc, (int32_t)4) - 1]); + SANDBOX_AWAIT_S(3, rb_num2int, sb()->ref(argv, std::min(argc, (int32_t)4) - 1)); get_private_data(self)->set(SANDBOX_SLOT(3), SANDBOX_SLOT(0), SANDBOX_SLOT(1), SANDBOX_SLOT(2)); - return ((VALUE *)(**sb() + argv))[std::min(argc, (int32_t)4) - 1]; + return sb()->ref(std::min(argc, (int32_t)4) - 1); } return SANDBOX_UNDEF; diff --git a/binding-sandbox/tilemap-binding.cpp b/binding-sandbox/tilemap-binding.cpp index be665db2..0fd05733 100644 --- a/binding-sandbox/tilemap-binding.cpp +++ b/binding-sandbox/tilemap-binding.cpp @@ -102,7 +102,7 @@ static VALUE initialize(int32_t argc, wasm_ptr_t argv, VALUE self) { SANDBOX_SLOT(0) = SANDBOX_NIL; Viewport *viewport = nullptr; if (argc > 0) { - SANDBOX_SLOT(0) = *(VALUE *)(**sb() + argv); + SANDBOX_SLOT(0) = sb()->ref(argv, 0); if (SANDBOX_SLOT(0) != SANDBOX_NIL) { viewport = get_private_data(SANDBOX_SLOT(0)); } diff --git a/binding-sandbox/tilemapvx-binding.cpp b/binding-sandbox/tilemapvx-binding.cpp index 76514e25..ffa9dc53 100644 --- a/binding-sandbox/tilemapvx-binding.cpp +++ b/binding-sandbox/tilemapvx-binding.cpp @@ -101,7 +101,7 @@ static VALUE initialize(int32_t argc, wasm_ptr_t argv, VALUE self) { SANDBOX_SLOT(0) = SANDBOX_NIL; Viewport *viewport = nullptr; if (argc > 0) { - SANDBOX_SLOT(0) = *(VALUE *)(**sb() + argv); + SANDBOX_SLOT(0) = sb()->ref(argv, 0); if (SANDBOX_SLOT(0) != SANDBOX_NIL) { viewport = get_private_data(SANDBOX_SLOT(0)); } diff --git a/binding-sandbox/viewport-binding.cpp b/binding-sandbox/viewport-binding.cpp index a7163345..b312c89f 100644 --- a/binding-sandbox/viewport-binding.cpp +++ b/binding-sandbox/viewport-binding.cpp @@ -47,12 +47,12 @@ static VALUE initialize(int32_t argc, wasm_ptr_t argv, VALUE self) { viewport = new Viewport; } else if (argc == 1) { GFX_LOCK; - viewport = new Viewport(get_private_data(((VALUE *)(**sb() + argv))[0])); + viewport = new Viewport(get_private_data(sb()->ref(argv, 0))); } else { - SANDBOX_AWAIT_S(0, rb_num2int, ((VALUE *)(**sb() + argv))[0]); - SANDBOX_AWAIT_S(1, rb_num2int, ((VALUE *)(**sb() + argv))[1]); - SANDBOX_AWAIT_S(2, rb_num2int, ((VALUE *)(**sb() + argv))[2]); - SANDBOX_AWAIT_S(3, rb_num2int, ((VALUE *)(**sb() + argv))[3]); + SANDBOX_AWAIT_S(0, rb_num2int, sb()->ref(argv, 0)); + SANDBOX_AWAIT_S(1, rb_num2int, sb()->ref(argv, 1)); + SANDBOX_AWAIT_S(2, rb_num2int, sb()->ref(argv, 2)); + SANDBOX_AWAIT_S(3, rb_num2int, sb()->ref(argv, 3)); GFX_LOCK; viewport = new Viewport(SANDBOX_SLOT(0), SANDBOX_SLOT(1), SANDBOX_SLOT(2), SANDBOX_SLOT(3)); } diff --git a/binding-sandbox/viewportelement-binding.h b/binding-sandbox/viewportelement-binding.h index ad24f04e..95e3a099 100644 --- a/binding-sandbox/viewportelement-binding.h +++ b/binding-sandbox/viewportelement-binding.h @@ -37,7 +37,7 @@ namespace mkxp_sandbox { { Viewport *viewport = nullptr; if (argc > 0) { - SANDBOX_SLOT(0) = *(VALUE *)(**sb() + argv); + SANDBOX_SLOT(0) = sb()->ref(argv, 0); if (SANDBOX_SLOT(0) != SANDBOX_NIL) { viewport = get_private_data(SANDBOX_SLOT(0)); } diff --git a/binding-sandbox/wasi.cpp b/binding-sandbox/wasi.cpp index f1da6812..9f0acb6a 100644 --- a/binding-sandbox/wasi.cpp +++ b/binding-sandbox/wasi.cpp @@ -827,7 +827,7 @@ extern "C" u32 w2c_wasi__snapshot__preview1_path_open(wasi_t *wasi, u32 fd, u32 case PHYSFS_ERR_NO_WRITE_DIR: return WASI_EROFS; case PHYSFS_ERR_PERMISSION: - return WASI_EPERM; + return WASI_EACCES; default: return WASI_EIO; } @@ -900,7 +900,7 @@ extern "C" u32 w2c_wasi__snapshot__preview1_path_remove_directory(wasi_t *wasi, case PHYSFS_ERR_NO_WRITE_DIR: return WASI_EROFS; case PHYSFS_ERR_PERMISSION: - return WASI_EPERM; + return WASI_EACCES; default: return WASI_EIO; } @@ -975,7 +975,7 @@ extern "C" u32 w2c_wasi__snapshot__preview1_path_unlink_file(wasi_t *wasi, u32 f case PHYSFS_ERR_NO_WRITE_DIR: return WASI_EROFS; case PHYSFS_ERR_PERMISSION: - return WASI_EPERM; + return WASI_EACCES; default: return WASI_EIO; } diff --git a/binding-sandbox/windowvx-binding.cpp b/binding-sandbox/windowvx-binding.cpp index 05c843be..8af57440 100644 --- a/binding-sandbox/windowvx-binding.cpp +++ b/binding-sandbox/windowvx-binding.cpp @@ -45,10 +45,10 @@ static VALUE initialize(int32_t argc, wasm_ptr_t argv, VALUE self) { GFX_LOCK; if (rgssVer >= 3) { if (argc == 4) { - SANDBOX_AWAIT_S(1, rb_num2int, ((VALUE *)(**sb() + argv))[0]); - SANDBOX_AWAIT_S(2, rb_num2int, ((VALUE *)(**sb() + argv))[1]); - SANDBOX_AWAIT_S(3, rb_num2int, ((VALUE *)(**sb() + argv))[2]); - SANDBOX_AWAIT_S(4, rb_num2int, ((VALUE *)(**sb() + argv))[3]); + SANDBOX_AWAIT_S(1, rb_num2int, sb()->ref(argv, 0)); + SANDBOX_AWAIT_S(2, rb_num2int, sb()->ref(argv, 1)); + SANDBOX_AWAIT_S(3, rb_num2int, sb()->ref(argv, 2)); + SANDBOX_AWAIT_S(4, rb_num2int, sb()->ref(argv, 3)); } WindowVX *window = new WindowVX(SANDBOX_SLOT(1), SANDBOX_SLOT(2), SANDBOX_SLOT(3), SANDBOX_SLOT(4)); set_private_data(self, window); diff --git a/libretro/sandbox-bindgen.rb b/libretro/sandbox-bindgen.rb index 4961ded4..95fbe246 100644 --- a/libretro/sandbox-bindgen.rb +++ b/libretro/sandbox-bindgen.rb @@ -49,21 +49,21 @@ ARG_HANDLERS = { 'const char *' => { keep: true, buf_size: 'std::strlen(ARG) + 1', - serialize: "std::strcpy((char *)(*bind + BUF), ARG);\n", + serialize: "_sbindgen_strcpy((char *)bind.ptr(BUF), ARG);\n", }, 'const VALUE *' => { keep: true, condition: lambda { |func_name, args, arg_index| arg_index > 0 && args[arg_index - 1] == 'int' }, # Only handle arguments of type `const VALUE *` if the previous argument is of type `int` buf_size: 'PREV_ARG * sizeof(VALUE)', serialize: <<~HEREDOC - std::memcpy(*bind + BUF, ARG, PREV_ARG * sizeof(VALUE)); + _sbindgen_value_array_copy((VALUE *)bind.ptr(BUF), ARG, PREV_ARG); HEREDOC }, 'volatile VALUE *' => { keep: true, buf_size: 'sizeof(VALUE)', serialize: <<~HEREDOC - *(VALUE *)(*bind + BUF) = *ARG; + bind.ref(BUF) = *ARG; HEREDOC }, 'void *' => { @@ -198,20 +198,6 @@ HEADER_START = <<~HEREDOC // Autogenerated by sandbox-bindgen.rb. Don't manually modify this file - modify sandbox-bindgen.rb instead! - #if WABT_BIG_ENDIAN - # define SERIALIZE_32(value) __builtin_bswap32(value) - # define SERIALIZE_64(value) __builtin_bswap64(value) - #else - # define SERIALIZE_32(value) (value) - # define SERIALIZE_64(value) (value) - #endif - - #ifdef MKXPZ_SANDBOX_MEMORY64 - # define SERIALIZE_VALUE(value) SERIALIZE_64(value) - #else - # define SERIALIZE_VALUE(value) SERIALIZE_32(value) - #endif - namespace mkxp_sandbox { struct bindings : binding_base { bindings(std::shared_ptr m); @@ -232,10 +218,6 @@ HEREDOC HEADER_END = <<~HEREDOC } - #undef SERIALIZE_32 - #undef SERIALIZE_64 - #undef SERIALIZE_VALUE - #endif // MKXP_SANDBOX_BINDGEN_H HEREDOC @@ -266,23 +248,11 @@ PRELUDE = <<~HEREDOC #include #include "mkxp-sandbox-bindgen.h" - static_assert(alignof(VALUE) % sizeof(VALUE) == 0, "Alignment of `VALUE` must be divisible by size of `VALUE` for Ruby garbage collection to work. If you compiled Ruby for wasm64, try compiling it for wasm32 instead."); - - #define SLOT(slot_index) (*(typename slot_type<(slot_index), slots>::type *)(*bind + bind.stack_pointer() + slot_offset<(slot_index), slots>::value)) - - #if WABT_BIG_ENDIAN - # define SERIALIZE_32(value) __builtin_bswap32(value) - # define SERIALIZE_64(value) __builtin_bswap64(value) - #else - # define SERIALIZE_32(value) (value) - # define SERIALIZE_64(value) (value) - #endif + #define _SBINDGEN_SLOT(slot_index) (bind.ref::type>(bind.stack_pointer() + slot_offset<(slot_index), slots>::value)) #ifdef MKXPZ_SANDBOX_MEMORY64 - # define SERIALIZE_VALUE(value) SERIALIZE_64(value) # define WASM_RT_ISIZE WASM_RT_I64 #else - # define SERIALIZE_VALUE(value) SERIALIZE_32(value) # define WASM_RT_ISIZE WASM_RT_I32 #endif @@ -299,6 +269,27 @@ PRELUDE = <<~HEREDOC bindings::bindings(std::shared_ptr m) : binding_base(m) {} + static void _sbindgen_strcpy(char *dst, const char *src) { + #ifdef MKXPZ_BIG_ENDIAN + do { + *--dst = *src; + } while (*src++); + #else + std::strcpy(dst, src); + #endif + } + + static void _sbindgen_value_array_copy(VALUE *dst, const VALUE *src, wasm_size_t num_values) { + #ifdef MKXPZ_BIG_ENDIAN + while (num_values > 0) { + *--dst = *src++; + --num_values; + }; + #else + std::memcpy(dst, src, num_values * sizeof(VALUE)); + #endif + } + ////////////////////////////////////////////////////////////////////////////// HEREDOC @@ -319,41 +310,41 @@ POSTSCRIPT = <<~HEREDOC throw std::bad_alloc(); } - std::strcpy((char *)(**this + str), wrap_struct_name); - ((wasm_ptr_t *)(**this + buf))[0] = SERIALIZE_VALUE(str); + _sbindgen_strcpy((char *)ptr(str), wrap_struct_name); + ref(buf, 0) = str; - ((wasm_ptr_t *)(**this + buf))[1] = dmark == NULL ? 0 : SERIALIZE_VALUE(wasm_rt_push_funcref(&instance().w2c_T0, wasm_rt_funcref_t { + ref(buf, 1) = dmark == NULL ? 0 : 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, - })); + }); - ((wasm_ptr_t *)(**this + buf))[2] = dfree == NULL ? 0 : SERIALIZE_VALUE(wasm_rt_push_funcref(&instance().w2c_T0, wasm_rt_funcref_t { + ref(buf, 2) = dfree == NULL ? 0 : 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, - })); + }); - ((wasm_ptr_t *)(**this + buf))[3] = dsize == NULL ? 0 : SERIALIZE_VALUE(wasm_rt_push_funcref(&instance().w2c_T0, wasm_rt_funcref_t { + ref(buf, 3) = dsize == NULL ? 0 : 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 *)(**this + buf))[4] = dcompact == NULL ? 0 : SERIALIZE_VALUE(wasm_rt_push_funcref(&instance().w2c_T0, wasm_rt_funcref_t { + ref(buf, 4) = dcompact == NULL ? 0 : 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 *)(**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); + ref(buf, 5) = 0; + ref(buf, 6) = parent; + ref(buf, 7) = data; + ref(buf, 8) = flags; return buf; } @@ -376,7 +367,7 @@ for call_type in CALL_TYPES call_bindings.append( <<~HEREDOC static #{call_type[0] == :void ? 'void' : call_type[0] == :value ? 'VALUE' : VAR_TYPE_TABLE[call_type[0]]} _sbindgen_call_#{call_type_hash(call_type)}(#{(["#{call_type[0] == :void ? 'void' : call_type[0] == :value ? 'VALUE' : VAR_TYPE_TABLE[call_type[0]]} (*func)(#{(0...call_type[1].length).map { |i| call_type[1][i] == :value ? 'VALUE' : VAR_TYPE_TABLE[call_type[1][i]] }.join(', ')})"] + (0...call_type[1].length).map { |i| "#{call_type[1][i] == :value ? 'VALUE' : VAR_TYPE_TABLE[call_type[1][i]]} a#{i}" }).join(', ')}) { - #{call_type[0] == :void ? '' : 'return '}#{call_type[0] != :value ? '' : 'SERIALIZE_VALUE('}func(#{(0...call_type[1].length).map { |i| call_type[1][i] == :value ? "SERIALIZE_VALUE(a#{i})" : "a#{i}" }.join(', ')})#{call_type[0] != :value ? '' : ')'}; + #{call_type[0] == :void ? '' : 'return '}func(#{(0...call_type[1].length).map { |i| "a#{i}" }.join(', ')}); } HEREDOC ) @@ -451,7 +442,7 @@ File.readlines('tags', chomp: true).each do |line| coroutine_initializer += <<~HEREDOC switch (a#{args.length - 1}) { case -1: - SLOT(#{num_slots}) = wasm_rt_push_funcref(&bind.instance().w2c_T0, wasm_rt_funcref_t { + _SBINDGEN_SLOT(#{num_slots}) = wasm_rt_push_funcref(&bind.instance().w2c_T0, wasm_rt_funcref_t { .func_type = wasm2c_#{MODULE_NAME}_get_func_type(3, 1, #{FUNC_TYPE_TABLE[:s32]}, #{FUNC_TYPE_TABLE[:ptr]}, #{FUNC_TYPE_TABLE[:value]}, #{FUNC_TYPE_TABLE[:value]}), .func = (wasm_rt_function_ptr_t)_sbindgen_call_#{call_type_hash([:value, [:s32, :ptr, :value]])}, .func_tailcallee = {.fn = NULL}, @@ -459,7 +450,7 @@ File.readlines('tags', chomp: true).each do |line| }); break; case -2: - SLOT(#{num_slots}) = wasm_rt_push_funcref(&bind.instance().w2c_T0, wasm_rt_funcref_t { + _SBINDGEN_SLOT(#{num_slots}) = wasm_rt_push_funcref(&bind.instance().w2c_T0, wasm_rt_funcref_t { .func_type = wasm2c_#{MODULE_NAME}_get_func_type(2, 1, #{FUNC_TYPE_TABLE[:value]}, #{FUNC_TYPE_TABLE[:value]}, #{FUNC_TYPE_TABLE[:value]}), .func = (wasm_rt_function_ptr_t)_sbindgen_call_#{call_type_hash([:value, [:value, :value]])}, .func_tailcallee = {.fn = NULL}, @@ -470,7 +461,7 @@ File.readlines('tags', chomp: true).each do |line| for j in 0..16 case_str = <<~HEREDOC case #{j}: - SLOT(#{num_slots}) = wasm_rt_push_funcref(&bind.instance().w2c_T0, wasm_rt_funcref_t { + _SBINDGEN_SLOT(#{num_slots}) = wasm_rt_push_funcref(&bind.instance().w2c_T0, wasm_rt_funcref_t { .func_type = wasm2c_#{MODULE_NAME}_get_func_type(#{j + 1}, 1, #{([FUNC_TYPE_TABLE[:value]] * (j + 2)).join(', ')}), .func = (wasm_rt_function_ptr_t)_sbindgen_call_#{call_type_hash([:value, [:value] * (j + 1)])}, .func_tailcallee = {.fn = NULL}, @@ -487,7 +478,7 @@ File.readlines('tags', chomp: true).each do |line| HEREDOC else coroutine_initializer += <<~HEREDOC - SLOT(#{num_slots}) = wasm_rt_push_funcref(&bind.instance().w2c_T0, wasm_rt_funcref_t { + _SBINDGEN_SLOT(#{num_slots}) = wasm_rt_push_funcref(&bind.instance().w2c_T0, wasm_rt_funcref_t { .func_type = wasm2c_#{MODULE_NAME}_get_func_type(#{handler[:func_ptr_args].length}, #{handler[:func_ptr_rets].length}#{handler[:func_ptr_args].empty? && handler[:func_ptr_rets].empty? ? '' : ', ' + (handler[:func_ptr_args] + handler[:func_ptr_rets]).map { |type| FUNC_TYPE_TABLE[type] }.join(', ')}), .func = (wasm_rt_function_ptr_t)_sbindgen_call_#{call_type_hash([handler[:func_ptr_rets].empty? ? :void : handler[:func_ptr_rets][0], handler[:func_ptr_args]])}, .func_tailcallee = {.fn = NULL}, @@ -500,10 +491,10 @@ File.readlines('tags', chomp: true).each do |line| num_slots += 1 elsif !handler[:buf_size].nil? coroutine_initializer += <<~HEREDOC - SLOT(#{num_slots}) = bind.sandbox_malloc(#{handler[:buf_size].gsub('PREV_ARG', "a#{i - 1}").gsub('ARG', "a#{i}")}); - if (SLOT(#{num_slots}) == 0) throw std::bad_alloc(); + _SBINDGEN_SLOT(#{num_slots}) = bind.sandbox_malloc(#{handler[:buf_size].gsub('PREV_ARG', "a#{i - 1}").gsub('ARG', "a#{i}")}); + if (_SBINDGEN_SLOT(#{num_slots}) == 0) throw std::bad_alloc(); HEREDOC - coroutine_initializer += handler[:serialize].gsub('PREV_ARG', "a#{i - 1}").gsub('ARG', "a#{i}").gsub('BUF', "SLOT(#{num_slots})") + coroutine_initializer += handler[:serialize].gsub('PREV_ARG', "a#{i - 1}").gsub('ARG', "a#{i}").gsub('BUF', "_SBINDGEN_SLOT(#{num_slots})") coroutine_initializer += "\n" transformed_args.add(i) num_slots += 1 @@ -525,13 +516,13 @@ File.readlines('tags', chomp: true).each do |line| if (sp > fp) { throw std::bad_alloc(); } - SLOT(#{num_slots}) = sp; - SLOT(#{num_slots + 1}) = fp; + _SBINDGEN_SLOT(#{num_slots}) = sp; + _SBINDGEN_SLOT(#{num_slots + 1}) = fp; w2c_ruby_rb_wasm_set_stack_pointer(&bind.instance(), sp); std::va_list a; va_start(a, a#{args.length - 2}); for (long i = 0; i < a#{args.length - 2}; ++i) { - ((VALUE *)(*bind + sp))[i] = va_arg(a, VALUE); + bind.ref(sp, i) = va_arg(a, VALUE); } va_end(a); } @@ -552,11 +543,11 @@ File.readlines('tags', chomp: true).each do |line| if (sp > fp) { throw std::bad_alloc(); } - SLOT(#{num_slots}) = sp; - SLOT(#{num_slots + 1}) = fp; + _SBINDGEN_SLOT(#{num_slots}) = sp; + _SBINDGEN_SLOT(#{num_slots + 1}) = fp; w2c_ruby_rb_wasm_set_stack_pointer(&bind.instance(), sp); for (wasm_size_t i = 0; i < n; ++i) { - ((VALUE *)(*bind + sp))[i] = va_arg(a, VALUE); + bind.ref(sp, i) = va_arg(a, VALUE); } va_end(a); } @@ -575,10 +566,10 @@ File.readlines('tags', chomp: true).each do |line| arg = args[i] if arg == '...' num_slots += 2 - "SLOT(#{num_slots - 2}) = 0;\nSLOT(#{num_slots - 1}) = 0;" + "_SBINDGEN_SLOT(#{num_slots - 2}) = 0;\n_SBINDGEN_SLOT(#{num_slots - 1}) = 0;" elsif transformed_args.include?(i) num_slots += 1 - "SLOT(#{num_slots - 1}) = 0;" + "_SBINDGEN_SLOT(#{num_slots - 1}) = 0;" else nil end @@ -614,9 +605,9 @@ File.readlines('tags', chomp: true).each do |line| #{handler[:primitive] == :void ? '' : 'r = '}w2c_#{MODULE_NAME}_#{func_name}(#{(['&bind.instance()'] + (0...args.length).map do |i| if args[i] == '...' || transformed_args.include?(i) j += 1 - "SLOT(#{j - 1})" + "_SBINDGEN_SLOT(#{j - 1})" else - args[i] == 'VALUE' ? "SERIALIZE_VALUE(a#{i})" : args[i] == 'const rb_data_type_t *' ? "a#{i}.get()" : "a#{i}" + args[i] == 'const rb_data_type_t *' ? "a#{i}.get()" : "a#{i}" end end).join(', ')}); if (w2c_#{MODULE_NAME}_asyncify_get_state(&bind.instance()) != 1) break; @@ -632,10 +623,10 @@ File.readlines('tags', chomp: true).each do |line| arg = args[i] if arg == '...' num_slots -= 2 - " if (SLOT(#{num_slots + 1}) != 0) w2c_ruby_rb_wasm_set_stack_pointer(&bind.instance(), SLOT(#{num_slots + 1}));" + " if (_SBINDGEN_SLOT(#{num_slots + 1}) != 0) w2c_ruby_rb_wasm_set_stack_pointer(&bind.instance(), _SBINDGEN_SLOT(#{num_slots + 1}));" elsif transformed_args.include?(i) num_slots -= 1 - " if (SLOT(#{num_slots}) != 0) bind.sandbox_free(SLOT(#{num_slots}));" + " if (_SBINDGEN_SLOT(#{num_slots}) != 0) bind.sandbox_free(_SBINDGEN_SLOT(#{num_slots}));" else nil end @@ -653,7 +644,7 @@ File.readlines('tags', chomp: true).each do |line| #{coroutine_initializer.empty? ? '' : (coroutine_initializer.split("\n").map { |line| " #{line}".rstrip }.join("\n") + "\n\n")} for (;;) { #{coroutine_inner.split("\n").map { |line| " #{line}" }.join("\n")} } - }#{handler[:primitive] == :void ? '' : ret == 'VALUE' ? "\n\n return SERIALIZE_VALUE(r);" : "\n\n return r;"} + }#{handler[:primitive] == :void ? '' : "\n\n return r;"} }#{coroutine_destructor.empty? ? '' : ("\n" + coroutine_destructor)} HEREDOC @@ -675,28 +666,16 @@ end File.open('mkxp-sandbox-bindgen.h', 'w') do |file| file.write(HEADER_START) for global_name in globals - file.write(" inline VALUE #{global_name}() const noexcept { return *(VALUE *)(**this + instance().w2c_#{global_name}); }\n") + file.write(" inline VALUE #{global_name}() const noexcept { return ref(instance().w2c_#{global_name}); }\n") end file.write(" };") for declaration in declarations file.write("\n\n" + declaration.split("\n").map { |line| " #{line}" }.join("\n").rstrip) end file.write("\n\n") - file.write("#if WABT_BIG_ENDIAN\n") - file.write("# ifdef MKXPZ_SANDBOX_MEMORY64\n") for const in consts - file.write("# define SANDBOX_#{const[0]} 0x#{[const[1]].pack('Q<').unpack('H*')[0]}u\n") + file.write("#define SANDBOX_#{const[0]} ((VALUE)#{const[1]}U)\n") end - file.write("# else\n") - for const in consts - file.write("# define SANDBOX_#{const[0]} 0x#{[const[1]].pack('L<').unpack('H*')[0]}u\n") - end - file.write("# endif\n") - file.write("#else\n") - for const in consts - file.write("# define SANDBOX_#{const[0]} 0x#{[const[1]].pack('L>').unpack('H*')[0]}u\n") - end - file.write("#endif\n") file.write(HEADER_END) end File.open('mkxp-sandbox-bindgen.cpp', 'w') do |file| diff --git a/src/display/bitmap.cpp b/src/display/bitmap.cpp index d914102c..991bdebf 100644 --- a/src/display/bitmap.cpp +++ b/src/display/bitmap.cpp @@ -1941,6 +1941,10 @@ bool Bitmap::getRaw(void *output, int output_size) Debug() << "GAME BUG: Game is calling getRaw on low-res Bitmap; you may want to patch the game to improve graphics quality."; } +#if defined(MKXPZ_RETRO) && defined(MKXPZ_BIG_ENDIAN) + output -= output_size; +#endif + if (!p->animation.enabled && (p->surface || p->megaSurface)) { void *src = (p->megaSurface) ? p->megaSurface->pixels : p->surface->pixels; memcpy(output, src, output_size); @@ -1949,6 +1953,11 @@ bool Bitmap::getRaw(void *output, int output_size) FBO::bind(getGLTypes().fbo); gl.ReadPixels(0,0,width(),height(),GL_RGBA,GL_UNSIGNED_BYTE,output); } + +#if defined(MKXPZ_RETRO) && defined(MKXPZ_BIG_ENDIAN) + std::reverse((uint8_t *)output, (uint8_t *)output + output_size); +#endif + return true; } @@ -1969,8 +1978,17 @@ void Bitmap::replaceRaw(void *pixel_data, int size) if (size != w*h*4) throw Exception(Exception::MKXPError, "Replacement bitmap data is not large enough (given %i bytes, need %i)", size, requiredsize); +#if defined(MKXPZ_RETRO) && defined(MKXPZ_BIG_ENDIAN) + output -= output_size; + std::reverse((uint8_t *)pixel_data, (uint8_t *)pixel_data + size); +#endif + TEX::bind(getGLTypes().tex); TEX::uploadImage(w, h, pixel_data, GL_RGBA); + +#if defined(MKXPZ_RETRO) && defined(MKXPZ_BIG_ENDIAN) + std::reverse((uint8_t *)pixel_data, (uint8_t *)pixel_data + size); +#endif taintArea(IntRect(0,0,w,h)); p->onModified(); diff --git a/src/etc/table.cpp b/src/etc/table.cpp index 306c072f..edad0118 100644 --- a/src/etc/table.cpp +++ b/src/etc/table.cpp @@ -115,7 +115,12 @@ void Table::serialize(char *buffer) const writeInt32(&buffer, zs); writeInt32(&buffer, size); +#if defined(MKXPZ_RETRO) && defined(MKXPZ_BIG_ENDIAN) + for (const int16_t datum : data) + *(int16_t *)(buffer -= sizeof(int16_t)) = datum; +#else memcpy(buffer, dataPtr(data), sizeof(int16_t)*size); +#endif } @@ -137,7 +142,13 @@ Table *Table::deserialize(const char *data, int len) throw Exception(Exception::RGSSError, "Marshal: Table: bad file format"); Table *t = new Table(x, y, z); + +#if defined(MKXPZ_RETRO) && defined(MKXPZ_BIG_ENDIAN) + for (int16_t &datum : t->data) + datum = *(int16_t *)(data -= sizeof(int16_t)); +#else memcpy(dataPtr(t->data), data, sizeof(int16_t)*size); +#endif return t; } diff --git a/src/util/serial-util.h b/src/util/serial-util.h index 07ea977e..c8a7eeba 100644 --- a/src/util/serial-util.h +++ b/src/util/serial-util.h @@ -31,10 +31,15 @@ readInt32(const char **dataP) { int32_t result; +#if defined(MKXPZ_RETRO) && defined(MKXPZ_BIG_ENDIAN) + *dataP -= 4; + memcpy(&result, *dataP, 4); +#else memcpy(&result, *dataP, 4); *dataP += 4; +#endif -#ifdef MKXPZ_BIG_ENDIAN +#if !defined(MKXPZ_RETRO) && defined(MKXPZ_BIG_ENDIAN) # ifdef _MSC_VER static_assert(sizeof(unsigned long) == sizeof(int32_t), "unsigned long should be 32 bits"); result = (int32_t)_byteswap_ulong((unsigned long)result); @@ -49,7 +54,7 @@ readInt32(const char **dataP) static inline double readDouble(const char **dataP) { -#ifdef MKXPZ_BIG_ENDIAN +#if !defined(MKXPZ_RETRO) && defined(MKXPZ_BIG_ENDIAN) uint64_t result; memcpy(&result, *dataP, 8); @@ -65,8 +70,13 @@ readDouble(const char **dataP) #else double result; +# if defined(MKXPZ_RETRO) && defined(MKXPZ_BIG_ENDIAN) + *dataP -= 8; + memcpy(&result, *dataP, 8); +# else memcpy(&result, *dataP, 8); *dataP += 8; +# endif return result; #endif @@ -75,7 +85,7 @@ readDouble(const char **dataP) static inline void writeInt32(char **dataP, int32_t value) { -#ifdef MKXPZ_BIG_ENDIAN +#if !defined(MKXPZ_RETRO) && defined(MKXPZ_BIG_ENDIAN) # ifdef _MSC_VER static_assert(sizeof(unsigned long) == sizeof(int32_t), "unsigned long should be 32 bits"); value = (int32_t)_byteswap_ulong((unsigned long)value); @@ -84,14 +94,19 @@ writeInt32(char **dataP, int32_t value) # endif #endif +#if defined(MKXPZ_RETRO) && defined(MKXPZ_BIG_ENDIAN) + *dataP -= 4; + memcpy(*dataP, &value, 4); +#else memcpy(*dataP, &value, 4); *dataP += 4; +#endif } static inline void writeDouble(char **dataP, double value) { -#ifdef MKXPZ_BIG_ENDIAN +#if !defined(MKXPZ_RETRO) && defined(MKXPZ_BIG_ENDIAN) uint64_t valueUint = *(uint64_t *)&value; # ifdef _MSC_VER @@ -101,10 +116,14 @@ writeDouble(char **dataP, double value) # endif memcpy(*dataP, &valueUint, 8); + *dataP += 8; +#elif defined(MKXPZ_RETRO) && defined(MKXPZ_BIG_ENDIAN) + *dataP -= 8; + memcpy(*dataP, &value, 8); #else memcpy(*dataP, &value, 8); -#endif *dataP += 8; +#endif } #endif // SERIALUTIL_H