Skip to content

Commit 153f816

Browse files
committed
[GR-15990] Use InteropLibary to execute Pointer#findNullByte
PullRequest: truffleruby/2875
2 parents 21d0dc2 + 7967cad commit 153f816

File tree

6 files changed

+74
-47
lines changed

6 files changed

+74
-47
lines changed

src/main/java/org/truffleruby/core/encoding/EncodingManager.java

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
import java.util.Map;
1919
import java.util.concurrent.ConcurrentHashMap;
2020

21+
import com.oracle.truffle.api.CompilerDirectives;
22+
import com.oracle.truffle.api.interop.InteropException;
23+
import com.oracle.truffle.api.interop.InteropLibrary;
2124
import org.graalvm.nativeimage.ImageInfo;
2225
import org.graalvm.nativeimage.ProcessProperties;
2326
import org.jcodings.Encoding;
@@ -36,7 +39,6 @@
3639
import org.truffleruby.extra.ffi.Pointer;
3740
import org.truffleruby.platform.NativeConfiguration;
3841
import org.truffleruby.platform.TruffleNFIPlatform;
39-
import org.truffleruby.platform.TruffleNFIPlatform.NativeFunction;
4042

4143
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
4244
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
@@ -151,10 +153,18 @@ private void initializeLocaleEncoding(TruffleNFIPlatform nfi, NativeConfiguratio
151153

152154
// char *nl_langinfo(nl_item item);
153155
// nl_item is int on at least Linux and macOS
154-
final NativeFunction nl_langinfo = nfi.getFunction("nl_langinfo", "(sint32):string");
156+
final Object nl_langinfo = nfi.getFunction("nl_langinfo", "(sint32):string");
155157

156-
final long address = nfi.asPointer(nl_langinfo.call(codeset));
157-
final byte[] bytes = new Pointer(address).readZeroTerminatedByteArray(context, 0);
158+
final long address;
159+
try {
160+
address = nfi.asPointer(InteropLibrary.getUncached().execute(nl_langinfo, codeset));
161+
} catch (InteropException e) {
162+
throw CompilerDirectives.shouldNotReachHere(e);
163+
}
164+
final byte[] bytes = new Pointer(address).readZeroTerminatedByteArray(
165+
context,
166+
InteropLibrary.getUncached(),
167+
0);
158168
localeEncodingName = RopeOperations.decodeAscii(bytes);
159169
} else {
160170
localeEncodingName = Charset.defaultCharset().name();

src/main/java/org/truffleruby/core/format/read/bytes/ReadStringPointerNode.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
*/
1010
package org.truffleruby.core.format.read.bytes;
1111

12+
import com.oracle.truffle.api.interop.InteropLibrary;
1213
import org.truffleruby.core.encoding.Encodings;
1314
import org.truffleruby.core.format.FormatFrameDescriptor;
1415
import org.truffleruby.core.format.FormatNode;
@@ -47,13 +48,18 @@ protected MissingValue decode(Nil nil) {
4748

4849
@Specialization
4950
protected RubyString read(VirtualFrame frame, long address,
50-
@CachedLibrary(limit = "getRubyLibraryCacheLimit()") RubyLibrary rubyLibrary) {
51+
@CachedLibrary(limit = "getRubyLibraryCacheLimit()") RubyLibrary rubyLibrary,
52+
@CachedLibrary(limit = "1") InteropLibrary interop) {
5153
final Pointer pointer = new Pointer(address);
5254
checkAssociated(
5355
(Pointer[]) FrameUtil.getObjectSafe(frame, FormatFrameDescriptor.SOURCE_ASSOCIATED_SLOT),
5456
pointer);
5557

56-
final byte[] bytes = pointer.readZeroTerminatedByteArray(getContext(), 0, limit);
58+
final byte[] bytes = pointer.readZeroTerminatedByteArray(
59+
getContext(),
60+
interop,
61+
0,
62+
limit);
5763
return makeStringNode.executeMake(bytes, Encodings.US_ASCII, CodeRange.CR_7BIT);
5864
}
5965

src/main/java/org/truffleruby/extra/ffi/Pointer.java

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
import java.lang.reflect.Field;
1313

14+
import com.oracle.truffle.api.interop.InteropException;
15+
import com.oracle.truffle.api.interop.InteropLibrary;
1416
import org.truffleruby.RubyContext;
1517
import org.truffleruby.SuppressFBWarnings;
1618
import org.truffleruby.core.FinalizationService;
@@ -190,17 +192,29 @@ public double readDouble(long offset) {
190192
return UNSAFE.getDouble(address + offset);
191193
}
192194

193-
public byte[] readZeroTerminatedByteArray(RubyContext context, long offset) {
194-
return readBytes(offset, checkStringSize(findNullByte(context, offset)));
195+
public byte[] readZeroTerminatedByteArray(RubyContext context, InteropLibrary interopLibrary, long offset) {
196+
return readBytes(offset, checkStringSize(findNullByte(
197+
context,
198+
interopLibrary,
199+
offset)));
195200
}
196201

197-
public byte[] readZeroTerminatedByteArray(RubyContext context, long offset, long limit) {
198-
return readBytes(offset, checkStringSize(findNullByte(context, offset, limit)));
202+
public byte[] readZeroTerminatedByteArray(RubyContext context, InteropLibrary interopLibrary, long offset,
203+
long limit) {
204+
return readBytes(offset, checkStringSize(findNullByte(
205+
context,
206+
interopLibrary,
207+
offset,
208+
limit)));
199209
}
200210

201-
private long findNullByte(RubyContext context, long offset) {
211+
private long findNullByte(RubyContext context, InteropLibrary interopLibrary, long offset) {
202212
if (context.getOptions().NATIVE_PLATFORM) {
203-
return (long) context.getTruffleNFI().getStrlen().call(address + offset);
213+
try {
214+
return (long) interopLibrary.execute(context.getTruffleNFI().getStrlen(), address + offset);
215+
} catch (InteropException e) {
216+
throw CompilerDirectives.shouldNotReachHere(e);
217+
}
204218
} else {
205219
int n = 0;
206220
while (true) {
@@ -212,9 +226,13 @@ private long findNullByte(RubyContext context, long offset) {
212226
}
213227
}
214228

215-
private long findNullByte(RubyContext context, long offset, long limit) {
229+
private long findNullByte(RubyContext context, InteropLibrary interopLibrary, long offset, long limit) {
216230
if (context.getOptions().NATIVE_PLATFORM) {
217-
return (long) context.getTruffleNFI().getStrnlen().call(address + offset, limit);
231+
try {
232+
return (long) interopLibrary.execute(context.getTruffleNFI().getStrnlen(), address + offset, limit);
233+
} catch (InteropException e) {
234+
throw CompilerDirectives.shouldNotReachHere(e);
235+
}
218236
} else {
219237
int n = 0;
220238
while (n < limit) {

src/main/java/org/truffleruby/extra/ffi/PointerNodes.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
import java.math.BigInteger;
1313

14+
import com.oracle.truffle.api.interop.InteropLibrary;
1415
import com.oracle.truffle.api.library.CachedLibrary;
1516
import com.oracle.truffle.api.nodes.Node;
1617
import com.oracle.truffle.api.object.Shape;
@@ -273,10 +274,12 @@ protected RubyString readNullPointer(long address, long limit) {
273274

274275
@Specialization(guards = "limit != 0")
275276
protected RubyString readStringToNull(long address, long limit,
276-
@Cached RopeNodes.MakeLeafRopeNode makeLeafRopeNode) {
277+
@Cached RopeNodes.MakeLeafRopeNode makeLeafRopeNode,
278+
@CachedLibrary(limit = "1") InteropLibrary interop) {
277279
final Pointer ptr = new Pointer(address);
278280
checkNull(ptr);
279-
final byte[] bytes = ptr.readZeroTerminatedByteArray(getContext(), 0, limit);
281+
final byte[] bytes = ptr
282+
.readZeroTerminatedByteArray(getContext(), interop, 0, limit);
280283
final Rope rope = makeLeafRopeNode
281284
.executeMake(bytes, ASCIIEncoding.INSTANCE, CodeRange.CR_UNKNOWN, NotProvided.INSTANCE);
282285

@@ -292,10 +295,12 @@ protected RubyString readStringToNull(long address, long limit,
292295

293296
@Specialization
294297
protected RubyString readStringToNull(long address, Nil limit,
295-
@Cached RopeNodes.MakeLeafRopeNode makeLeafRopeNode) {
298+
@Cached RopeNodes.MakeLeafRopeNode makeLeafRopeNode,
299+
@CachedLibrary(limit = "1") InteropLibrary interop) {
296300
final Pointer ptr = new Pointer(address);
297301
checkNull(ptr);
298-
final byte[] bytes = ptr.readZeroTerminatedByteArray(getContext(), 0);
302+
final byte[] bytes = ptr
303+
.readZeroTerminatedByteArray(getContext(), interop, 0);
299304
final Rope rope = makeLeafRopeNode
300305
.executeMake(bytes, ASCIIEncoding.INSTANCE, CodeRange.CR_UNKNOWN, NotProvided.INSTANCE);
301306

src/main/java/org/truffleruby/language/loader/FeatureLoader.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@
4848
import org.truffleruby.platform.NativeConfiguration;
4949
import org.truffleruby.platform.Platform;
5050
import org.truffleruby.platform.TruffleNFIPlatform;
51-
import org.truffleruby.platform.TruffleNFIPlatform.NativeFunction;
5251
import org.truffleruby.shared.Metrics;
5352
import org.truffleruby.shared.TruffleRuby;
5453

@@ -79,7 +78,7 @@ public class FeatureLoader {
7978
private boolean cextImplementationLoaded = false;
8079

8180
private String cwd = null;
82-
private NativeFunction getcwd;
81+
private Object getcwd;
8382
private static final int PATH_MAX = 1024; // jnr-posix hard codes this value
8483

8584
private static final String[] EXTENSIONS = new String[]{ TruffleRuby.EXTENSION, RubyLanguage.CEXT_EXTENSION };
@@ -198,11 +197,19 @@ private String initializeWorkingDirectory() {
198197
final Pointer buffer = IOThreadBufferAllocateNode
199198
.getBuffer(rubyThread, bufferSize, ConditionProfile.getUncached());
200199
try {
201-
final long address = nfi.asPointer(getcwd.call(buffer.getAddress(), bufferSize));
200+
final long address;
201+
try {
202+
address = nfi.asPointer(InteropLibrary.getUncached().execute(getcwd, buffer.getAddress(), bufferSize));
203+
} catch (InteropException e) {
204+
throw CompilerDirectives.shouldNotReachHere(e);
205+
}
202206
if (address == 0) {
203207
RubyContext.send(context.getCoreLibrary().errnoModule, "handle");
204208
}
205-
final byte[] bytes = buffer.readZeroTerminatedByteArray(context, 0);
209+
final byte[] bytes = buffer.readZeroTerminatedByteArray(
210+
context,
211+
InteropLibrary.getUncached(),
212+
0);
206213
final Encoding localeEncoding = context.getEncodingManager().getLocaleEncoding().jcoding;
207214
return new String(bytes, EncodingManager.charsetForEncoding(localeEncoding));
208215
} finally {

src/main/java/org/truffleruby/platform/TruffleNFIPlatform.java

Lines changed: 6 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
package org.truffleruby.platform;
1111

1212
import org.truffleruby.RubyContext;
13-
import org.truffleruby.interop.InteropNodes;
1413
import org.truffleruby.interop.TranslateInteropExceptionNode;
1514

1615
import com.oracle.truffle.api.CompilerDirectives;
@@ -27,8 +26,8 @@ public class TruffleNFIPlatform {
2726
final Object defaultLibrary;
2827

2928
private final String size_t;
30-
private final NativeFunction strlen;
31-
private final NativeFunction strnlen;
29+
private final Object strlen;
30+
private final Object strnlen;
3231

3332
public TruffleNFIPlatform(RubyContext context) {
3433
defaultLibrary = context
@@ -98,39 +97,21 @@ private String toNFIType(String type) {
9897
}
9998
}
10099

101-
public NativeFunction getFunction(String functionName, String signature) {
100+
public Object getFunction(String functionName, String signature) {
102101
final Object symbol = lookup(defaultLibrary, functionName);
103-
final Object function = bind(symbol, signature);
104-
return new NativeFunction(function);
102+
return bind(symbol, signature);
105103
}
106104

107105
public String size_t() {
108106
return size_t;
109107
}
110108

111-
public NativeFunction getStrlen() {
109+
public Object getStrlen() {
112110
return strlen;
113111
}
114112

115-
public NativeFunction getStrnlen() {
113+
public Object getStrnlen() {
116114
return strnlen;
117115
}
118116

119-
public static class NativeFunction {
120-
121-
private final Object function;
122-
private final InteropLibrary functionInteropLibrary;
123-
124-
private NativeFunction(Object function) {
125-
this.function = function;
126-
this.functionInteropLibrary = InteropLibrary.getFactory().getUncached(this.function);
127-
}
128-
129-
public Object call(Object... arguments) {
130-
return InteropNodes
131-
.execute(function, arguments, functionInteropLibrary, TranslateInteropExceptionNode.getUncached());
132-
}
133-
134-
}
135-
136117
}

0 commit comments

Comments
 (0)