Skip to content

Commit 58c83f3

Browse files
authored
Merge pull request #256 from headius/coderange_cat_1.2_for_9.3
Use handles to indirect catWithCodeRange or cat19
2 parents faaabb6 + 5330d2a commit 58c83f3

File tree

1 file changed

+28
-1
lines changed

1 file changed

+28
-1
lines changed

src/main/java/org/jruby/rack/ext/Input.java

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
import java.io.ByteArrayOutputStream;
1111
import java.io.IOException;
1212
import java.io.InputStream;
13+
import java.lang.invoke.MethodHandle;
14+
import java.lang.invoke.MethodHandles;
15+
import java.lang.invoke.MethodType;
1316
import java.lang.reflect.InvocationTargetException;
1417
import java.lang.reflect.Method;
1518

@@ -21,6 +24,7 @@
2124
import org.jruby.anno.JRubyMethod;
2225
import org.jruby.javasupport.JavaEmbedUtils;
2326
import org.jruby.runtime.Block;
27+
import org.jruby.runtime.Helpers;
2428
import org.jruby.runtime.ObjectAllocator;
2529
import org.jruby.runtime.ThreadContext;
2630
import org.jruby.runtime.builtin.IRubyObject;
@@ -39,6 +43,24 @@
3943
*/
4044
@SuppressWarnings("serial")
4145
public class Input extends RubyObject {
46+
private static final MethodHandle CONCAT_WITH_CODERANGE;
47+
48+
static {
49+
// set up coderange-aware concat that works with the new catWithCodeRange as well as earlier JRuby without it.
50+
// TODO: remove and replace with direct call once 9.3 is fully unsupported
51+
MethodHandle catWithCR = null;
52+
MethodHandles.Lookup lookup = MethodHandles.publicLookup();
53+
try {
54+
catWithCR = lookup.findVirtual(RubyString.class, "catWithCodeRange", MethodType.methodType(int.class, ByteList.class, int.class));
55+
} catch (NoSuchMethodException | IllegalAccessException e) {
56+
try {
57+
catWithCR = lookup.findVirtual(RubyString.class, "cat19", MethodType.methodType(int.class, ByteList.class, int.class));
58+
} catch (Exception t) {
59+
Helpers.throwException(t);
60+
}
61+
}
62+
CONCAT_WITH_CODERANGE = catWithCR;
63+
}
4264

4365
static final ObjectAllocator ALLOCATOR = new ObjectAllocator() {
4466
public IRubyObject allocate(Ruby runtime, RubyClass klass) {
@@ -144,7 +166,12 @@ public IRubyObject read(final ThreadContext context, final IRubyObject[] args) {
144166
if ( bytes != null ) {
145167
if ( buffer != null ) {
146168
buffer.clear();
147-
buffer.catWithCodeRange(new ByteList(bytes, false), StringSupport.CR_UNKNOWN);
169+
try {
170+
int _ = (int) CONCAT_WITH_CODERANGE.invokeExact(new ByteList(bytes, false), StringSupport.CR_UNKNOWN);
171+
} catch (Throwable t) {
172+
Helpers.throwException(t);
173+
}
174+
148175
return buffer;
149176
}
150177
return context.runtime.newString(new ByteList(bytes, false));

0 commit comments

Comments
 (0)