Skip to content

Commit 735617b

Browse files
committed
[GR-35273] Migrate FastR to new NFI interface.
PullRequest: fastr/2693
2 parents fe7347a + 8079003 commit 735617b

File tree

6 files changed

+86
-66
lines changed

6 files changed

+86
-66
lines changed

com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -37,12 +37,13 @@
3737
import com.oracle.truffle.api.frame.Frame;
3838
import com.oracle.truffle.api.frame.FrameInstance.FrameAccess;
3939
import com.oracle.truffle.api.frame.MaterializedFrame;
40-
import com.oracle.truffle.api.interop.InteropException;
4140
import com.oracle.truffle.api.interop.InteropLibrary;
4241
import com.oracle.truffle.api.object.DynamicObject;
4342
import com.oracle.truffle.api.source.Source;
4443
import com.oracle.truffle.api.source.SourceSection;
44+
import com.oracle.truffle.nfi.api.SignatureLibrary;
4545
import com.oracle.truffle.r.ffi.impl.javaGD.JavaGDContext;
46+
import com.oracle.truffle.r.ffi.impl.nfi.TruffleNFI_Context;
4647
import com.oracle.truffle.r.ffi.impl.upcalls.UpCallsRFFI;
4748
import com.oracle.truffle.r.nodes.RASTUtils;
4849
import com.oracle.truffle.r.nodes.function.ClassHierarchyNode;
@@ -1415,15 +1416,12 @@ public Object R_make_altcomplex_class(String className, String packageName, Obje
14151416
private static AltrepMethodDescriptor createAltrepMethodDescriptor(Object method, String signature) {
14161417
InteropLibrary interop = InteropLibrary.getUncached();
14171418
if (!interop.isExecutable(method)) {
1418-
if (interop.isMemberInvocable(method, "bind")) {
1419-
try {
1420-
Object boundMethod = interop.invokeMember(method, "bind", signature);
1421-
return new AltrepMethodDescriptor(boundMethod, Type.NFI);
1422-
} catch (InteropException e) {
1423-
throw RInternalError.shouldNotReachHere(e);
1424-
}
1419+
if (interop.isPointer(method)) {
1420+
Object parsedSignature = TruffleNFI_Context.parseSignature(signature);
1421+
Object boundMethod = SignatureLibrary.getUncached().bind(parsedSignature, method);
1422+
return new AltrepMethodDescriptor(boundMethod, Type.NFI);
14251423
} else {
1426-
throw RInternalError.shouldNotReachHere("method is from NFI, it should have 'bind' invocable member");
1424+
throw RInternalError.shouldNotReachHere("method is from NFI, it should be a pointer");
14271425
}
14281426
}
14291427
return new AltrepMethodDescriptor(method, Type.LLVM);

com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_C.java

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -24,10 +24,8 @@
2424

2525
import com.oracle.truffle.api.CompilerAsserts;
2626
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
27-
import com.oracle.truffle.api.interop.InteropException;
28-
import com.oracle.truffle.api.interop.InteropLibrary;
2927
import com.oracle.truffle.api.interop.TruffleObject;
30-
import com.oracle.truffle.r.runtime.RInternalError;
28+
import com.oracle.truffle.nfi.api.SignatureLibrary;
3129
import com.oracle.truffle.r.runtime.ffi.CRFFI;
3230
import com.oracle.truffle.r.runtime.ffi.InvokeCNode;
3331
import com.oracle.truffle.r.runtime.ffi.InvokeCNode.FunctionObjectGetter;
@@ -62,12 +60,8 @@ public static final class NFIFunctionObjectGetter extends FunctionObjectGetter {
6260
@TruffleBoundary
6361
public TruffleObject execute(TruffleObject address, int arity, NativeCallInfo nativeCallInfo) {
6462
// cache signatures
65-
try {
66-
return (TruffleObject) InteropLibrary.getFactory().getUncached().invokeMember(address, "bind",
67-
getSignatureForArity(arity));
68-
} catch (InteropException ex) {
69-
throw RInternalError.shouldNotReachHere(ex);
70-
}
63+
Object signature = TruffleNFI_Context.parseSignature(getSignatureForArity(arity));
64+
return (TruffleObject) SignatureLibrary.getUncached().bind(signature, address);
7165
}
7266
}
7367

com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Call.java

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -31,11 +31,11 @@
3131
import com.oracle.truffle.api.dsl.ImportStatic;
3232
import com.oracle.truffle.api.dsl.Specialization;
3333
import com.oracle.truffle.api.frame.VirtualFrame;
34-
import com.oracle.truffle.api.interop.InteropException;
3534
import com.oracle.truffle.api.interop.InteropLibrary;
3635
import com.oracle.truffle.api.interop.TruffleObject;
3736
import com.oracle.truffle.api.library.CachedLibrary;
3837
import com.oracle.truffle.api.nodes.Node;
38+
import com.oracle.truffle.nfi.api.SignatureLibrary;
3939
import com.oracle.truffle.r.ffi.impl.nfi.TruffleNFI_CallFactory.TruffleNFI_InvokeCallNodeGen;
4040
import com.oracle.truffle.r.runtime.DSLConfig;
4141
import com.oracle.truffle.r.runtime.RInternalError;
@@ -49,27 +49,24 @@
4949

5050
public class TruffleNFI_Call implements CallRFFI {
5151

52-
private static String getSignatureForArity(int arity) {
53-
CompilerAsserts.neverPartOfCompilation();
54-
StringBuilder str = new StringBuilder(10 * (arity + 2)).append("(");
55-
for (int i = 0; i < arity + 1; i++) {
56-
str.append(i > 0 ? ", " : "");
57-
str.append("pointer");
58-
}
59-
return str.append("): pointer").toString();
60-
}
52+
abstract static class NodeAdapter extends Node {
53+
@Child private SignatureLibrary signatures = SignatureLibrary.getFactory().createDispatched(DSLConfig.getInteropLibraryCacheSize());
6154

62-
private abstract static class NodeAdapter extends Node {
63-
@Child private InteropLibrary interop = InteropLibrary.getFactory().createDispatched(DSLConfig.getInteropLibraryCacheSize());
55+
static Object getSignatureForArity(int arity) {
56+
CompilerAsserts.neverPartOfCompilation();
57+
StringBuilder str = new StringBuilder(10 * (arity + 2)).append("(");
58+
for (int i = 0; i < arity + 1; i++) {
59+
str.append(i > 0 ? ", " : "");
60+
str.append("pointer");
61+
}
62+
String signature = str.append("): pointer").toString();
63+
return TruffleNFI_Context.parseSignature(signature);
64+
}
6465

6566
@TruffleBoundary
66-
protected TruffleObject getFunction(String name, String signature) {
67+
protected TruffleObject getFunction(String name, Object signature) {
6768
DLL.SymbolHandle symbolHandle = DLL.findSymbol(name, TruffleNFI_Context.getInstance().getRLibDLLInfo());
68-
try {
69-
return (TruffleObject) interop.invokeMember(symbolHandle.asTruffleObject(), "bind", signature);
70-
} catch (InteropException ex) {
71-
throw RInternalError.shouldNotReachHere(ex);
72-
}
69+
return (TruffleObject) signatures.bind(signature, symbolHandle.asTruffleObject());
7370
}
7471
}
7572

@@ -78,7 +75,12 @@ public abstract static class TruffleNFI_InvokeCallNode extends NodeAdapter imple
7875

7976
@TruffleBoundary
8077
protected TruffleObject getFunction(int arity) {
81-
return getFunction("dot_call" + arity, getSignatureForArity(arity));
78+
return getFunction(arity, getSignatureForArity(arity));
79+
}
80+
81+
@TruffleBoundary
82+
protected TruffleObject getFunction(int arity, Object signature) {
83+
return getFunction("dot_call" + arity, signature);
8284
}
8385

8486
@Specialization(guards = {"args.length == cachedArgsLength", "nativeCallInfo.address.asTruffleObject() == cachedAddress"})
@@ -99,9 +101,10 @@ protected Object invokeCallCachedLength(NativeCallInfo nativeCallInfo, Object[]
99101
@Cached("createMaterializeNodess(cachedArgsLength)") FFIMaterializeNode[] ffiMaterializeNode,
100102
@Cached("createWrapperNodes(cachedArgsLength)") FFIToNativeMirrorNode[] ffiToNativeMirrorNodes,
101103
@Cached("create()") FFIUnwrapNode unwrap,
104+
@Cached("getSignatureForArity(cachedArgsLength)") Object cachedSignature,
102105
@CachedLibrary(limit = "getInteropLibraryCacheSize()") InteropLibrary interop) {
103-
return doInvoke(nativeCallInfo, nativeCallInfo.address.asTruffleObject(), getFunction(cachedArgsLength), args, cachedArgsLength, ffiMaterializeNode, ffiToNativeMirrorNodes, interop,
104-
unwrap);
106+
return doInvoke(nativeCallInfo, nativeCallInfo.address.asTruffleObject(), getFunction(cachedArgsLength, cachedSignature), args, cachedArgsLength, ffiMaterializeNode,
107+
ffiToNativeMirrorNodes, interop, unwrap);
105108
}
106109

107110
private static Object doInvoke(NativeCallInfo nativeCallInfo, TruffleObject address, TruffleObject function, Object[] args, int cachedArgsLength, FFIMaterializeNode[] ffiMaterializeNode,
@@ -151,13 +154,13 @@ public void execute(VirtualFrame frame, NativeCallInfo nativeCallInfo, Object[]
151154
switch (args.length) {
152155
case 0:
153156
logCall(nativeCallInfo.name, args);
154-
TruffleObject callVoid0Function = getFunction("dot_call_void0", CallVoid0Sig);
157+
TruffleObject callVoid0Function = getFunction("dot_call_void0", TruffleNFI_Context.parseSignature(CallVoid0Sig));
155158
execute0Interop.execute(callVoid0Function, nativeCallInfo.address.asTruffleObject());
156159
break;
157160
case 1:
158161
logCall(nativeCallInfo.name, args);
159162
wrappedArgs = ffiWrap.wrapAll(args, ffiMaterialize1, ffiWrapper1);
160-
TruffleObject callVoid1Function = getFunction("dot_call_void1", CallVoid1Sig);
163+
TruffleObject callVoid1Function = getFunction("dot_call_void1", TruffleNFI_Context.parseSignature(CallVoid1Sig));
161164
execute1Interop.execute(callVoid1Function, nativeCallInfo.address.asTruffleObject(), wrappedArgs[0]);
162165
break;
163166
default:

com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Context.java

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -22,6 +22,7 @@
2222
*/
2323
package com.oracle.truffle.r.ffi.impl.nfi;
2424

25+
import com.oracle.truffle.api.CompilerAsserts;
2526
import com.oracle.truffle.api.CompilerDirectives;
2627
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
2728
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
@@ -32,6 +33,7 @@
3233
import com.oracle.truffle.api.interop.UnknownIdentifierException;
3334
import com.oracle.truffle.api.interop.UnsupportedMessageException;
3435
import com.oracle.truffle.api.source.Source;
36+
import com.oracle.truffle.nfi.api.SignatureLibrary;
3537
import com.oracle.truffle.r.ffi.impl.altrep.AltrepDownCallNodeFactoryImpl;
3638
import com.oracle.truffle.r.ffi.impl.common.LibPaths;
3739
import com.oracle.truffle.r.ffi.impl.mixed.TruffleMixed_DLL;
@@ -129,6 +131,12 @@ public Type getDefaultRFFIType() {
129131
return Type.NFI;
130132
}
131133

134+
public static Object parseSignature(String signature) {
135+
CompilerAsserts.neverPartOfCompilation();
136+
Source sigSource = Source.newBuilder("nfi", signature, "(nfi-signature)").build();
137+
return RContext.getInstance().getEnv().parseInternal(sigSource).call();
138+
}
139+
132140
/**
133141
* Looks up the given given function and returns the NFI function object.
134142
*/
@@ -156,8 +164,9 @@ public TruffleObject lookupNativeFunction(NativeFunction function) {
156164
}
157165
try {
158166
InteropLibrary interop = InteropLibrary.getFactory().getUncached();
159-
TruffleObject symbol = ((TruffleObject) interop.readMember(dllInfo, function.getCallName()));
160-
TruffleObject target = (TruffleObject) interop.invokeMember(symbol, "bind", function.getSignature());
167+
Object symbol = interop.readMember(dllInfo, function.getCallName());
168+
Object signature = parseSignature(function.getSignature());
169+
TruffleObject target = (TruffleObject) SignatureLibrary.getUncached().bind(signature, symbol);
161170
nativeFunctions[index] = target;
162171
} catch (InteropException e) {
163172
throw RInternalError.shouldNotReachHere(e);
@@ -219,8 +228,8 @@ private long initCallbacksAddress() {
219228
try {
220229
InteropLibrary interop = InteropLibrary.getFactory().getUncached();
221230
Object getCallbacksAddress = interop.readMember(getLibRHandle(), "Rinternals_getCallbacksAddress");
222-
TruffleObject getCallbacksAddressFunction = (TruffleObject) interop.invokeMember(getCallbacksAddress, "bind", "(): sint64");
223-
return (long) interop.execute(getCallbacksAddressFunction);
231+
Object signature = parseSignature("(): sint64");
232+
return (long) SignatureLibrary.getUncached().call(signature, getCallbacksAddress);
224233
} catch (InteropException ex) {
225234
throw RInternalError.shouldNotReachHere(ex);
226235
}
@@ -231,6 +240,7 @@ private void initCallbacks(RContext context) {
231240
// create and fill a new callbacks table
232241
callbacks = NativeMemory.allocate(Callbacks.values().length * (long) Long.BYTES, "callbacks");
233242
InteropLibrary interop = InteropLibrary.getFactory().getUncached();
243+
SignatureLibrary signatures = SignatureLibrary.getUncached();
234244
Object addCallback;
235245
try {
236246
addCallback = interop.readMember(getLibRHandle(), "Rinternals_addCallback");
@@ -240,9 +250,8 @@ private void initCallbacks(RContext context) {
240250
try {
241251
Callbacks.createCalls(new TruffleNFI_UpCallsRFFIImpl());
242252
for (Callbacks callback : Callbacks.values()) {
243-
String addCallbackSignature = String.format("(env, sint64, sint32, %s): void", callback.nfiSignature);
244-
TruffleObject addCallbackFunction = (TruffleObject) interop.invokeMember(addCallback, "bind", addCallbackSignature);
245-
interop.execute(addCallbackFunction, callbacks, callback.ordinal(), callback.call);
253+
Object addCallbackSignature = parseSignature(String.format("(env, sint64, sint32, %s): void", callback.nfiSignature));
254+
signatures.call(addCallbackSignature, addCallback, callbacks, callback.ordinal(), callback.call);
246255
}
247256
} catch (InteropException ex) {
248257
throw RInternalError.shouldNotReachHere(ex);

com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/FASTR_serializeNode.java

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -23,17 +23,17 @@
2323

2424
package com.oracle.truffle.r.ffi.impl.nodes;
2525

26+
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
2627
import com.oracle.truffle.api.TruffleLanguage;
28+
import com.oracle.truffle.api.dsl.Cached;
2729
import com.oracle.truffle.api.dsl.CachedContext;
2830
import com.oracle.truffle.api.dsl.GenerateUncached;
2931
import com.oracle.truffle.api.dsl.Specialization;
30-
import com.oracle.truffle.api.interop.ArityException;
3132
import com.oracle.truffle.api.interop.InteropLibrary;
32-
import com.oracle.truffle.api.interop.TruffleObject;
33-
import com.oracle.truffle.api.interop.UnknownIdentifierException;
34-
import com.oracle.truffle.api.interop.UnsupportedMessageException;
35-
import com.oracle.truffle.api.interop.UnsupportedTypeException;
3633
import com.oracle.truffle.api.library.CachedLibrary;
34+
import com.oracle.truffle.api.nodes.Node;
35+
import com.oracle.truffle.nfi.api.SignatureLibrary;
36+
import com.oracle.truffle.r.ffi.impl.nfi.TruffleNFI_Context;
3737
import com.oracle.truffle.r.runtime.RInternalError;
3838
import com.oracle.truffle.r.runtime.RSerialize;
3939
import com.oracle.truffle.r.runtime.context.RContext;
@@ -50,6 +50,24 @@ public static FASTR_serializeNode create() {
5050
return FASTR_serializeNodeGen.create();
5151
}
5252

53+
@GenerateUncached
54+
abstract static class BindSignatureNode extends Node {
55+
56+
abstract Object execute(Object function);
57+
58+
@TruffleBoundary
59+
static Object createSignature() {
60+
return TruffleNFI_Context.parseSignature(outBytesFuncSignature);
61+
}
62+
63+
@Specialization
64+
Object doBind(Object function,
65+
@Cached(value = "createSignature()", allowUncached = true) Object signature,
66+
@CachedLibrary("signature") SignatureLibrary signatures) {
67+
return signatures.bind(signature, function);
68+
}
69+
}
70+
5371
/**
5472
* Serializes object into buffer of bytes and passes this buffer into outBytesFunc native
5573
* callback.
@@ -69,17 +87,14 @@ public static FASTR_serializeNode create() {
6987
@Specialization
7088
protected Object doIt(Object object, @SuppressWarnings("unused") int type, int version, Object stream, Object outBytesFunc,
7189
@CachedContext(TruffleRLanguage.class) TruffleLanguage.ContextReference<RContext> ctxRef,
90+
@Cached BindSignatureNode bind,
7291
@CachedLibrary(limit = "getInteropLibraryCacheSize()") InteropLibrary interopLibrary) {
7392

74-
TruffleObject outBytesFuncExecutable = null;
75-
if (interopLibrary.isMemberInvocable(outBytesFunc, "bind")) {
76-
try {
77-
outBytesFuncExecutable = (TruffleObject) interopLibrary.invokeMember(outBytesFunc, "bind", outBytesFuncSignature);
78-
} catch (UnsupportedMessageException | ArityException | UnknownIdentifierException | UnsupportedTypeException e) {
79-
throw RInternalError.shouldNotReachHere(e);
80-
}
93+
Object outBytesFuncExecutable = null;
94+
if (!interopLibrary.isExecutable(outBytesFunc)) {
95+
outBytesFuncExecutable = bind.execute(outBytesFunc);
8196
} else {
82-
outBytesFuncExecutable = (TruffleObject) outBytesFunc;
97+
outBytesFuncExecutable = outBytesFunc;
8398
}
8499
assert outBytesFuncExecutable != null;
85100
assert interopLibrary.isExecutable(outBytesFuncExecutable);

mx.fastr/suite.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@
300300
"com.oracle.truffle.r.ffi.processor",
301301
"com.oracle.truffle.r.nodes",
302302
"org.rosuda.javaGD",
303+
"truffle:TRUFFLE_NFI",
303304
'BATIK-ALL-1.14',
304305
],
305306
"requires" : [

0 commit comments

Comments
 (0)