diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_C.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_C.java index c6a44575fbe04e3278328db0b434fb5601f18f72..57f9b36dad911f2e1f2f9f03980b7bc0dc2118e3 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_C.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_C.java @@ -22,8 +22,8 @@ */ package com.oracle.truffle.r.ffi.impl.nfi; +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.interop.ForeignAccess; import com.oracle.truffle.api.interop.InteropException; @@ -44,77 +44,37 @@ public class TruffleNFI_C implements CRFFI { @Specialization(guards = "args.length == 0") protected void invokeCall0(NativeCallInfo nativeCallInfo, @SuppressWarnings("unused") Object[] args, @SuppressWarnings("unused") boolean hasStrings, @Cached("createExecute(args.length)") Node executeNode) { - try { - TruffleObject callFunction = (TruffleObject) ForeignAccess.sendInvoke(bindNode, - nativeCallInfo.address.asTruffleObject(), "bind", "(): void"); - ForeignAccess.sendExecute(executeNode, callFunction); - } catch (InteropException ex) { - throw RInternalError.shouldNotReachHere(ex); + synchronized (TruffleNFI_Call.class) { + try { + TruffleObject callFunction = (TruffleObject) ForeignAccess.sendInvoke(bindNode, nativeCallInfo.address.asTruffleObject(), "bind", "(): void"); + ForeignAccess.sendExecute(executeNode, callFunction); + } catch (InteropException ex) { + throw RInternalError.shouldNotReachHere(ex); + } } } - @Specialization(guards = "args.length == 1") + @Specialization(limit = "99", guards = "args.length == cachedArgsLength") protected void invokeCall1(NativeCallInfo nativeCallInfo, Object[] args, @SuppressWarnings("unused") boolean hasStrings, - @Cached("createExecute(args.length)") Node executeNode) { - try { - Object[] nargs = new Object[args.length]; - TruffleObject callFunction = (TruffleObject) ForeignAccess.sendInvoke(bindNode, - nativeCallInfo.address.asTruffleObject(), "bind", getSignature(args, nargs)); - ForeignAccess.sendExecute(executeNode, callFunction, nargs[0]); - } catch (InteropException ex) { - throw RInternalError.shouldNotReachHere(ex); - } - } - - @Specialization(guards = "args.length == 2") - protected void invokeCall2(NativeCallInfo nativeCallInfo, Object[] args, @SuppressWarnings("unused") boolean hasStrings, - @Cached("createExecute(args.length)") Node executeNode) { - try { - Object[] nargs = new Object[args.length]; - TruffleObject callFunction = (TruffleObject) ForeignAccess.sendInvoke(bindNode, - nativeCallInfo.address.asTruffleObject(), "bind", getSignature(args, nargs)); - ForeignAccess.sendExecute(executeNode, callFunction, nargs[0], nargs[1]); - } catch (InteropException ex) { - throw RInternalError.shouldNotReachHere(ex); + @Cached("args.length") int cachedArgsLength, + @Cached("createExecute(cachedArgsLength)") Node executeNode) { + synchronized (TruffleNFI_Call.class) { + try { + Object[] nargs = new Object[cachedArgsLength]; + TruffleObject callFunction = (TruffleObject) ForeignAccess.sendInvoke(bindNode, nativeCallInfo.address.asTruffleObject(), "bind", getSignature(args, nargs)); + ForeignAccess.sendExecute(executeNode, callFunction, nargs); + } catch (InteropException ex) { + throw RInternalError.shouldNotReachHere(ex); + } } } - @Specialization(guards = "args.length == 3") - protected void invokeCall3(NativeCallInfo nativeCallInfo, Object[] args, @SuppressWarnings("unused") boolean hasStrings, - @Cached("createExecute(args.length)") Node executeNode) { - try { - Object[] nargs = new Object[args.length]; - TruffleObject callFunction = (TruffleObject) ForeignAccess.sendInvoke(bindNode, - nativeCallInfo.address.asTruffleObject(), "bind", getSignature(args, nargs)); - ForeignAccess.sendExecute(executeNode, callFunction, nargs[0], nargs[1], nargs[2]); - } catch (InteropException ex) { - throw RInternalError.shouldNotReachHere(ex); - } - } - - @Specialization(guards = "args.length == 4") - protected void invokeCall4(NativeCallInfo nativeCallInfo, Object[] args, @SuppressWarnings("unused") boolean hasStrings, - @Cached("createExecute(args.length)") Node executeNode) { - try { - Object[] nargs = new Object[args.length]; - TruffleObject callFunction = (TruffleObject) ForeignAccess.sendInvoke(bindNode, - nativeCallInfo.address.asTruffleObject(), "bind", getSignature(args, nargs)); - ForeignAccess.sendExecute(executeNode, callFunction, nargs[0], nargs[1], nargs[2], nargs[3]); - } catch (InteropException ex) { - throw RInternalError.shouldNotReachHere(ex); - } - } - - @Fallback - protected void invokeCallN(@SuppressWarnings("unused") NativeCallInfo nativeCallInfo, @SuppressWarnings("unused") Object[] args, @SuppressWarnings("unused") boolean hasStrings) { - throw RInternalError.unimplemented(".C (too many args)"); - } - public static Node createExecute(int n) { return Message.createExecute(n).createNode(); } } + @TruffleBoundary private static String getSignature(Object[] args, Object[] nargs) { StringBuilder sb = new StringBuilder(); sb.append('('); @@ -124,8 +84,8 @@ public class TruffleNFI_C implements CRFFI { sb.append("[sint32]"); } else if (arg instanceof double[]) { sb.append("[double]"); - } else if (arg instanceof byte[]) { - sb.append("[uint8]"); + } else if (arg instanceof byte[][]) { + sb.append("[pointer]"); } else { throw RInternalError.unimplemented(".C type: " + arg.getClass().getSimpleName()); } diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Call.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Call.java index 0efd2c10b1fab6696a0bd2f5b603c85cfeaf2a21..6caf24cf5804b525ce207305cd4e9815311fd655 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Call.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nfi/TruffleNFI_Call.java @@ -26,6 +26,7 @@ import static com.oracle.truffle.r.ffi.impl.common.RFFIUtils.traceDownCall; import static com.oracle.truffle.r.ffi.impl.common.RFFIUtils.traceDownCallReturn; import static com.oracle.truffle.r.ffi.impl.common.RFFIUtils.traceEnabled; +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.interop.ForeignAccess; @@ -231,165 +232,69 @@ public class TruffleNFI_Call implements CallRFFI { } public abstract static class TruffleNFI_InvokeCallNode extends Node implements InvokeCallNode { - @Child private Node bindNode = Message.createInvoke(1).createNode(); - - @Specialization(guards = "args.length == 0") - protected Object invokeCall0(NativeCallInfo nativeCallInfo, Object[] args, - @Cached("createExecute(args.length)") Node executeNode) { - Object result = null; - boolean isNullSetting = prepareCall(nativeCallInfo.name, args); - try { - TruffleObject callFunction = (TruffleObject) ForeignAccess.sendInvoke(bindNode, - nativeCallInfo.address.asTruffleObject(), "bind", "(): object"); - result = ForeignAccess.sendExecute(executeNode, callFunction); - return result; - } catch (InteropException ex) { - throw RInternalError.shouldNotReachHere(ex); - } finally { - prepareReturn(nativeCallInfo.name, result, isNullSetting); - } - } + private static final String[] SIGNATURES = new String[32]; - @Specialization(guards = "args.length == 1") - protected Object invokeCall1(NativeCallInfo nativeCallInfo, Object[] args, - @Cached("createExecute(args.length)") Node executeNode) { - Object result = null; - boolean isNullSetting = prepareCall(nativeCallInfo.name, args); - try { - TruffleObject callFunction = (TruffleObject) ForeignAccess.sendInvoke(bindNode, - nativeCallInfo.address.asTruffleObject(), "bind", "(object): object"); - result = ForeignAccess.sendExecute(executeNode, callFunction, args[0]); - return result; - } catch (InteropException ex) { - throw RInternalError.shouldNotReachHere(ex); - } finally { - prepareReturn(nativeCallInfo.name, result, isNullSetting); - } - } - - @Specialization(guards = "args.length == 2") - protected Object invokeCall2(NativeCallInfo nativeCallInfo, Object[] args, - @Cached("createExecute(args.length)") Node executeNode) { - Object result = null; - boolean isNullSetting = prepareCall(nativeCallInfo.name, args); - try { - TruffleObject callFunction = (TruffleObject) ForeignAccess.sendInvoke(bindNode, - nativeCallInfo.address.asTruffleObject(), "bind", "(object, object): object"); - result = ForeignAccess.sendExecute(executeNode, callFunction, args[0], args[1]); - return result; - } catch (InteropException ex) { - throw RInternalError.shouldNotReachHere(ex); - } finally { - prepareReturn(nativeCallInfo.name, result, isNullSetting); - } - } - - @Specialization(guards = "args.length == 3") - protected Object invokeCall3(NativeCallInfo nativeCallInfo, Object[] args, - @Cached("createExecute(args.length)") Node executeNode) { - Object result = null; - boolean isNullSetting = prepareCall(nativeCallInfo.name, args); - try { - TruffleObject callFunction = (TruffleObject) ForeignAccess.sendInvoke(bindNode, - nativeCallInfo.address.asTruffleObject(), "bind", "(object, object, object): object"); - result = ForeignAccess.sendExecute(executeNode, callFunction, args[0], args[1], args[2]); - return result; - } catch (InteropException ex) { - throw RInternalError.shouldNotReachHere(ex); - } finally { - prepareReturn(nativeCallInfo.name, result, isNullSetting); - } - } - - @Specialization(guards = "args.length == 4") - protected Object invokeCall4(NativeCallInfo nativeCallInfo, Object[] args, - @Cached("createExecute(args.length)") Node executeNode) { - Object result = null; - boolean isNullSetting = prepareCall(nativeCallInfo.name, args); - try { - TruffleObject callFunction = (TruffleObject) ForeignAccess.sendInvoke(bindNode, - nativeCallInfo.address.asTruffleObject(), "bind", "(object, object, object, object): object"); - result = ForeignAccess.sendExecute(executeNode, callFunction, args[0], args[1], args[2], - args[3]); - return result; - } catch (InteropException ex) { - throw RInternalError.shouldNotReachHere(ex); - } finally { - prepareReturn(nativeCallInfo.name, result, isNullSetting); - } - } + @Child private Node bindNode = Message.createInvoke(1).createNode(); - @Specialization(guards = "args.length == 5") - protected Object invokeCall5(NativeCallInfo nativeCallInfo, Object[] args, - @Cached("createExecute(args.length)") Node executeNode) { - Object result = null; - boolean isNullSetting = prepareCall(nativeCallInfo.name, args); - try { - TruffleObject callFunction = (TruffleObject) ForeignAccess.sendInvoke(bindNode, - nativeCallInfo.address.asTruffleObject(), "bind", "(object, object, object, object, object): object"); - result = ForeignAccess.sendExecute(executeNode, callFunction, args[0], args[1], - args[2], args[3], args[4]); - return result; - } catch (InteropException ex) { - throw RInternalError.shouldNotReachHere(ex); - } finally { - prepareReturn(nativeCallInfo.name, result, isNullSetting); + @TruffleBoundary + protected TruffleObject getFunction(TruffleObject address, int arity) { + // cache signatures + String signature; + if (arity >= SIGNATURES.length || SIGNATURES[arity] == null) { + StringBuilder str = new StringBuilder().append('('); + for (int i = 0; i < arity; i++) { + str.append(i > 0 ? ", object" : "object"); + } + str.append("): object"); + signature = str.toString(); + if (arity < SIGNATURES.length) { + SIGNATURES[arity] = signature; + } + } else { + signature = SIGNATURES[arity]; } - } - - @Specialization(guards = "args.length == 6") - protected Object invokeCall6(NativeCallInfo nativeCallInfo, Object[] args, - @Cached("createExecute(args.length)") Node executeNode) { - Object result = null; - boolean isNullSetting = prepareCall(nativeCallInfo.name, args); try { - TruffleObject callFunction = (TruffleObject) ForeignAccess.sendInvoke(bindNode, - nativeCallInfo.address.asTruffleObject(), "bind", "(object, object, object, object, object, object): object"); - result = ForeignAccess.sendExecute(executeNode, callFunction, args[0], args[1], - args[2], args[3], args[4], args[5]); - return result; + return (TruffleObject) ForeignAccess.sendInvoke(bindNode, address, "bind", signature); } catch (InteropException ex) { throw RInternalError.shouldNotReachHere(ex); - } finally { - prepareReturn(nativeCallInfo.name, result, isNullSetting); } } - @Specialization(guards = "args.length == 7") - protected Object invokeCall7(NativeCallInfo nativeCallInfo, Object[] args, - @Cached("createExecute(args.length)") Node executeNode) { - Object result = null; - boolean isNullSetting = prepareCall(nativeCallInfo.name, args); - try { - TruffleObject callFunction = (TruffleObject) ForeignAccess.sendInvoke(bindNode, - nativeCallInfo.address.asTruffleObject(), "bind", "(object, object, object, object, object, object, object): object"); - result = ForeignAccess.sendExecute(executeNode, callFunction, args[0], args[1], - args[2], args[3], args[4], args[5], - args[6]); - return result; - } catch (InteropException ex) { - throw RInternalError.shouldNotReachHere(ex); - } finally { - prepareReturn(nativeCallInfo.name, result, isNullSetting); + @Specialization(guards = {"args.length == cachedArgsLength", "nativeCallInfo.address.asTruffleObject() == cachedAddress"}) + protected Object invokeCallCached(NativeCallInfo nativeCallInfo, Object[] args, + @SuppressWarnings("unused") @Cached("args.length") int cachedArgsLength, + @Cached("createExecute(cachedArgsLength)") Node executeNode, + @SuppressWarnings("unused") @Cached("nativeCallInfo.address.asTruffleObject()") TruffleObject cachedAddress, + @Cached("getFunction(cachedAddress, cachedArgsLength)") TruffleObject cachedFunction) { + synchronized (TruffleNFI_Call.class) { + Object result = null; + boolean isNullSetting = prepareCall(nativeCallInfo.name, args); + try { + result = ForeignAccess.sendExecute(executeNode, cachedFunction, args); + return result; + } catch (InteropException ex) { + throw RInternalError.shouldNotReachHere(ex); + } finally { + prepareReturn(nativeCallInfo.name, result, isNullSetting); + } } } - @Specialization(guards = "args.length == 8") - protected Object invokeCall8(NativeCallInfo nativeCallInfo, Object[] args, - @Cached("createExecute(args.length)") Node executeNode) { - Object result = null; - boolean isNullSetting = prepareCall(nativeCallInfo.name, args); - try { - TruffleObject callFunction = (TruffleObject) ForeignAccess.sendInvoke(bindNode, - nativeCallInfo.address.asTruffleObject(), "bind", "(object, object, object, object, object, object, object, object): object"); - result = ForeignAccess.sendExecute(executeNode, callFunction, args[0], args[1], - args[2], args[3], args[4], args[5], - args[6], args[7]); - return result; - } catch (InteropException ex) { - throw RInternalError.shouldNotReachHere(ex); - } finally { - prepareReturn(nativeCallInfo.name, result, isNullSetting); + @Specialization(limit = "99", guards = "args.length == cachedArgsLength") + protected Object invokeCallCachedLength(NativeCallInfo nativeCallInfo, Object[] args, + @Cached("args.length") int cachedArgsLength, + @Cached("createExecute(cachedArgsLength)") Node executeNode) { + synchronized (TruffleNFI_Call.class) { + Object result = null; + boolean isNullSetting = prepareCall(nativeCallInfo.name, args); + try { + result = ForeignAccess.sendExecute(executeNode, getFunction(nativeCallInfo.address.asTruffleObject(), cachedArgsLength), args); + return result; + } catch (InteropException ex) { + throw RInternalError.shouldNotReachHere(ex); + } finally { + prepareReturn(nativeCallInfo.name, result, isNullSetting); + } } } @@ -407,24 +312,26 @@ public class TruffleNFI_Call implements CallRFFI { @Override public void execute(NativeCallInfo nativeCallInfo, Object[] args) { - boolean isNullSetting = prepareCall(nativeCallInfo.name, args); - try { - switch (args.length) { - case 0: - TruffleObject callVoid0Function = (TruffleObject) ForeignAccess.sendInvoke(bindNode, - nativeCallInfo.address.asTruffleObject(), "bind", CallVoid0Sig); - ForeignAccess.sendExecute(execute0Node, callVoid0Function); - break; - case 1: - TruffleObject callVoid1Function = (TruffleObject) ForeignAccess.sendInvoke(bindNode, - nativeCallInfo.address.asTruffleObject(), "bind", CallVoid1Sig); - ForeignAccess.sendExecute(execute1Node, callVoid1Function, args[0]); - break; + synchronized (TruffleNFI_Call.class) { + boolean isNullSetting = prepareCall(nativeCallInfo.name, args); + try { + switch (args.length) { + case 0: + TruffleObject callVoid0Function = (TruffleObject) ForeignAccess.sendInvoke(bindNode, + nativeCallInfo.address.asTruffleObject(), "bind", CallVoid0Sig); + ForeignAccess.sendExecute(execute0Node, callVoid0Function); + break; + case 1: + TruffleObject callVoid1Function = (TruffleObject) ForeignAccess.sendInvoke(bindNode, + nativeCallInfo.address.asTruffleObject(), "bind", CallVoid1Sig); + ForeignAccess.sendExecute(execute1Node, callVoid1Function, args[0]); + break; + } + } catch (InteropException ex) { + throw RInternalError.shouldNotReachHere(ex); + } finally { + prepareReturn(nativeCallInfo.name, null, isNullSetting); } - } catch (InteropException ex) { - throw RInternalError.shouldNotReachHere(ex); - } finally { - prepareReturn(nativeCallInfo.name, null, isNullSetting); } } } diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/FFIWrapNode.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/FFIWrapNode.java index 662dcfd26b378c93d55fa5883f2dca1cbf8f56ae..2ae0b803e372d6040849900704aa52227a2efc0f 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/FFIWrapNode.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/FFIWrapNode.java @@ -22,16 +22,48 @@ */ package com.oracle.truffle.r.ffi.impl.upcalls; +import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.r.runtime.data.RDataFactory; +import com.oracle.truffle.r.runtime.data.RObject; -public final class FFIWrapNode extends Node { +public abstract class FFIWrapNode extends Node { - @SuppressWarnings("static-method") - public Object execute(Object value) { + public abstract Object execute(Object value); + + @Specialization + protected static Object wrap(int value) { + return wrap(RDataFactory.createIntVectorFromScalar(value)); + } + + @Specialization + protected static Object wrap(double value) { + return wrap(RDataFactory.createDoubleVectorFromScalar(value)); + } + + @Specialization + protected static Object wrap(byte value) { + return wrap(RDataFactory.createLogicalVectorFromScalar(value)); + } + + @Specialization + protected static Object wrap(String value) { + return wrap(RDataFactory.createStringVectorFromScalar(value)); + } + + @Specialization + protected static Object wrap(RObject value) { + return value; + } + + @Fallback + protected static Object wrap(Object value) { + System.out.println("invalid wrapping: " + value.getClass().getSimpleName()); return value; } public static FFIWrapNode create() { - return new FFIWrapNode(); + return FFIWrapNodeGen.create(); } } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RBaseObject.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RBaseObject.java index 52e181b7b495afc5e697ff40bff8347e407e17ff..b918df63e05ee7f040c2bed474b88bfe750fe094 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RBaseObject.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RBaseObject.java @@ -22,7 +22,7 @@ */ package com.oracle.truffle.r.runtime.data; -abstract class RBaseObject implements RTypedValue { +abstract class RBaseObject extends RObject implements RTypedValue { private int typedValueInfo; diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RObject.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RObject.java new file mode 100644 index 0000000000000000000000000000000000000000..1b3555e35bade73c1fea251848d3169a5205df5d --- /dev/null +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RObject.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.r.runtime.data; + +public abstract class RObject { + + private Object nativeMirror; + + public final void setNativeMirror(Object mirror) { + this.nativeMirror = mirror; + } + + public final Object getNativeMirror() { + return nativeMirror; + } +} diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RScalar.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RScalar.java index 9bfb531713c0f5371afb487a77fc86a0e3fdf978..e5fd6e43c40d9a6cd62b7b72c546c6fd18e6a6c4 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RScalar.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RScalar.java @@ -26,7 +26,7 @@ import com.oracle.truffle.api.CompilerDirectives.ValueType; import com.oracle.truffle.r.runtime.RInternalError; @ValueType -public abstract class RScalar implements RTypedValue { +public abstract class RScalar extends RObject implements RTypedValue { @Override public final int getTypedValueInfo() { diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CharSXPWrapper.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CharSXPWrapper.java index 62f5679c8c57b19df52ece5bb3f5ffcff0a08ffc..92763196ffc5a7d1515017bdf8db8fa535778c91 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CharSXPWrapper.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ffi/CharSXPWrapper.java @@ -22,6 +22,7 @@ */ package com.oracle.truffle.r.runtime.ffi; +import com.oracle.truffle.r.runtime.data.RObject; import com.oracle.truffle.r.runtime.data.RTruffleObject; /** @@ -32,9 +33,8 @@ import com.oracle.truffle.r.runtime.data.RTruffleObject; * represent a {@code CHARSXP}, so this class exists to do so. * * N.B. Use limited to RFFI implementations. - * */ -public final class CharSXPWrapper implements RTruffleObject { +public final class CharSXPWrapper extends RObject implements RTruffleObject { private final String contents; private CharSXPWrapper(String contents) {