Make sure sandbox stack grows upwards in big-endian libretro builds

This commit is contained in:
刘皓 2025-05-10 19:23:43 -04:00
parent 3ba12e5672
commit 58e6f71ef3
No known key found for this signature in database
GPG key ID: 7901753DB465B711
3 changed files with 30 additions and 5 deletions

View file

@ -289,7 +289,13 @@ namespace mkxp_sandbox {
fiber->stack.pop_back(); fiber->stack.pop_back();
} }
++fiber->stack_index; ++fiber->stack_index;
b.stack_ptr = w2c_ruby_rb_wasm_get_stack_pointer(&b.instance()) - CEIL_WASMSTACKALIGN(declared_slots_size<T>::value); b.stack_ptr = w2c_ruby_rb_wasm_get_stack_pointer(&b.instance())
#ifdef MKXPZ_BIG_ENDIAN
+
#else
-
#endif // MKXPZ_BIG_ENDIAN
CEIL_WASMSTACKALIGN(declared_slots_size<T>::value);
assert(b.stack_ptr % sizeof(VALUE) == 0); assert(b.stack_ptr % sizeof(VALUE) == 0);
assert(b.stack_ptr % WASMSTACKALIGN == 0); assert(b.stack_ptr % WASMSTACKALIGN == 0);
if (declared_slots_size<T>::value != 0) { if (declared_slots_size<T>::value != 0) {
@ -333,7 +339,16 @@ namespace mkxp_sandbox {
assert(fiber->stack.size() == fiber->stack_index); assert(fiber->stack.size() == fiber->stack_index);
w2c_ruby_rb_wasm_set_stack_pointer(&bind->instance(), fiber->stack.back().stack_ptr + CEIL_WASMSTACKALIGN(declared_slots_size<T>::value)); w2c_ruby_rb_wasm_set_stack_pointer(
&bind->instance(),
fiber->stack.back().stack_ptr
#ifdef MKXPZ_BIG_ENDIAN
-
#else
+
#endif // MKXPZ_BIG_ENDIAN
CEIL_WASMSTACKALIGN(declared_slots_size<T>::value)
);
bind->stack_ptr = fiber->stack.back().stack_ptr; bind->stack_ptr = fiber->stack.back().stack_ptr;
fiber->stack.pop_back(); fiber->stack.pop_back();
} }

View file

@ -269,6 +269,16 @@ PRELUDE = <<~HEREDOC
bindings::bindings(std::shared_ptr<struct w2c_#{MODULE_NAME}> m) : binding_base(m) {} bindings::bindings(std::shared_ptr<struct w2c_#{MODULE_NAME}> m) : binding_base(m) {}
static wasm_ptr_t _sbindgen_stack_push(wasm_ptr_t frame_pointer, wasm_size_t num_bytes) {
return frame_pointer
#ifdef MKXPZ_BIG_ENDIAN
+
#else
-
#endif // MKXPZ_BIG_ENDIAN
num_bytes;
}
static void _sbindgen_strcpy(char *dst, const char *src) { static void _sbindgen_strcpy(char *dst, const char *src) {
#ifdef MKXPZ_BIG_ENDIAN #ifdef MKXPZ_BIG_ENDIAN
do { do {
@ -512,7 +522,7 @@ File.readlines('tags', chomp: true).each do |line|
coroutine_initializer += <<~HEREDOC coroutine_initializer += <<~HEREDOC
{ {
wasm_ptr_t fp = w2c_ruby_rb_wasm_get_stack_pointer(&bind.instance()); wasm_ptr_t fp = w2c_ruby_rb_wasm_get_stack_pointer(&bind.instance());
wasm_ptr_t sp = fp - CEIL_WASMSTACKALIGN(a#{args.length - 2} * sizeof(VALUE)); wasm_ptr_t sp = _sbindgen_stack_push(fp, CEIL_WASMSTACKALIGN(a#{args.length - 2} * sizeof(VALUE)));
if (sp > fp) { if (sp > fp) {
throw std::bad_alloc(); throw std::bad_alloc();
} }
@ -539,7 +549,7 @@ File.readlines('tags', chomp: true).each do |line|
do ++n; while (va_arg(b, VALUE)); do ++n; while (va_arg(b, VALUE));
va_end(b); va_end(b);
wasm_ptr_t fp = w2c_ruby_rb_wasm_get_stack_pointer(&bind.instance()); wasm_ptr_t fp = w2c_ruby_rb_wasm_get_stack_pointer(&bind.instance());
wasm_ptr_t sp = fp - CEIL_WASMSTACKALIGN(n * sizeof(VALUE)); wasm_ptr_t sp = _sbindgen_stack_push(fp, CEIL_WASMSTACKALIGN(n * sizeof(VALUE)));
if (sp > fp) { if (sp > fp) {
throw std::bad_alloc(); throw std::bad_alloc();
} }

View file

@ -1979,7 +1979,7 @@ void Bitmap::replaceRaw(void *pixel_data, int size)
throw Exception(Exception::MKXPError, "Replacement bitmap data is not large enough (given %i bytes, need %i)", size, requiredsize); 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) #if defined(MKXPZ_RETRO) && defined(MKXPZ_BIG_ENDIAN)
output -= output_size; pixel_data -= output_size;
std::reverse((uint8_t *)pixel_data, (uint8_t *)pixel_data + size); std::reverse((uint8_t *)pixel_data, (uint8_t *)pixel_data + size);
#endif #endif