Skip to content
Snippets Groups Projects
Commit 23aacfd4 authored by Mick Jordan's avatar Mick Jordan
Browse files

Merge pull request #543 in G/fastr from...

Merge pull request #543 in G/fastr from ~MICK.JORDAN_ORACLE.COM/fastr:feature/truffle-rffi to master

* commit 'c9b4f171':
  testrffi: add test for C string null termination
  Initial Truffle RFFI implementation
parents 99dec1bb c9b4f171
No related branches found
No related tags found
No related merge requests found
Showing
with 1319 additions and 1 deletion
......@@ -127,5 +127,8 @@ test_gnur
test_fastr
lib.install.cran*
package.blacklist
*.ll
*.su
*.bc
com.oracle.truffle.r.test.native/embedded/lib
bench-results.json
/*
* Copyright (c) 2014, 2016, 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.engine.interop;
import com.oracle.truffle.api.interop.TruffleObject;
/**
* A {@link TruffleObject} that represents an array of {@code unsigned char} values, that is
* {@code NULL} terminated in the C domain.
*/
public class NativeCharArray extends NativeUInt8Array {
public NativeCharArray(byte[] bytes) {
super(bytes, true);
}
}
/*
* Copyright (c) 2014, 2016, 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.engine.interop;
import com.oracle.truffle.api.interop.CanResolve;
import com.oracle.truffle.api.interop.MessageResolution;
import com.oracle.truffle.api.interop.Resolve;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.r.engine.TruffleRLanguage;
@MessageResolution(receiverType = NativeCharArray.class, language = TruffleRLanguage.class)
public class NativeCharArrayMR {
@Resolve(message = "READ")
public abstract static class NCAReadNode extends Node {
protected byte access(NativeCharArray receiver, int index) {
return receiver.read(index);
}
}
@Resolve(message = "WRITE")
public abstract static class NCAWriteNode extends Node {
protected Object access(NativeCharArray receiver, int index, byte value) {
receiver.write(index, value);
return value;
}
}
@Resolve(message = "HAS_SIZE")
public abstract static class NCAHasSizeNode extends Node {
protected boolean access(@SuppressWarnings("unused") NativeCharArray receiver) {
return true;
}
}
@Resolve(message = "GET_SIZE")
public abstract static class NCAGetSizeNode extends Node {
protected int access(NativeCharArray receiver) {
return receiver.getSize();
}
}
@Resolve(message = "UNBOX")
public abstract static class NCAUnboxNode extends Node {
protected long access(NativeCharArray receiver) {
return receiver.convertToNative();
}
}
@CanResolve
public abstract static class NCACheck extends Node {
protected static boolean test(TruffleObject receiver) {
return receiver instanceof NativeCharArray;
}
}
}
/*
* Copyright (c) 2016, 2016, 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.engine.interop;
import com.oracle.truffle.r.runtime.data.RTruffleObject;
public class NativeDoubleArray extends NativeNACheck implements RTruffleObject {
public final double[] value;
public NativeDoubleArray(Object obj, double[] value) {
super(obj);
this.value = value;
}
public NativeDoubleArray(double[] value) {
this(null, value);
}
}
/*
* Copyright (c) 2016, 2016, 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.engine.interop;
import com.oracle.truffle.api.interop.CanResolve;
import com.oracle.truffle.api.interop.MessageResolution;
import com.oracle.truffle.api.interop.Resolve;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.r.engine.TruffleRLanguage;
import com.oracle.truffle.r.runtime.RRuntime;
@MessageResolution(receiverType = NativeDoubleArray.class, language = TruffleRLanguage.class)
public class NativeDoubleArrayMR {
@Resolve(message = "READ")
public abstract static class NDAReadNode extends Node {
protected double access(NativeDoubleArray receiver, int index) {
return receiver.value[index];
}
}
@Resolve(message = "WRITE")
public abstract static class NDAWriteNode extends Node {
protected double access(NativeDoubleArray receiver, int index, double value) {
if (value == RRuntime.DOUBLE_NA) {
receiver.setIncomplete();
}
receiver.value[index] = value;
return value;
}
}
@CanResolve
public abstract static class NDACheck extends Node {
protected static boolean test(TruffleObject receiver) {
return receiver instanceof NativeDoubleArray;
}
}
}
/*
* Copyright (c) 2016, 2016, 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.engine.interop;
import com.oracle.truffle.r.runtime.data.RTruffleObject;
public class NativeIntegerArray extends NativeNACheck implements RTruffleObject {
public final int[] value;
public NativeIntegerArray(Object obj, int[] value) {
super(obj);
this.value = value;
}
public NativeIntegerArray(int[] value) {
this(null, value);
}
}
/*
* Copyright (c) 2016, 2016, 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.engine.interop;
import com.oracle.truffle.api.interop.CanResolve;
import com.oracle.truffle.api.interop.MessageResolution;
import com.oracle.truffle.api.interop.Resolve;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.r.engine.TruffleRLanguage;
import com.oracle.truffle.r.runtime.RRuntime;
@MessageResolution(receiverType = NativeIntegerArray.class, language = TruffleRLanguage.class)
public class NativeIntegerArrayMR {
@Resolve(message = "READ")
public abstract static class NIAReadNode extends Node {
protected int access(NativeIntegerArray receiver, int index) {
return receiver.value[index];
}
}
@Resolve(message = "WRITE")
public abstract static class NIAWriteNode extends Node {
protected int access(NativeIntegerArray receiver, int index, int value) {
if (value == RRuntime.INT_NA) {
receiver.setIncomplete();
}
receiver.value[index] = value;
return value;
}
}
@CanResolve
public abstract static class NIACheck extends Node {
protected static boolean test(TruffleObject receiver) {
return receiver instanceof NativeIntegerArray;
}
}
}
/*
* Copyright (c) 2014, 2016, 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.engine.interop;
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
import com.oracle.truffle.r.runtime.RRuntime;
import com.oracle.truffle.r.runtime.data.RTruffleObject;
/**
* Handles the requirement that the R FFI sees "logical" arrays as {@code int[]} but the actual
* array in FastR is represented as {@code byte[]}.
*/
public class NativeLogicalArray extends NativeNACheck implements RTruffleObject {
@CompilationFinal public final byte[] data;
public NativeLogicalArray(Object obj, byte[] value) {
super(obj);
this.data = value;
}
int read(int index) {
return data[index] & 0xFF;
}
void write(int index, int value) {
byte newVal;
if (value == RRuntime.INT_NA) {
newVal = RRuntime.LOGICAL_NA;
setIncomplete();
} else {
newVal = (byte) (value & 0xFF);
}
data[index] = newVal;
}
}
/*
* Copyright (c) 2014, 2016, 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.engine.interop;
import com.oracle.truffle.api.interop.CanResolve;
import com.oracle.truffle.api.interop.MessageResolution;
import com.oracle.truffle.api.interop.Resolve;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.r.engine.TruffleRLanguage;
@MessageResolution(receiverType = NativeLogicalArray.class, language = TruffleRLanguage.class)
public class NativeLogicalArrayMR {
@Resolve(message = "READ")
public abstract static class NLAReadNode extends Node {
protected int access(NativeLogicalArray receiver, int index) {
return receiver.read(index);
}
}
@Resolve(message = "WRITE")
public abstract static class NLAWriteNode extends Node {
protected Object access(NativeLogicalArray receiver, int index, int value) {
receiver.write(index, value);
return value;
}
}
@Resolve(message = "GET_SIZE")
public abstract static class NLAGetSizeNode extends Node {
protected int access(NativeLogicalArray receiver) {
return receiver.data.length;
}
}
@CanResolve
public abstract static class NLACheck extends Node {
protected static boolean test(TruffleObject receiver) {
return receiver instanceof NativeLogicalArray;
}
}
}
/*
* Copyright (c) 2014, 2016, 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.engine.interop;
import com.oracle.truffle.r.runtime.data.RVector;
/**
* Handles the {@code complete} flag in an {@link RVector} when an {@code NA} value is assigned in
* native code.
*
*/
public class NativeNACheck {
private final RVector<?> vec;
protected NativeNACheck(Object x) {
if (x instanceof RVector<?>) {
vec = (RVector<?>) x;
} else {
// scalar (length 1) vector or no associated R object
vec = null;
}
}
public void setIncomplete() {
if (vec != null) {
vec.setComplete(false);
}
}
}
/*
* Copyright (c) 2016, 2016, 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.engine.interop;
public class NativeRawArray extends NativeUInt8Array {
public NativeRawArray(byte[] bytes) {
super(bytes, false);
}
}
/*
* Copyright (c) 2016, 2016, 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.engine.interop;
import com.oracle.truffle.api.interop.CanResolve;
import com.oracle.truffle.api.interop.MessageResolution;
import com.oracle.truffle.api.interop.Resolve;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.r.engine.TruffleRLanguage;
@MessageResolution(receiverType = NativeRawArray.class, language = TruffleRLanguage.class)
public class NativeRawArrayMR {
@Resolve(message = "READ")
public abstract static class NRAReadNode extends Node {
protected byte access(NativeRawArray receiver, int index) {
return receiver.bytes[index];
}
}
@Resolve(message = "WRITE")
public abstract static class NRAWriteNode extends Node {
protected Object access(NativeRawArray receiver, int index, byte value) {
receiver.bytes[index] = value;
return value;
}
}
@Resolve(message = "GET_SIZE")
public abstract static class NRAGetSizeNode extends Node {
protected int access(NativeRawArray receiver) {
return receiver.bytes.length;
}
}
@Resolve(message = "UNBOX")
public abstract static class NRAUnboxNode extends Node {
protected long access(NativeRawArray receiver) {
return receiver.convertToNative();
}
}
@CanResolve
public abstract static class NRACheck extends Node {
protected static boolean test(TruffleObject receiver) {
return receiver instanceof NativeRawArray;
}
}
}
/*
* Copyright (c) 2016, 2016, 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.engine.interop;
import static com.oracle.truffle.r.engine.interop.UnsafeAdapter.UNSAFE;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
import com.oracle.truffle.r.runtime.data.RTruffleObject;
import sun.misc.Unsafe;
/**
* Parent class of {@link NativeRawArray} and {@link NativeCharArray}, that holds the common logic
* for a C type {@code uint8*}, that may or may not be {@code NULL} terminated (in the C domain),
* and may escape into the native domain via an UNBOX message.
*
* N.B. Java never stores a {@code NULL} value in a String or the byte array from
* {@link String#getBytes}.
*
* If {@link #fakeNull()} is {@code true}, then {@link #read} returns 0, else it is an error;
* similar for {@link #write}.
*/
public abstract class NativeUInt8Array implements RTruffleObject {
public final byte[] bytes;
/**
* If the array escapes the Truffle world via {@link #convertToNative()}, this value will be
* non-zero and is used exclusively thereafter.
*/
@CompilationFinal protected long nativeAddress;
private final int effectiveLength;
protected NativeUInt8Array(byte[] bytes, boolean nullTerminate) {
this.bytes = bytes;
this.effectiveLength = bytes.length + (nullTerminate ? 1 : 0);
}
private boolean fakeNull() {
return bytes.length != effectiveLength;
}
private void checkNativeIndex(int index) {
if (index < 0 || index >= effectiveLength) {
throw new ArrayIndexOutOfBoundsException(index);
}
}
void write(int index, byte value) {
if (nativeAddress != 0) {
checkNativeIndex(index);
UNSAFE.putByte(nativeAddress + index, value);
} else {
if (index == bytes.length && fakeNull()) {
// ignore
} else {
bytes[index] = value;
}
}
}
byte read(int index) {
if (nativeAddress != 0) {
checkNativeIndex(index);
return UNSAFE.getByte(nativeAddress + index);
} else {
if (index == bytes.length && fakeNull()) {
return (byte) 0;
}
return bytes[index];
}
}
int getSize() {
return bytes.length;
}
long convertToNative() {
if (nativeAddress == 0) {
CompilerDirectives.transferToInterpreterAndInvalidate();
nativeAddress = UNSAFE.allocateMemory(effectiveLength);
UNSAFE.copyMemory(bytes, Unsafe.ARRAY_BYTE_BASE_OFFSET, null, nativeAddress, bytes.length);
if (fakeNull()) {
UNSAFE.putByte(nativeAddress + bytes.length, (byte) 0);
}
}
return nativeAddress;
}
public byte[] getBytes() {
if (nativeAddress != 0) {
// copy back
UNSAFE.copyMemory(null, nativeAddress, bytes, Unsafe.ARRAY_BYTE_BASE_OFFSET, bytes.length);
}
return bytes;
}
}
/*
* Copyright (c) 2016, 2016, 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.engine.interop;
import com.oracle.truffle.api.interop.CanResolve;
import com.oracle.truffle.api.interop.MessageResolution;
import com.oracle.truffle.api.interop.Resolve;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.r.engine.TruffleRLanguage;
import com.oracle.truffle.r.runtime.data.RDouble;
@MessageResolution(receiverType = RDouble.class, language = TruffleRLanguage.class)
public class RDoubleMR {
@Resolve(message = "IS_BOXED")
public abstract static class RDoubleIsBoxedNode extends Node {
protected Object access(@SuppressWarnings("unused") RDouble receiver) {
return true;
}
}
@Resolve(message = "HAS_SIZE")
public abstract static class RDoubleHasSizeNode extends Node {
protected Object access(@SuppressWarnings("unused") RDouble receiver) {
return false;
}
}
@Resolve(message = "IS_NULL")
public abstract static class RDoubleIsNullNode extends Node {
protected Object access(@SuppressWarnings("unused") RDouble receiver) {
return false;
}
}
@Resolve(message = "UNBOX")
public abstract static class RDoubleUnboxNode extends Node {
protected double access(RDouble receiver) {
return receiver.getValue();
}
}
@CanResolve
public abstract static class RDoubleCheck extends Node {
protected static boolean test(TruffleObject receiver) {
return receiver instanceof RDouble;
}
}
}
......@@ -38,12 +38,14 @@ import com.oracle.truffle.r.runtime.context.RContext;
import com.oracle.truffle.r.runtime.context.RForeignAccessFactory;
import com.oracle.truffle.r.runtime.data.RComplex;
import com.oracle.truffle.r.runtime.data.RComplexVector;
import com.oracle.truffle.r.runtime.data.RDouble;
import com.oracle.truffle.r.runtime.data.RDoubleSequence;
import com.oracle.truffle.r.runtime.data.RDoubleVector;
import com.oracle.truffle.r.runtime.data.RExternalPtr;
import com.oracle.truffle.r.runtime.data.RFunction;
import com.oracle.truffle.r.runtime.data.RIntSequence;
import com.oracle.truffle.r.runtime.data.RIntVector;
import com.oracle.truffle.r.runtime.data.RInteger;
import com.oracle.truffle.r.runtime.data.RList;
import com.oracle.truffle.r.runtime.data.RLogicalVector;
import com.oracle.truffle.r.runtime.data.RNull;
......@@ -99,7 +101,10 @@ public final class RForeignAccessFactoryImpl implements RForeignAccessFactory {
RFunction.class, RNull.class, REnvironment.class,
RList.class, RSymbol.class,
RPairList.class, RExternalPtr.class, RUnboundValue.class,
DLLInfo.class, DotSymbol.class};
DLLInfo.class, DotSymbol.class,
NativeRawArray.class, NativeCharArray.class, NativeIntegerArray.class,
NativeDoubleArray.class, NativeLogicalArray.class,
RDouble.class, RInteger.class};
private static final class ForeignAccessState {
......@@ -211,6 +216,20 @@ public final class RForeignAccessFactoryImpl implements RForeignAccessFactory {
foreignAccess = RExternalPtrMRForeign.createAccess();
} else if (RUnboundValue.class.isAssignableFrom(clazz)) {
foreignAccess = RUnboundValueMRForeign.createAccess();
} else if (NativeRawArray.class.isAssignableFrom(clazz)) {
foreignAccess = NativeRawArrayMRForeign.createAccess();
} else if (NativeLogicalArray.class.isAssignableFrom(clazz)) {
foreignAccess = NativeLogicalArrayMRForeign.createAccess();
} else if (NativeCharArray.class.isAssignableFrom(clazz)) {
foreignAccess = NativeCharArrayMRForeign.createAccess();
} else if (NativeDoubleArray.class.isAssignableFrom(clazz)) {
foreignAccess = NativeDoubleArrayMRForeign.createAccess();
} else if (NativeIntegerArray.class.isAssignableFrom(clazz)) {
foreignAccess = NativeIntegerArrayMRForeign.createAccess();
} else if (RInteger.class.isAssignableFrom(clazz)) {
foreignAccess = RIntegerMRForeign.createAccess();
} else if (RDouble.class.isAssignableFrom(clazz)) {
foreignAccess = RDoubleMRForeign.createAccess();
} else {
if (RAbstractVector.class.isAssignableFrom(clazz)) {
foreignAccess = ForeignAccess.create(RAbstractVector.class, new RAbstractVectorAccessFactory());
......
/*
* Copyright (c) 2016, 2016, 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.engine.interop;
import com.oracle.truffle.api.interop.CanResolve;
import com.oracle.truffle.api.interop.MessageResolution;
import com.oracle.truffle.api.interop.Resolve;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.r.engine.TruffleRLanguage;
import com.oracle.truffle.r.runtime.data.RInteger;
@MessageResolution(receiverType = RInteger.class, language = TruffleRLanguage.class)
public class RIntegerMR {
@Resolve(message = "IS_BOXED")
public abstract static class RIntegerIsBoxedNode extends Node {
protected Object access(@SuppressWarnings("unused") RInteger receiver) {
return true;
}
}
@Resolve(message = "HAS_SIZE")
public abstract static class RIntegerHasSizeNode extends Node {
protected Object access(@SuppressWarnings("unused") RInteger receiver) {
return false;
}
}
@Resolve(message = "IS_NULL")
public abstract static class RIntegerIsNullNode extends Node {
protected Object access(@SuppressWarnings("unused") RInteger receiver) {
return false;
}
}
@Resolve(message = "UNBOX")
public abstract static class RIntegerUnboxNode extends Node {
protected double access(RInteger receiver) {
return receiver.getValue();
}
}
@CanResolve
public abstract static class RIntegerCheck extends Node {
protected static boolean test(TruffleObject receiver) {
return receiver instanceof RInteger;
}
}
}
/*
* Copyright (c) 2014, 2016, 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.engine.interop;
import java.lang.reflect.Field;
import sun.misc.Unsafe;
class UnsafeAdapter {
static final Unsafe UNSAFE = initUnsafe();
private static Unsafe initUnsafe() {
try {
return Unsafe.getUnsafe();
} catch (SecurityException se) {
try {
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
return (Unsafe) theUnsafe.get(Unsafe.class);
} catch (Exception e) {
throw new RuntimeException("exception while trying to get Unsafe", e);
}
}
}
}
/*
* Copyright (c) 2014, 2016, 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.engine.interop.ffi;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.interop.ForeignAccess;
import com.oracle.truffle.api.interop.Message;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.r.engine.interop.NativeRawArray;
import com.oracle.truffle.r.engine.interop.NativeDoubleArray;
import com.oracle.truffle.r.engine.interop.NativeIntegerArray;
import com.oracle.truffle.r.runtime.RInternalError;
import com.oracle.truffle.r.runtime.ffi.CRFFI;
import com.oracle.truffle.r.runtime.ffi.NativeCallInfo;
import com.oracle.truffle.r.runtime.ffi.jni.JNI_C;
import com.oracle.truffle.r.runtime.ffi.truffle.TruffleRFFIFrameHelper;
class TruffleC implements CRFFI {
private static class TruffleCRFFINode extends JNI_C.JNI_CRFFINode {
@Override
public synchronized void invoke(NativeCallInfo nativeCallInfo, Object[] args) {
if (nativeCallInfo.address.value instanceof Long) {
super.invoke(nativeCallInfo, args);
} else {
VirtualFrame frame = TruffleRFFIFrameHelper.create();
TruffleDLL.ensureParsed(nativeCallInfo);
Object[] wargs = wrap(args);
try {
Node messageNode = Message.createExecute(0).createNode();
ForeignAccess.sendExecute(messageNode, frame, nativeCallInfo.address.asTruffleObject(), wargs);
} catch (Throwable t) {
throw RInternalError.shouldNotReachHere(t);
}
}
}
Object[] wrap(Object[] args) {
Object[] nargs = new Object[args.length];
for (int i = 0; i < args.length; i++) {
Object arg = args[i];
Object narg;
if (arg instanceof int[]) {
narg = new NativeIntegerArray((int[]) arg);
} else if (arg instanceof double[]) {
narg = new NativeDoubleArray((double[]) arg);
} else if (arg instanceof byte[]) {
narg = new NativeRawArray((byte[]) arg);
} else {
throw RInternalError.unimplemented(".C type: " + arg.getClass().getSimpleName());
}
nargs[i] = narg;
}
return nargs;
}
}
@Override
public CRFFINode createCRFFINode() {
return new TruffleCRFFINode();
}
}
/*
* Copyright (c) 2016, 2016, 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.engine.interop.ffi;
import com.oracle.truffle.r.runtime.ffi.DLL;
import com.oracle.truffle.r.runtime.ffi.RFFIFactory;
/**
* Access to primitive C operations.
*/
public class TruffleCAccess {
private static final TruffleDLL.TruffleHandle handle = new TruffleDLL.TruffleHandle("libR");
public enum Function {
READ_POINTER_INT,
READ_ARRAY_INT,
READ_POINTER_DOUBLE,
READ_ARRAY_DOUBLE;
private DLL.SymbolHandle symbolHandle;
public DLL.SymbolHandle getSymbolHandle() {
if (symbolHandle == null) {
symbolHandle = RFFIFactory.getRFFI().getDLLRFFI().dlsym(handle, cName());
}
return symbolHandle;
}
public String cName() {
return "caccess_" + name().toLowerCase();
}
}
}
/*
* Copyright (c) 2014, 2016, 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.engine.interop.ffi;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.ImportStatic;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.interop.ForeignAccess;
import com.oracle.truffle.api.interop.Message;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.interop.java.JavaInterop;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.r.engine.interop.ffi.TruffleCallFactory.InvokeTruffleNodeGen;
import com.oracle.truffle.r.engine.interop.ffi.TruffleCallFactory.SplitTruffleCallRFFINodeGen;
import com.oracle.truffle.r.runtime.RInternalError;
import com.oracle.truffle.r.runtime.context.RContext;
import com.oracle.truffle.r.runtime.context.RContext.ContextState;
import com.oracle.truffle.r.runtime.data.RNull;
import com.oracle.truffle.r.runtime.ffi.CallRFFI;
import com.oracle.truffle.r.runtime.ffi.NativeCallInfo;
import com.oracle.truffle.r.runtime.ffi.RFFIVariables;
import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle;
import com.oracle.truffle.r.runtime.ffi.jni.JNI_Call;
import com.oracle.truffle.r.runtime.ffi.jni.JNI_Call.JNI_CallRFFINode;
import com.oracle.truffle.r.runtime.ffi.truffle.TruffleRFFIFrameHelper;
class TruffleCall implements CallRFFI {
private static TruffleCall truffleCall;
private static TruffleObject truffleCallTruffleObject;
private static TruffleObject truffleCallHelper;
@SuppressWarnings("unused")
TruffleCall() {
new JNI_Call();
truffleCall = this;
truffleCallTruffleObject = JavaInterop.asTruffleObject(truffleCall);
TrufflePkgInit.initialize();
truffleCallHelper = TruffleCallHelper.initialize();
}
static class ContextStateImpl implements RContext.ContextState {
private RContext context;
private boolean initVariablesDone;
@Override
public ContextState initialize(RContext contextA) {
this.context = contextA;
context.addExportedSymbol("_fastr_rffi_call", truffleCallTruffleObject);
context.addExportedSymbol("_fastr_rffi_callhelper", truffleCallHelper);
return this;
}
@Override
public void beforeDestroy(RContext contextA) {
}
}
static ContextStateImpl newContextState() {
return new ContextStateImpl();
}
private enum INIT_VAR_FUN {
OBJ,
DOUBLE,
INT;
private final String funName;
private SymbolHandle symbolHandle;
INIT_VAR_FUN() {
funName = "Call_initvar_" + name().toLowerCase();
}
}
private static void initVariables(RContext context) {
// must have parsed the variables module in libR
for (INIT_VAR_FUN initVarFun : INIT_VAR_FUN.values()) {
TruffleDLL.ensureParsed("libR", initVarFun.funName, true);
initVarFun.symbolHandle = new SymbolHandle(context.getEnv().importSymbol("@" + initVarFun.funName));
}
VirtualFrame frame = TruffleRFFIFrameHelper.create();
Node executeNode = Message.createExecute(2).createNode();
RFFIVariables[] variables = RFFIVariables.values();
for (int i = 0; i < variables.length; i++) {
RFFIVariables var = variables[i];
Object value = var.getValue();
if (value == null) {
continue;
}
try {
if (value instanceof Double) {
ForeignAccess.sendExecute(executeNode, frame, INIT_VAR_FUN.DOUBLE.symbolHandle.asTruffleObject(), i, value);
} else if (value instanceof Integer) {
ForeignAccess.sendExecute(executeNode, frame, INIT_VAR_FUN.INT.symbolHandle.asTruffleObject(), i, value);
} else {
// TODO
// ForeignAccess.sendExecute(executeNode, frame,
// INIT_VAR_FUN.OBJ.symbolHandle.asTruffleObject(), i, value);
}
} catch (Throwable t) {
throw RInternalError.shouldNotReachHere(t);
}
}
}
public static class InvokeJNI extends Node {
@Child JNI_CallRFFINode jniCall = new JNI_CallRFFINode();
public Object invokeCall(NativeCallInfo nativeCallInfo, Object[] args) {
return jniCall.invokeCall(nativeCallInfo, args);
}
public Object invokeVoidCall(NativeCallInfo nativeCallInfo, Object[] args) {
jniCall.invokeVoidCall(nativeCallInfo, args);
return RNull.instance;
}
}
/**
* Experimentally the node created for the message send contains cached information regarding
* the target, which is {@link RContext} specific, leading to invalid data being accessed in
* SHARED_PARENT_RW contexts (specifically the cached exported symbols used for package
* initialization). So we guard the node with a check that the context has not changed.
*
*/
@ImportStatic({Message.class, RContext.class})
public abstract static class InvokeTruffle extends Node {
public abstract Object execute(NativeCallInfo nativeCallInfo, Object[] args, RContext context);
@Specialization(guards = {"context == cachedContext"})
protected Object invokeCallCached(NativeCallInfo nativeCallInfo, Object[] args, @SuppressWarnings("unused") RContext context, //
@SuppressWarnings("unused") @Cached("getInstance()") RContext cachedContext,
@Cached("createExecute(0).createNode()") Node messageNode,
@SuppressWarnings("unused") @Cached("ensureReady(nativeCallInfo)") boolean ready) {
return doInvoke(messageNode, nativeCallInfo, args);
}
@Specialization(contains = "invokeCallCached")
protected Object invokeCallNormal(NativeCallInfo nativeCallInfo, Object[] args, @SuppressWarnings("unused") RContext context) {
return doInvoke(Message.createExecute(0).createNode(), nativeCallInfo, args);
}
private static Object doInvoke(Node messageNode, NativeCallInfo nativeCallInfo, Object[] args) {
VirtualFrame frame = TruffleRFFIFrameHelper.create();
try {
return ForeignAccess.sendExecute(messageNode, frame, nativeCallInfo.address.asTruffleObject(), args);
} catch (Throwable t) {
throw RInternalError.shouldNotReachHere(t);
}
}
public static boolean ensureReady(NativeCallInfo nativeCallInfo) {
TruffleDLL.ensureParsed(nativeCallInfo);
ContextStateImpl contextState = TruffleRFFIContextState.getContextState().callState;
if (!contextState.initVariablesDone) {
initVariables(contextState.context);
contextState.initVariablesDone = true;
}
return true;
}
public static InvokeTruffle create() {
return InvokeTruffleNodeGen.create();
}
}
/**
* This class exists to separate out the delegated JNI calls from the Truffle calls.
*/
public abstract static class SplitTruffleCallRFFINode extends Node {
public abstract Object execute(NativeCallInfo nativeCallInfo, Object[] args, boolean voidCall);
@Specialization(guards = {"isJNICall(nativeCallInfo)", "!voidCall"})
protected Object invokeCall(NativeCallInfo nativeCallInfo, Object[] args, @SuppressWarnings("unused") boolean voidCall, //
@Cached("new()") InvokeJNI invokeJNI) {
return invokeJNI.invokeCall(nativeCallInfo, args);
}
@Specialization(guards = {"isJNICall(nativeCallInfo)", "voidCall"})
protected Object invokeVoidCall(NativeCallInfo nativeCallInfo, Object[] args, @SuppressWarnings("unused") boolean voidCall, //
@Cached("new()") InvokeJNI invokeJNI) {
return invokeJNI.invokeVoidCall(nativeCallInfo, args);
}
@Specialization(guards = "!isJNICall(nativeCallInfo)")
protected Object invokeCall(NativeCallInfo nativeCallInfo, Object[] args, @SuppressWarnings("unused") boolean voidCall, //
@Cached("create()") InvokeTruffle invokeTruffle) {
return invokeTruffle.execute(nativeCallInfo, args, RContext.getInstance());
}
public static boolean isJNICall(NativeCallInfo nativeCallInfo) {
return nativeCallInfo.address.value instanceof Long;
}
}
private static class TruffleCallRFFINode extends CallRFFINode {
@Child SplitTruffleCallRFFINode splitTruffleCallRFFINode = SplitTruffleCallRFFINodeGen.create();
@Override
public synchronized Object invokeCall(NativeCallInfo nativeCallInfo, Object[] args) {
return splitTruffleCallRFFINode.execute(nativeCallInfo, args, false);
}
@Override
public synchronized void invokeVoidCall(NativeCallInfo nativeCallInfo, Object[] args) {
splitTruffleCallRFFINode.execute(nativeCallInfo, args, true);
}
@Override
public void setTempDir(String tempDir) {
// TODO Truffleize
new JNI_CallRFFINode().setTempDir(tempDir);
}
@Override
public void setInteractive(boolean interactive) {
// TODO Truffleize
new JNI_CallRFFINode().setInteractive(interactive);
}
}
/**
* Upcalled from Rinternal et al.
*
* @param function
*/
public void unimplemented(String function) {
throw RInternalError.unimplemented("RFFI function: '" + function + "' not implemented");
}
@Override
public CallRFFINode createCallRFFINode() {
return new TruffleCallRFFINode();
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment