Skip to content
Snippets Groups Projects
Commit 28cfd5c0 authored by Lukas Stadler's avatar Lukas Stadler Committed by stepan
Browse files

change FFIProcessor to generate foreign access factories directly

parent d81131c3
No related branches found
No related tags found
No related merge requests found
Showing
with 299 additions and 83 deletions
...@@ -25,7 +25,7 @@ package com.oracle.truffle.r.ffi.impl.interop.pkginit; ...@@ -25,7 +25,7 @@ package com.oracle.truffle.r.ffi.impl.interop.pkginit;
import com.oracle.truffle.api.interop.MessageResolution; import com.oracle.truffle.api.interop.MessageResolution;
import com.oracle.truffle.api.interop.Resolve; import com.oracle.truffle.api.interop.Resolve;
import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.r.ffi.impl.common.UpCallUnwrap; import com.oracle.truffle.r.ffi.impl.upcalls.UpCallUnwrap;
import com.oracle.truffle.r.runtime.ffi.DLL.DLLInfo; import com.oracle.truffle.r.runtime.ffi.DLL.DLLInfo;
@MessageResolution(receiverType = SetDotSymbolValuesCall.class) @MessageResolution(receiverType = SetDotSymbolValuesCall.class)
......
...@@ -34,12 +34,12 @@ import com.oracle.truffle.api.interop.TruffleObject; ...@@ -34,12 +34,12 @@ import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.nodes.ExplodeLoop; import com.oracle.truffle.api.nodes.ExplodeLoop;
import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.r.ffi.impl.common.RFFIUtils; import com.oracle.truffle.r.ffi.impl.common.RFFIUtils;
import com.oracle.truffle.r.ffi.impl.common.UpCallUnwrap;
import com.oracle.truffle.r.ffi.impl.llvm.TruffleLLVM_CallFactory.ToNativeNodeGen; import com.oracle.truffle.r.ffi.impl.llvm.TruffleLLVM_CallFactory.ToNativeNodeGen;
import com.oracle.truffle.r.ffi.impl.llvm.TruffleLLVM_CallFactory.TruffleLLVM_InvokeCallNodeGen; import com.oracle.truffle.r.ffi.impl.llvm.TruffleLLVM_CallFactory.TruffleLLVM_InvokeCallNodeGen;
import com.oracle.truffle.r.ffi.impl.llvm.upcalls.BytesToNativeCharArrayCall; import com.oracle.truffle.r.ffi.impl.llvm.upcalls.BytesToNativeCharArrayCall;
import com.oracle.truffle.r.ffi.impl.llvm.upcalls.CharSXPToNativeArrayCall; import com.oracle.truffle.r.ffi.impl.llvm.upcalls.CharSXPToNativeArrayCall;
import com.oracle.truffle.r.ffi.impl.upcalls.Callbacks; import com.oracle.truffle.r.ffi.impl.upcalls.Callbacks;
import com.oracle.truffle.r.ffi.impl.upcalls.UpCallUnwrap;
import com.oracle.truffle.r.ffi.impl.upcalls.UpCallsRFFI; import com.oracle.truffle.r.ffi.impl.upcalls.UpCallsRFFI;
import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.RInternalError;
import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.RRuntime;
......
...@@ -28,6 +28,11 @@ import com.oracle.truffle.api.dsl.Cached; ...@@ -28,6 +28,11 @@ import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Fallback;
import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.dsl.TypeSystemReference; import com.oracle.truffle.api.dsl.TypeSystemReference;
import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodesFactory.CADDRNodeGen;
import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodesFactory.CADRNodeGen;
import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodesFactory.CARNodeGen;
import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodesFactory.CDDRNodeGen;
import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodesFactory.CDRNodeGen;
import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode;
import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetNamesAttributeNode; import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetNamesAttributeNode;
import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.RInternalError;
...@@ -83,6 +88,10 @@ public final class ListAccessNodes { ...@@ -83,6 +88,10 @@ public final class ListAccessNodes {
protected Object car(@SuppressWarnings("unused") Object obj) { protected Object car(@SuppressWarnings("unused") Object obj) {
throw RInternalError.unimplemented("CAR only works on pair lists, language objects, argument lists, and symbols"); throw RInternalError.unimplemented("CAR only works on pair lists, language objects, argument lists, and symbols");
} }
public static CARNode create() {
return CARNodeGen.create();
}
} }
@TypeSystemReference(RTypes.class) @TypeSystemReference(RTypes.class)
...@@ -123,7 +132,10 @@ public final class ListAccessNodes { ...@@ -123,7 +132,10 @@ public final class ListAccessNodes {
@Fallback @Fallback
protected Object cdr(@SuppressWarnings("unused") Object obj) { protected Object cdr(@SuppressWarnings("unused") Object obj) {
throw RInternalError.unimplemented("CDR only works on pair lists, language objects, and argument lists"); throw RInternalError.unimplemented("CDR only works on pair lists, language objects, and argument lists");
}
public static CDRNode create() {
return CDRNodeGen.create();
} }
} }
...@@ -143,6 +155,10 @@ public final class ListAccessNodes { ...@@ -143,6 +155,10 @@ public final class ListAccessNodes {
protected Object cadr(@SuppressWarnings("unused") Object obj) { protected Object cadr(@SuppressWarnings("unused") Object obj) {
throw RInternalError.unimplemented("CADR only works on pair lists and language objects"); throw RInternalError.unimplemented("CADR only works on pair lists and language objects");
} }
public static CADRNode create() {
return CADRNodeGen.create();
}
} }
@TypeSystemReference(RTypes.class) @TypeSystemReference(RTypes.class)
...@@ -161,6 +177,10 @@ public final class ListAccessNodes { ...@@ -161,6 +177,10 @@ public final class ListAccessNodes {
protected Object caddr(@SuppressWarnings("unused") Object obj) { protected Object caddr(@SuppressWarnings("unused") Object obj) {
throw RInternalError.unimplemented("CADDR only works on pair lists and language objects"); throw RInternalError.unimplemented("CADDR only works on pair lists and language objects");
} }
public static CADDRNode create() {
return CADDRNodeGen.create();
}
} }
@TypeSystemReference(RTypes.class) @TypeSystemReference(RTypes.class)
...@@ -179,7 +199,10 @@ public final class ListAccessNodes { ...@@ -179,7 +199,10 @@ public final class ListAccessNodes {
@Fallback @Fallback
protected Object cddr(@SuppressWarnings("unused") Object obj) { protected Object cddr(@SuppressWarnings("unused") Object obj) {
throw RInternalError.unimplemented("CDDR only works on pair lists and language objects"); throw RInternalError.unimplemented("CDDR only works on pair lists and language objects");
}
public static CDDRNode create() {
return CDDRNodeGen.create();
} }
} }
} }
...@@ -26,6 +26,10 @@ import com.oracle.truffle.api.CompilerDirectives; ...@@ -26,6 +26,10 @@ import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Fallback;
import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.dsl.TypeSystemReference; import com.oracle.truffle.api.dsl.TypeSystemReference;
import com.oracle.truffle.r.ffi.impl.nodes.MiscNodesFactory.LENGTHNodeGen;
import com.oracle.truffle.r.ffi.impl.nodes.MiscNodesFactory.RDoNewObjectNodeGen;
import com.oracle.truffle.r.ffi.impl.nodes.MiscNodesFactory.RDoSlotAssignNodeGen;
import com.oracle.truffle.r.ffi.impl.nodes.MiscNodesFactory.RDoSlotNodeGen;
import com.oracle.truffle.r.nodes.access.AccessSlotNode; import com.oracle.truffle.r.nodes.access.AccessSlotNode;
import com.oracle.truffle.r.nodes.access.AccessSlotNodeGen; import com.oracle.truffle.r.nodes.access.AccessSlotNodeGen;
import com.oracle.truffle.r.nodes.access.UpdateSlotNode; import com.oracle.truffle.r.nodes.access.UpdateSlotNode;
...@@ -102,6 +106,10 @@ public final class MiscNodes { ...@@ -102,6 +106,10 @@ public final class MiscNodes {
CompilerDirectives.transferToInterpreter(); CompilerDirectives.transferToInterpreter();
throw RError.error(RError.SHOW_CALLER2, RError.Message.LENGTH_MISAPPLIED, SEXPTYPE.gnuRTypeForObject(obj).name()); throw RError.error(RError.SHOW_CALLER2, RError.Message.LENGTH_MISAPPLIED, SEXPTYPE.gnuRTypeForObject(obj).name());
} }
public static LENGTHNode create() {
return LENGTHNodeGen.create();
}
} }
@TypeSystemReference(RTypes.class) @TypeSystemReference(RTypes.class)
...@@ -122,6 +130,10 @@ public final class MiscNodes { ...@@ -122,6 +130,10 @@ public final class MiscNodes {
Object doSlot(@SuppressWarnings("unused") Object o, Object name) { Object doSlot(@SuppressWarnings("unused") Object o, Object name) {
throw RError.error(RError.SHOW_CALLER2, RError.Message.INVALID_ARGUMENT_OF_TYPE, "name", SEXPTYPE.gnuRTypeForObject(name).name()); throw RError.error(RError.SHOW_CALLER2, RError.Message.INVALID_ARGUMENT_OF_TYPE, "name", SEXPTYPE.gnuRTypeForObject(name).name());
} }
public static RDoSlotNode create() {
return RDoSlotNodeGen.create();
}
} }
@TypeSystemReference(RTypes.class) @TypeSystemReference(RTypes.class)
...@@ -142,6 +154,10 @@ public final class MiscNodes { ...@@ -142,6 +154,10 @@ public final class MiscNodes {
Object doSlot(@SuppressWarnings("unused") Object o, Object name, @SuppressWarnings("unused") Object value) { Object doSlot(@SuppressWarnings("unused") Object o, Object name, @SuppressWarnings("unused") Object value) {
throw RError.error(RError.SHOW_CALLER2, RError.Message.INVALID_ARGUMENT_OF_TYPE, "name", SEXPTYPE.gnuRTypeForObject(name).name()); throw RError.error(RError.SHOW_CALLER2, RError.Message.INVALID_ARGUMENT_OF_TYPE, "name", SEXPTYPE.gnuRTypeForObject(name).name());
} }
public static RDoSlotAssignNode create() {
return RDoSlotAssignNodeGen.create();
}
} }
@TypeSystemReference(RTypes.class) @TypeSystemReference(RTypes.class)
...@@ -157,6 +173,10 @@ public final class MiscNodes { ...@@ -157,6 +173,10 @@ public final class MiscNodes {
Object doNewObject(Object classDef) { Object doNewObject(Object classDef) {
return newObjectNode.execute(classDef); return newObjectNode.execute(classDef);
} }
public static RDoNewObjectNode create() {
return RDoNewObjectNodeGen.create();
}
} }
@TypeSystemReference(RTypes.class) @TypeSystemReference(RTypes.class)
......
/*
* Copyright (c) 2017, 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.ffi.impl.upcalls;
import com.oracle.truffle.api.CallTarget;
import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.interop.ForeignAccess.Factory;
import com.oracle.truffle.api.interop.ForeignAccess.Factory26;
import com.oracle.truffle.api.interop.Message;
import com.oracle.truffle.api.nodes.RootNode;
public abstract class AbstractDowncallForeign implements Factory26, Factory {
@Override
public CallTarget accessIsNull() {
return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(false));
}
@Override
public CallTarget accessIsExecutable() {
return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(true));
}
@Override
public CallTarget accessIsBoxed() {
return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(false));
}
@Override
public CallTarget accessHasSize() {
return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(false));
}
@Override
public CallTarget accessGetSize() {
return null;
}
@Override
public CallTarget accessUnbox() {
return null;
}
@Override
public CallTarget accessRead() {
return null;
}
@Override
public CallTarget accessWrite() {
return null;
}
@Override
public CallTarget accessInvoke(int argumentsLength) {
return null;
}
@Override
public CallTarget accessNew(int argumentsLength) {
return null;
}
@Override
public CallTarget accessKeyInfo() {
return null;
}
@Override
public CallTarget accessKeys() {
return null;
}
@Override
public CallTarget accessIsPointer() {
return Truffle.getRuntime().createCallTarget(RootNode.createConstantNode(false));
}
@Override
public CallTarget accessAsPointer() {
return null;
}
@Override
public CallTarget accessToNative() {
return null;
}
@Override
public CallTarget accessMessage(Message unknown) {
return null;
}
}
...@@ -22,7 +22,19 @@ ...@@ -22,7 +22,19 @@
*/ */
package com.oracle.truffle.r.ffi.impl.upcalls; package com.oracle.truffle.r.ffi.impl.upcalls;
import com.oracle.truffle.r.ffi.impl.nodes.ATTRIB;
import com.oracle.truffle.r.ffi.impl.nodes.AsCharNode;
import com.oracle.truffle.r.ffi.impl.nodes.AsIntegerNode;
import com.oracle.truffle.r.ffi.impl.nodes.AsLogicalNode;
import com.oracle.truffle.r.ffi.impl.nodes.AsRealNode;
import com.oracle.truffle.r.ffi.impl.nodes.CoerceVectorNode;
import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodes.CADDRNode;
import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodes.CADRNode;
import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodes.CARNode;
import com.oracle.truffle.r.ffi.impl.nodes.ListAccessNodes.CDRNode;
import com.oracle.truffle.r.ffi.impl.nodes.MiscNodes.LENGTHNode;
import com.oracle.truffle.r.ffi.processor.RFFICstring; import com.oracle.truffle.r.ffi.processor.RFFICstring;
import com.oracle.truffle.r.ffi.processor.RFFIUpCallNode;
import com.oracle.truffle.r.runtime.data.RDoubleVector; import com.oracle.truffle.r.runtime.data.RDoubleVector;
import com.oracle.truffle.r.runtime.data.RExternalPtr; import com.oracle.truffle.r.runtime.data.RExternalPtr;
import com.oracle.truffle.r.runtime.data.RIntVector; import com.oracle.truffle.r.runtime.data.RIntVector;
...@@ -60,14 +72,19 @@ public interface StdUpCallsRFFI { ...@@ -60,14 +72,19 @@ public interface StdUpCallsRFFI {
RStringVector Rf_ScalarString(Object value); RStringVector Rf_ScalarString(Object value);
@RFFIUpCallNode(AsIntegerNode.class)
int Rf_asInteger(Object x); int Rf_asInteger(Object x);
@RFFIUpCallNode(AsRealNode.class)
double Rf_asReal(Object x); double Rf_asReal(Object x);
@RFFIUpCallNode(AsLogicalNode.class)
int Rf_asLogical(Object x); int Rf_asLogical(Object x);
@RFFIUpCallNode(AsCharNode.class)
Object Rf_asChar(Object x); Object Rf_asChar(Object x);
@RFFIUpCallNode(CoerceVectorNode.class)
Object Rf_coerceVector(Object x, int mode); Object Rf_coerceVector(Object x, int mode);
Object Rf_mkCharLenCE(@RFFICstring(convert = false) Object bytes, int len, int encoding); Object Rf_mkCharLenCE(@RFFICstring(convert = false) Object bytes, int len, int encoding);
...@@ -89,6 +106,7 @@ public interface StdUpCallsRFFI { ...@@ -89,6 +106,7 @@ public interface StdUpCallsRFFI {
Object Rf_findVarInFrame3(Object envArg, Object symbolArg, int doGet); Object Rf_findVarInFrame3(Object envArg, Object symbolArg, int doGet);
@RFFIUpCallNode(ATTRIB.class)
Object ATTRIB(Object obj); Object ATTRIB(Object obj);
Object Rf_getAttrib(Object obj, Object name); Object Rf_getAttrib(Object obj, Object name);
...@@ -127,6 +145,7 @@ public interface StdUpCallsRFFI { ...@@ -127,6 +145,7 @@ public interface StdUpCallsRFFI {
int Rf_ncols(Object x); int Rf_ncols(Object x);
@RFFIUpCallNode(LENGTHNode.class)
int LENGTH(Object x); int LENGTH(Object x);
int /* void */ SET_STRING_ELT(Object x, long i, Object v); int /* void */ SET_STRING_ELT(Object x, long i, Object v);
...@@ -163,12 +182,16 @@ public interface StdUpCallsRFFI { ...@@ -163,12 +182,16 @@ public interface StdUpCallsRFFI {
Object TAG(Object e); Object TAG(Object e);
@RFFIUpCallNode(CARNode.class)
Object CAR(Object e); Object CAR(Object e);
@RFFIUpCallNode(CDRNode.class)
Object CDR(Object e); Object CDR(Object e);
@RFFIUpCallNode(CADRNode.class)
Object CADR(Object e); Object CADR(Object e);
@RFFIUpCallNode(CADDRNode.class)
Object CADDR(Object e); Object CADDR(Object e);
Object CDDR(Object e); Object CDDR(Object e);
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
* or visit www.oracle.com if you need additional information or have any * or visit www.oracle.com if you need additional information or have any
* questions. * questions.
*/ */
package com.oracle.truffle.r.ffi.impl.common; package com.oracle.truffle.r.ffi.impl.upcalls;
import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
......
...@@ -40,6 +40,7 @@ import javax.lang.model.element.ElementKind; ...@@ -40,6 +40,7 @@ import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement; import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement; import javax.lang.model.element.VariableElement;
import javax.lang.model.type.MirroredTypeException;
import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror; import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.Types; import javax.lang.model.util.Types;
...@@ -157,55 +158,27 @@ public final class FFIProcessor extends AbstractProcessor { ...@@ -157,55 +158,27 @@ public final class FFIProcessor extends AbstractProcessor {
for (int i = 0; i < methods.length; i++) { for (int i = 0; i < methods.length; i++) {
ExecutableElement m = methods[i]; ExecutableElement m = methods[i];
generateCallClass(m); generateCallClass(m);
generateMessageClass(m);
} }
} }
private void generateCallClass(ExecutableElement m) throws IOException { private void generateCallClass(ExecutableElement m) throws IOException {
String name = m.getSimpleName().toString(); RFFIUpCallNode nodeAnnotation = m.getAnnotation(RFFIUpCallNode.class);
String callName = name + "Call"; String node = null;
JavaFileObject fileObj = processingEnv.getFiler().createSourceFile("com.oracle.truffle.r.ffi.impl.upcalls." + callName); if (nodeAnnotation != null) {
Writer w = fileObj.openWriter(); try {
w.append("// GENERATED; DO NOT EDIT\n"); nodeAnnotation.value();
w.append("package ").append("com.oracle.truffle.r.ffi.impl.upcalls").append(";\n\n"); } catch (MirroredTypeException e) {
w.append("import com.oracle.truffle.api.interop.ForeignAccess;\n"); node = ((TypeElement) processingEnv.getTypeUtils().asElement(e.getTypeMirror())).getQualifiedName().toString();
w.append("import com.oracle.truffle.api.interop.TruffleObject;\n"); }
w.append("import com.oracle.truffle.r.runtime.data.RTruffleObject;\n"); }
w.append("// Checkstyle: stop method name check\n\n"); // process arguments first to see if unwrap is necessary
w.append("public final class ").append(callName).append(" implements RTruffleObject {\n");
w.append('\n');
w.append(" public final UpCallsRFFI upCallsImpl;\n");
w.append('\n');
w.append(" protected ").append(callName).append("(UpCallsRFFI upCallsImpl) {\n");
w.append(" this.upCallsImpl = upCallsImpl;\n");
w.append(" }\n");
w.append('\n');
w.append(" public static boolean isInstance(TruffleObject value) {\n");
w.append(" return value instanceof ").append(callName).append(";\n");
w.append(" }\n");
w.append('\n');
w.append(" @Override\n");
w.append(" public ForeignAccess getForeignAccess() {\n");
w.append(" return ").append(callName).append("MRForeign.ACCESS;\n");
w.append(" }\n");
w.append("}\n");
w.close();
}
private void generateMessageClass(ExecutableElement m) throws IOException {
String name = m.getSimpleName().toString();
String callName = name + "Call";
String returnType = getTypeName(m.getReturnType());
List<? extends VariableElement> params = m.getParameters(); List<? extends VariableElement> params = m.getParameters();
StringBuilder arguments = new StringBuilder(); StringBuilder arguments = new StringBuilder();
boolean usesUnwrap = false; int unwrapCount = 0;
for (int i = 0; i < params.size(); i++) {
// process arguments first to see if unwrap is necessary if (i != 0) {
int lparams = params.size(); arguments.append(", ");
for (int i = 0; i < lparams; i++) { }
String is = Integer.toString(i);
String paramTypeName = getTypeName(params.get(i).asType()); String paramTypeName = getTypeName(params.get(i).asType());
boolean isScalar = true; boolean isScalar = true;
boolean needCast = !paramTypeName.equals("java.lang.Object"); boolean needCast = !paramTypeName.equals("java.lang.Object");
...@@ -213,60 +186,91 @@ public final class FFIProcessor extends AbstractProcessor { ...@@ -213,60 +186,91 @@ public final class FFIProcessor extends AbstractProcessor {
arguments.append('(').append(paramTypeName).append(") "); arguments.append('(').append(paramTypeName).append(") ");
} }
if (isScalar) { if (isScalar) {
usesUnwrap = true; arguments.append("unwrap").append(unwrapCount).append(".unwrap(");
arguments.append("unwrap.unwrap("); unwrapCount++;
} }
arguments.append("arguments[").append(is).append("]"); arguments.append("arguments.get(").append(i).append(")");
if (isScalar) { if (isScalar) {
arguments.append(')'); arguments.append(')');
} }
if (i != lparams - 1) {
arguments.append(", ");
}
} }
JavaFileObject fileObj = processingEnv.getFiler().createSourceFile("com.oracle.truffle.r.ffi.impl.upcalls." + callName + "MR"); String name = m.getSimpleName().toString();
String callName = name + "Call";
JavaFileObject fileObj = processingEnv.getFiler().createSourceFile("com.oracle.truffle.r.ffi.impl.upcalls." + callName);
Writer w = fileObj.openWriter(); Writer w = fileObj.openWriter();
w.append("// GENERATED; DO NOT EDIT\n"); w.append("// GENERATED; DO NOT EDIT\n");
w.append("package ").append("com.oracle.truffle.r.ffi.impl.upcalls").append(";\n\n"); w.append("\n");
w.append("import com.oracle.truffle.api.interop.MessageResolution;\n"); w.append("package com.oracle.truffle.r.ffi.impl.upcalls;\n");
w.append("import com.oracle.truffle.api.interop.Resolve;\n"); w.append("\n");
w.append("import com.oracle.truffle.api.nodes.Node;\n"); w.append("import java.util.List;\n");
if (usesUnwrap) { w.append("\n");
w.append("import com.oracle.truffle.r.ffi.impl.common.UpCallUnwrap;\n"); w.append("import com.oracle.truffle.api.CallTarget;\n");
w.append("import com.oracle.truffle.api.Truffle;\n");
w.append("import com.oracle.truffle.api.frame.VirtualFrame;\n");
w.append("import com.oracle.truffle.api.interop.ForeignAccess;\n");
w.append("import com.oracle.truffle.api.interop.TruffleObject;\n");
w.append("import com.oracle.truffle.api.nodes.RootNode;\n");
w.append("import com.oracle.truffle.r.ffi.impl.upcalls.UpCallsRFFI;\n");
w.append("import com.oracle.truffle.r.runtime.data.RTruffleObject;\n");
w.append("\n");
w.append("// Checkstyle: stop method name check\n");
w.append("\n");
w.append("final class ").append(callName).append(" implements RTruffleObject {\n");
w.append('\n');
if (node == null) {
w.append(" private final UpCallsRFFI upCallsImpl;\n");
w.append('\n');
} }
w.append("// Checkstyle: stop method name check\n\n"); w.append(" ").append(callName).append("(UpCallsRFFI upCallsImpl) {\n");
w.append(" assert upCallsImpl != null;\n");
w.append("@MessageResolution(receiverType = ").append(name).append("Call.class)\n"); if (node == null) {
w.append("public class ").append(callName).append("MR {\n"); w.append(" this.upCallsImpl = upCallsImpl;\n");
w.append(" @Resolve(message = \"EXECUTE\")\n"); }
w.append(" public abstract static class ").append(callName).append("Execute extends Node {\n"); w.append(" }\n");
if (usesUnwrap) { w.append('\n');
w.append("\n @Child private UpCallUnwrap unwrap = new UpCallUnwrap();\n\n"); w.append(" private static final class ").append(callName).append("Factory extends AbstractDowncallForeign {\n");
w.append(" @Override\n");
w.append(" public boolean canHandle(TruffleObject obj) {\n");
w.append(" return obj instanceof ").append(callName).append(";\n");
w.append(" }\n");
w.append("\n");
w.append(" @Override\n");
w.append(" public CallTarget accessExecute(int argumentsLength) {\n");
w.append(" return Truffle.getRuntime().createCallTarget(new RootNode(null) {\n");
w.append("\n");
if (unwrapCount > 0) {
for (int i = 0; i < unwrapCount; i++) {
w.append(" @Child private UpCallUnwrap unwrap").append(Integer.toString(i)).append(" = new UpCallUnwrap();\n");
}
w.append("\n");
} }
w.append(" protected ").append(returnType).append(" access(").append(callName).append(" receiver, "); if (node != null) {
if (params.size() == 0) { w.append(" @Child private ").append(node).append(" node").append(" = ").append(node).append(".create();\n");
w.append("@SuppressWarnings(\"unused\") "); w.append("\n");
} }
w.append("Object[] arguments) {\n"); w.append(" @Override\n");
w.append(" ").append("return").append(" receiver.upCallsImpl.").append(name).append("("); w.append(" public Object execute(VirtualFrame frame) {\n");
w.append(" List<Object> arguments = ForeignAccess.getArguments(frame);\n");
w.append(arguments); w.append(" assert arguments.size() == ").append(Integer.toString(params.size())).append(" : \"wrong number of arguments passed to ").append(name).append("\";\n");
if (node != null) {
w.append(");\n"); w.append(" return node.executeObject(").append(arguments).append(");\n");
} else {
w.append(" return ((").append(callName).append(") ForeignAccess.getReceiver(frame)).upCallsImpl.").append(name).append("(").append(arguments).append(");\n");
}
w.append(" }\n");
w.append(" });\n");
w.append(" }\n"); w.append(" }\n");
w.append(" }\n"); w.append(" }\n");
w.append("\n"); w.append("\n");
w.append(" private static final ForeignAccess ACCESS = ForeignAccess.create(new ").append(callName).append("Factory(), null);\n");
w.append(" @Resolve(message = \"IS_EXECUTABLE\")\n"); w.append("\n");
w.append(" public abstract static class ").append(callName).append("IsExecutable extends Node {\n"); w.append(" @Override\n");
w.append(" protected Object access(@SuppressWarnings(\"unused\") ").append(callName).append(" receiver) {\n"); w.append(" public ForeignAccess getForeignAccess() {\n");
w.append(" return true;\n"); w.append(" return ACCESS;\n");
w.append(" }\n");
w.append(" }\n"); w.append(" }\n");
w.append("}\n"); w.append("}\n");
w.close(); w.close();
} }
private void generateCallbacks(ExecutableElement[] methods) throws IOException { private void generateCallbacks(ExecutableElement[] methods) throws IOException {
......
/*
* Copyright (c) 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.ffi.processor;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
/**
* Tags upcall functions that have a corresponding node implementation.
*/
@Target({ElementType.METHOD})
public @interface RFFIUpCallNode {
Class<?> value();
}
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