diff --git a/binding-sandbox/audio-binding.cpp b/binding-sandbox/audio-binding.cpp index c054677c..bf918010 100644 --- a/binding-sandbox/audio-binding.cpp +++ b/binding-sandbox/audio-binding.cpp @@ -38,6 +38,8 @@ static VALUE bgm_play(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_AWAIT(check_arity, argc, 1, -1); + SANDBOX_SLOT(0) = 0.0; SANDBOX_SLOT(2) = 100; SANDBOX_SLOT(3) = 100; @@ -92,6 +94,8 @@ 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_AWAIT(check_arity, argc, 1, -1); + SANDBOX_SLOT(1) = -127; SANDBOX_AWAIT_S(0, rb_num2int, sb()->ref(argv, 0)); if (argc >= 2) { @@ -155,6 +159,8 @@ 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_AWAIT(check_arity, argc, 1, -1); + SANDBOX_SLOT(1) = -127; SANDBOX_AWAIT_S(0, rb_num2int, sb()->ref(argv, 0)); if (argc >= 2) { @@ -176,6 +182,8 @@ static VALUE bgs_play(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_AWAIT(check_arity, argc, 1, -1); + SANDBOX_SLOT(0) = 0.0; SANDBOX_SLOT(2) = 100; SANDBOX_SLOT(3) = 100; @@ -246,6 +254,8 @@ static VALUE me_play(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_AWAIT(check_arity, argc, 1, -1); + SANDBOX_SLOT(1) = 100; SANDBOX_SLOT(2) = 100; @@ -295,6 +305,8 @@ static VALUE se_play(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_AWAIT(check_arity, argc, 1, -1); + SANDBOX_SLOT(1) = 100; SANDBOX_SLOT(2) = 100; diff --git a/binding-sandbox/binding-util.cpp b/binding-sandbox/binding-util.cpp index 56a8f829..54e2f1ca 100644 --- a/binding-sandbox/binding-util.cpp +++ b/binding-sandbox/binding-util.cpp @@ -118,3 +118,41 @@ void exception_raise::operator()(const Exception &exception) { SANDBOX_AWAIT(rb_exc_raise, SANDBOX_SLOT(0)); } } + +void check_arity::operator()(int32_t argc, int32_t min_argc, int32_t max_argc) { + BOOST_ASIO_CORO_REENTER (this) { + if (argc < min_argc || (max_argc != -1 && argc > max_argc)) { + SANDBOX_AWAIT(rb_error_arity, argc, min_argc, max_argc); + } + } +} + +void check_type::operator()(VALUE obj, VALUE klass) { + BOOST_ASIO_CORO_REENTER (this) { + SANDBOX_AWAIT_S(0, rb_obj_is_kind_of, obj, klass); + if (!SANDBOX_VALUE_TO_BOOL(SANDBOX_SLOT(0))) { + SANDBOX_AWAIT_S(0, rb_str_new_cstr, "no implicit conversion of "); + SANDBOX_AWAIT_S(1, rb_obj_class, obj); + SANDBOX_AWAIT_S(1, rb_class_name, SANDBOX_SLOT(1)); + SANDBOX_AWAIT(rb_str_append, SANDBOX_SLOT(0), SANDBOX_SLOT(1)); + SANDBOX_AWAIT(rb_str_cat_cstr, SANDBOX_SLOT(0), " into "); + SANDBOX_AWAIT_S(1, rb_class_name, klass); + SANDBOX_AWAIT(rb_str_append, SANDBOX_SLOT(0), SANDBOX_SLOT(1)); + SANDBOX_AWAIT_S(0, rb_class_new_instance, 1, &SANDBOX_SLOT(0), sb()->rb_eTypeError()); + SANDBOX_AWAIT(rb_exc_raise, SANDBOX_SLOT(0)); + } + } +} + +void raise_disposed_access::operator()(VALUE obj) { + BOOST_ASIO_CORO_REENTER (this) { + SANDBOX_AWAIT_S(1, rb_obj_class, obj); + SANDBOX_AWAIT_S(1, rb_class_name, SANDBOX_SLOT(1)); + SANDBOX_AWAIT_S(2, rb_intern, "downcase!"); + SANDBOX_AWAIT(rb_funcall, SANDBOX_SLOT(1), SANDBOX_SLOT(2), 0); + SANDBOX_AWAIT_S(0, rb_str_new_cstr, "disposed "); + SANDBOX_AWAIT(rb_str_append, SANDBOX_SLOT(0), SANDBOX_SLOT(1)); + SANDBOX_AWAIT_S(0, rb_class_new_instance, 1, &SANDBOX_SLOT(0), rgss_error_class); + SANDBOX_AWAIT(rb_exc_raise, SANDBOX_SLOT(0)); + } +} diff --git a/binding-sandbox/binding-util.h b/binding-sandbox/binding-util.h index 086cf813..46e9ccab 100644 --- a/binding-sandbox/binding-util.h +++ b/binding-sandbox/binding-util.h @@ -136,7 +136,7 @@ #define SANDBOX_DEF_CLASS_PROP_F(S, prop, name) SANDBOX_DEF_CLASS_PROP(float, rb_float_new, rb_num2dbl, S, prop, name) #define SANDBOX_DEF_CLASS_PROP_D(S, prop, name) SANDBOX_DEF_CLASS_PROP(double, rb_float_new, rb_num2dbl, S, prop, name) -#define SANDBOX_DEF_CLASS_PROP_OBJ_REF(S, V, prop, name) \ +#define SANDBOX_DEF_CLASS_PROP_OBJ_REF(S, V, klass, prop, name) \ static VALUE get_##name(VALUE self) { \ using namespace ::mkxp_sandbox; \ return sb()->bind()()(self, #name); \ @@ -146,6 +146,9 @@ struct coro : boost::asio::coroutine { \ VALUE operator()(VALUE self, VALUE value) { \ BOOST_ASIO_CORO_REENTER (this) { \ + if (value != SANDBOX_NIL) { \ + SANDBOX_AWAIT(check_type, value, klass); \ + } \ { \ V *v = value == SANDBOX_NIL ? nullptr : get_private_data(value); \ S::set##prop(v); \ @@ -158,16 +161,24 @@ return sb()->bind()()(self, value); \ } -#define SANDBOX_DEF_CLASS_PROP_OBJ_VAL(S, V, prop, name) \ +#define SANDBOX_DEF_CLASS_PROP_OBJ_VAL(S, V, klass, prop, name) \ static VALUE get_##name(VALUE self) { \ using namespace ::mkxp_sandbox; \ return sb()->bind()()(self, #name); \ } \ static VALUE set_##name(VALUE self, VALUE value) { \ using namespace ::mkxp_sandbox; \ - V *v = get_private_data(value); \ - S::set##prop(*v); \ - return value; \ + struct coro : boost::asio::coroutine { \ + VALUE operator()(VALUE self, VALUE value) { \ + BOOST_ASIO_CORO_REENTER (this) { \ + SANDBOX_AWAIT(check_type, value, klass); \ + V *v = get_private_data(value); \ + S::set##prop(*v); \ + } \ + return value; \ + } \ + }; \ + return sb()->bind()()(self, value); \ } #define SANDBOX_DEF_PROP_B(S, prop, name) \ @@ -209,7 +220,7 @@ #define SANDBOX_DEF_PROP_F(S, prop, name) SANDBOX_DEF_PROP(float, rb_float_new, rb_num2dbl, S, prop, name) #define SANDBOX_DEF_PROP_D(S, prop, name) SANDBOX_DEF_PROP(double, rb_float_new, rb_num2dbl, S, prop, name) -#define SANDBOX_DEF_PROP_OBJ_REF(S, V, prop, name) \ +#define SANDBOX_DEF_PROP_OBJ_REF(S, V, klass, prop, name) \ static VALUE get_##name(VALUE self) { \ using namespace ::mkxp_sandbox; \ return sb()->bind()()(self, #name); \ @@ -219,6 +230,9 @@ struct coro : boost::asio::coroutine { \ VALUE operator()(VALUE self, VALUE value) { \ BOOST_ASIO_CORO_REENTER (this) { \ + if (value != SANDBOX_NIL) { \ + SANDBOX_AWAIT(check_type, value, klass); \ + } \ { \ S *s = get_private_data(self); \ V *v = value == SANDBOX_NIL ? nullptr : get_private_data(value); \ @@ -232,17 +246,25 @@ return sb()->bind()()(self, value); \ } -#define SANDBOX_DEF_PROP_OBJ_VAL(S, V, prop, name) \ +#define SANDBOX_DEF_PROP_OBJ_VAL(S, V, klass, prop, name) \ static VALUE get_##name(VALUE self) { \ using namespace ::mkxp_sandbox; \ return sb()->bind()()(self, #name); \ } \ static VALUE set_##name(VALUE self, VALUE value) { \ using namespace ::mkxp_sandbox; \ - S *s = get_private_data(self); \ - V *v = get_private_data(value); \ - s->set##prop(*v); \ - return value; \ + struct coro : boost::asio::coroutine { \ + VALUE operator()(VALUE self, VALUE value) { \ + BOOST_ASIO_CORO_REENTER (this) { \ + SANDBOX_AWAIT(check_type, value, klass); \ + S *s = get_private_data(self); \ + V *v = get_private_data(value); \ + s->set##prop(*v); \ + } \ + return value; \ + } \ + }; \ + return sb()->bind()()(self, value); \ } #define SANDBOX_DEF_GFX_PROP_B(S, prop, name) \ @@ -305,7 +327,7 @@ #define SANDBOX_DEF_GFX_PROP_F(S, prop, name) SANDBOX_DEF_GFX_PROP(float, rb_float_new, rb_num2dbl, S, prop, name) #define SANDBOX_DEF_GFX_PROP_D(S, prop, name) SANDBOX_DEF_GFX_PROP(double, rb_float_new, rb_num2dbl, S, prop, name) -#define SANDBOX_DEF_GFX_PROP_OBJ_REF(S, V, prop, name) \ +#define SANDBOX_DEF_GFX_PROP_OBJ_REF(S, V, klass, prop, name) \ static VALUE get_##name(VALUE self) { \ using namespace ::mkxp_sandbox; \ return sb()->bind()()(self, #name); \ @@ -315,6 +337,9 @@ struct coro : boost::asio::coroutine { \ VALUE operator()(VALUE self, VALUE value) { \ BOOST_ASIO_CORO_REENTER (this) { \ + if (value != SANDBOX_NIL) { \ + SANDBOX_AWAIT(check_type, value, klass); \ + } \ SANDBOX_GUARD_L(get_private_data(self)->set##prop(sb().e, value == SANDBOX_NIL ? nullptr : get_private_data(value))); \ SANDBOX_AWAIT(rb_iv_set, self, #name, value); \ } \ @@ -324,7 +349,7 @@ return sb()->bind()()(self, value); \ } -#define SANDBOX_DEF_GFX_PROP_OBJ_VAL(S, V, prop, name) \ +#define SANDBOX_DEF_GFX_PROP_OBJ_VAL(S, V, klass, prop, name) \ static VALUE get_##name(VALUE self) { \ using namespace ::mkxp_sandbox; \ return sb()->bind()()(self, #name); \ @@ -334,6 +359,7 @@ struct coro : boost::asio::coroutine { \ VALUE operator()(VALUE self, VALUE value) { \ BOOST_ASIO_CORO_REENTER (this) { \ + SANDBOX_AWAIT(check_type, value, klass); \ SANDBOX_GUARD_L(get_private_data(self)->set##prop(sb().e, *get_private_data(value))); \ } \ return value; \ @@ -382,7 +408,7 @@ #define SANDBOX_DEF_GRA_PROP_F(prop, name) SANDBOX_DEF_GRA_PROP(float, rb_float_new, rb_num2dbl, prop, name) #define SANDBOX_DEF_GRA_PROP_D(prop, name) SANDBOX_DEF_GRA_PROP(double, rb_float_new, rb_num2dbl, prop, name) -#define SANDBOX_DEF_GRA_PROP_OBJ_REF(V, prop, name) \ +#define SANDBOX_DEF_GRA_PROP_OBJ_REF(V, klass, prop, name) \ static VALUE get_##name(VALUE self) { \ using namespace ::mkxp_sandbox; \ return sb()->bind()()(self, #name); \ @@ -392,6 +418,9 @@ struct coro : boost::asio::coroutine { \ VALUE operator()(VALUE self, VALUE value) { \ BOOST_ASIO_CORO_REENTER (this) { \ + if (value != SANDBOX_NIL) { \ + SANDBOX_AWAIT(check_type, value, klass); \ + } \ { \ V *v = value == SANDBOX_NIL ? nullptr : get_private_data(value); \ GFX_LOCK; \ @@ -406,18 +435,26 @@ return sb()->bind()()(self, value); \ } -#define SANDBOX_DEF_GRA_PROP_OBJ_VAL(V, prop, name) \ +#define SANDBOX_DEF_GRA_PROP_OBJ_VAL(V, klass, prop, name) \ static VALUE get_##name(VALUE self) { \ using namespace ::mkxp_sandbox; \ return sb()->bind()()(self, #name); \ } \ static VALUE set_##name(VALUE self, VALUE value) { \ using namespace ::mkxp_sandbox; \ - V *v = get_private_data(value); \ - GFX_LOCK; \ - shState->graphics().set##prop(*v); \ - GFX_UNLOCK; \ - return value; \ + struct coro : boost::asio::coroutine { \ + VALUE operator()(VALUE self, VALUE value) { \ + BOOST_ASIO_CORO_REENTER (this) { \ + SANDBOX_AWAIT(check_type, value, klass); \ + V *v = get_private_data(value); \ + GFX_LOCK; \ + shState->graphics().set##prop(*v); \ + GFX_UNLOCK; \ + } \ + return value; \ + } \ + }; \ + return sb()->bind()()(self, value); \ } #define SANDBOX_INIT_FUNC_PROP_BIND(func, target, name) do { \ @@ -561,6 +598,20 @@ namespace mkxp_sandbox { typedef decl_slots slots; void operator()(const Exception &exception); }; + + struct check_arity : boost::asio::coroutine { + void operator()(int32_t argc, int32_t min_argc, int32_t max_argc); + }; + + struct check_type : boost::asio::coroutine { + typedef decl_slots slots; + void operator()(VALUE obj, VALUE klass); + }; + + struct raise_disposed_access : boost::asio::coroutine { + typedef decl_slots slots; + void operator()(VALUE klass); + }; } #endif // MKXPZ_SANDBOX_BINDING_UTIL_H diff --git a/binding-sandbox/bitmap-binding.cpp b/binding-sandbox/bitmap-binding.cpp index 379111d9..283f513a 100644 --- a/binding-sandbox/bitmap-binding.cpp +++ b/binding-sandbox/bitmap-binding.cpp @@ -19,7 +19,6 @@ ** along with mkxp. If not, see . */ -#include #include "bitmap-binding.h" #include "disposable-binding.h" #include "etc-binding.h" @@ -62,6 +61,8 @@ 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) { + SANDBOX_AWAIT(check_arity, argc, 1, -1); + if (argc == 1) { SANDBOX_AWAIT_S(0, rb_string_value_cstr, &sb()->ref(argv, 0)); } else { @@ -142,7 +143,7 @@ static VALUE height(VALUE self) { return sb()->bind()()(self); } -SANDBOX_DEF_GFX_PROP_OBJ_REF(Bitmap, Bitmap, Hires, hires); +SANDBOX_DEF_GFX_PROP_OBJ_REF(Bitmap, Bitmap, bitmap_class, Hires, hires); static VALUE rect(VALUE self) { struct coro : boost::asio::coroutine { @@ -167,7 +168,8 @@ 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(check_arity, argc, 4, -1); + 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); @@ -176,7 +178,9 @@ static VALUE blt(int32_t argc, wasm_ptr_t argv, VALUE self) { SANDBOX_AWAIT_S(4, rb_num2int, sb()->ref(argv, 4)); } + SANDBOX_AWAIT(check_type, SANDBOX_SLOT(0), bitmap_class); if (get_private_data(SANDBOX_SLOT(0)) != nullptr) { + SANDBOX_AWAIT(check_type, SANDBOX_SLOT(1), rect_class); if (argc > 4) { SANDBOX_GUARD_L(get_private_data(self)->blt(sb().e, SANDBOX_SLOT(2), SANDBOX_SLOT(3), *get_private_data(SANDBOX_SLOT(0)), get_private_data(SANDBOX_SLOT(1))->toIntRect(), SANDBOX_SLOT(4))); } else { @@ -198,6 +202,8 @@ 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_AWAIT(check_arity, argc, 3, -1); + SANDBOX_SLOT(0) = sb()->ref(argv, 0); SANDBOX_SLOT(1) = sb()->ref(argv, 1); SANDBOX_SLOT(2) = sb()->ref(argv, 2); @@ -205,7 +211,9 @@ static VALUE stretch_blt(int32_t argc, wasm_ptr_t argv, VALUE self) { SANDBOX_AWAIT_S(3, rb_num2int, sb()->ref(argv, 3)); } + SANDBOX_AWAIT(check_type, SANDBOX_SLOT(1), bitmap_class); if (get_private_data(SANDBOX_SLOT(1)) != nullptr) { + SANDBOX_AWAIT(check_type, SANDBOX_SLOT(2), rect_class); if (argc > 4) { SANDBOX_GUARD_L(get_private_data(self)->stretchBlt(sb().e, get_private_data(SANDBOX_SLOT(0))->toIntRect(), *get_private_data(SANDBOX_SLOT(1)), get_private_data(SANDBOX_SLOT(2))->toIntRect(), SANDBOX_SLOT(3));); } else { @@ -228,12 +236,17 @@ static VALUE fill_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 == 2) { + SANDBOX_AWAIT(check_type, sb()->ref(argv, 0), rect_class); + SANDBOX_AWAIT(check_type, sb()->ref(argv, 1), color_class); SANDBOX_GUARD_L(get_private_data(self)->fillRect(sb().e, get_private_data(sb()->ref(argv, 0))->toIntRect(), get_private_data(sb()->ref(argv, 1))->norm)); } else { + SANDBOX_AWAIT(check_arity, argc, 5, -1); + 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)); + SANDBOX_AWAIT(check_type, sb()->ref(argv, 4), color_class); SANDBOX_GUARD_L(get_private_data(self)->fillRect(sb().e, SANDBOX_SLOT(0), SANDBOX_SLOT(1), SANDBOX_SLOT(2), SANDBOX_SLOT(3), get_private_data(sb()->ref(argv, 4))->norm)); } } @@ -298,6 +311,7 @@ static VALUE set_pixel(VALUE self, VALUE x, VALUE y, VALUE colorObj) { SANDBOX_AWAIT_S(0, rb_num2int, x); SANDBOX_AWAIT_S(1, rb_num2int, y); + SANDBOX_AWAIT(check_type, colorObj, color_class); SANDBOX_GUARD_L(get_private_data(self)->setPixel(sb().e, SANDBOX_SLOT(0), SANDBOX_SLOT(1), *get_private_data(colorObj))); } @@ -339,6 +353,7 @@ static VALUE draw_text(int32_t argc, wasm_ptr_t argv, VALUE self) { } else { SANDBOX_AWAIT_S(0, rb_string_value_cstr, &sb()->ref(argv, 1)); } + SANDBOX_AWAIT(check_type, sb()->ref(argv, 0), rect_class); if (argc == 2) { SANDBOX_GUARD_L(get_private_data(self)->drawText(sb().e, get_private_data(sb()->ref(argv, 0))->toIntRect(), sb()->str(SANDBOX_SLOT(0)));); } else { @@ -346,6 +361,8 @@ static VALUE draw_text(int32_t argc, wasm_ptr_t argv, VALUE self) { SANDBOX_GUARD_L(get_private_data(self)->drawText(sb().e, get_private_data(sb()->ref(argv, 0))->toIntRect(), sb()->str(SANDBOX_SLOT(0)), SANDBOX_SLOT(2));); } } else { + SANDBOX_AWAIT(check_arity, argc, 5, -1); + 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)); @@ -474,12 +491,7 @@ static VALUE snap_to_bitmap(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 - if (argc < 1) { - SANDBOX_SLOT(1) = -1; - } else { - SANDBOX_AWAIT_S(1, rb_num2int, sb()->ref(argv, 0)); - } + SANDBOX_AWAIT_S(1, rb_num2int, sb()->ref(argv, 0)); SANDBOX_AWAIT_S(0, rb_obj_alloc, bitmap_class); @@ -507,8 +519,13 @@ static VALUE gradient_fill_rect(int32_t argc, wasm_ptr_t argv, VALUE self) { } else { SANDBOX_SLOT(4) = false; } + SANDBOX_AWAIT(check_type, sb()->ref(argv, 0), rect_class); + SANDBOX_AWAIT(check_type, sb()->ref(argv, 1), color_class); + SANDBOX_AWAIT(check_type, sb()->ref(argv, 2), color_class); SANDBOX_GUARD_L(get_private_data(self)->gradientFillRect(sb().e, 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(check_arity, argc, 6, -1); + 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)); @@ -518,6 +535,8 @@ static VALUE gradient_fill_rect(int32_t argc, wasm_ptr_t argv, VALUE self) { } else { SANDBOX_SLOT(4) = false; } + SANDBOX_AWAIT(check_type, sb()->ref(argv, 4), color_class); + SANDBOX_AWAIT(check_type, sb()->ref(argv, 5), color_class); SANDBOX_GUARD_L(get_private_data(self)->gradientFillRect(sb().e, 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))); } } @@ -536,8 +555,11 @@ 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) { + SANDBOX_AWAIT(check_type, sb()->ref(argv, 0), rect_class); SANDBOX_GUARD_L(get_private_data(self)->clearRect(sb().e, get_private_data(sb()->ref(argv, 0))->toIntRect())); } else { + SANDBOX_AWAIT(check_arity, argc, 4, -1); + 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)); @@ -715,7 +737,7 @@ static VALUE add_frame(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(check_arity, argc, 1, -1); if (argc < 2) { SANDBOX_SLOT(1) = -1; } else { @@ -725,6 +747,10 @@ static VALUE add_frame(int32_t argc, wasm_ptr_t argv, VALUE self) { } } if (argc >= 1) { + SANDBOX_AWAIT(check_type, sb()->ref(argv, 0), bitmap_class); + if (!has_private_data(sb()->ref(argv, 0))) { + SANDBOX_AWAIT(raise_disposed_access, sb()->ref(argv, 0)); + } SANDBOX_GUARD_L(SANDBOX_SLOT(1) = get_private_data(self)->addFrame(sb().e, *get_private_data(sb()->ref(argv, 0)), SANDBOX_SLOT(1))); } SANDBOX_AWAIT_S(0, rb_ll2inum, SANDBOX_SLOT(1)); @@ -743,7 +769,7 @@ static VALUE remove_frame(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 < 2) { + if (argc < 1) { SANDBOX_SLOT(0) = -1; } else { SANDBOX_AWAIT_S(0, rb_num2int, sb()->ref(argv, 0)); @@ -795,7 +821,23 @@ SANDBOX_DEF_GFX_PROP_F(Bitmap, AnimationFPS, frame_rate); SANDBOX_DEF_GFX_PROP_B(Bitmap, Looping, looping); static VALUE get_font(VALUE self) { - return sb()->bind()()(self, "font"); + struct coro : boost::asio::coroutine { + typedef decl_slots slots; + + VALUE operator()(VALUE self) { + BOOST_ASIO_CORO_REENTER (this) { + if (get_private_data(self)->isDisposed()) { + SANDBOX_AWAIT(raise_disposed_access, self); + } + + SANDBOX_AWAIT_S(0, rb_iv_get, self, "font"); + } + + return SANDBOX_SLOT(0); + } + }; + + return sb()->bind()()(self); } static VALUE set_font(VALUE self, VALUE value) { @@ -804,6 +846,7 @@ static VALUE set_font(VALUE self, VALUE value) { VALUE operator()(VALUE self, VALUE value) { BOOST_ASIO_CORO_REENTER (this) { + SANDBOX_AWAIT(check_type, value, font_class); if (get_private_data(value) != nullptr) { SANDBOX_GUARD_L(get_private_data(self)->setFont(sb().e, *get_private_data(value))); diff --git a/binding-sandbox/etc-binding.cpp b/binding-sandbox/etc-binding.cpp index 93780860..8d14d472 100644 --- a/binding-sandbox/etc-binding.cpp +++ b/binding-sandbox/etc-binding.cpp @@ -46,7 +46,7 @@ struct color_binding_init : boost::asio::coroutine { if (argc == 0) { set_private_data(self, new Color); } else { - // TODO: make these optional + SANDBOX_AWAIT(check_arity, argc, 3, -1); 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)); @@ -90,9 +90,10 @@ 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) { + SANDBOX_AWAIT(check_type, sb()->ref(argv, 0), color_class); *get_private_data(self) = *get_private_data(sb()->ref(argv, 0)); } else { - // TODO: make these optional + SANDBOX_AWAIT(check_arity, argc, 3, -1); 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)); @@ -179,7 +180,7 @@ struct tone_binding_init : boost::asio::coroutine { if (argc == 0) { set_private_data(self, new Tone); } else { - // TODO: make these optional + SANDBOX_AWAIT(check_arity, argc, 3, -1); 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)); @@ -223,9 +224,10 @@ 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) { + SANDBOX_AWAIT(check_type, sb()->ref(argv, 0), tone_class); *get_private_data(self) = *get_private_data(sb()->ref(argv, 0)); } else { - // TODO: make these optional + SANDBOX_AWAIT(check_arity, argc, 3, -1); 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)); @@ -312,7 +314,7 @@ struct rect_binding_init : boost::asio::coroutine { if (argc == 0) { set_private_data(self, new Rect); } else { - // TODO: make these optional + SANDBOX_AWAIT(check_arity, argc, 4, -1); 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)); @@ -352,9 +354,10 @@ 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) { + SANDBOX_AWAIT(check_type, sb()->ref(argv, 0), rect_class); *get_private_data(self) = *get_private_data(sb()->ref(argv, 0)); } else { - // TODO: make these optional + SANDBOX_AWAIT(check_arity, argc, 4, -1); 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)); diff --git a/binding-sandbox/flashable-binding.h b/binding-sandbox/flashable-binding.h index 7c213caf..ddac1387 100644 --- a/binding-sandbox/flashable-binding.h +++ b/binding-sandbox/flashable-binding.h @@ -23,6 +23,7 @@ #define MKXPZ_SANDBOX_FLASHABLE_BINDING_H #include "binding-util.h" +#include "etc-binding.h" #include "etc.h" namespace mkxp_sandbox { @@ -35,6 +36,9 @@ namespace mkxp_sandbox { VALUE operator()(VALUE self, VALUE obj, VALUE value) { BOOST_ASIO_CORO_REENTER (this) { SANDBOX_AWAIT_S(0, rb_num2int, value); + if (obj != SANDBOX_NIL) { + SANDBOX_AWAIT(check_type, obj, color_class); + } get_private_data(self)->flash(obj == SANDBOX_NIL ? nullptr : &get_private_data(obj)->norm, SANDBOX_SLOT(0)); } diff --git a/binding-sandbox/font-binding.cpp b/binding-sandbox/font-binding.cpp index 686eec19..18128399 100644 --- a/binding-sandbox/font-binding.cpp +++ b/binding-sandbox/font-binding.cpp @@ -200,10 +200,10 @@ static VALUE set_size(VALUE self, VALUE value) { SANDBOX_DEF_PROP_B(Font, Bold, bold); SANDBOX_DEF_PROP_B(Font, Italic, italic); -SANDBOX_DEF_PROP_OBJ_VAL(Font, Color, Color, color); +SANDBOX_DEF_PROP_OBJ_VAL(Font, Color, color_class, Color, color); SANDBOX_DEF_PROP_B(Font, Shadow, shadow); SANDBOX_DEF_PROP_B(Font, Outline, outline); -SANDBOX_DEF_PROP_OBJ_VAL(Font, Color, OutColor, out_color); +SANDBOX_DEF_PROP_OBJ_VAL(Font, Color, color_class, OutColor, out_color); static VALUE get_default_name(VALUE self) { return sb()->bind()()(self, "default_name"); @@ -235,10 +235,10 @@ static VALUE set_default_name(VALUE self, VALUE value) { SANDBOX_DEF_CLASS_PROP_I(Font, DefaultSize, default_size); SANDBOX_DEF_CLASS_PROP_B(Font, DefaultBold, default_bold); SANDBOX_DEF_CLASS_PROP_B(Font, DefaultItalic, default_italic); -SANDBOX_DEF_CLASS_PROP_OBJ_VAL(Font, Color, DefaultColor, default_color); +SANDBOX_DEF_CLASS_PROP_OBJ_VAL(Font, Color, color_class, DefaultColor, default_color); SANDBOX_DEF_CLASS_PROP_B(Font, DefaultShadow, default_shadow); SANDBOX_DEF_CLASS_PROP_B(Font, DefaultOutline, default_outline); -SANDBOX_DEF_CLASS_PROP_OBJ_VAL(Font, Color, DefaultOutColor, default_out_color); +SANDBOX_DEF_CLASS_PROP_OBJ_VAL(Font, Color, color_class, DefaultOutColor, default_out_color); static VALUE exist(VALUE self, VALUE value) { struct coro : boost::asio::coroutine { diff --git a/binding-sandbox/graphics-binding.cpp b/binding-sandbox/graphics-binding.cpp index a117123c..fd1c014a 100644 --- a/binding-sandbox/graphics-binding.cpp +++ b/binding-sandbox/graphics-binding.cpp @@ -315,7 +315,8 @@ 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(check_arity, argc, 2, -1); + SANDBOX_AWAIT_S(0, rb_num2int, sb()->ref(argv, 0)); SANDBOX_AWAIT_S(1, rb_num2int, sb()->ref(argv, 1)); GFX_LOCK; @@ -349,7 +350,8 @@ static VALUE play_movie(int32_t argc, wasm_ptr_t argv, VALUE self) { BOOST_ASIO_CORO_REENTER (this) { GFX_LOCK; - // TODO: require at least 1 argument + SANDBOX_AWAIT(check_arity, argc, 1, -1); + SANDBOX_AWAIT_S(0, rb_string_value_cstr, &sb()->ref(argv, 0)); if (argc >= 2) { SANDBOX_AWAIT_S(1, rb_num2int, sb()->ref(argv, 1)); diff --git a/binding-sandbox/plane-binding.cpp b/binding-sandbox/plane-binding.cpp index b1b6d54e..95169d7d 100644 --- a/binding-sandbox/plane-binding.cpp +++ b/binding-sandbox/plane-binding.cpp @@ -20,6 +20,7 @@ */ #include "plane-binding.h" +#include "bitmap-binding.h" #include "disposable-binding.h" #include "etc-binding.h" #include "viewportelement-binding.h" @@ -55,9 +56,9 @@ static VALUE initialize(int32_t argc, wasm_ptr_t argv, VALUE self) { return sb()->bind()()(argc, argv, self); } -SANDBOX_DEF_GFX_PROP_OBJ_REF(Plane, Bitmap, Bitmap, bitmap); -SANDBOX_DEF_GFX_PROP_OBJ_VAL(Plane, Color, Color, color); -SANDBOX_DEF_GFX_PROP_OBJ_VAL(Plane, Tone, Tone, tone); +SANDBOX_DEF_GFX_PROP_OBJ_REF(Plane, Bitmap, bitmap_class, Bitmap, bitmap); +SANDBOX_DEF_GFX_PROP_OBJ_VAL(Plane, Color, color_class, Color, color); +SANDBOX_DEF_GFX_PROP_OBJ_VAL(Plane, Tone, tone_class, Tone, tone); SANDBOX_DEF_GFX_PROP_I(Plane, OX, ox); SANDBOX_DEF_GFX_PROP_I(Plane, OY, oy); SANDBOX_DEF_GFX_PROP_F(Plane, ZoomX, zoom_x); diff --git a/binding-sandbox/sprite-binding.cpp b/binding-sandbox/sprite-binding.cpp index 851b5412..d160f7dd 100644 --- a/binding-sandbox/sprite-binding.cpp +++ b/binding-sandbox/sprite-binding.cpp @@ -20,6 +20,7 @@ */ #include "sprite-binding.h" +#include "bitmap-binding.h" #include "disposable-binding.h" #include "etc-binding.h" #include "flashable-binding.h" @@ -56,8 +57,8 @@ static VALUE initialize(int32_t argc, wasm_ptr_t argv, VALUE self) { return sb()->bind()()(argc, argv, self); } -SANDBOX_DEF_GFX_PROP_OBJ_REF(Sprite, Bitmap, Bitmap, bitmap); -SANDBOX_DEF_GFX_PROP_OBJ_VAL(Sprite, Rect, SrcRect, src_rect); +SANDBOX_DEF_GFX_PROP_OBJ_REF(Sprite, Bitmap, bitmap_class, Bitmap, bitmap); +SANDBOX_DEF_GFX_PROP_OBJ_VAL(Sprite, Rect, rect_class, SrcRect, src_rect); SANDBOX_DEF_GFX_PROP_I(Sprite, X, x); SANDBOX_DEF_GFX_PROP_I(Sprite, Y, y); SANDBOX_DEF_GFX_PROP_I(Sprite, OX, ox); @@ -69,8 +70,8 @@ SANDBOX_DEF_GFX_PROP_B(Sprite, Mirror, mirror); SANDBOX_DEF_GFX_PROP_I(Sprite, BushDepth, bush_depth); SANDBOX_DEF_GFX_PROP_I(Sprite, Opacity, opacity); SANDBOX_DEF_GFX_PROP_I(Sprite, BlendType, blend_type); -SANDBOX_DEF_GFX_PROP_OBJ_VAL(Sprite, Color, Color, color); -SANDBOX_DEF_GFX_PROP_OBJ_VAL(Sprite, Tone, Tone, tone); +SANDBOX_DEF_GFX_PROP_OBJ_VAL(Sprite, Color, color_class, Color, color); +SANDBOX_DEF_GFX_PROP_OBJ_VAL(Sprite, Tone, tone_class, Tone, tone); static VALUE width(VALUE self) { struct coro : boost::asio::coroutine { @@ -106,7 +107,7 @@ static VALUE height(VALUE self) { SANDBOX_DEF_GFX_PROP_I(Sprite, BushOpacity, bush_opacity); -SANDBOX_DEF_GFX_PROP_OBJ_REF(Sprite, Bitmap, Pattern, pattern); +SANDBOX_DEF_GFX_PROP_OBJ_REF(Sprite, Bitmap, bitmap_class, Pattern, pattern); SANDBOX_DEF_GFX_PROP_I(Sprite, PatternBlendType, pattern_blend_type); SANDBOX_DEF_GFX_PROP_B(Sprite, PatternTile, pattern_tile); SANDBOX_DEF_GFX_PROP_I(Sprite, PatternOpacity, pattern_opacity); diff --git a/binding-sandbox/table-binding.cpp b/binding-sandbox/table-binding.cpp index 14caf352..9a6d29f0 100644 --- a/binding-sandbox/table-binding.cpp +++ b/binding-sandbox/table-binding.cpp @@ -36,9 +36,10 @@ 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) { + SANDBOX_AWAIT(check_arity, argc, 1, 3); + SANDBOX_SLOT(1) = SANDBOX_SLOT(2) = 1; - // TODO: throw error if too many or too few arguments SANDBOX_AWAIT_S(0, rb_num2int, sb()->ref(argv, 0)); SANDBOX_SLOT(0) = std::max(SANDBOX_SLOT(0), (int32_t)0); if (argc >= 2) { @@ -89,9 +90,10 @@ static VALUE resize(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_AWAIT(check_arity, argc, 1, 3); + SANDBOX_SLOT(1) = SANDBOX_SLOT(2) = 1; - // TODO: throw error if too many or too few arguments SANDBOX_AWAIT_S(0, rb_num2int, sb()->ref(argv, 0)); SANDBOX_SLOT(0) = std::max(SANDBOX_SLOT(0), (int32_t)0); if (argc >= 2) { @@ -131,6 +133,8 @@ static VALUE get(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_AWAIT(check_arity, argc, 1, 3); + SANDBOX_SLOT(2) = SANDBOX_SLOT(3) = 0; SANDBOX_AWAIT_S(1, rb_num2int, sb()->ref(argv, 0)); @@ -138,7 +142,6 @@ static VALUE get(int32_t argc, wasm_ptr_t argv, VALUE self) { SANDBOX_AWAIT_S(2, rb_num2int, sb()->ref(argv, 1)); if (argc >= 3) { SANDBOX_AWAIT_S(3, rb_num2int, sb()->ref(argv, 2)); - // TODO: throw error if too many arguments } } @@ -162,9 +165,9 @@ static VALUE set(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) = SANDBOX_SLOT(2) = 0; + SANDBOX_AWAIT(check_arity, argc, 2, 4); - // TODO: throw error if too few arguments + SANDBOX_SLOT(1) = SANDBOX_SLOT(2) = 0; SANDBOX_AWAIT_S(0, rb_num2int, sb()->ref(argv, 0)); if (argc >= 3) { diff --git a/binding-sandbox/tilemap-binding.cpp b/binding-sandbox/tilemap-binding.cpp index 6392cebb..6ef751b1 100644 --- a/binding-sandbox/tilemap-binding.cpp +++ b/binding-sandbox/tilemap-binding.cpp @@ -20,8 +20,11 @@ */ #include "tilemap-binding.h" +#include "bitmap-binding.h" #include "disposable-binding.h" #include "etc-binding.h" +#include "table-binding.h" +#include "viewport-binding.h" #include "tilemap.h" using namespace mkxp_sandbox; @@ -62,6 +65,7 @@ struct tilemap_autotiles_binding_init : boost::asio::coroutine { SANDBOX_AWAIT_S(0, rb_num2ulong, i); + SANDBOX_AWAIT(check_type, obj, bitmap_class); get_private_data(self)->set(SANDBOX_SLOT(0), get_private_data(obj)); SANDBOX_AWAIT_S(1, rb_iv_get, self, "array"); SANDBOX_AWAIT(rb_ary_store, SANDBOX_SLOT(1), SANDBOX_SLOT(0), obj); @@ -100,6 +104,10 @@ static VALUE initialize(int32_t argc, wasm_ptr_t argv, VALUE self) { BOOST_ASIO_CORO_REENTER (this) { GFX_LOCK; + if (argc > 0) { + SANDBOX_AWAIT(check_type, sb()->ref(argv, 0), viewport_class); + } + { SANDBOX_SLOT(0) = SANDBOX_NIL; Viewport *viewport = nullptr; @@ -171,21 +179,37 @@ static VALUE update(VALUE self) { } static VALUE viewport(VALUE self) { - return sb()->bind()()(self, "viewport"); + struct coro : boost::asio::coroutine { + typedef decl_slots slots; + + VALUE operator()(VALUE self) { + BOOST_ASIO_CORO_REENTER (this) { + if (get_private_data(self)->isDisposed()) { + SANDBOX_AWAIT(raise_disposed_access, self); + } + + SANDBOX_AWAIT_S(0, rb_iv_get, self, "viewport"); + } + + return SANDBOX_SLOT(0); + } + }; + + return sb()->bind()()(self); } -SANDBOX_DEF_GFX_PROP_OBJ_REF(Tilemap, Bitmap, Tileset, tileset); -SANDBOX_DEF_GFX_PROP_OBJ_REF(Tilemap, Table, MapData, map_data); -SANDBOX_DEF_GFX_PROP_OBJ_REF(Tilemap, Table, FlashData, flash_data); -SANDBOX_DEF_GFX_PROP_OBJ_REF(Tilemap, Table, Priorities, priorities); +SANDBOX_DEF_GFX_PROP_OBJ_REF(Tilemap, Bitmap, bitmap_class, Tileset, tileset); +SANDBOX_DEF_GFX_PROP_OBJ_REF(Tilemap, Table, table_class, MapData, map_data); +SANDBOX_DEF_GFX_PROP_OBJ_REF(Tilemap, Table, table_class, FlashData, flash_data); +SANDBOX_DEF_GFX_PROP_OBJ_REF(Tilemap, Table, table_class, Priorities, priorities); SANDBOX_DEF_GFX_PROP_B(Tilemap, Visible, visible); SANDBOX_DEF_GFX_PROP_I(Tilemap, OX, ox); SANDBOX_DEF_GFX_PROP_I(Tilemap, OY, oy); SANDBOX_DEF_GFX_PROP_I(Tilemap, Opacity, opacity); SANDBOX_DEF_GFX_PROP_I(Tilemap, BlendType, blend_type); -SANDBOX_DEF_GFX_PROP_OBJ_VAL(Tilemap, Color, Color, color); -SANDBOX_DEF_GFX_PROP_OBJ_VAL(Tilemap, Tone, Tone, tone); +SANDBOX_DEF_GFX_PROP_OBJ_VAL(Tilemap, Color, color_class, Color, color); +SANDBOX_DEF_GFX_PROP_OBJ_VAL(Tilemap, Tone, tone_class, Tone, tone); void tilemap_binding_init::operator()() { BOOST_ASIO_CORO_REENTER (this) { diff --git a/binding-sandbox/tilemapvx-binding.cpp b/binding-sandbox/tilemapvx-binding.cpp index d52f69cb..230f08ba 100644 --- a/binding-sandbox/tilemapvx-binding.cpp +++ b/binding-sandbox/tilemapvx-binding.cpp @@ -20,7 +20,10 @@ */ #include "tilemapvx-binding.h" +#include "bitmap-binding.h" #include "disposable-binding.h" +#include "table-binding.h" +#include "viewport-binding.h" #include "tilemapvx.h" using namespace mkxp_sandbox; @@ -61,6 +64,7 @@ struct bitmap_array_binding_init : boost::asio::coroutine { SANDBOX_AWAIT_S(0, rb_num2ulong, i); + SANDBOX_AWAIT(check_type, obj, bitmap_class); get_private_data(self)->set(SANDBOX_SLOT(0), get_private_data(obj)); SANDBOX_AWAIT_S(1, rb_iv_get, self, "array"); SANDBOX_AWAIT(rb_ary_store, SANDBOX_SLOT(1), SANDBOX_SLOT(0), obj); @@ -97,6 +101,10 @@ 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 > 0) { + SANDBOX_AWAIT(check_type, sb()->ref(argv, 0), viewport_class); + } + { SANDBOX_SLOT(0) = SANDBOX_NIL; Viewport *viewport = nullptr; @@ -159,15 +167,15 @@ static VALUE update(VALUE self) { return sb()->bind()()(self); } -SANDBOX_DEF_GFX_PROP_OBJ_REF(TilemapVX, Viewport, Viewport, viewport); -SANDBOX_DEF_GFX_PROP_OBJ_REF(TilemapVX, Table, MapData, map_data); -SANDBOX_DEF_GFX_PROP_OBJ_REF(TilemapVX, Table, FlashData, flash_data); +SANDBOX_DEF_GFX_PROP_OBJ_REF(TilemapVX, Viewport, viewport_class, Viewport, viewport); +SANDBOX_DEF_GFX_PROP_OBJ_REF(TilemapVX, Table, table_class, MapData, map_data); +SANDBOX_DEF_GFX_PROP_OBJ_REF(TilemapVX, Table, table_class, FlashData, flash_data); SANDBOX_DEF_GFX_PROP_B(TilemapVX, Visible, visible); SANDBOX_DEF_GFX_PROP_I(TilemapVX, OX, ox); SANDBOX_DEF_GFX_PROP_I(TilemapVX, OY, oy); -SANDBOX_DEF_GFX_PROP_OBJ_REF(TilemapVX, Table, Flags, flags); -SANDBOX_DEF_GFX_PROP_OBJ_REF(TilemapVX, Table, Flags, passages); +SANDBOX_DEF_GFX_PROP_OBJ_REF(TilemapVX, Table, table_class, Flags, flags); +SANDBOX_DEF_GFX_PROP_OBJ_REF(TilemapVX, Table, table_class, Flags, passages); void tilemapvx_binding_init::operator()() { BOOST_ASIO_CORO_REENTER (this) { diff --git a/binding-sandbox/viewport-binding.cpp b/binding-sandbox/viewport-binding.cpp index 594c774b..e34b694a 100644 --- a/binding-sandbox/viewport-binding.cpp +++ b/binding-sandbox/viewport-binding.cpp @@ -47,6 +47,7 @@ static VALUE initialize(int32_t argc, wasm_ptr_t argv, VALUE self) { viewport = new Viewport; } else if (argc == 1) { GFX_LOCK; + SANDBOX_AWAIT(check_type, sb()->ref(argv, 0), rect_class); viewport = new Viewport(get_private_data(sb()->ref(argv, 0))); } else { SANDBOX_AWAIT_S(0, rb_num2int, sb()->ref(argv, 0)); @@ -76,11 +77,11 @@ static VALUE initialize(int32_t argc, wasm_ptr_t argv, VALUE self) { return sb()->bind()()(argc, argv, self); } -SANDBOX_DEF_GFX_PROP_OBJ_VAL(Viewport, Rect, Rect, rect); +SANDBOX_DEF_GFX_PROP_OBJ_VAL(Viewport, Rect, rect_class, Rect, rect); SANDBOX_DEF_GFX_PROP_I(Viewport, OX, ox); SANDBOX_DEF_GFX_PROP_I(Viewport, OY, oy); -SANDBOX_DEF_GFX_PROP_OBJ_VAL(Viewport, Color, Color, color); -SANDBOX_DEF_GFX_PROP_OBJ_VAL(Viewport, Tone, Tone, tone); +SANDBOX_DEF_GFX_PROP_OBJ_VAL(Viewport, Color, color_class, Color, color); +SANDBOX_DEF_GFX_PROP_OBJ_VAL(Viewport, Tone, tone_class, Tone, tone); void viewport_binding_init::operator()() { BOOST_ASIO_CORO_REENTER (this) { diff --git a/binding-sandbox/viewportelement-binding.h b/binding-sandbox/viewportelement-binding.h index d8ee14e9..253f35be 100644 --- a/binding-sandbox/viewportelement-binding.h +++ b/binding-sandbox/viewportelement-binding.h @@ -24,6 +24,7 @@ #include "binding-util.h" #include "sceneelement-binding.h" +#include "viewport-binding.h" #include "viewport.h" namespace mkxp_sandbox { @@ -34,6 +35,10 @@ namespace mkxp_sandbox { BOOST_ASIO_CORO_REENTER (this) { SANDBOX_SLOT(0) = SANDBOX_NIL; + if (argc > 0) { + SANDBOX_AWAIT(check_type, sb()->ref(argv, 0), viewport_class); + } + { Viewport *viewport = nullptr; if (argc > 0) { @@ -59,13 +64,34 @@ namespace mkxp_sandbox { template struct viewportelement_binding_init : boost::asio::coroutine { private: - SANDBOX_DEF_PROP_OBJ_REF(C, Viewport, Viewport, viewport); + SANDBOX_DEF_PROP_OBJ_REF(C, Viewport, viewport_class, Viewport, viewport); + + static VALUE viewport(VALUE self) { + struct coro : boost::asio::coroutine { + typedef decl_slots slots; + + VALUE operator()(VALUE self) { + BOOST_ASIO_CORO_REENTER (this) { + if (get_private_data(self)->isDisposed()) { + SANDBOX_AWAIT(raise_disposed_access, self); + } + + SANDBOX_AWAIT_S(0, rb_iv_get, self, "viewport"); + } + + return SANDBOX_SLOT(0); + } + }; + + return sb()->bind()()(self); + } public: void operator()(VALUE klass) { BOOST_ASIO_CORO_REENTER (this) { SANDBOX_AWAIT(sceneelement_binding_init, klass); - SANDBOX_INIT_PROP_BIND(klass, viewport); + SANDBOX_AWAIT(rb_define_method, klass, "viewport", (VALUE (*)(ANYARGS))viewport, 0); \ + SANDBOX_AWAIT(rb_define_method, klass, "viewport=", (VALUE (*)(ANYARGS))set_viewport, 1); \ } } }; diff --git a/binding-sandbox/window-binding.cpp b/binding-sandbox/window-binding.cpp index 7dc7863b..01d1daa0 100644 --- a/binding-sandbox/window-binding.cpp +++ b/binding-sandbox/window-binding.cpp @@ -20,6 +20,7 @@ */ #include "window-binding.h" +#include "bitmap-binding.h" #include "disposable-binding.h" #include "etc-binding.h" #include "viewportelement-binding.h" @@ -67,10 +68,10 @@ static VALUE update(VALUE self) { return sb()->bind()()(self); } -SANDBOX_DEF_GFX_PROP_OBJ_REF(Window, Bitmap, Windowskin, windowskin); -SANDBOX_DEF_GFX_PROP_OBJ_REF(Window, Bitmap, Contents, contents); +SANDBOX_DEF_GFX_PROP_OBJ_REF(Window, Bitmap, bitmap_class, Windowskin, windowskin); +SANDBOX_DEF_GFX_PROP_OBJ_REF(Window, Bitmap, bitmap_class, Contents, contents); SANDBOX_DEF_GFX_PROP_B(Window, Stretch, stretch); -SANDBOX_DEF_GFX_PROP_OBJ_VAL(Window, Rect, CursorRect, cursor_rect); +SANDBOX_DEF_GFX_PROP_OBJ_VAL(Window, Rect, rect_class, CursorRect, cursor_rect); SANDBOX_DEF_GFX_PROP_B(Window, Active, active); SANDBOX_DEF_GFX_PROP_B(Window, Pause, pause); SANDBOX_DEF_GFX_PROP_I(Window, X, x); diff --git a/binding-sandbox/windowvx-binding.cpp b/binding-sandbox/windowvx-binding.cpp index fe65eddb..d6c2e76a 100644 --- a/binding-sandbox/windowvx-binding.cpp +++ b/binding-sandbox/windowvx-binding.cpp @@ -95,9 +95,9 @@ static VALUE update(VALUE self) { return sb()->bind()()(self); } -SANDBOX_DEF_GFX_PROP_OBJ_REF(WindowVX, Bitmap, Windowskin, windowskin); -SANDBOX_DEF_GFX_PROP_OBJ_REF(WindowVX, Bitmap, Contents, contents); -SANDBOX_DEF_GFX_PROP_OBJ_VAL(WindowVX, Rect, CursorRect, cursor_rect); +SANDBOX_DEF_GFX_PROP_OBJ_REF(WindowVX, Bitmap, bitmap_class, Windowskin, windowskin); +SANDBOX_DEF_GFX_PROP_OBJ_REF(WindowVX, Bitmap, bitmap_class, Contents, contents); +SANDBOX_DEF_GFX_PROP_OBJ_VAL(WindowVX, Rect, rect_class, CursorRect, cursor_rect); SANDBOX_DEF_GFX_PROP_B(WindowVX, Active, active); SANDBOX_DEF_GFX_PROP_B(WindowVX, Pause, pause); SANDBOX_DEF_GFX_PROP_I(WindowVX, X, x); @@ -166,7 +166,7 @@ static VALUE is_closed(VALUE self) { SANDBOX_DEF_GFX_PROP_B(WindowVX, ArrowsVisible, arrows_visible); SANDBOX_DEF_GFX_PROP_I(WindowVX, Padding, padding); SANDBOX_DEF_GFX_PROP_I(WindowVX, PaddingBottom, padding_bottom); -SANDBOX_DEF_GFX_PROP_OBJ_VAL(WindowVX, Tone, Tone, tone); +SANDBOX_DEF_GFX_PROP_OBJ_VAL(WindowVX, Tone, tone_class, Tone, tone); void windowvx_binding_init::operator()() { BOOST_ASIO_CORO_REENTER (this) {