diff --git a/.github/actions/compilers/entrypoint.sh b/.github/actions/compilers/entrypoint.sh index 198ac0e1746da6..a83d90be91e161 100755 --- a/.github/actions/compilers/entrypoint.sh +++ b/.github/actions/compilers/entrypoint.sh @@ -70,14 +70,6 @@ fi pushd ${builddir} -case "${INPUT_APPEND_CONFIGURE}" in -*--with-shared-gc*) - export RUBY_GC_LIBRARY='librubygc.default.so' - mkdir -p /home/runner/shared-gc - grouped make shared-gc SHARED_GC=default - ;; -esac - grouped make showflags grouped make all grouped make test diff --git a/NEWS.md b/NEWS.md index 25e42db1a944eb..61e7bc790a5bfb 100644 --- a/NEWS.md +++ b/NEWS.md @@ -80,7 +80,7 @@ The following default gems are updated. * RubyGems 3.6.0.dev * bundler 2.6.0.dev * erb 4.0.4 -* fiddle 1.1.3.dev +* fiddle 1.1.4.dev * io-console 0.7.2 * irb 1.14.1 * json 2.7.2 diff --git a/benchmark/data/citm_catalog.json b/benchmark/data/citm_catalog.json index 245fdbbedf478e..149b2aa358839f 100644 --- a/benchmark/data/citm_catalog.json +++ b/benchmark/data/citm_catalog.json @@ -1406,7 +1406,7 @@ "description": null, "id": 138586671, "logo": "/images/UE0AAAAACEKqLwAAAAlDSVRN", - "name": "Boris Godounov - M.Moussorgski (version de concert)", + "name": "Boris Godunov - M.Moussorgski (version de concert)", "subTopicIds": [ 337184284, 337184298, @@ -50466,4 +50466,4 @@ "venueNames": { "PLEYEL_PLEYEL": "Salle Pleyel" } -} \ No newline at end of file +} diff --git a/bootstraptest/test_method.rb b/bootstraptest/test_method.rb index af9443b8c6f5b8..f6f04541d6be09 100644 --- a/bootstraptest/test_method.rb +++ b/bootstraptest/test_method.rb @@ -1374,3 +1374,24 @@ def foo(...) foo(:foo, b: :ok) foo(*["foo"], b: :ok) } + +assert_equal 'ok', %q{ + Thing = Struct.new(:value) + + Obj = Thing.new("ok") + + def delegate(...) + Obj.value(...) + end + + def no_args + delegate + end + + def splat_args(*args) + delegate(*args) + end + + no_args + splat_args +} diff --git a/ext/fiddle/closure.c b/ext/fiddle/closure.c index 7aa9407619c71b..d526d870e85e7f 100644 --- a/ext/fiddle/closure.c +++ b/ext/fiddle/closure.c @@ -61,7 +61,7 @@ const rb_data_type_t closure_data_type = { .dfree = dealloc, .dsize = closure_memsize }, - .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, + .flags = FIDDLE_DEFAULT_TYPED_DATA_FLAGS, }; struct callback_args { @@ -300,6 +300,7 @@ initialize_body(VALUE user_data) cl->argv[i] = rb_fiddle_int_to_ffi_type(NUM2INT(arg)); } cl->argv[argc] = NULL; + OBJ_FREEZE_RAW(normalized_args); ret = rb_fiddle_type_ensure(ret); rb_iv_set(data->self, "@ctype", ret); diff --git a/ext/fiddle/extconf.rb b/ext/fiddle/extconf.rb index 6b0ea753fc373b..28999806579744 100644 --- a/ext/fiddle/extconf.rb +++ b/ext/fiddle/extconf.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true require 'mkmf' -if RUBY_ENGINE == "jruby" +unless RUBY_ENGINE == "ruby" File.write('Makefile', dummy_makefile("").join) return end @@ -223,6 +223,8 @@ def enable_debug_build_flag(flags) $LOCAL_LIBS.prepend("#{libffi.a} ").strip! # to exts.mk $INCFLAGS.gsub!(/-I#{libffi.dir}/, '-I$(LIBFFI_DIR)') end + +have_func("rb_str_to_interned_str") create_makefile 'fiddle' do |conf| if !libffi next conf << "LIBFFI_CLEAN = none\n" diff --git a/ext/fiddle/fiddle.gemspec b/ext/fiddle/fiddle.gemspec index 65de7a30af95fd..0092f5200337fa 100644 --- a/ext/fiddle/fiddle.gemspec +++ b/ext/fiddle/fiddle.gemspec @@ -38,11 +38,10 @@ Gem::Specification.new do |spec| "lib/fiddle.rb", "lib/fiddle/closure.rb", "lib/fiddle/cparser.rb", + "lib/fiddle/ffi_backend.rb", "lib/fiddle/function.rb", "lib/fiddle/import.rb", - "lib/fiddle/jruby.rb", "lib/fiddle/pack.rb", - "lib/fiddle/ruby.rb", "lib/fiddle/struct.rb", "lib/fiddle/types.rb", "lib/fiddle/value.rb", diff --git a/ext/fiddle/fiddle.h b/ext/fiddle/fiddle.h index 54391b95f57073..c0ab8a91ec2fa2 100644 --- a/ext/fiddle/fiddle.h +++ b/ext/fiddle/fiddle.h @@ -236,4 +236,14 @@ VALUE rb_fiddle_new_function(VALUE address, VALUE arg_types, VALUE ret_type); typedef void (*rb_fiddle_freefunc_t)(void*); VALUE rb_fiddle_ptr_new_wrap(void *ptr, long size, rb_fiddle_freefunc_t func, VALUE wrap0, VALUE wrap1); +enum { + FIDDLE_DEFAULT_TYPED_DATA_FLAGS = ( + RUBY_TYPED_FREE_IMMEDIATELY | + RUBY_TYPED_WB_PROTECTED | +#ifdef RUBY_TYPED_FROZEN_SHAREABLE + RUBY_TYPED_FROZEN_SHAREABLE | +#endif + 0) +}; + #endif diff --git a/ext/fiddle/function.c b/ext/fiddle/function.c index 73dfb129a54d3f..21a7ad6d2342d3 100644 --- a/ext/fiddle/function.c +++ b/ext/fiddle/function.c @@ -59,7 +59,7 @@ const rb_data_type_t function_data_type = { .dfree = deallocate, .dsize = function_memsize }, - .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, + .flags = FIDDLE_DEFAULT_TYPED_DATA_FLAGS, }; static VALUE @@ -153,6 +153,9 @@ initialize(int argc, VALUE argv[], VALUE self) rb_get_kwargs(kwargs, kw, 0, kw_max_, args); if (args[kw_name] != Qundef) { name = args[kw_name]; +#ifdef HAVE_RB_STR_TO_INTERNED_STR + name = rb_str_to_interned_str(name); +#endif } if (args[kw_need_gvl] != Qundef) { need_gvl = args[kw_need_gvl]; diff --git a/ext/fiddle/handle.c b/ext/fiddle/handle.c index 558d6d45516641..0d03133cabe755 100644 --- a/ext/fiddle/handle.c +++ b/ext/fiddle/handle.c @@ -56,7 +56,8 @@ static const rb_data_type_t fiddle_handle_data_type = { .dfree = fiddle_handle_free, .dsize = fiddle_handle_memsize }, - .flags = RUBY_TYPED_WB_PROTECTED, + .flags = FIDDLE_DEFAULT_TYPED_DATA_FLAGS & ~RUBY_TYPED_FREE_IMMEDIATELY, + /* keeping while its symbols are referred. */ }; /* diff --git a/ext/fiddle/lib/fiddle.rb b/ext/fiddle/lib/fiddle.rb index b1c6cd08bf6c41..6718b012efee5b 100644 --- a/ext/fiddle/lib/fiddle.rb +++ b/ext/fiddle/lib/fiddle.rb @@ -1,6 +1,10 @@ # frozen_string_literal: true -require "fiddle/#{RUBY_ENGINE}" +if RUBY_ENGINE == 'ruby' + require 'fiddle.so' +else + require 'fiddle/ffi_backend' +end require 'fiddle/closure' require 'fiddle/function' require 'fiddle/version' diff --git a/ext/fiddle/lib/fiddle/jruby.rb b/ext/fiddle/lib/fiddle/ffi_backend.rb similarity index 72% rename from ext/fiddle/lib/fiddle/jruby.rb rename to ext/fiddle/lib/fiddle/ffi_backend.rb index 9ad61d4d9d1d5b..0c7c379777fad6 100644 --- a/ext/fiddle/lib/fiddle/jruby.rb +++ b/ext/fiddle/lib/fiddle/ffi_backend.rb @@ -1,4 +1,4 @@ -# This is part of JRuby's FFI-based fiddle implementation. +# This is based on JRuby's FFI-based fiddle implementation. require 'ffi' @@ -74,7 +74,7 @@ module Types WINDOWS = FFI::Platform.windows? - module JRuby + module FFIBackend FFITypes = { 'c' => FFI::Type::INT8, 'h' => FFI::Type::INT16, @@ -104,16 +104,16 @@ module JRuby Types::VARIADIC => FFI::Type::Builtin::VARARGS, } - def self.__ffi_type__(dl_type) - if dl_type.is_a?(Symbol) - dl_type = Types.const_get(dl_type.to_s.upcase) + def self.to_ffi_type(fiddle_type) + if fiddle_type.is_a?(Symbol) + fiddle_type = Types.const_get(fiddle_type.to_s.upcase) end - if !dl_type.is_a?(Integer) && dl_type.respond_to?(:to_int) - dl_type = dl_type.to_int + if !fiddle_type.is_a?(Integer) && fiddle_type.respond_to?(:to_int) + fiddle_type = fiddle_type.to_int end - ffi_type = FFITypes[dl_type] - ffi_type = FFITypes[-dl_type] if ffi_type.nil? && dl_type.is_a?(Integer) && dl_type < 0 - raise TypeError.new("cannot convert #{dl_type} to ffi") unless ffi_type + ffi_type = FFITypes[fiddle_type] + ffi_type = FFITypes[-fiddle_type] if ffi_type.nil? && fiddle_type.is_a?(Integer) && fiddle_type < 0 + raise TypeError.new("cannot convert #{fiddle_type} to ffi") unless ffi_type ffi_type end end @@ -133,8 +133,8 @@ def initialize(ptr, args, return_type, abi = DEFAULT, kwargs = nil) @ptr, @args, @return_type, @abi = ptr, args, return_type, abi raise TypeError.new "invalid argument types" unless args.is_a?(Array) - ffi_return_type = Fiddle::JRuby::__ffi_type__(@return_type) - ffi_args = @args.map { |t| Fiddle::JRuby.__ffi_type__(t) } + ffi_return_type = Fiddle::FFIBackend.to_ffi_type(@return_type) + ffi_args = @args.map { |t| Fiddle::FFIBackend.to_ffi_type(t) } pointer = FFI::Pointer.new(ptr.to_i) options = {convention: @abi} if ffi_args.last == FFI::Type::Builtin::VARARGS @@ -149,14 +149,25 @@ def initialize(ptr, args, return_type, abi = DEFAULT, kwargs = nil) end end - def call(*args, &block); + def call(*args, &block) if @function.is_a?(FFI::VariadicInvoker) n_fixed_args = @args.size - 1 n_fixed_args.step(args.size - 1, 2) do |i| if args[i] == :const_string || args[i] == Types::CONST_STRING args[i + 1] = String.try_convert(args[i + 1]) || args[i + 1] end - args[i] = Fiddle::JRuby.__ffi_type__(args[i]) + args[i] = Fiddle::FFIBackend.to_ffi_type(args[i]) + end + else + args.map! do |arg| + if arg.respond_to?(:to_ptr) + begin + arg = arg.to_ptr + end until arg.is_a?(FFI::Pointer) || !arg.respond_to?(:to_ptr) + arg + else + arg + end end end result = @function.call(*args, &block) @@ -170,19 +181,21 @@ def initialize(ret, args, abi = Function::DEFAULT) raise TypeError.new "invalid argument types" unless args.is_a?(Array) @ctype, @args = ret, args - ffi_args = @args.map { |t| Fiddle::JRuby.__ffi_type__(t) } + ffi_args = @args.map { |t| Fiddle::FFIBackend.to_ffi_type(t) } if ffi_args.size == 1 && ffi_args[0] == FFI::Type::Builtin::VOID ffi_args = [] end - @function = FFI::Function.new( - Fiddle::JRuby.__ffi_type__(@ctype), - ffi_args, - self, - :convention => abi - ) + return_type = Fiddle::FFIBackend.to_ffi_type(@ctype) + raise "#{self.class} must implement #call" unless respond_to?(:call) + callable = method(:call) + @function = FFI::Function.new(return_type, ffi_args, callable, convention: abi) @freed = false end + def to_ptr + @function + end + def to_i @function.to_i end @@ -550,51 +563,51 @@ def cleared? RUBY_FREE = Fiddle::Pointer::LibC::FREE.address NULL = Fiddle::Pointer.new(0) - ALIGN_VOIDP = Fiddle::JRuby::FFITypes[Types::VOIDP].alignment - ALIGN_CHAR = Fiddle::JRuby::FFITypes[Types::CHAR].alignment - ALIGN_SHORT = Fiddle::JRuby::FFITypes[Types::SHORT].alignment - ALIGN_INT = Fiddle::JRuby::FFITypes[Types::INT].alignment - ALIGN_LONG = Fiddle::JRuby::FFITypes[Types::LONG].alignment - ALIGN_LONG_LONG = Fiddle::JRuby::FFITypes[Types::LONG_LONG].alignment - ALIGN_INT8_T = Fiddle::JRuby::FFITypes[Types::INT8_T].alignment - ALIGN_INT16_T = Fiddle::JRuby::FFITypes[Types::INT16_T].alignment - ALIGN_INT32_T = Fiddle::JRuby::FFITypes[Types::INT32_T].alignment - ALIGN_INT64_T = Fiddle::JRuby::FFITypes[Types::INT64_T].alignment - ALIGN_FLOAT = Fiddle::JRuby::FFITypes[Types::FLOAT].alignment - ALIGN_DOUBLE = Fiddle::JRuby::FFITypes[Types::DOUBLE].alignment - ALIGN_BOOL = Fiddle::JRuby::FFITypes[Types::BOOL].alignment - ALIGN_SIZE_T = Fiddle::JRuby::FFITypes[Types::SIZE_T].alignment + ALIGN_VOIDP = Fiddle::FFIBackend::FFITypes[Types::VOIDP].alignment + ALIGN_CHAR = Fiddle::FFIBackend::FFITypes[Types::CHAR].alignment + ALIGN_SHORT = Fiddle::FFIBackend::FFITypes[Types::SHORT].alignment + ALIGN_INT = Fiddle::FFIBackend::FFITypes[Types::INT].alignment + ALIGN_LONG = Fiddle::FFIBackend::FFITypes[Types::LONG].alignment + ALIGN_LONG_LONG = Fiddle::FFIBackend::FFITypes[Types::LONG_LONG].alignment + ALIGN_INT8_T = Fiddle::FFIBackend::FFITypes[Types::INT8_T].alignment + ALIGN_INT16_T = Fiddle::FFIBackend::FFITypes[Types::INT16_T].alignment + ALIGN_INT32_T = Fiddle::FFIBackend::FFITypes[Types::INT32_T].alignment + ALIGN_INT64_T = Fiddle::FFIBackend::FFITypes[Types::INT64_T].alignment + ALIGN_FLOAT = Fiddle::FFIBackend::FFITypes[Types::FLOAT].alignment + ALIGN_DOUBLE = Fiddle::FFIBackend::FFITypes[Types::DOUBLE].alignment + ALIGN_BOOL = Fiddle::FFIBackend::FFITypes[Types::BOOL].alignment + ALIGN_SIZE_T = Fiddle::FFIBackend::FFITypes[Types::SIZE_T].alignment ALIGN_SSIZE_T = ALIGN_SIZE_T - ALIGN_PTRDIFF_T = Fiddle::JRuby::FFITypes[Types::PTRDIFF_T].alignment - ALIGN_INTPTR_T = Fiddle::JRuby::FFITypes[Types::INTPTR_T].alignment - ALIGN_UINTPTR_T = Fiddle::JRuby::FFITypes[Types::UINTPTR_T].alignment - - SIZEOF_VOIDP = Fiddle::JRuby::FFITypes[Types::VOIDP].size - SIZEOF_CHAR = Fiddle::JRuby::FFITypes[Types::CHAR].size - SIZEOF_UCHAR = Fiddle::JRuby::FFITypes[Types::UCHAR].size - SIZEOF_SHORT = Fiddle::JRuby::FFITypes[Types::SHORT].size - SIZEOF_USHORT = Fiddle::JRuby::FFITypes[Types::USHORT].size - SIZEOF_INT = Fiddle::JRuby::FFITypes[Types::INT].size - SIZEOF_UINT = Fiddle::JRuby::FFITypes[Types::UINT].size - SIZEOF_LONG = Fiddle::JRuby::FFITypes[Types::LONG].size - SIZEOF_ULONG = Fiddle::JRuby::FFITypes[Types::ULONG].size - SIZEOF_LONG_LONG = Fiddle::JRuby::FFITypes[Types::LONG_LONG].size - SIZEOF_ULONG_LONG = Fiddle::JRuby::FFITypes[Types::ULONG_LONG].size - SIZEOF_INT8_T = Fiddle::JRuby::FFITypes[Types::INT8_T].size - SIZEOF_UINT8_T = Fiddle::JRuby::FFITypes[Types::UINT8_T].size - SIZEOF_INT16_T = Fiddle::JRuby::FFITypes[Types::INT16_T].size - SIZEOF_UINT16_T = Fiddle::JRuby::FFITypes[Types::UINT16_T].size - SIZEOF_INT32_T = Fiddle::JRuby::FFITypes[Types::INT32_T].size - SIZEOF_UINT32_T = Fiddle::JRuby::FFITypes[Types::UINT32_T].size - SIZEOF_INT64_T = Fiddle::JRuby::FFITypes[Types::INT64_T].size - SIZEOF_UINT64_T = Fiddle::JRuby::FFITypes[Types::UINT64_T].size - SIZEOF_FLOAT = Fiddle::JRuby::FFITypes[Types::FLOAT].size - SIZEOF_DOUBLE = Fiddle::JRuby::FFITypes[Types::DOUBLE].size - SIZEOF_BOOL = Fiddle::JRuby::FFITypes[Types::BOOL].size - SIZEOF_SIZE_T = Fiddle::JRuby::FFITypes[Types::SIZE_T].size + ALIGN_PTRDIFF_T = Fiddle::FFIBackend::FFITypes[Types::PTRDIFF_T].alignment + ALIGN_INTPTR_T = Fiddle::FFIBackend::FFITypes[Types::INTPTR_T].alignment + ALIGN_UINTPTR_T = Fiddle::FFIBackend::FFITypes[Types::UINTPTR_T].alignment + + SIZEOF_VOIDP = Fiddle::FFIBackend::FFITypes[Types::VOIDP].size + SIZEOF_CHAR = Fiddle::FFIBackend::FFITypes[Types::CHAR].size + SIZEOF_UCHAR = Fiddle::FFIBackend::FFITypes[Types::UCHAR].size + SIZEOF_SHORT = Fiddle::FFIBackend::FFITypes[Types::SHORT].size + SIZEOF_USHORT = Fiddle::FFIBackend::FFITypes[Types::USHORT].size + SIZEOF_INT = Fiddle::FFIBackend::FFITypes[Types::INT].size + SIZEOF_UINT = Fiddle::FFIBackend::FFITypes[Types::UINT].size + SIZEOF_LONG = Fiddle::FFIBackend::FFITypes[Types::LONG].size + SIZEOF_ULONG = Fiddle::FFIBackend::FFITypes[Types::ULONG].size + SIZEOF_LONG_LONG = Fiddle::FFIBackend::FFITypes[Types::LONG_LONG].size + SIZEOF_ULONG_LONG = Fiddle::FFIBackend::FFITypes[Types::ULONG_LONG].size + SIZEOF_INT8_T = Fiddle::FFIBackend::FFITypes[Types::INT8_T].size + SIZEOF_UINT8_T = Fiddle::FFIBackend::FFITypes[Types::UINT8_T].size + SIZEOF_INT16_T = Fiddle::FFIBackend::FFITypes[Types::INT16_T].size + SIZEOF_UINT16_T = Fiddle::FFIBackend::FFITypes[Types::UINT16_T].size + SIZEOF_INT32_T = Fiddle::FFIBackend::FFITypes[Types::INT32_T].size + SIZEOF_UINT32_T = Fiddle::FFIBackend::FFITypes[Types::UINT32_T].size + SIZEOF_INT64_T = Fiddle::FFIBackend::FFITypes[Types::INT64_T].size + SIZEOF_UINT64_T = Fiddle::FFIBackend::FFITypes[Types::UINT64_T].size + SIZEOF_FLOAT = Fiddle::FFIBackend::FFITypes[Types::FLOAT].size + SIZEOF_DOUBLE = Fiddle::FFIBackend::FFITypes[Types::DOUBLE].size + SIZEOF_BOOL = Fiddle::FFIBackend::FFITypes[Types::BOOL].size + SIZEOF_SIZE_T = Fiddle::FFIBackend::FFITypes[Types::SIZE_T].size SIZEOF_SSIZE_T = SIZEOF_SIZE_T - SIZEOF_PTRDIFF_T = Fiddle::JRuby::FFITypes[Types::PTRDIFF_T].size - SIZEOF_INTPTR_T = Fiddle::JRuby::FFITypes[Types::INTPTR_T].size - SIZEOF_UINTPTR_T = Fiddle::JRuby::FFITypes[Types::UINTPTR_T].size - SIZEOF_CONST_STRING = Fiddle::JRuby::FFITypes[Types::VOIDP].size + SIZEOF_PTRDIFF_T = Fiddle::FFIBackend::FFITypes[Types::PTRDIFF_T].size + SIZEOF_INTPTR_T = Fiddle::FFIBackend::FFITypes[Types::INTPTR_T].size + SIZEOF_UINTPTR_T = Fiddle::FFIBackend::FFITypes[Types::UINTPTR_T].size + SIZEOF_CONST_STRING = Fiddle::FFIBackend::FFITypes[Types::VOIDP].size end diff --git a/ext/fiddle/lib/fiddle/ruby.rb b/ext/fiddle/lib/fiddle/ruby.rb deleted file mode 100644 index ee5a9a937979c6..00000000000000 --- a/ext/fiddle/lib/fiddle/ruby.rb +++ /dev/null @@ -1 +0,0 @@ -require "fiddle.so" diff --git a/ext/fiddle/lib/fiddle/version.rb b/ext/fiddle/lib/fiddle/version.rb index 3444e24f926a2a..ad7a9655d393b0 100644 --- a/ext/fiddle/lib/fiddle/version.rb +++ b/ext/fiddle/lib/fiddle/version.rb @@ -1,3 +1,3 @@ module Fiddle - VERSION = "1.1.3.dev" + VERSION = "1.1.4.dev" end diff --git a/ext/fiddle/memory_view.c b/ext/fiddle/memory_view.c index fa66fc2c7b26d1..5fd7b9b408fe25 100644 --- a/ext/fiddle/memory_view.c +++ b/ext/fiddle/memory_view.c @@ -64,8 +64,13 @@ fiddle_memview_memsize(const void *ptr) } static const rb_data_type_t fiddle_memview_data_type = { - "fiddle/memory_view", - {fiddle_memview_mark, fiddle_memview_free, fiddle_memview_memsize,}, + .wrap_struct_name = "fiddle/memory_view", + .function = { + .dmark = fiddle_memview_mark, + .dfree = fiddle_memview_free, + .dsize = fiddle_memview_memsize, + }, + .flags = FIDDLE_DEFAULT_TYPED_DATA_FLAGS, }; static VALUE diff --git a/ext/fiddle/pinned.c b/ext/fiddle/pinned.c index 019a3020e2647e..94962b0ff6a9ed 100644 --- a/ext/fiddle/pinned.c +++ b/ext/fiddle/pinned.c @@ -24,9 +24,13 @@ pinned_memsize(const void *ptr) } static const rb_data_type_t pinned_data_type = { - "fiddle/pinned", - {pinned_mark, xfree, pinned_memsize, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED + .wrap_struct_name = "fiddle/pinned", + .function = { + .dmark = pinned_mark, + .dfree = RUBY_TYPED_DEFAULT_FREE, + .dsize = pinned_memsize, + }, + .flags = FIDDLE_DEFAULT_TYPED_DATA_FLAGS, }; static VALUE diff --git a/ext/fiddle/pointer.c b/ext/fiddle/pointer.c index 5c375fe9d2f08c..00bd76e9b2f107 100644 --- a/ext/fiddle/pointer.c +++ b/ext/fiddle/pointer.c @@ -94,7 +94,7 @@ static const rb_data_type_t fiddle_ptr_data_type = { .dfree = fiddle_ptr_free, .dsize = fiddle_ptr_memsize, }, - .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED + .flags = FIDDLE_DEFAULT_TYPED_DATA_FLAGS, }; #ifdef HAVE_RUBY_MEMORY_VIEW_H diff --git a/lib/rdoc/generator/darkfish.rb b/lib/rdoc/generator/darkfish.rb index 96bb4fb66f39f0..5709fabf810206 100644 --- a/lib/rdoc/generator/darkfish.rb +++ b/lib/rdoc/generator/darkfish.rb @@ -780,4 +780,19 @@ def template_for file, page = true, klass = ERB template end + # Returns an excerpt of the content for usage in meta description tags + def excerpt(content) + text = content.is_a?(RDoc::Comment) ? content.text : content + + # Match from a capital letter to the first period, discarding any links, so + # that we don't end up matching badges in the README + first_paragraph_match = text.match(/[A-Z][^\.:\/]+\./) + return text[0...150].gsub(/\n/, " ").squeeze(" ") unless first_paragraph_match + + extracted_text = first_paragraph_match[0] + second_paragraph = first_paragraph_match.post_match.match(/[A-Z][^\.:\/]+\./) + extracted_text << " " << second_paragraph[0] if second_paragraph + + extracted_text[0...150].gsub(/\n/, " ").squeeze(" ") + end end diff --git a/lib/rdoc/generator/template/darkfish/_head.rhtml b/lib/rdoc/generator/template/darkfish/_head.rhtml index 69649ad3b53736..9e6fb4f94ca90c 100644 --- a/lib/rdoc/generator/template/darkfish/_head.rhtml +++ b/lib/rdoc/generator/template/darkfish/_head.rhtml @@ -3,6 +3,28 @@