diff --git a/.github/workflows/autobuild.yml b/.github/workflows/autobuild.yml index 73fc04550..10c3ddb88 100644 --- a/.github/workflows/autobuild.yml +++ b/.github/workflows/autobuild.yml @@ -310,8 +310,8 @@ jobs: - uses: actions/cache@v4 with: path: | - retro/build - key: retro-phase1-${{ hashFiles('retro/Makefile', 'retro/extra-ruby-bindings.h') }} + retro/build/retro-phase1 + key: retro-phase1-${{ hashFiles('retro/Makefile', 'retro/extra-ruby-bindings.h', 'retro/sandbox-bindgen.rb') }} - name: Install apt dependencies run: | diff --git a/retro/Makefile b/retro/Makefile index 64e66a35b..09cbd8826 100644 --- a/retro/Makefile +++ b/retro/Makefile @@ -46,7 +46,8 @@ clean: clean-ruby-bindings: rm -f $(OUTDIR)/mkxp-sandbox-bindgen.cpp; \ rm -f $(OUTDIR)/mkxp-sandbox-bindgen.h; \ - rm -f $(LIBDIR)/tags + rm -f $(LIBDIR)/tags.c; \ + rm -f $(LIBDIR)/tags; \ $(OUTDIR)/libretro.h: mkdir -p $(OUTDIR); \ @@ -112,8 +113,11 @@ $(OUTDIR)/mkxp-sandbox-bindgen.cpp $(OUTDIR)/mkxp-sandbox-bindgen.h: $(LIBDIR)/t mv mkxp-sandbox-bindgen.h $(OUTDIR); \ mv mkxp-sandbox-bindgen.cpp $(OUTDIR) -$(LIBDIR)/tags: $(LIBDIR)/include/ruby-$(RUBY_VERSION).0 - $(CTAGS) -R --fields=S --kinds-c=p --kinds-c++=p -o $(LIBDIR)/tags $(LIBDIR)/include/ruby-$(RUBY_VERSION).0 +$(LIBDIR)/tags: $(LIBDIR)/tags.c + $(CTAGS) -R --fields=S --kinds-c=p --kinds-c++=p -o $(LIBDIR)/tags $(LIBDIR)/tags.c + +$(LIBDIR)/tags.c: $(RUBY) $(LIBDIR)/include/ruby-$(RUBY_VERSION).0 + echo '#include ' | $(CC) -E -I$(LIBDIR)/include/ruby-$(RUBY_VERSION).0 -I$(LIBDIR)/include/ruby-$(RUBY_VERSION).0/$(shell $(RUBY) -e 'puts RUBY_PLATFORM') -o $(LIBDIR)/tags.c - $(RUBY) $(LIBDIR)/include/ruby-$(RUBY_VERSION).0: $(DOWNLOADS)/baseruby/Makefile cd $(DOWNLOADS)/baseruby; \ diff --git a/retro/sandbox-bindgen.rb b/retro/sandbox-bindgen.rb index f044bfb55..c5a3656f7 100644 --- a/retro/sandbox-bindgen.rb +++ b/retro/sandbox-bindgen.rb @@ -45,10 +45,14 @@ ] ARG_HANDLERS = { - 'VALUE' => { keep: true, primitive: :ptr }, - 'ID' => { keep: true, primitive: :ptr }, + 'VALUE' => { keep: true, primitive: :size }, + 'ID' => { keep: true, primitive: :size }, 'int' => { primitive: :s32 }, 'unsigned int' => { primitive: :u32 }, + 'long' => { primitive: :size }, + 'unsigned long' => { primitive: :size }, + 'long long' => { primitive: :s64 }, + 'unsigned long long' => { primitive: :u64 }, 'const char *' => { keep: true, buf_size: 'std::strlen(ARG) + 1', @@ -57,14 +61,14 @@ '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(wasm_ptr_t)', + buf_size: 'PREV_ARG * sizeof(VALUE)', serialize: <<~HEREDOC for (int i = 0; i < PREV_ARG; ++i) { - ((wasm_ptr_t *)(module_instance->w2c_memory.data + BUF))[i] = SERIALIZE_PTR(ARG[i]); + ((VALUE *)(module_instance->w2c_memory.data + BUF))[i] = SERIALIZE_PTR(ARG[i]); } HEREDOC }, - 'VALUE (*)(ANYARGS)' => { + 'VALUE (*)()' => { keep: true, anyargs: true, formatter: lambda { |name| "VALUE (*#{name})(void *, ANYARGS)" }, @@ -72,15 +76,15 @@ }, 'VALUE (*)(VALUE)' => { keep: true, - func_ptr_args: [:ptr], - func_ptr_rets: [:ptr], + func_ptr_args: [:size], + func_ptr_rets: [:size], formatter: lambda { |name| "VALUE (*#{name})(void *, VALUE)" }, declaration: 'VALUE (*)(void *, VALUE)', }, 'VALUE (*)(VALUE,VALUE)' => { keep: true, - func_ptr_args: [:ptr, :ptr], - func_ptr_rets: [:ptr], + func_ptr_args: [:size, :size], + func_ptr_rets: [:size], formatter: lambda { |name| "VALUE (*#{name})(void *, VALUE, VALUE)" }, declaration: 'VALUE (*)(void *, VALUE, VALUE)', }, @@ -88,13 +92,19 @@ RET_HANDLERS = { 'void' => { keep: true, primitive: :void }, - 'VALUE' => { keep: true, primitive: :ptr }, - 'ID' => { keep: true, primitive: :ptr }, + 'VALUE' => { keep: true, primitive: :size }, + 'ID' => { keep: true, primitive: :size }, 'int' => { primitive: :s32 }, 'unsigned int' => { primitive: :u32 }, + 'long' => { primitive: :size }, + 'unsigned long' => { primitive: :size }, + 'long long' => { primitive: :s64 }, + 'unsigned long long' => { primitive: :u64 }, } VAR_TYPE_TABLE = { + ssize: 'wasm_ssize_t', + size: 'wasm_size_t', ptr: 'wasm_ptr_t', s32: 'int32_t', u32: 'uint32_t', @@ -105,7 +115,9 @@ } FUNC_TYPE_TABLE = { - ptr: 'WASM_RT_I32', + ssize: MEMORY64 ? 'WASM_RT_I64' : 'WASM_RT_I32', + size: MEMORY64 ? 'WASM_RT_I64' : 'WASM_RT_I32', + ptr: MEMORY64 ? 'WASM_RT_I64' : 'WASM_RT_I32', s32: 'WASM_RT_I32', u32: 'WASM_RT_I32', s64: 'WASM_RT_I64', @@ -150,9 +162,11 @@ // Autogenerated by sandbox-bindgen.rb. Don't manually modify this file - modify sandbox-bindgen.rb instead! #define ANYARGS ... - typedef uint#{MEMORY64 ? '64' : '32'}_t wasm_ptr_t; - typedef wasm_ptr_t VALUE; - typedef wasm_ptr_t ID; + typedef int#{MEMORY64 ? '64' : '32'}_t wasm_ssize_t; + typedef uint#{MEMORY64 ? '64' : '32'}_t wasm_size_t; + typedef wasm_size_t wasm_ptr_t; + typedef wasm_size_t VALUE; + typedef wasm_size_t ID; struct SandboxBind { private: @@ -212,7 +226,7 @@ SandboxBind::SandboxBind(std::shared_ptr m) : next_func_ptr(m->w2c_T0.size), module_instance(m) {} - wasm_ptr_t SandboxBind::_sbindgen_malloc(wasm_ptr_t size) { + wasm_ptr_t SandboxBind::_sbindgen_malloc(wasm_size_t size) { wasm_ptr_t buf = w2c_#{MODULE_NAME}_#{MALLOC_FUNC}(module_instance.get(), size); // Verify that the entire allocated buffer is in valid memory @@ -231,13 +245,13 @@ } // Make sure that an integer overflow won't occur if we double the max size of the funcref table - wasm_ptr_t new_max_size; + wasm_size_t new_max_size; if (__builtin_add_overflow(module_instance->w2c_T0.max_size, module_instance->w2c_T0.max_size, &new_max_size)) { return -1; } // Double the max size of the funcref table - wasm_ptr_t old_max_size = module_instance->w2c_T0.max_size; + wasm_size_t old_max_size = module_instance->w2c_T0.max_size; module_instance->w2c_T0.max_size = new_max_size; // Double the size of the funcref table buffer @@ -268,6 +282,7 @@ func_name = line[0] next unless func_name.start_with?('rb_') + next if func_name.end_with?('_static') next if IGNORED_FUNCTIONS.include?(func_name) # Only bind functions whose return type matches one of the return types we have a handler for @@ -303,7 +318,7 @@ if handler[:anyargs] binding += <<~HEREDOC module_instance->w2c_T0.data[v#{i}] = wasm_rt_funcref_t { - .func_type = wasm2c_#{MODULE_NAME}_get_func_type(a#{args.length - 1} == -1 ? 3 : a#{args.length - 1} == -2 ? 2 : a#{args.length - 1} + 1, 1, #{([:ptr] * 16).map { |type| FUNC_TYPE_TABLE[type] }.join(', ')}), + .func_type = wasm2c_#{MODULE_NAME}_get_func_type(a#{args.length - 1} == -1 ? 3 : a#{args.length - 1} == -2 ? 2 : a#{args.length - 1} + 1, 1, #{([:size] * 16).map { |type| FUNC_TYPE_TABLE[type] }.join(', ')}), .func = (wasm_rt_function_ptr_t)a#{i}, .func_tailcallee = {.fn = NULL}, .module_instance = module_instance.get(), @@ -345,7 +360,7 @@ case func_name when 'rb_funcall' binding += <<~HEREDOC - wasm_ptr_t v = _sbindgen_malloc(a#{args.length - 2} * sizeof(wasm_ptr_t)); + wasm_ptr_t v = _sbindgen_malloc(a#{args.length - 2} * sizeof(VALUE)); if (v == 0) { HEREDOC buffers.reverse_each { |buf| binding += " w2c_#{MODULE_NAME}_#{FREE_FUNC}(module_instance.get(), #{buf});\n" } @@ -355,7 +370,7 @@ std::va_list a; va_start(a, a#{args.length - 2}); for (long i = 0; i < a#{args.length - 2}; ++i) { - ((wasm_ptr_t *)(module_instance->w2c_memory.data + v))[i] = SERIALIZE_PTR(va_arg(a, wasm_ptr_t)); + ((VALUE *)(module_instance->w2c_memory.data + v))[i] = SERIALIZE_PTR(va_arg(a, VALUE)); } va_end(a); HEREDOC @@ -366,10 +381,10 @@ std::va_list a, b; va_start(a, a#{args.length - 2}); va_copy(b, a); - wasm_ptr_t n = 0; - do ++n; while (va_arg(b, wasm_ptr_t)); + wasm_size_t n = 0; + do ++n; while (va_arg(b, VALUE)); va_end(b); - wasm_ptr_t v = _sbindgen_malloc(n * sizeof(wasm_ptr_t)); + wasm_ptr_t v = _sbindgen_malloc(n * sizeof(VALUE)); if (v == 0) { va_end(a); HEREDOC @@ -377,8 +392,8 @@ binding += <<~HEREDOC throw SandboxOutOfMemoryException(); } - for (wasm_ptr_t i = 0; i < n; ++i) { - ((wasm_ptr_t *)(module_instance->w2c_memory.data + v))[i] = SERIALIZE_PTR(va_arg(a, wasm_ptr_t)); + for (wasm_size_t i = 0; i < n; ++i) { + ((VALUE *)(module_instance->w2c_memory.data + v))[i] = SERIALIZE_PTR(va_arg(a, VALUE)); } HEREDOC binding += "\n" diff --git a/src/sandbox/wasi.cpp b/src/sandbox/wasi.cpp index 066fcb0ef..254d45d6f 100644 --- a/src/sandbox/wasi.cpp +++ b/src/sandbox/wasi.cpp @@ -27,7 +27,6 @@ #include #include #include "wasi.h" -#include "sandbox.h" #include #include "../core.h"