From 84ee4cdcb4f8b6683c4551e05a2b155dd7257613 Mon Sep 17 00:00:00 2001 From: Charles Oliver Nutter Date: Tue, 12 Mar 2024 00:38:24 -0500 Subject: [PATCH 1/2] Use new name for cat19 This cannot be merged until JRuby has released a version that supports it, and should not be released until we have decided how to transition away from older JRuby versions that do not have this name. See https://github.com/ruby/stringio/issues/83 --- ext/java/org/jruby/ext/stringio/StringIO.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/java/org/jruby/ext/stringio/StringIO.java b/ext/java/org/jruby/ext/stringio/StringIO.java index 04775bd..5d1210d 100644 --- a/ext/java/org/jruby/ext/stringio/StringIO.java +++ b/ext/java/org/jruby/ext/stringio/StringIO.java @@ -1299,7 +1299,7 @@ private long stringIOWrite(ThreadContext context, Ruby runtime, IRubyObject arg) if (enc == EncodingUtils.ascii8bitEncoding(runtime) || encStr == EncodingUtils.ascii8bitEncoding(runtime)) { EncodingUtils.encStrBufCat(runtime, ptr.string, strByteList, enc); } else { - ptr.string.cat19(str); + ptr.string.catWithCodeRange(str); } } else { strioExtend(ptr.pos, len); From 345a252ae501c0332287d09afa551623a32af466 Mon Sep 17 00:00:00 2001 From: Charles Oliver Nutter Date: Tue, 12 Mar 2024 16:38:20 -0500 Subject: [PATCH 2/2] Use handles to work on both old and new name --- ext/java/org/jruby/ext/stringio/StringIO.java | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/ext/java/org/jruby/ext/stringio/StringIO.java b/ext/java/org/jruby/ext/stringio/StringIO.java index 5d1210d..d1d50c7 100644 --- a/ext/java/org/jruby/ext/stringio/StringIO.java +++ b/ext/java/org/jruby/ext/stringio/StringIO.java @@ -55,6 +55,9 @@ import org.jruby.util.io.ModeFlags; import org.jruby.util.io.OpenFile; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; import java.util.Arrays; import static org.jruby.RubyEnumerator.enumeratorize; @@ -1270,6 +1273,23 @@ public IRubyObject write(ThreadContext context, IRubyObject[] args) { return RubyFixnum.newFixnum(runtime, len); } + private static final MethodHandle CAT_WITH_CODE_RANGE; + + static { + MethodHandle cat; + try { + cat = MethodHandles.publicLookup().findVirtual(RubyString.class, "catWithCodeRange", MethodType.methodType(RubyString.class, RubyString.class)); + } catch (NoSuchMethodException | IllegalAccessException ex) { + try { + cat = MethodHandles.publicLookup().findVirtual(RubyString.class, "cat19", MethodType.methodType(RubyString.class, RubyString.class)); + } catch (NoSuchMethodException | IllegalAccessException ex2) { + throw new ExceptionInInitializerError(ex2); + } + } + + CAT_WITH_CODE_RANGE = cat; + } + // MRI: strio_write private long stringIOWrite(ThreadContext context, Ruby runtime, IRubyObject arg) { checkWritable(); @@ -1299,7 +1319,11 @@ private long stringIOWrite(ThreadContext context, Ruby runtime, IRubyObject arg) if (enc == EncodingUtils.ascii8bitEncoding(runtime) || encStr == EncodingUtils.ascii8bitEncoding(runtime)) { EncodingUtils.encStrBufCat(runtime, ptr.string, strByteList, enc); } else { - ptr.string.catWithCodeRange(str); + try { + RubyString unused = (RubyString) CAT_WITH_CODE_RANGE.invokeExact(ptr.string, str); + } catch (Throwable t) { + throw new RuntimeException(t); + } } } else { strioExtend(ptr.pos, len);