Skip to content

Commit

Permalink
[GR-37533] Backports for 24.0 batch 2
Browse files Browse the repository at this point in the history
PullRequest: truffleruby/4178
  • Loading branch information
eregon committed Feb 19, 2024
2 parents e7103f0 + f9b982e commit a69cf90
Show file tree
Hide file tree
Showing 86 changed files with 1,715 additions and 1,873 deletions.
421 changes: 36 additions & 385 deletions 3rd_party_licenses.txt

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,17 @@ Compatibility:
* Limit maximum encoding set size by 256 (#3039, @thomasmarshall, @goyox86).
* Remove deprecated methods `Dir.exists?`, `File.exists?`, and `Kernel#=~` (#3039, @patricklinpl, @nirvdrum).
* Remove deprecated `FileTest.exists?` method (#3039, @andrykonchin).
* Fix {Method,Proc}#parameters and return `*`, `**` and `&` names for anonymous parameters (@andrykonchin).
* Remove deprecated `Fixnum` and `Bignum` constants (#3039, @andrykonchin).
* Add `rb_enc_interned_str_cstr` function (#3408, @goyox86, @thomasmarshall).
* Add `rb_str_to_interned_str` function (#3408, @thomasmarshall).

Performance:

* Change the `Hash` representation from traditional buckets to a "compact hash table" for improved locality, performance and memory footprint (#3172, @moste00).
* Optimize calls with `ruby2_keywords` forwarding by deciding it per call site instead of per callee thanks to [my fix in CRuby 3.2](https://bugs.ruby-lang.org/issues/18625) (@eregon).
* Optimize feature loading when require is called with an absolute path to a .rb file (@rwstauner).
* Avoid extra copies for Strings passed as `:string` arguments to a FFI call and used later for Regexp matching (#3293, @eregon).

Changes:

Expand Down
2 changes: 1 addition & 1 deletion bench/asciidoctor/asciidoctor/lib/asciidoctor/document.rb
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ def initialize data = nil, options = {}
# safely resolve the safe mode from const, int or string
if !(safe_mode = options[:safe])
@safe = SafeMode::SECURE
elsif ::Fixnum === safe_mode
elsif ::Integer === safe_mode # this is fixed in upstream in v1.5.5 (https://github.com/asciidoctor/asciidoctor/blob/main/CHANGELOG.adoc#155-2016-10-05---mojavelinux)
# be permissive in case API user wants to define new levels
@safe = safe_mode
else
Expand Down
1,072 changes: 23 additions & 1,049 deletions doc/legal/jruby-copying.txt

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion doc/legal/legal.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ MIT licence, see `mit.txt`.

## JRuby

TruffleRuby contains code from JRuby 9.2.19.0, including Java implementation
TruffleRuby contains code from JRuby 9.4.4.0, including Java implementation
code, build system, shell script launchers, standard library modified from MRI,
and so on.

Expand Down
2 changes: 1 addition & 1 deletion lib/cext/ABI_check.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
10
13
29 changes: 7 additions & 22 deletions lib/truffle/ffi/autopointer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -76,21 +76,21 @@ class AutoPointer < Pointer
# going to be useful if you subclass {AutoPointer}, and override
# #release, which by default does nothing.
def initialize(ptr, proc=nil, &block)
raise TypeError, "Invalid pointer" if ptr.nil? || !ptr.kind_of?(Pointer) ||
ptr.kind_of?(MemoryPointer) || ptr.kind_of?(AutoPointer)
super(ptr.type_size, ptr)
raise TypeError, "Invalid pointer" if ptr.nil? || !ptr.kind_of?(Pointer) \
|| ptr.kind_of?(MemoryPointer) || ptr.kind_of?(AutoPointer)

@releaser = if proc
if not proc.respond_to?(:call)
raise RuntimeError.new("proc must be callable")
end
CallableReleaser.new(ptr, proc)
Releaser.new(ptr, proc)

else
if not self.class.respond_to?(:release)
if not self.class.respond_to?(:release, true)
raise RuntimeError.new("no release method defined")
end
DefaultReleaser.new(ptr, self.class)
Releaser.new(ptr, self.class.method(:release))
end

ObjectSpace.define_finalizer(self, @releaser)
Expand All @@ -107,6 +107,7 @@ def free
# @return [Boolean] +autorelease+
# Set +autorelease+ property. See {Pointer Autorelease section at Pointer}.
def autorelease=(autorelease)
raise FrozenError.new("can't modify frozen #{self.class}") if frozen?
@releaser.autorelease=(autorelease)
end

Expand Down Expand Up @@ -149,23 +150,7 @@ def free
def call(*args)
release(@ptr) if @autorelease && @ptr
end
end

# DefaultReleaser is a {Releaser} used when an {AutoPointer} is defined
# without Proc or Method. In this case, the pointer to release must be of
# a class derived from AutoPointer with a {release} class method.
class DefaultReleaser < Releaser
# @param [Pointer] ptr
# @return [nil]
# Release +ptr+ using the {release} class method of its class.
def release(ptr)
@proc.release(ptr)
end
end

# CallableReleaser is a {Releaser} used when an {AutoPointer} is defined with a
# Proc or a Method.
class CallableReleaser < Releaser
# Release +ptr+ by using Proc or Method defined at +ptr+
# {AutoPointer#initialize initialization}.
#
Expand All @@ -182,7 +167,7 @@ def release(ptr)
# @return [Type::POINTER]
# @raise {RuntimeError} if class does not implement a +#release+ method
def self.native_type
if not self.respond_to?(:release)
if not self.respond_to?(:release, true)
raise RuntimeError.new("no release method defined for #{self.inspect}")
end
Type::POINTER
Expand Down
43 changes: 43 additions & 0 deletions lib/truffle/ffi/compat.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#
# Copyright (C) 2023-2023 Lars Kanis
#
# This file is part of ruby-ffi.
#
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * Neither the name of the Ruby FFI project nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#

module FFI
if defined?(Ractor.make_shareable)
# This is for FFI internal use only.
def self.make_shareable(obj)
Ractor.make_shareable(obj)
end
else
def self.make_shareable(obj)
obj.freeze
end
end
end
4 changes: 2 additions & 2 deletions lib/truffle/ffi/data_converter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
module FFI
# This module is used to extend somes classes and give then a common API.
#
# Most of methods defined here must be overriden.
# Most of methods defined here must be overridden.
module DataConverter
# Get native type.
#
Expand All @@ -41,7 +41,7 @@ module DataConverter
# Get native type from +type+.
#
# @overload native_type
# @raise {NotImplementedError} This method must be overriden.
# @raise {NotImplementedError} This method must be overridden.
def native_type(type = nil)
if type
@native_type = FFI.find_type(type)
Expand Down
89 changes: 89 additions & 0 deletions lib/truffle/ffi/dynamic_library.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#
# Copyright (C) 2008-2010 Wayne Meissner
#
# This file is part of ruby-ffi.
#
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * Neither the name of the Ruby FFI project nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#

module FFI
class DynamicLibrary
SEARCH_PATH = %w[/usr/lib /usr/local/lib /opt/local/lib]
if FFI::Platform::ARCH == 'aarch64' && FFI::Platform.mac?
SEARCH_PATH << '/opt/homebrew/lib'
end

SEARCH_PATH_MESSAGE = "Searched in <system library path>, #{SEARCH_PATH.join(', ')}".freeze

def self.load_library(name, flags)
if name == FFI::CURRENT_PROCESS
FFI::DynamicLibrary.open(nil, RTLD_LAZY | RTLD_LOCAL)
else
flags ||= RTLD_LAZY | RTLD_LOCAL

libnames = (name.is_a?(::Array) ? name : [name])
libnames = libnames.map(&:to_s).map { |n| [n, FFI.map_library_name(n)].uniq }.flatten.compact
errors = []

libnames.each do |libname|
lib = try_load(libname, flags, errors)
return lib if lib

unless libname.start_with?("/") || FFI::Platform.windows?
SEARCH_PATH.each do |prefix|
path = "#{prefix}/#{libname}"
if File.exist?(path)
lib = try_load(path, flags, errors)
return lib if lib
end
end
end
end

raise LoadError, [*errors, SEARCH_PATH_MESSAGE].join(".\n")
end
end
private_class_method :load_library

def self.try_load(libname, flags, errors)
begin
lib = FFI::DynamicLibrary.open(libname, flags)
return lib if lib

# LoadError for C ext & JRuby, RuntimeError for TruffleRuby
rescue LoadError, RuntimeError => ex
if ex.message =~ /(([^ \t()])+\.so([^ \t:()])*):([ \t])*(invalid ELF header|file too short|invalid file format)/
if File.binread($1) =~ /(?:GROUP|INPUT) *\( *([^ \)]+)/
return try_load($1, flags, errors)
end
end

errors << ex
nil
end
end
private_class_method :try_load
end
end
29 changes: 18 additions & 11 deletions lib/truffle/ffi/enum.rb
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ class Bitmask < Enum
# @param [nil, Symbol] tag name of new Bitmask
def initialize(*args)
@native_type = args.first.kind_of?(FFI::Type) ? args.shift : Type::INT
@signed = [Type::INT8, Type::INT16, Type::INT32, Type::INT64].include?(@native_type)
info, @tag = *args
@kv_map = Hash.new
unless info.nil?
Expand Down Expand Up @@ -220,7 +221,7 @@ def initialize(*args)
# @param [Symbol] query
# @return [Integer]
# @overload [](query)
# Get bitmaks value from symbol array
# Get bitmask value from symbol array
# @param [Array<Symbol>] query
# @return [Integer]
# @overload [](*query)
Expand All @@ -240,7 +241,7 @@ def [](*query)
when Symbol
flat_query.inject(0) do |val, o|
v = @kv_map[o]
if v then val |= v else val end
if v then val | v else val end
end
when Integer, ->(o) { o.respond_to?(:to_int) }
val = flat_query.inject(0) { |mask, o| mask |= o.to_int }
Expand All @@ -260,35 +261,41 @@ def [](*query)
def to_native(query, ctx)
return 0 if query.nil?
flat_query = [query].flatten
flat_query.inject(0) do |val, o|
res = flat_query.inject(0) do |val, o|
case o
when Symbol
v = @kv_map[o]
raise ArgumentError, "invalid bitmask value, #{o.inspect}" unless v
val |= v
val | v
when Integer
val |= o
val | o
when ->(obj) { obj.respond_to?(:to_int) }
val |= o.to_int
val | o.to_int
else
raise ArgumentError, "invalid bitmask value, #{o.inspect}"
end
end
# Take two's complement of positive values bigger than the max value
# for the type when native type is signed.
if @signed && res >= (1 << (@native_type.size * 8 - 1))
res = -(-res & ((1 << (@native_type.size * 8)) - 1))
end
res
end

# @param [Integer] val
# @param ctx unused
# @return [Array<Symbol, Integer>] list of symbol names corresponding to val, plus an optional remainder if some bits don't match any constant
def from_native(val, ctx)
list = @kv_map.select { |_, v| v & val != 0 }.keys
flags = @kv_map.select { |_, v| v & val != 0 }
list = flags.keys
# force an unsigned value of the correct size
val &= (1 << (@native_type.size * 8)) - 1 if @signed
# If there are unmatch flags,
# return them in an integer,
# else information can be lost.
# Similar to Enum behavior.
remainder = val ^ list.inject(0) do |tmp, o|
v = @kv_map[o]
if v then tmp |= v else tmp end
end
remainder = val ^ flags.values.reduce(0, :|)
list.push remainder unless remainder == 0
return list
end
Expand Down
3 changes: 3 additions & 0 deletions lib/truffle/ffi/ffi.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,11 @@
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

require 'ffi/compat'
require 'ffi/platform'
require 'ffi/data_converter'
require 'ffi/types'
require 'ffi/library_path'
require 'ffi/library'
require 'ffi/errno'
require 'ffi/abstract_memory'
Expand All @@ -45,3 +47,4 @@
require 'ffi/variadic'
require 'ffi/enum'
require 'ffi/version'
require 'ffi/function'

0 comments on commit a69cf90

Please sign in to comment.