Skip to content
Snippets Groups Projects
Commit 6f6d6ba0 authored by Florian Angerer's avatar Florian Angerer
Browse files

Implemented builtin 'do.call.external' for invoking foreign functions.

parent 9581e815
Branches
No related tags found
No related merge requests found
......@@ -430,6 +430,7 @@ public class BasePackage extends RBuiltinPackage {
add(FastRInterop.InteropNew.class, FastRInteropFactory.InteropNewNodeGen::create);
add(FastRInterop.IsNull.class, FastRInteropFactory.IsNullNodeGen::create);
add(FastRInterop.IsExecutable.class, FastRInteropFactory.IsExecutableNodeGen::create);
add(FastRInterop.DoCallExternal.class, FastRInteropFactory.DoCallExternalNodeGen::create);
add(FastRInterop.IsExternal.class, FastRInteropFactory.IsExternalNodeGen::create);
add(FastRInterop.JavaClass.class, FastRInteropFactory.JavaClassNodeGen::create);
add(FastRInterop.JavaClassName.class, FastRInteropFactory.JavaClassNameNodeGen::create);
......
......@@ -84,10 +84,12 @@ import com.oracle.truffle.r.runtime.data.RNull;
import com.oracle.truffle.r.runtime.data.RRaw;
import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector;
import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
import com.oracle.truffle.r.runtime.data.model.RAbstractListVector;
import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector;
import com.oracle.truffle.r.runtime.data.model.RAbstractRawVector;
import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
import com.oracle.truffle.r.runtime.data.nodes.GetReadonlyData;
import com.oracle.truffle.r.runtime.interop.Foreign2R;
import com.oracle.truffle.r.runtime.interop.ForeignArray2R;
import com.oracle.truffle.r.runtime.interop.R2Foreign;
......@@ -867,4 +869,44 @@ public class FastRInterop {
}
return Class.forName(className);
}
@RBuiltin(name = "do.call.external", visibility = ON, kind = PRIMITIVE, parameterNames = {"receiver", "what", "args"}, behavior = COMPLEX)
public abstract static class DoCallExternal extends RBuiltinNode.Arg3 {
static {
Casts casts = new Casts(DoCallExternal.class);
casts.arg("args").mustBe(RAbstractListVector.class, RError.Message.GENERIC, "third argument must be a list");
}
@Child private GetReadonlyData.ObjectContent getDataNode;
protected Node createInvoke(int nargs) {
return Message.createInvoke(nargs).createNode();
}
@Specialization
public Object invoke(TruffleObject obj, String what, RAbstractListVector args,
@Cached("createInvoke(args.getLength())") Node invokeNode) {
if (getDataNode == null) {
getDataNode = insert(GetReadonlyData.ObjectContent.create());
}
Object[] argValues = getDataNode.execute(args);
try {
return ForeignAccess.sendInvoke(invokeNode, obj, what, argValues);
} catch (UnsupportedTypeException e) {
throw error(RError.Message.GENERIC, "Invalid argument types provided");
} catch (ArityException e) {
throw error(RError.Message.INVALID_ARG_NUMBER, what);
} catch (UnknownIdentifierException e) {
throw error(RError.Message.UNKNOWN_FUNCTION, what);
} catch (UnsupportedMessageException e) {
throw error(RError.Message.MUST_BE_STRING_OR_FUNCTION, "what");
} catch (RuntimeException e) {
throw error(RError.Message.GENERIC, e.getMessage());
}
}
}
}
......@@ -24,10 +24,13 @@ package com.oracle.truffle.r.runtime.data.nodes;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.r.runtime.RInternalError;
import com.oracle.truffle.r.runtime.data.NativeDataAccess;
import com.oracle.truffle.r.runtime.data.RDoubleVector;
import com.oracle.truffle.r.runtime.data.RIntVector;
import com.oracle.truffle.r.runtime.data.RList;
import com.oracle.truffle.r.runtime.data.RVector;
import com.oracle.truffle.r.runtime.data.model.RAbstractListVector;
/**
* Nodes contained in this class return an array that is either directly backing the vector data, or
......@@ -74,4 +77,27 @@ public class GetReadonlyData {
return GetReadonlyDataFactory.IntNodeGen.create();
}
}
public abstract static class ObjectContent extends Node {
public abstract Object[] execute(RAbstractListVector vector);
@Specialization(guards = "!vec.hasNativeMemoryData()")
protected Object[] doManagedRVector(RList vec) {
return vec.getInternalManagedData();
}
@Specialization(guards = "vec.hasNativeMemoryData()")
protected Object[] doNativeDataRVector(@SuppressWarnings("unused") RList vec) {
throw RInternalError.shouldNotReachHere("list cannot have native memory");
}
@Specialization
protected Object[] doGeneric(RAbstractListVector vec) {
return vec.materialize().getInternalManagedData();
}
public static ObjectContent create() {
return GetReadonlyDataFactory.ObjectContentNodeGen.create();
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment