mirror of
https://github.com/mkxp-z/mkxp-z.git
synced 2025-09-10 12:02:53 +02:00
Use C compiler to preprocess Ruby headers before passing to Ctags
Ctags by itself misses a few functions defined in the Ruby API.
This commit is contained in:
parent
19cafa332c
commit
1439b3181d
4 changed files with 50 additions and 32 deletions
4
.github/workflows/autobuild.yml
vendored
4
.github/workflows/autobuild.yml
vendored
|
@ -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: |
|
||||
|
|
|
@ -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 <ruby.h>' | $(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; \
|
||||
|
|
|
@ -45,10 +45,14 @@ IGNORED_FUNCTIONS = Set[
|
|||
]
|
||||
|
||||
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 @@ ARG_HANDLERS = {
|
|||
'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 @@ ARG_HANDLERS = {
|
|||
},
|
||||
'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 @@ ARG_HANDLERS = {
|
|||
|
||||
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 @@ VAR_TYPE_TABLE = {
|
|||
}
|
||||
|
||||
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 @@ HEADER_START = <<~HEREDOC
|
|||
// 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 @@ PRELUDE = <<~HEREDOC
|
|||
SandboxBind::SandboxBind(std::shared_ptr<struct w2c_#{MODULE_NAME}> 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 @@ PRELUDE = <<~HEREDOC
|
|||
}
|
||||
|
||||
// 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 @@ File.readlines('tags', chomp: true).each do |line|
|
|||
|
||||
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 @@ File.readlines('tags', chomp: true).each do |line|
|
|||
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 @@ File.readlines('tags', chomp: true).each do |line|
|
|||
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 @@ File.readlines('tags', chomp: true).each do |line|
|
|||
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 @@ File.readlines('tags', chomp: true).each do |line|
|
|||
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 @@ File.readlines('tags', chomp: true).each do |line|
|
|||
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"
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#include <sstream>
|
||||
#include <zip.h>
|
||||
#include "wasi.h"
|
||||
#include "sandbox.h"
|
||||
#include <mkxp-retro-ruby.h>
|
||||
#include "../core.h"
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue