diff --git a/patches/ruby/3.1/fiddle-closure.patch b/patches/ruby/3.1/fiddle-closure.patch new file mode 100644 index 0000000..1ff3584 --- /dev/null +++ b/patches/ruby/3.1/fiddle-closure.patch @@ -0,0 +1,145 @@ +From 17aa5c633d13f3ef6dcbec7f08a01b20ed4fbc12 Mon Sep 17 00:00:00 2001 +From: Sutou Kouhei +Date: Thu, 15 Sep 2022 07:08:20 +0900 +Subject: [PATCH] merge revision(s) a4ad6bd9aac564e93219284c912b26a72f9e82fc: + + [ruby/fiddle] closure: free resources when an exception is raised in + Closure.new + + GitHub: GH-102 + + https://github.com/ruby/fiddle/commit/81a8a56239 + --- + ext/fiddle/closure.c | 56 ++++++++++++++++++++++++++++++++++++++++------------ + 1 file changed, 43 insertions(+), 13 deletions(-) +--- + ext/fiddle/closure.c | 56 ++++++++++++++++++++++++++++++++++---------- + version.h | 6 ++--- + 2 files changed, 46 insertions(+), 16 deletions(-) + +diff --git a/ext/fiddle/closure.c b/ext/fiddle/closure.c +index 27f448a24f0108..c08ec5940da84c 100644 +--- a/ext/fiddle/closure.c ++++ b/ext/fiddle/closure.c +@@ -224,9 +224,16 @@ allocate(VALUE klass) + return i; + } + ++typedef struct { ++ VALUE self; ++ int argc; ++ VALUE *argv; ++} initialize_data; ++ + static VALUE +-initialize(int rbargc, VALUE argv[], VALUE self) ++initialize_body(VALUE user_data) + { ++ initialize_data *data = (initialize_data *)user_data; + VALUE ret; + VALUE args; + VALUE normalized_args; +@@ -237,14 +244,14 @@ initialize(int rbargc, VALUE argv[], VALUE self) + ffi_status result; + int i, argc; + +- if (2 == rb_scan_args(rbargc, argv, "21", &ret, &args, &abi)) +- abi = INT2NUM(FFI_DEFAULT_ABI); ++ if (2 == rb_scan_args(data->argc, data->argv, "21", &ret, &args, &abi)) ++ abi = INT2NUM(FFI_DEFAULT_ABI); + + Check_Type(args, T_ARRAY); + + argc = RARRAY_LENINT(args); + +- TypedData_Get_Struct(self, fiddle_closure, &closure_data_type, cl); ++ TypedData_Get_Struct(data->self, fiddle_closure, &closure_data_type, cl); + + cl->argv = (ffi_type **)xcalloc(argc + 1, sizeof(ffi_type *)); + +@@ -257,8 +264,8 @@ initialize(int rbargc, VALUE argv[], VALUE self) + cl->argv[argc] = NULL; + + ret = rb_fiddle_type_ensure(ret); +- rb_iv_set(self, "@ctype", ret); +- rb_iv_set(self, "@args", normalized_args); ++ rb_iv_set(data->self, "@ctype", ret); ++ rb_iv_set(data->self, "@args", normalized_args); + + cif = &cl->cif; + pcl = cl->pcl; +@@ -269,25 +276,48 @@ initialize(int rbargc, VALUE argv[], VALUE self) + rb_fiddle_int_to_ffi_type(NUM2INT(ret)), + cl->argv); + +- if (FFI_OK != result) +- rb_raise(rb_eRuntimeError, "error prepping CIF %d", result); ++ if (FFI_OK != result) { ++ rb_raise(rb_eRuntimeError, "error prepping CIF %d", result); ++ } + + #if USE_FFI_CLOSURE_ALLOC + result = ffi_prep_closure_loc(pcl, cif, callback, +- (void *)self, cl->code); ++ (void *)(data->self), cl->code); + #else + result = ffi_prep_closure(pcl, cif, callback, (void *)(data->self)); + cl->code = (void *)pcl; + i = mprotect(pcl, sizeof(*pcl), PROT_READ | PROT_EXEC); + if (i) { +- rb_sys_fail("mprotect"); ++ rb_sys_fail("mprotect"); + } + #endif + +- if (FFI_OK != result) +- rb_raise(rb_eRuntimeError, "error prepping closure %d", result); ++ if (FFI_OK != result) { ++ rb_raise(rb_eRuntimeError, "error prepping closure %d", result); ++ } ++ ++ return data->self; ++} + +- return self; ++static VALUE ++initialize_rescue(VALUE user_data, VALUE exception) ++{ ++ initialize_data *data = (initialize_data *)user_data; ++ dealloc(RTYPEDDATA_DATA(data->self)); ++ RTYPEDDATA_DATA(data->self) = NULL; ++ rb_exc_raise(exception); ++ return data->self; ++} ++ ++static VALUE ++initialize(int argc, VALUE *argv, VALUE self) ++{ ++ initialize_data data; ++ data.self = self; ++ data.argc = argc; ++ data.argv = argv; ++ return rb_rescue(initialize_body, (VALUE)&data, ++ initialize_rescue, (VALUE)&data); + } + + static VALUE +diff --git a/version.h b/version.h +index 7c8bc046b33c54..99b715563a17ba 100644 +--- a/version.h ++++ b/version.h +@@ -11,11 +11,11 @@ + # define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR + #define RUBY_VERSION_TEENY 5 + #define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR +-#define RUBY_PATCHLEVEL 252 ++#define RUBY_PATCHLEVEL 253 + + #define RUBY_RELEASE_YEAR 2024 +-#define RUBY_RELEASE_MONTH 4 +-#define RUBY_RELEASE_DAY 23 ++#define RUBY_RELEASE_MONTH 5 ++#define RUBY_RELEASE_DAY 2 + + #include "ruby/version.h" +