From a6f795795fae925e6a636520a846db6e7443294b Mon Sep 17 00:00:00 2001 From: Mick Jordan <mick.jordan@oracle.com> Date: Wed, 8 Feb 2017 14:40:39 -0800 Subject: [PATCH] rffi: refactor UpCallsRFFIImpl classes to ensure tracing always happens --- .../ffi/llvm/TruffleLLVM_UpCallsRFFIImpl.java | 6 +- .../r/nodes/ffi/JavaUpCallsRFFIImpl.java | 1145 +++++++++++++++ .../truffle/r/nodes/ffi/RFFIUpCallMethod.java | 16 +- .../r/nodes/ffi/TraceUpCallsAdapter.java | 892 ------------ .../truffle/r/nodes/ffi/UpCallsRFFIImpl.java | 1261 +++++------------ .../truffle/r/runtime/ffi/jni/JNI_Call.java | 5 +- 6 files changed, 1514 insertions(+), 1811 deletions(-) create mode 100644 com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/JavaUpCallsRFFIImpl.java delete mode 100644 com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/TraceUpCallsAdapter.java diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ffi/llvm/TruffleLLVM_UpCallsRFFIImpl.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ffi/llvm/TruffleLLVM_UpCallsRFFIImpl.java index b903c34a33..d5f87c5150 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ffi/llvm/TruffleLLVM_UpCallsRFFIImpl.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ffi/llvm/TruffleLLVM_UpCallsRFFIImpl.java @@ -32,7 +32,7 @@ import com.oracle.truffle.r.engine.interop.NativeIntegerArray; import com.oracle.truffle.r.engine.interop.NativeLogicalArray; import com.oracle.truffle.r.engine.interop.NativeRawArray; import com.oracle.truffle.r.nodes.ffi.RFFIUtils; -import com.oracle.truffle.r.nodes.ffi.UpCallsRFFIImpl; +import com.oracle.truffle.r.nodes.ffi.JavaUpCallsRFFIImpl; import com.oracle.truffle.r.runtime.REnvVars; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.data.RDataFactory; @@ -47,10 +47,10 @@ import com.oracle.truffle.r.runtime.ffi.CharSXPWrapper; import com.oracle.truffle.r.runtime.ffi.RFFIVariables; /** - * (Incomplete) Variant of {@link UpCallsRFFIImpl} for Truffle LLVM. + * (Incomplete) Variant of {@link JavaUpCallsRFFIImpl} for Truffle LLVM. * */ -public class TruffleLLVM_UpCallsRFFIImpl extends UpCallsRFFIImpl implements VariableUpCallsRFFI { +public class TruffleLLVM_UpCallsRFFIImpl extends JavaUpCallsRFFIImpl implements VariableUpCallsRFFI { private static TruffleLLVM_UpCallsRFFIImpl singleton; private static TruffleObject singletonTruffleObject; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/JavaUpCallsRFFIImpl.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/JavaUpCallsRFFIImpl.java new file mode 100644 index 0000000000..8441fc32c7 --- /dev/null +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/JavaUpCallsRFFIImpl.java @@ -0,0 +1,1145 @@ +/* + * Copyright (c) 2014, 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.nodes.ffi; + +import static com.oracle.truffle.r.nodes.ffi.RFFIUtils.*; + +import java.nio.charset.StandardCharsets; +import java.util.function.Function; + +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.frame.Frame; +import com.oracle.truffle.api.frame.FrameInstance.FrameAccess; +import com.oracle.truffle.api.object.DynamicObject; +import com.oracle.truffle.api.source.Source; +import com.oracle.truffle.api.source.SourceSection; +import com.oracle.truffle.r.nodes.ffi.ParseResult.ParseStatus; +import com.oracle.truffle.r.runtime.RArguments; +import com.oracle.truffle.r.runtime.RCaller; +import com.oracle.truffle.r.runtime.RCleanUp; +import com.oracle.truffle.r.runtime.REnvVars; +import com.oracle.truffle.r.runtime.RError; +import com.oracle.truffle.r.runtime.RErrorHandling; +import com.oracle.truffle.r.runtime.RInternalError; +import com.oracle.truffle.r.runtime.RRuntime; +import com.oracle.truffle.r.runtime.RSource; +import com.oracle.truffle.r.runtime.RSrcref; +import com.oracle.truffle.r.runtime.RStartParams.SA_TYPE; +import com.oracle.truffle.r.runtime.RType; +import com.oracle.truffle.r.runtime.Utils; +import com.oracle.truffle.r.runtime.context.Engine.ParseException; +import com.oracle.truffle.r.runtime.context.RContext; +import com.oracle.truffle.r.runtime.data.RAttributable; +import com.oracle.truffle.r.runtime.data.RAttributesLayout; +import com.oracle.truffle.r.runtime.data.RComplex; +import com.oracle.truffle.r.runtime.data.RComplexVector; +import com.oracle.truffle.r.runtime.data.RDataFactory; +import com.oracle.truffle.r.runtime.data.RDoubleSequence; +import com.oracle.truffle.r.runtime.data.RDoubleVector; +import com.oracle.truffle.r.runtime.data.RExpression; +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.RLanguage; +import com.oracle.truffle.r.runtime.data.RList; +import com.oracle.truffle.r.runtime.data.RLogicalVector; +import com.oracle.truffle.r.runtime.data.RNull; +import com.oracle.truffle.r.runtime.data.RPairList; +import com.oracle.truffle.r.runtime.data.RPromise; +import com.oracle.truffle.r.runtime.data.RRaw; +import com.oracle.truffle.r.runtime.data.RRawVector; +import com.oracle.truffle.r.runtime.data.RS4Object; +import com.oracle.truffle.r.runtime.data.RSequence; +import com.oracle.truffle.r.runtime.data.RShareable; +import com.oracle.truffle.r.runtime.data.RStringVector; +import com.oracle.truffle.r.runtime.data.RSymbol; +import com.oracle.truffle.r.runtime.data.RUnboundValue; +import com.oracle.truffle.r.runtime.data.model.RAbstractListVector; +import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; +import com.oracle.truffle.r.runtime.data.model.RAbstractVector; +import com.oracle.truffle.r.runtime.env.REnvironment; +import com.oracle.truffle.r.runtime.env.REnvironment.PutException; +import com.oracle.truffle.r.runtime.ffi.CharSXPWrapper; +import com.oracle.truffle.r.runtime.ffi.UpCallsRFFI; +import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle; +import com.oracle.truffle.r.runtime.gnur.SEXPTYPE; +import com.oracle.truffle.r.runtime.nodes.DuplicationHelper; +import com.oracle.truffle.r.runtime.nodes.RNode; +import com.oracle.truffle.r.runtime.rng.RRNG; + +/** + * This class provides a simple Java-based implementation of {@link UpCallsRFFI}, where all the + * argument values are standarde Java types, i.e. no special types used by Truffle NFI or Truffle + * LLVM. + * + * TODO Many of the implementations here are incomplete and/or duplicate code that exists in the + * Truffle side of the implementation, i.e., {@link RNode} subclasses. A complete refactoring that + * accesses the Truffle implementations (possibly somewhat refactored owing to the fact that the + * Truffle side is driven by the builtins yet these functions don't not always map 1-1 to a builtin) + * is desirable. In some cases it may be possible to "implement" the functions in R (which is a + * simple way to achieve the above). + */ +public class JavaUpCallsRFFIImpl implements UpCallsRFFI { + + // Checkstyle: stop method name check + + @Override + public RIntVector Rf_ScalarInteger(int value) { + return RDataFactory.createIntVectorFromScalar(value); + } + + @Override + public RLogicalVector Rf_ScalarLogical(int value) { + byte byteValue; + if (value == RRuntime.INT_NA) { + byteValue = RRuntime.LOGICAL_NA; + } else { + byteValue = (byte) (value & 0xFF); + } + return RDataFactory.createLogicalVectorFromScalar(byteValue); + } + + @Override + public RDoubleVector Rf_ScalarDouble(double value) { + return RDataFactory.createDoubleVectorFromScalar(value); + } + + @Override + public RStringVector Rf_ScalarString(Object value) { + CharSXPWrapper chars = guaranteeInstanceOf(value, CharSXPWrapper.class); + return RDataFactory.createStringVectorFromScalar(chars.getContents()); + } + + @Override + public int Rf_asInteger(Object x) { + return (int) FFIUpCallRootNode.getCallTarget(RFFIUpCallMethod.Rf_asInteger).call(x); + } + + @Override + public double Rf_asReal(Object x) { + return (double) FFIUpCallRootNode.getCallTarget(RFFIUpCallMethod.Rf_asReal).call(x); + } + + @Override + public int Rf_asLogical(Object x) { + return (int) FFIUpCallRootNode.getCallTarget(RFFIUpCallMethod.Rf_asLogical).call(x); + } + + @Override + public Object Rf_asChar(Object x) { + return FFIUpCallRootNode.getCallTarget(RFFIUpCallMethod.Rf_asChar).call(x); + } + + @Override + public Object Rf_mkCharLenCE(Object bytes, int len, int encoding) { + // TODO: handle encoding properly + return CharSXPWrapper.create(new String((byte[]) bytes, StandardCharsets.UTF_8)); + } + + @Override + public Object Rf_cons(Object car, Object cdr) { + return RDataFactory.createPairList(car, cdr); + } + + @Override + public void Rf_defineVar(Object symbolArg, Object value, Object envArg) { + REnvironment env = (REnvironment) envArg; + RSymbol name = (RSymbol) symbolArg; + try { + env.put(name.getName(), value); + } catch (PutException ex) { + throw RError.error(RError.SHOW_CALLER2, ex); + } + } + + @Override + public Object R_do_MAKE_CLASS(Object clazz) { + String name = "getClass"; + RFunction getClass = (RFunction) RContext.getRRuntimeASTAccess().forcePromise(name, REnvironment.getRegisteredNamespace("methods").get(name)); + return RContext.getEngine().evalFunction(getClass, null, RCaller.createInvalid(null), null, clazz); + } + + @Override + public Object Rf_findVar(Object symbolArg, Object envArg) { + return findVarInFrameHelper(envArg, symbolArg, true); + } + + @Override + public Object Rf_findVarInFrame(Object envArg, Object symbolArg) { + return findVarInFrameHelper(envArg, symbolArg, false); + } + + @Override + public Object Rf_findVarInFrame3(Object envArg, Object symbolArg, int doGet) { + // GNU R has code for IS_USER_DATBASE that uses doGet + // This is a lookup in the single environment (envArg) only, i.e. inherits=false + return findVarInFrameHelper(envArg, symbolArg, false); + } + + private static Object findVarInFrameHelper(Object envArg, Object symbolArg, boolean inherits) { + if (envArg == RNull.instance) { + throw RError.error(RError.SHOW_CALLER2, RError.Message.USE_NULL_ENV_DEFUNCT); + } + if (!(envArg instanceof REnvironment)) { + throw RError.error(RError.SHOW_CALLER2, RError.Message.ARG_NOT_AN_ENVIRONMENT, inherits ? "findVar" : "findVarInFrame"); + } + RSymbol name = (RSymbol) symbolArg; + REnvironment env = (REnvironment) envArg; + while (env != REnvironment.emptyEnv()) { + Object value = env.get(name.getName()); + if (value != null) { + return value; + } + if (!inherits) { + // simgle frame lookup + break; + } + env = env.getParent(); + } + return RUnboundValue.instance; + } + + @Override + public Object Rf_getAttrib(Object obj, Object name) { + Object result = RNull.instance; + if (obj instanceof RAttributable) { + RAttributable attrObj = (RAttributable) obj; + DynamicObject attrs = attrObj.getAttributes(); + if (attrs != null) { + String nameAsString = ((RSymbol) name).getName().intern(); + Object attr = attrs.get(nameAsString); + if (attr != null) { + result = attr; + } + } + } + return result; + } + + @Override + @TruffleBoundary + public void Rf_setAttrib(Object obj, Object name, Object val) { + if (obj instanceof RAttributable) { + RAttributable attrObj = (RAttributable) obj; + String nameAsString; + if (name instanceof RSymbol) { + nameAsString = ((RSymbol) name).getName(); + } else { + nameAsString = RRuntime.asString(name); + assert nameAsString != null; + } + nameAsString = nameAsString.intern(); + if (val == RNull.instance) { + removeAttr(attrObj, nameAsString); + } else if ("class" == nameAsString) { + attrObj.initAttributes().define(nameAsString, val); + } else { + attrObj.setAttr(nameAsString, val); + } + } + } + + @TruffleBoundary + private static void removeAttr(RAttributable a, String name) { + a.removeAttr(name); + } + + public static RStringVector getClassHr(Object v) { + RStringVector result; + if (v instanceof RAttributable) { + result = ((RAttributable) v).getClassHierarchy(); + } else if (v instanceof Byte) { + result = RLogicalVector.implicitClassHeader; + } else if (v instanceof String) { + result = RStringVector.implicitClassHeader; + } else if (v instanceof Integer) { + result = RIntVector.implicitClassHeader; + } else if (v instanceof Double) { + result = RDoubleVector.implicitClassHeader; + } else if (v instanceof RComplex) { + result = RComplexVector.implicitClassHeader; + } else if (v instanceof RRaw) { + result = RRawVector.implicitClassHeader; + } else { + guaranteeInstanceOf(v, RNull.class); + result = RNull.implicitClassHeader; + } + return result; + } + + @Override + public int Rf_inherits(Object x, Object clazz) { + int result = 0; + RStringVector hierarchy = getClassHr(x); + for (int i = 0; i < hierarchy.getLength(); i++) { + if (hierarchy.getDataAt(i).equals(clazz)) { + result = 1; + } + } + return result; + } + + @Override + public Object Rf_install(Object name) { + return RDataFactory.createSymbolInterned((String) name); + } + + @Override + public Object Rf_lengthgets(Object x, int newSize) { + RAbstractVector vec = (RAbstractVector) RRuntime.asAbstractVector(x); + return vec.resize(newSize); + } + + @Override + public int Rf_isString(Object x) { + return RRuntime.checkType(x, RType.Character) ? 1 : 0; + } + + @Override + public int Rf_isNull(Object x) { + return x == RNull.instance ? 1 : 0; + } + + @Override + public Object Rf_PairToVectorList(Object x) { + if (x == RNull.instance) { + return RDataFactory.createList(); + } + RPairList pl = (RPairList) x; + return pl.toRList(); + } + + @Override + public void Rf_error(Object msg) { + throw RError.error(RError.SHOW_CALLER2, RError.Message.GENERIC, msg); + } + + @Override + public void Rf_warning(Object msg) { + RError.warning(RError.SHOW_CALLER2, RError.Message.GENERIC, msg); + } + + @Override + public void Rf_warningcall(Object call, Object msg) { + RErrorHandling.warningcallRFFI(call, (String) msg); + } + + @Override + public Object Rf_allocateVector(int mode, int n) { + SEXPTYPE type = SEXPTYPE.mapInt(mode); + if (n < 0) { + throw RError.error(RError.SHOW_CALLER2, RError.Message.NEGATIVE_LENGTH_VECTORS_NOT_ALLOWED); + // TODO check long vector + } + switch (type) { + case INTSXP: + return RDataFactory.createIntVector(new int[n], RDataFactory.COMPLETE_VECTOR); + case REALSXP: + return RDataFactory.createDoubleVector(new double[n], RDataFactory.COMPLETE_VECTOR); + case LGLSXP: + return RDataFactory.createLogicalVector(new byte[n], RDataFactory.COMPLETE_VECTOR); + case STRSXP: + return RDataFactory.createStringVector(new String[n], RDataFactory.COMPLETE_VECTOR); + case CPLXSXP: + return RDataFactory.createComplexVector(new double[2 * n], RDataFactory.COMPLETE_VECTOR); + case RAWSXP: + return RDataFactory.createRawVector(new byte[n]); + case VECSXP: + return RDataFactory.createList(n); + case LANGSXP: + return RDataFactory.createLangPairList(n); + default: + throw unimplemented("unexpected SEXPTYPE " + type); + } + } + + @Override + public Object Rf_allocateArray(int mode, Object dimsObj) { + RIntVector dims = (RIntVector) dimsObj; + int n = 1; + int[] newDims = new int[dims.getLength()]; + // TODO check long vector + for (int i = 0; i < newDims.length; i++) { + newDims[i] = dims.getDataAt(i); + n *= newDims[i]; + } + RAbstractVector result = (RAbstractVector) Rf_allocateVector(mode, n); + setDims(newDims, result); + return result; + + } + + @TruffleBoundary + private static void setDims(int[] newDims, RAbstractVector result) { + result.setDimensions(newDims); + } + + @Override + public Object Rf_allocateMatrix(int mode, int nrow, int ncol) { + SEXPTYPE type = SEXPTYPE.mapInt(mode); + if (nrow < 0 || ncol < 0) { + throw RError.error(RError.SHOW_CALLER2, RError.Message.NEGATIVE_EXTENTS_TO_MATRIX); + } + // TODO check long vector + int[] dims = new int[]{nrow, ncol}; + switch (type) { + case INTSXP: + return RDataFactory.createIntVector(new int[nrow * ncol], RDataFactory.COMPLETE_VECTOR, dims); + case REALSXP: + return RDataFactory.createDoubleVector(new double[nrow * ncol], RDataFactory.COMPLETE_VECTOR, dims); + case LGLSXP: + return RDataFactory.createLogicalVector(new byte[nrow * ncol], RDataFactory.COMPLETE_VECTOR, dims); + case STRSXP: + return RDataFactory.createStringVector(new String[nrow * ncol], RDataFactory.COMPLETE_VECTOR, dims); + case CPLXSXP: + return RDataFactory.createComplexVector(new double[2 * (nrow * ncol)], RDataFactory.COMPLETE_VECTOR, dims); + default: + throw unimplemented(); + } + } + + @Override + public int Rf_nrows(Object x) { + return RRuntime.nrows(x); + } + + @Override + public int Rf_ncols(Object x) { + return RRuntime.ncols(x); + } + + @Override + public int LENGTH(Object x) { + return (int) FFIUpCallRootNode.getCallTarget(RFFIUpCallMethod.LENGTH).call(x); + } + + @Override + public void SET_STRING_ELT(Object x, int i, Object v) { + RStringVector vector = guaranteeInstanceOf(x, RStringVector.class); + CharSXPWrapper element = guaranteeInstanceOf(v, CharSXPWrapper.class); + vector.setElement(i, element.getContents()); + } + + @Override + public void SET_VECTOR_ELT(Object x, int i, Object v) { + RList list = guaranteeInstanceOf(x, RList.class); + list.setElement(i, v); + } + + @Override + public Object RAW(Object x) { + if (x instanceof RRawVector) { + return ((RRawVector) x).getDataWithoutCopying(); + } else if (x instanceof RRaw) { + return new byte[]{((RRaw) x).getValue()}; + } else { + throw unimplemented(); + } + } + + @Override + public Object LOGICAL(Object x) { + if (x instanceof RLogicalVector) { + return ((RLogicalVector) x).getDataWithoutCopying(); + } else if (x instanceof Byte) { + return new byte[]{(Byte) x}; + } else { + throw unimplemented(); + } + } + + @Override + public Object INTEGER(Object x) { + if (x instanceof RIntVector) { + return ((RIntVector) x).getDataWithoutCopying(); + } else if (x instanceof RIntSequence) { + return ((RIntSequence) x).materialize().getDataWithoutCopying(); + } else if (x instanceof Integer) { + return new int[]{(Integer) x}; + } else if (x instanceof RLogicalVector) { + RLogicalVector vec = (RLogicalVector) x; + int[] result = new int[vec.getLength()]; + for (int i = 0; i < result.length; i++) { + result[i] = vec.getDataAt(i); + } + return result; + } else { + guaranteeInstanceOf(x, Byte.class); + return new int[]{(Byte) x}; + } + } + + @Override + public Object REAL(Object x) { + if (x instanceof RDoubleVector) { + return ((RDoubleVector) x).getDataWithoutCopying(); + } else if (x instanceof RDoubleSequence) { + return ((RDoubleSequence) x).materialize().getDataWithoutCopying(); + } else { + guaranteeInstanceOf(x, Double.class); + return new double[]{(Double) x}; + } + } + + @Override + public Object STRING_ELT(Object x, int i) { + RAbstractStringVector vector = guaranteeInstanceOf(RRuntime.asAbstractVector(x), RAbstractStringVector.class); + return CharSXPWrapper.create(vector.getDataAt(i)); + } + + @Override + public Object VECTOR_ELT(Object x, int i) { + Object vec = x; + if (vec instanceof RExpression) { + return ((RExpression) vec).getDataAt(i); + } + RAbstractListVector list = guaranteeInstanceOf(RRuntime.asAbstractVector(vec), RAbstractListVector.class); + return list.getDataAt(i); + } + + @Override + public int NAMED(Object x) { + if (x instanceof RShareable) { + return ((RShareable) x).isShared() ? 1 : 0; + } else { + throw unimplemented(); + } + } + + @Override + public Object SET_TYPEOF_FASTR(Object x, int v) { + int code = SEXPTYPE.gnuRCodeForObject(x); + if (code == SEXPTYPE.LISTSXP.code && v == SEXPTYPE.LANGSXP.code) { + return RLanguage.fromList(x, RLanguage.RepType.CALL); + } else { + throw unimplemented(); + } + } + + @Override + public int TYPEOF(Object x) { + if (x instanceof CharSXPWrapper) { + return SEXPTYPE.CHARSXP.code; + } else { + return SEXPTYPE.gnuRCodeForObject(x); + } + } + + @Override + @TruffleBoundary + public int OBJECT(Object x) { + if (x instanceof RAttributable) { + return ((RAttributable) x).getAttr(RRuntime.CLASS_ATTR_KEY) == null ? 0 : 1; + } else { + return 0; + } + } + + @Override + public Object Rf_duplicate(Object x, int deep) { + guarantee(x != null, "unexpected type: null instead of " + x.getClass().getSimpleName()); + guarantee(x instanceof RShareable || x instanceof RSequence || x instanceof RExternalPtr, + "unexpected type: " + x + " is " + x.getClass().getSimpleName() + " instead of RShareable or RExternalPtr"); + if (x instanceof RShareable) { + return deep == 1 ? ((RShareable) x).deepCopy() : ((RShareable) x).copy(); + } else if (x instanceof RSequence) { + return ((RSequence) x).materializeToShareable(); + } else { + return ((RExternalPtr) x).copy(); + } + } + + @Override + public int Rf_anyDuplicated(Object x, int fromLast) { + RAbstractVector vec = (RAbstractVector) x; + if (vec.getLength() == 0) { + return 0; + } else { + return DuplicationHelper.analyze(vec, null, true, fromLast != 0).getIndex(); + } + } + + @Override + public Object PRINTNAME(Object x) { + guaranteeInstanceOf(x, RSymbol.class); + return CharSXPWrapper.create(((RSymbol) x).getName()); + } + + @Override + public Object TAG(Object e) { + if (e instanceof RPairList) { + return ((RPairList) e).getTag(); + } else { + guaranteeInstanceOf(e, RExternalPtr.class); + // at the moment, this can only be used to null out the pointer + return ((RExternalPtr) e).getTag(); + } + } + + @Override + public Object CAR(Object e) { + return FFIUpCallRootNode.getCallTarget(RFFIUpCallMethod.CAR).call(e); + } + + @Override + public Object CDR(Object e) { + return FFIUpCallRootNode.getCallTarget(RFFIUpCallMethod.CDR).call(e); + } + + @Override + public Object CADR(Object e) { + return FFIUpCallRootNode.getCallTarget(RFFIUpCallMethod.CADR).call(e); + } + + @Override + public Object CADDR(Object e) { + return FFIUpCallRootNode.getCallTarget(RFFIUpCallMethod.CADDR).call(e); + } + + @Override + public Object CDDR(Object e) { + return FFIUpCallRootNode.getCallTarget(RFFIUpCallMethod.CDDR).call(e); + } + + @Override + public Object SET_TAG(Object x, Object y) { + if (x instanceof RPairList) { + ((RPairList) x).setTag(y); + } else { + guaranteeInstanceOf(x, RExternalPtr.class); + // at the moment, this can only be used to null out the pointer + ((RExternalPtr) x).setTag(y); + } + return y; + } + + @Override + public Object SETCAR(Object x, Object y) { + guaranteeInstanceOf(x, RPairList.class); + ((RPairList) x).setCar(y); + return y; + } + + @Override + public Object SETCDR(Object x, Object y) { + guaranteeInstanceOf(x, RPairList.class); + ((RPairList) x).setCdr(y); + return y; + } + + @Override + public Object SETCADR(Object x, Object y) { + SETCAR(CDR(x), y); + return y; + } + + @Override + public Object SYMVALUE(Object x) { + if (!(x instanceof RSymbol)) { + throw RInternalError.shouldNotReachHere(); + } + Object res = REnvironment.baseEnv().get(((RSymbol) x).getName()); + if (res == null) { + return RUnboundValue.instance; + } else { + return res; + } + } + + @Override + public void SET_SYMVALUE(Object x, Object v) { + if (!(x instanceof RSymbol)) { + throw RInternalError.shouldNotReachHere(); + } + REnvironment.baseEnv().safePut(((RSymbol) x).getName(), v); + } + + @Override + public int R_BindingIsLocked(Object sym, Object env) { + guaranteeInstanceOf(sym, RSymbol.class); + guaranteeInstanceOf(env, REnvironment.class); + return ((REnvironment) env).bindingIsLocked(((RSymbol) sym).getName()) ? 1 : 0; + } + + @Override + public Object R_FindNamespace(Object name) { + Object result = RContext.getInstance().stateREnvironment.getNamespaceRegistry().get(RRuntime.asString(name)); + return result; + } + + @Override + public Object Rf_eval(Object expr, Object env) { + guarantee(env instanceof REnvironment); + Object result; + if (expr instanceof RPromise) { + result = RContext.getRRuntimeASTAccess().forcePromise(null, expr); + } else if (expr instanceof RExpression) { + result = RContext.getEngine().eval((RExpression) expr, (REnvironment) env, RCaller.topLevel); + } else if (expr instanceof RLanguage) { + result = RContext.getEngine().eval((RLanguage) expr, (REnvironment) env, RCaller.topLevel); + } else if (expr instanceof RPairList) { + RPairList l = (RPairList) expr; + RFunction f = (RFunction) l.car(); + Object args = l.cdr(); + if (args == RNull.instance) { + result = RContext.getEngine().evalFunction(f, env == REnvironment.globalEnv() ? null : ((REnvironment) env).getFrame(), RCaller.topLevel, null, new Object[0]); + } else { + RList argsList = ((RPairList) args).toRList(); + result = RContext.getEngine().evalFunction(f, env == REnvironment.globalEnv() ? null : ((REnvironment) env).getFrame(), RCaller.topLevel, argsList.getNames(), + argsList.getDataNonShared()); + } + } else { + // just return value + result = expr; + } + return result; + } + + @Override + public Object Rf_findfun(Object symbolObj, Object envObj) { + guarantee(envObj instanceof REnvironment); + REnvironment env = (REnvironment) envObj; + guarantee(symbolObj instanceof RSymbol); + RSymbol symbol = (RSymbol) symbolObj; + // Works but not remotely efficient + Source source = RSource.fromTextInternal("get(\"" + symbol.getName() + "\", mode=\"function\")", RSource.Internal.RF_FINDFUN); + try { + Object result = RContext.getEngine().parseAndEval(source, env.getFrame(), false); + return result; + } catch (ParseException ex) { + throw RInternalError.shouldNotReachHere(ex); + } + } + + @Override + public Object Rf_GetOption1(Object tag) { + guarantee(tag instanceof RSymbol); + Object result = RContext.getInstance().stateROptions.getValue(((RSymbol) tag).getName()); + return result; + } + + @Override + public void Rf_gsetVar(Object symbol, Object value, Object rho) { + guarantee(symbol instanceof RSymbol); + REnvironment baseEnv = RContext.getInstance().stateREnvironment.getBaseEnv(); + guarantee(rho == baseEnv); + try { + baseEnv.put(((RSymbol) symbol).getName(), value); + } catch (PutException e) { + e.printStackTrace(); + } + } + + @Override + public void DUPLICATE_ATTRIB(Object to, Object from) { + if (from instanceof RAttributable) { + guaranteeInstanceOf(to, RAttributable.class); + DynamicObject attributes = ((RAttributable) from).getAttributes(); + ((RAttributable) to).initAttributes(attributes == null ? null : RAttributesLayout.copy(attributes)); + } + // TODO: copy OBJECT? and S4 attributes + } + + @Override + public int R_computeIdentical(Object x, Object y, int flags) { + RFunction indenticalBuiltin = RContext.lookupBuiltin("identical"); + Object res = RContext.getEngine().evalFunction(indenticalBuiltin, null, null, null, x, y, RRuntime.asLogical((!((flags & 1) == 0))), + RRuntime.asLogical((!((flags & 2) == 0))), RRuntime.asLogical((!((flags & 4) == 0))), RRuntime.asLogical((!((flags & 8) == 0))), RRuntime.asLogical((!((flags & 16) == 0)))); + return (int) res; + } + + @Override + public void Rf_copyListMatrix(Object s, Object t, int byrow) { + throw unimplemented(); + } + + @Override + public void Rf_copyMatrix(Object s, Object t, int byrow) { + throw unimplemented(); + } + + @Override + public Object R_tryEval(Object expr, Object env, boolean silent) { + Object handlerStack = RErrorHandling.getHandlerStack(); + Object restartStack = RErrorHandling.getRestartStack(); + try { + // TODO handle silent + RErrorHandling.resetStacks(); + Object result = Rf_eval(expr, env); + return result; + } catch (Throwable t) { + return null; + } finally { + RErrorHandling.restoreStacks(handlerStack, restartStack); + } + } + + /** + * Helper function for {@code R_TopLevelExec} which is similar to {@code R_TryEval} except that + * a C function is invoked (in the native layer) instead of an R expression. assert: this is + * ONLY called from R_TopLevelExec prior to calling C function. + */ + @Override + public Object R_ToplevelExec() { + return RErrorHandling.resetAndGetHandlerStacks(); + } + + @Override + public int RDEBUG(Object x) { + REnvironment env = guaranteeInstanceOf(x, REnvironment.class); + if (env instanceof REnvironment.Function) { + REnvironment.Function funcEnv = (REnvironment.Function) env; + RFunction func = RArguments.getFunction(funcEnv.getFrame()); + return RContext.getRRuntimeASTAccess().isDebugged(func) ? 1 : 0; + } else { + return 0; + } + } + + @Override + public void SET_RDEBUG(Object x, int v) { + REnvironment env = guaranteeInstanceOf(x, REnvironment.class); + if (env instanceof REnvironment.Function) { + REnvironment.Function funcEnv = (REnvironment.Function) env; + RFunction func = RArguments.getFunction(funcEnv.getFrame()); + if (v == 1) { + RContext.getRRuntimeASTAccess().enableDebug(func, false); + } else { + RContext.getRRuntimeASTAccess().disableDebug(func); + } + } + } + + @Override + public int RSTEP(Object x) { + @SuppressWarnings("unused") + REnvironment env = guaranteeInstanceOf(x, REnvironment.class); + throw RInternalError.unimplemented("RSTEP"); + } + + @Override + public void SET_RSTEP(Object x, int v) { + @SuppressWarnings("unused") + REnvironment env = guaranteeInstanceOf(x, REnvironment.class); + throw RInternalError.unimplemented("SET_RSTEP"); + } + + @Override + public Object ENCLOS(Object x) { + REnvironment env = guaranteeInstanceOf(x, REnvironment.class); + Object result = env.getParent(); + if (result == null) { + result = RNull.instance; + } + return result; + } + + @Override + public Object PRVALUE(Object x) { + RPromise p = guaranteeInstanceOf(x, RPromise.class); + return p.isEvaluated() ? p.getValue() : RUnboundValue.instance; + } + + @Override + public Object R_ParseVector(Object text, int n, Object srcFile) { + // TODO general case + assert n == 1; + assert srcFile == RNull.instance; + String textString = RRuntime.asString(text); + assert textString != null; + + try { + Source source = RSource.fromTextInternal(textString, RSource.Internal.R_PARSEVECTOR); + RExpression exprs = RContext.getEngine().parse(source); + return new ParseResult(ParseStatus.PARSE_OK.ordinal(), exprs); + } catch (ParseException ex) { + // TODO incomplete + return new ParseResult(ParseStatus.PARSE_ERROR.ordinal(), RNull.instance); + } + } + + @Override + public Object R_lsInternal3(Object envArg, int allArg, int sortedArg) { + boolean sorted = sortedArg != 0; + boolean all = allArg != 0; + REnvironment env = guaranteeInstanceOf(envArg, REnvironment.class); + return env.ls(all, null, sorted); + } + + @Override + public String R_HomeDir() { + return REnvVars.rHome(); + } + + @Override + public void R_CleanUp(int sa, int status, int runlast) { + RCleanUp.stdCleanUp(SA_TYPE.values()[sa], status, runlast != 0); + } + + @Override + public Object R_GlobalContext() { + Utils.warn("Potential memory leak (global context object)"); + Frame frame = Utils.getActualCurrentFrame(); + if (frame == null) { + return RCaller.topLevel; + } + if (RContext.getInstance().stateInstrumentation.getBrowserState().inBrowser()) { + return RContext.getInstance().stateInstrumentation.getBrowserState().getInBrowserCaller(); + } + RCaller rCaller = RArguments.getCall(frame); + return rCaller == null ? RCaller.topLevel : rCaller; + } + + @Override + public Object R_GlobalEnv() { + return RContext.getInstance().stateREnvironment.getGlobalEnv(); + } + + @Override + public Object R_BaseEnv() { + return RContext.getInstance().stateREnvironment.getBaseEnv(); + } + + @Override + public Object R_BaseNamespace() { + return RContext.getInstance().stateREnvironment.getBaseNamespace(); + } + + @Override + public Object R_NamespaceRegistry() { + return RContext.getInstance().stateREnvironment.getNamespaceRegistry(); + } + + @Override + public int R_Interactive() { + return RContext.getInstance().isInteractive() ? 1 : 0; + } + + @Override + public int IS_S4_OBJECT(Object x) { + return x instanceof RS4Object ? 1 : 0; + } + + @Override + public void Rprintf(Object message) { + RContext.getInstance().getConsoleHandler().print((String) message); + } + + @Override + public void GetRNGstate() { + RRNG.getRNGState(); + } + + @Override + public void PutRNGstate() { + RRNG.putRNGState(); + } + + @Override + public double unif_rand() { + return RRNG.unifRand(); + } + + // Checkstyle: stop method name check + + @Override + public Object R_getGlobalFunctionContext() { + Utils.warn("Potential memory leak (global function context object)"); + Frame frame = Utils.getActualCurrentFrame(); + if (frame == null) { + return RNull.instance; + } + RCaller currentCaller = RArguments.getCall(frame); + while (currentCaller != null) { + if (!currentCaller.isPromise() && currentCaller.isValidCaller() && currentCaller != RContext.getInstance().stateInstrumentation.getBrowserState().getInBrowserCaller()) { + break; + } + currentCaller = currentCaller.getParent(); + } + return currentCaller == null || currentCaller == RCaller.topLevel ? RNull.instance : currentCaller; + } + + @Override + public Object R_getParentFunctionContext(Object c) { + Utils.warn("Potential memory leak (parent function context object)"); + RCaller currentCaller = guaranteeInstanceOf(c, RCaller.class); + while (true) { + currentCaller = currentCaller.getParent(); + if (currentCaller == null || + (!currentCaller.isPromise() && currentCaller.isValidCaller() && currentCaller != RContext.getInstance().stateInstrumentation.getBrowserState().getInBrowserCaller())) { + break; + } + } + return currentCaller == null || currentCaller == RCaller.topLevel ? RNull.instance : currentCaller; + } + + @Override + public Object R_getContextEnv(Object c) { + RCaller rCaller = guaranteeInstanceOf(c, RCaller.class); + if (rCaller == RCaller.topLevel) { + return RContext.getInstance().stateREnvironment.getGlobalEnv(); + } + Frame frame = Utils.getActualCurrentFrame(); + if (RArguments.getCall(frame) == rCaller) { + return REnvironment.frameToEnvironment(frame.materialize()); + } else { + Object result = Utils.iterateRFrames(FrameAccess.READ_ONLY, new Function<Frame, Object>() { + + @Override + public Object apply(Frame f) { + RCaller currentCaller = RArguments.getCall(f); + if (currentCaller == rCaller) { + return REnvironment.frameToEnvironment(f.materialize()); + } else { + return null; + } + } + }); + return result; + } + } + + @Override + public Object R_getContextFun(Object c) { + RCaller rCaller = guaranteeInstanceOf(c, RCaller.class); + if (rCaller == RCaller.topLevel) { + return RNull.instance; + } + Frame frame = Utils.getActualCurrentFrame(); + if (RArguments.getCall(frame) == rCaller) { + return RArguments.getFunction(frame); + } else { + Object result = Utils.iterateRFrames(FrameAccess.READ_ONLY, new Function<Frame, Object>() { + + @Override + public Object apply(Frame f) { + RCaller currentCaller = RArguments.getCall(f); + if (currentCaller == rCaller) { + return RArguments.getFunction(f); + } else { + return null; + } + } + }); + return result; + } + } + + @Override + public Object R_getContextCall(Object c) { + RCaller rCaller = guaranteeInstanceOf(c, RCaller.class); + if (rCaller == RCaller.topLevel) { + return RNull.instance; + } + return RContext.getRRuntimeASTAccess().getSyntaxCaller(rCaller); + } + + @Override + public Object R_getContextSrcRef(Object c) { + Object o = R_getContextFun(c); + if (!(o instanceof RFunction)) { + return RNull.instance; + } else { + RFunction f = (RFunction) o; + SourceSection ss = f.getRootNode().getSourceSection(); + String path = RSource.getPath(ss.getSource()); + // TODO: is it OK to pass "" if path is null? + return RSrcref.createLloc(ss, path == null ? "" : path); + } + } + + @Override + public int R_insideBrowser() { + return RContext.getInstance().stateInstrumentation.getBrowserState().inBrowser() ? 1 : 0; + } + + @Override + public int R_isGlobal(Object c) { + RCaller rCaller = guaranteeInstanceOf(c, RCaller.class); + + return rCaller == RCaller.topLevel ? 1 : 0; + } + + @Override + public int R_isEqual(Object x, Object y) { + return x == y ? 1 : 0; + } + + @Override + @TruffleBoundary + public Object Rf_classgets(Object x, Object y) { + RAbstractVector vector = guaranteeInstanceOf(x, RAbstractVector.class); + vector.setClassAttr(guaranteeInstanceOf(y, RStringVector.class)); + return RNull.instance; + } + + @Override + public RExternalPtr R_MakeExternalPtr(long addr, Object tag, Object prot) { + return RDataFactory.createExternalPtr(new SymbolHandle(addr), tag, prot); + } + + @Override + public long R_ExternalPtrAddr(Object x) { + RExternalPtr p = guaranteeInstanceOf(x, RExternalPtr.class); + return p.getAddr().asAddress(); + } + + @Override + public Object R_ExternalPtrTag(Object x) { + RExternalPtr p = guaranteeInstanceOf(x, RExternalPtr.class); + return p.getTag(); + } + + @Override + public Object R_ExternalPtrProt(Object x) { + RExternalPtr p = guaranteeInstanceOf(x, RExternalPtr.class); + return p.getProt(); + } + + @Override + public void R_SetExternalPtrAddr(Object x, long addr) { + RExternalPtr p = guaranteeInstanceOf(x, RExternalPtr.class); + p.setAddr(new SymbolHandle(addr)); + } + + @Override + public void R_SetExternalPtrTag(Object x, Object tag) { + RExternalPtr p = guaranteeInstanceOf(x, RExternalPtr.class); + p.setTag(tag); + } + + @Override + public void R_SetExternalPtrProt(Object x, Object prot) { + RExternalPtr p = guaranteeInstanceOf(x, RExternalPtr.class); + p.setProt(prot); + } + + @Override + public REnvironment R_NewHashedEnv(REnvironment parent, int initialSize) { + REnvironment env = RDataFactory.createNewEnv(REnvironment.UNNAMED, true, initialSize); + RArguments.initializeEnclosingFrame(env.getFrame(), parent.getFrame()); + return env; + } + +} diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/RFFIUpCallMethod.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/RFFIUpCallMethod.java index 3074783733..fc354a931d 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/RFFIUpCallMethod.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/RFFIUpCallMethod.java @@ -72,7 +72,7 @@ public enum RFFIUpCallMethod { R_SetExternalPtrTag("(object, object) : void"), R_ToplevelExec("() : object"), R_computeIdentical("(object, object, sint32) : sint32"), - R_do_MAKE_CLASS("(object) : object"), + R_do_MAKE_CLASS("(pointer) : object"), R_getContextCall("(object) : object"), R_getContextEnv("(object) : object"), R_getContextFun("(object) : object"), @@ -104,7 +104,7 @@ public enum RFFIUpCallMethod { Rf_copyMatrix("(object, object, sint32) : void"), Rf_defineVar("(object, object, object) : void"), Rf_duplicate("(object, sint32) : object"), - Rf_error("(object) : void"), + Rf_error("(pointer) : void"), Rf_eval("(object, object) : object"), Rf_findVar("(object, object) : object"), Rf_findVarInFrame("(object, object) : object"), @@ -112,18 +112,18 @@ public enum RFFIUpCallMethod { Rf_findfun("(object, object) : object"), Rf_getAttrib("(object, object) : object"), Rf_gsetVar("(object, object, object) : void"), - Rf_inherits("(object, object) : sint32"), - Rf_install("(object) : object"), + Rf_inherits("(pointer, object) : sint32"), + Rf_install("(pointer) : object"), Rf_isNull("(object) : sint32"), Rf_isString("(object) : sint32"), Rf_lengthgets("(object, sint32) : object"), - Rf_mkCharLenCE("(object, sint32, sint32) : object"), + Rf_mkCharLenCE("(pointer, sint32, sint32) : object"), Rf_ncols("(object) : sint32"), Rf_nrows("(object) : sint32"), Rf_setAttrib("(object, object, object) : void"), - Rf_warning("(object) : void"), - Rf_warningcall("(object, object) : void"), - Rprintf("(object) : void"), + Rf_warning("(pointer) : void"), + Rf_warningcall("(object, pointer) : void"), + Rprintf("(pointer) : void"), SETCADR("(object, object) : object"), SETCAR("(object, object) : object"), SETCDR("(object, object) : object"), diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/TraceUpCallsAdapter.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/TraceUpCallsAdapter.java deleted file mode 100644 index 2c42a92eb5..0000000000 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/TraceUpCallsAdapter.java +++ /dev/null @@ -1,892 +0,0 @@ -/* - * Copyright (c) 2016, 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.nodes.ffi; - -import com.oracle.truffle.r.runtime.data.RDoubleVector; -import com.oracle.truffle.r.runtime.data.RExternalPtr; -import com.oracle.truffle.r.runtime.data.RIntVector; -import com.oracle.truffle.r.runtime.data.RLogicalVector; -import com.oracle.truffle.r.runtime.data.RStringVector; -import com.oracle.truffle.r.runtime.env.REnvironment; -import com.oracle.truffle.r.runtime.ffi.UpCallsRFFI; - -public class TraceUpCallsAdapter implements UpCallsRFFI { - @Override - public RIntVector Rf_ScalarInteger(int value) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_ScalarInteger", value); - } - return null; - } - - @Override - public RLogicalVector Rf_ScalarLogical(int value) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_ScalarLogical", value); - } - return null; - } - - @Override - public RDoubleVector Rf_ScalarDouble(double value) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_ScalarDouble", value); - } - return null; - } - - @Override - public RStringVector Rf_ScalarString(Object value) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_ScalarString", value); - } - return null; - } - - @Override - public int Rf_asInteger(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_asInteger", x); - } - return 0; - } - - @Override - public double Rf_asReal(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_asReal", x); - } - return 0; - } - - @Override - public int Rf_asLogical(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_asLogical", x); - } - return 0; - } - - @Override - public Object Rf_asChar(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_asChar", x); - } - return null; - } - - @Override - public Object Rf_mkCharLenCE(Object bytes, int len, int encoding) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_mkCharLenCE", bytes); - } - return null; - } - - @Override - public Object Rf_cons(Object car, Object cdr) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_cons", car, cdr); - } - return null; - } - - @Override - public void Rf_defineVar(Object symbolArg, Object value, Object envArg) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_defineVar", symbolArg, value, envArg); - } - } - - @Override - public Object R_do_MAKE_CLASS(Object clazz) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("R_do_MAKE_CLASS", clazz); - } - return null; - } - - @Override - public Object Rf_findVar(Object symbolArg, Object envArg) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_findVar", symbolArg, envArg); - } - return null; - } - - @Override - public Object Rf_findVarInFrame(Object envArg, Object symbolArg) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_findVarInFrame", envArg, symbolArg); - } - return null; - } - - @Override - public Object Rf_findVarInFrame3(Object envArg, Object symbolArg, int doGet) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_findVarInFrame3", envArg, symbolArg); - } - return null; - } - - @Override - public Object Rf_getAttrib(Object obj, Object name) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_getAttrib", obj, name); - } - return null; - } - - @Override - public void Rf_setAttrib(Object obj, Object name, Object val) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_setAttrib", obj, name, val); - } - } - - @Override - public int Rf_inherits(Object x, Object clazz) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_inherits", x, clazz); - } - return 0; - } - - @Override - public Object Rf_install(Object name) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_install", name); - } - return null; - } - - @Override - public Object Rf_lengthgets(Object x, int newSize) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_lengthgets", x, newSize); - } - return null; - } - - @Override - public int Rf_isString(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_isString", x); - } - return 0; - } - - @Override - public int Rf_isNull(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_isNull", x); - } - return 0; - } - - @Override - public Object Rf_PairToVectorList(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_PairToVectorList", x); - } - return null; - } - - @Override - public void Rf_error(Object msg) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_error", msg); - } - } - - @Override - public void Rf_warning(Object msg) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_warning", msg); - } - } - - @Override - public void Rf_warningcall(Object call, Object msg) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_warningcall", call, msg); - } - } - - @Override - public Object Rf_allocateVector(int mode, int n) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_allocateVector", mode, n); - } - return null; - } - - @Override - public Object Rf_allocateArray(int mode, Object dimsObj) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_allocateArray", mode, dimsObj); - } - return null; - } - - @Override - public Object Rf_allocateMatrix(int mode, int nrow, int ncol) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_allocateMatrix", mode, ncol, nrow); - } - return null; - } - - @Override - public int Rf_nrows(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_nrows", x); - } - return 0; - } - - @Override - public int Rf_ncols(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_ncols", x); - } - return 0; - } - - @Override - public int LENGTH(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("LENGTH", x); - } - return 0; - } - - @Override - public void SET_STRING_ELT(Object x, int i, Object v) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("SET_STRING_ELT", x, i, v); - } - } - - @Override - public void SET_VECTOR_ELT(Object x, int i, Object v) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("SET_VECTOR_ELT", i, v); - } - } - - @Override - public Object RAW(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("RAW", x); - } - return null; - } - - @Override - public Object LOGICAL(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("LOGICAL", x); - } - return null; - } - - @Override - public Object INTEGER(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("INTEGER", x); - } - return null; - } - - @Override - public Object REAL(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("REAL", x); - } - return null; - } - - @Override - public Object STRING_ELT(Object x, int i) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("STRING_ELT", x, i); - } - return null; - } - - @Override - public Object VECTOR_ELT(Object x, int i) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("VECTOR_ELT", x, i); - } - return null; - } - - @Override - public int NAMED(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("NAMED", x); - } - return 0; - } - - @Override - public Object SET_TYPEOF_FASTR(Object x, int v) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("SET_TYPEOF_FASTR", x, v); - } - return null; - } - - @Override - public int TYPEOF(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("TYPEOF", x); - } - return 0; - } - - @Override - public int OBJECT(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("OBJECT", x); - } - return 0; - } - - @Override - public Object Rf_duplicate(Object x, int deep) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_duplicate", x, deep); - } - return null; - } - - @Override - public int Rf_anyDuplicated(Object x, int fromLast) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_anyDuplicated", x, fromLast); - } - return 0; - } - - @Override - public Object PRINTNAME(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("PRINTNAME", x); - } - return null; - } - - @Override - public Object TAG(Object e) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("TAG", e); - } - return null; - } - - @Override - public Object CAR(Object e) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("CAR", e); - } - return null; - } - - @Override - public Object CDR(Object e) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("CDR", e); - } - return null; - } - - @Override - public Object CADR(Object e) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("CADR", e); - } - return null; - } - - @Override - public Object CADDR(Object e) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("CADDR", e); - } - return null; - } - - @Override - public Object CDDR(Object e) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("CDDR", e); - } - return null; - } - - @Override - public Object SET_TAG(Object x, Object y) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("SET_TAG", x, y); - } - return null; - } - - @Override - public Object SETCAR(Object x, Object y) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("SETCAR", x, y); - } - return null; - } - - @Override - public Object SETCDR(Object x, Object y) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("SETCDR", x, y); - } - return null; - } - - @Override - public Object SETCADR(Object x, Object y) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("SETCADR", x); - } - return null; - } - - @Override - public Object SYMVALUE(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("SYMVALUE", x); - } - return null; - } - - @Override - public void SET_SYMVALUE(Object x, Object v) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("SET_SYMVALUE", x, v); - } - } - - @Override - public int R_BindingIsLocked(Object sym, Object env) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("R_BindingIsLocked", sym, env); - } - return 0; - } - - @Override - public Object R_FindNamespace(Object name) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("R_FindNamespace", name); - } - return null; - } - - @Override - public Object Rf_eval(Object expr, Object env) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_eval", expr, env); - } - return null; - } - - @Override - public Object Rf_findfun(Object symbolObj, Object envObj) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_findfun", symbolObj, envObj); - } - return null; - } - - @Override - public Object Rf_GetOption1(Object tag) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_GetOption1", tag); - } - return null; - } - - @Override - public void Rf_gsetVar(Object symbol, Object value, Object rho) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_gsetVar", symbol, value, rho); - } - } - - @Override - public void DUPLICATE_ATTRIB(Object to, Object from) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("DUPLICATE_ATTRIB", to, from); - } - } - - @Override - public int R_computeIdentical(Object x, Object y, int flags) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("R_computeIdentical", x, y, flags); - } - return 0; - } - - @Override - public void Rf_copyListMatrix(Object s, Object t, int byrow) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_copyListMatrix", t, byrow); - } - } - - @Override - public void Rf_copyMatrix(Object s, Object t, int byrow) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_copyMatrix", t, byrow); - } - } - - @Override - public Object R_tryEval(Object expr, Object env, boolean silent) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("R_tryEval", expr, env, silent); - } - return null; - } - - @Override - public Object R_ToplevelExec() { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("R_TopLevelExec"); - } - return null; - } - - @Override - public int RDEBUG(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("RDEBUG", x); - } - return 0; - } - - @Override - public void SET_RDEBUG(Object x, int v) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("SET_RDEBUG", x, v); - } - } - - @Override - public int RSTEP(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("RSTEP", x); - } - return 0; - } - - @Override - public void SET_RSTEP(Object x, int v) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("SET_RSTEP", x, v); - } - } - - @Override - public Object ENCLOS(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("ENCLOS", x); - } - return null; - } - - @Override - public Object PRVALUE(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("PRVALUE", x); - } - return null; - } - - @Override - public Object R_ParseVector(Object text, int n, Object srcFile) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("R_ParseVector", text, n, srcFile); - } - return null; - } - - @Override - public Object R_lsInternal3(Object envArg, int allArg, int sortedArg) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("R_lsInternal3", envArg, allArg, sortedArg); - } - return null; - } - - @Override - public String R_HomeDir() { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("R_HomeDir"); - } - return null; - } - - @Override - public void R_CleanUp(int sa, int status, int runlast) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("R_Cleanup", sa, status, runlast); - } - } - - @Override - public Object R_GlobalContext() { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("R_GlobalContext"); - } - return null; - } - - @Override - public Object R_GlobalEnv() { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("R_GlobalEnv"); - } - return null; - } - - @Override - public Object R_BaseEnv() { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("R_BaseEnv"); - } - return null; - } - - @Override - public Object R_BaseNamespace() { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("R_BaseNamespace"); - } - return null; - } - - @Override - public Object R_NamespaceRegistry() { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("R_NamespaceRegistry"); - } - return null; - } - - @Override - public int R_Interactive() { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("isInteractive"); - } - return 0; - } - - @Override - public int IS_S4_OBJECT(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("isS4Object"); - } - return 0; - } - - @Override - public void Rprintf(Object message) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rprintf", message); - } - } - - @Override - public void GetRNGstate() { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("GetRNGstate"); - } - } - - @Override - public void PutRNGstate() { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("PutRNGstate"); - } - } - - @Override - public double unif_rand() { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("unif_rand"); - } - return 0; - } - - @Override - public Object R_getGlobalFunctionContext() { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("R_getGlobalFunctionContext"); - } - return null; - } - - @Override - public Object R_getParentFunctionContext(Object c) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("R_getParentFunctionContext"); - } - return null; - } - - @Override - public Object R_getContextEnv(Object c) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("R_getContextEnv", c); - } - return null; - } - - @Override - public Object R_getContextFun(Object c) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("R_getContextFun", c); - } - return null; - } - - @Override - public Object R_getContextCall(Object c) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("R_getContextCall", c); - } - return null; - } - - @Override - public Object R_getContextSrcRef(Object c) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("R_getContextSrcRef", c); - } - return null; - } - - @Override - public int R_insideBrowser() { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("R_insideBrowser"); - } - return 0; - } - - @Override - public int R_isGlobal(Object c) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("R_isGlobal", c); - } - return 0; - } - - @Override - public int R_isEqual(Object x, Object y) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("isEqual", x, y); - } - return 0; - } - - @Override - public Object Rf_classgets(Object x, Object y) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("Rf_classgets", x, y); - } - return null; - } - - @Override - public RExternalPtr R_MakeExternalPtr(long addr, Object tag, Object prot) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("R_MakeExternalPtr", addr, tag, prot); - } - return null; - } - - @Override - public long R_ExternalPtrAddr(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("R_ExternalPtrAddr", x); - } - return 0; - } - - @Override - public Object R_ExternalPtrTag(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("R_ExternalPtrTag", x); - } - return null; - } - - @Override - public Object R_ExternalPtrProt(Object x) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("R_ExternalPtrProt", x); - } - return null; - } - - @Override - public void R_SetExternalPtrAddr(Object x, long addr) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("R_SetExternalPtrAddr", x); - } - } - - @Override - public void R_SetExternalPtrTag(Object x, Object tag) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("R_SetExternalPtrTag", x); - } - } - - @Override - public void R_SetExternalPtrProt(Object x, Object prot) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("R_ExternalPtrProt", x); - } - } - - @Override - public REnvironment R_NewHashedEnv(REnvironment parent, int initialSize) { - if (RFFIUtils.traceEnabled()) { - RFFIUtils.traceUpCall("R_NewHashedEnv", parent, initialSize); - } - return null; - } -} diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/UpCallsRFFIImpl.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/UpCallsRFFIImpl.java index dca6fda9cf..59a0dbc139 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/UpCallsRFFIImpl.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/ffi/UpCallsRFFIImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -22,1480 +22,928 @@ */ package com.oracle.truffle.r.nodes.ffi; -import static com.oracle.truffle.r.nodes.ffi.RFFIUtils.*; - -import java.nio.charset.StandardCharsets; -import java.util.function.Function; - -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.frame.Frame; -import com.oracle.truffle.api.frame.FrameInstance.FrameAccess; -import com.oracle.truffle.api.object.DynamicObject; -import com.oracle.truffle.api.source.Source; -import com.oracle.truffle.api.source.SourceSection; -import com.oracle.truffle.r.nodes.ffi.ParseResult.ParseStatus; -import com.oracle.truffle.r.runtime.RArguments; -import com.oracle.truffle.r.runtime.RCaller; -import com.oracle.truffle.r.runtime.RCleanUp; -import com.oracle.truffle.r.runtime.REnvVars; -import com.oracle.truffle.r.runtime.RError; +import static com.oracle.truffle.r.nodes.ffi.RFFIUtils.guaranteeInstanceOf; + import com.oracle.truffle.r.runtime.RErrorHandling; -import com.oracle.truffle.r.runtime.RInternalError; -import com.oracle.truffle.r.runtime.RRuntime; -import com.oracle.truffle.r.runtime.RSource; -import com.oracle.truffle.r.runtime.RSrcref; -import com.oracle.truffle.r.runtime.RStartParams.SA_TYPE; -import com.oracle.truffle.r.runtime.RType; -import com.oracle.truffle.r.runtime.Utils; -import com.oracle.truffle.r.runtime.context.Engine.ParseException; -import com.oracle.truffle.r.runtime.context.RContext; -import com.oracle.truffle.r.runtime.data.RAttributable; -import com.oracle.truffle.r.runtime.data.RAttributesLayout; -import com.oracle.truffle.r.runtime.data.RComplex; -import com.oracle.truffle.r.runtime.data.RComplexVector; -import com.oracle.truffle.r.runtime.data.RDataFactory; -import com.oracle.truffle.r.runtime.data.RDoubleSequence; import com.oracle.truffle.r.runtime.data.RDoubleVector; -import com.oracle.truffle.r.runtime.data.RExpression; 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.RLanguage; -import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RLogicalVector; -import com.oracle.truffle.r.runtime.data.RNull; -import com.oracle.truffle.r.runtime.data.RPairList; -import com.oracle.truffle.r.runtime.data.RPromise; -import com.oracle.truffle.r.runtime.data.RRaw; -import com.oracle.truffle.r.runtime.data.RRawVector; -import com.oracle.truffle.r.runtime.data.RS4Object; -import com.oracle.truffle.r.runtime.data.RSequence; -import com.oracle.truffle.r.runtime.data.RShareable; import com.oracle.truffle.r.runtime.data.RStringVector; -import com.oracle.truffle.r.runtime.data.RSymbol; -import com.oracle.truffle.r.runtime.data.RUnboundValue; import com.oracle.truffle.r.runtime.data.RVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractListVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractVector; import com.oracle.truffle.r.runtime.env.REnvironment; -import com.oracle.truffle.r.runtime.env.REnvironment.PutException; import com.oracle.truffle.r.runtime.ffi.CharSXPWrapper; import com.oracle.truffle.r.runtime.ffi.UpCallsRFFI; -import com.oracle.truffle.r.runtime.ffi.DLL.SymbolHandle; -import com.oracle.truffle.r.runtime.gnur.SEXPTYPE; -import com.oracle.truffle.r.runtime.nodes.DuplicationHelper; -import com.oracle.truffle.r.runtime.nodes.RNode; -import com.oracle.truffle.r.runtime.rng.RRNG; - -/** - * This class provides a simple Java-based implementation of {@link UpCallsRFFI}, using no Truffle - * mechanisms. - * - * TODO Many of the implementations here are incomplete and/or duplicate code that exists in the - * Truffle side of the implementation, i.e., {@link RNode} subclasses. A complete refactoring that - * accesses the Truffle implementations (possibly somewhat refactored owing to the fact that the - * Truffle side is driven by the builtins yet these functions don't not always map 1-1 to a builtin) - * is desirable. In some cases it may be possible to "implement" the functions in R (which is a - * simple way to achieve the above). - */ -public class UpCallsRFFIImpl implements UpCallsRFFI { - protected TraceUpCallsAdapter tracer; +public final class UpCallsRFFIImpl implements UpCallsRFFI { + // Checkstyle: stop method name check - public UpCallsRFFIImpl() { - if (RFFIUtils.traceEnabled()) { - tracer = new TraceUpCallsAdapter(); - } + private final UpCallsRFFI delegate; + private final boolean tracing; + + public UpCallsRFFIImpl(UpCallsRFFI delegate) { + this.delegate = delegate; FFIUpCallRootNode.register(); + tracing = RFFIUtils.traceEnabled(); } - // Checkstyle: stop method name check - @Override public RIntVector Rf_ScalarInteger(int value) { - if (tracer != null) { - tracer.Rf_ScalarInteger(value); + if (tracing) { + RFFIUtils.traceUpCall("Rf_ScalarInteger", value); } - return RDataFactory.createIntVectorFromScalar(value); + return delegate.Rf_ScalarInteger(value); } @Override public RLogicalVector Rf_ScalarLogical(int value) { - if (tracer != null) { - tracer.Rf_ScalarLogical(value); - } - byte byteValue; - if (value == RRuntime.INT_NA) { - byteValue = RRuntime.LOGICAL_NA; - } else { - byteValue = (byte) (value & 0xFF); + if (tracing) { + RFFIUtils.traceUpCall("Rf_ScalarLogical", value); } - return RDataFactory.createLogicalVectorFromScalar(byteValue); + return delegate.Rf_ScalarLogical(value); } @Override public RDoubleVector Rf_ScalarDouble(double value) { - if (tracer != null) { - tracer.Rf_ScalarDouble(value); + if (tracing) { + RFFIUtils.traceUpCall("Rf_ScalarDouble", value); } - return RDataFactory.createDoubleVectorFromScalar(value); + return delegate.Rf_ScalarDouble(value); } @Override public RStringVector Rf_ScalarString(Object value) { - if (tracer != null) { - tracer.Rf_ScalarString(value); + if (tracing) { + RFFIUtils.traceUpCall("Rf_ScalarString", value); } - CharSXPWrapper chars = guaranteeInstanceOf(value, CharSXPWrapper.class); - return RDataFactory.createStringVectorFromScalar(chars.getContents()); + return delegate.Rf_ScalarString(value); } @Override public int Rf_asInteger(Object x) { - if (tracer != null) { - tracer.Rf_asInteger(x); + if (tracing) { + RFFIUtils.traceUpCall("Rf_asInteger", x); } - return (int) FFIUpCallRootNode.getCallTarget(RFFIUpCallMethod.Rf_asInteger).call(x); + return delegate.Rf_asInteger(x); } @Override public double Rf_asReal(Object x) { - if (tracer != null) { - tracer.Rf_asReal(x); + if (tracing) { + RFFIUtils.traceUpCall("Rf_asReal", x); } - return (double) FFIUpCallRootNode.getCallTarget(RFFIUpCallMethod.Rf_asReal).call(x); + return delegate.Rf_asReal(x); } @Override public int Rf_asLogical(Object x) { - if (tracer != null) { - tracer.Rf_asLogical(x); + if (tracing) { + RFFIUtils.traceUpCall("Rf_asLogical", x); } - return (int) FFIUpCallRootNode.getCallTarget(RFFIUpCallMethod.Rf_asLogical).call(x); + return delegate.Rf_asLogical(x); } @Override public Object Rf_asChar(Object x) { - if (tracer != null) { - tracer.Rf_asChar(x); + if (tracing) { + RFFIUtils.traceUpCall("Rf_asChar", x); } - return FFIUpCallRootNode.getCallTarget(RFFIUpCallMethod.Rf_asChar).call(x); + return delegate.Rf_asChar(x); } @Override public Object Rf_mkCharLenCE(Object bytes, int len, int encoding) { - if (tracer != null) { - tracer.Rf_mkCharLenCE(bytes, len, encoding); + if (tracing) { + RFFIUtils.traceUpCall("Rf_mkCharLenCE", bytes); } - // TODO: handle encoding properly - return CharSXPWrapper.create(new String((byte[]) bytes, StandardCharsets.UTF_8)); + return delegate.Rf_mkCharLenCE(bytes, len, encoding); } @Override public Object Rf_cons(Object car, Object cdr) { - if (tracer != null) { - tracer.Rf_cons(car, cdr); + if (tracing) { + RFFIUtils.traceUpCall("Rf_cons", car, cdr); } - return RDataFactory.createPairList(car, cdr); + return delegate.Rf_cons(car, cdr); } @Override public void Rf_defineVar(Object symbolArg, Object value, Object envArg) { - if (tracer != null) { - tracer.Rf_defineVar(symbolArg, value, envArg); - } - REnvironment env = (REnvironment) envArg; - RSymbol name = (RSymbol) symbolArg; - try { - env.put(name.getName(), value); - } catch (PutException ex) { - throw RError.error(RError.SHOW_CALLER2, ex); + if (tracing) { + RFFIUtils.traceUpCall("Rf_defineVar", symbolArg, value, envArg); } + delegate.Rf_defineVar(symbolArg, value, envArg); } @Override public Object R_do_MAKE_CLASS(Object clazz) { - if (tracer != null) { - tracer.R_do_MAKE_CLASS(clazz); + if (tracing) { + RFFIUtils.traceUpCall("R_do_MAKE_CLASS", clazz); } - String name = "getClass"; - RFunction getClass = (RFunction) RContext.getRRuntimeASTAccess().forcePromise(name, REnvironment.getRegisteredNamespace("methods").get(name)); - return RContext.getEngine().evalFunction(getClass, null, RCaller.createInvalid(null), null, clazz); + return delegate.R_do_MAKE_CLASS(clazz); } @Override public Object Rf_findVar(Object symbolArg, Object envArg) { - if (tracer != null) { - tracer.Rf_findVar(symbolArg, envArg); + if (tracing) { + RFFIUtils.traceUpCall("Rf_findVar", symbolArg, envArg); } - return findVarInFrameHelper(envArg, symbolArg, true); + return delegate.Rf_findVar(symbolArg, envArg); } @Override public Object Rf_findVarInFrame(Object envArg, Object symbolArg) { - if (tracer != null) { - tracer.Rf_findVarInFrame(envArg, symbolArg); + if (tracing) { + RFFIUtils.traceUpCall("Rf_findVarInFrame", envArg, symbolArg); } - return findVarInFrameHelper(envArg, symbolArg, false); + return delegate.Rf_findVarInFrame(envArg, symbolArg); } @Override public Object Rf_findVarInFrame3(Object envArg, Object symbolArg, int doGet) { - if (tracer != null) { - tracer.Rf_findVarInFrame3(envArg, symbolArg, doGet); - } - // GNU R has code for IS_USER_DATBASE that uses doGet - // This is a lookup in the single environment (envArg) only, i.e. inherits=false - return findVarInFrameHelper(envArg, symbolArg, false); - } - - private static Object findVarInFrameHelper(Object envArg, Object symbolArg, boolean inherits) { - if (envArg == RNull.instance) { - throw RError.error(RError.SHOW_CALLER2, RError.Message.USE_NULL_ENV_DEFUNCT); - } - if (!(envArg instanceof REnvironment)) { - throw RError.error(RError.SHOW_CALLER2, RError.Message.ARG_NOT_AN_ENVIRONMENT, inherits ? "findVar" : "findVarInFrame"); + if (tracing) { + RFFIUtils.traceUpCall("Rf_findVarInFrame3", envArg, symbolArg); } - RSymbol name = (RSymbol) symbolArg; - REnvironment env = (REnvironment) envArg; - while (env != REnvironment.emptyEnv()) { - Object value = env.get(name.getName()); - if (value != null) { - return value; - } - if (!inherits) { - // simgle frame lookup - break; - } - env = env.getParent(); - } - return RUnboundValue.instance; + return delegate.Rf_findVarInFrame3(envArg, symbolArg, doGet); } @Override public Object Rf_getAttrib(Object obj, Object name) { - if (tracer != null) { - tracer.Rf_getAttrib(obj, name); - } - Object result = RNull.instance; - if (obj instanceof RAttributable) { - RAttributable attrObj = (RAttributable) obj; - DynamicObject attrs = attrObj.getAttributes(); - if (attrs != null) { - String nameAsString = ((RSymbol) name).getName().intern(); - Object attr = attrs.get(nameAsString); - if (attr != null) { - result = attr; - } - } + if (tracing) { + RFFIUtils.traceUpCall("Rf_getAttrib", obj, name); } - return result; + return delegate.Rf_getAttrib(obj, name); } @Override - @TruffleBoundary public void Rf_setAttrib(Object obj, Object name, Object val) { - if (tracer != null) { - tracer.Rf_setAttrib(obj, name, val); - } - if (obj instanceof RAttributable) { - RAttributable attrObj = (RAttributable) obj; - String nameAsString; - if (name instanceof RSymbol) { - nameAsString = ((RSymbol) name).getName(); - } else { - nameAsString = RRuntime.asString(name); - assert nameAsString != null; - } - nameAsString = nameAsString.intern(); - if (val == RNull.instance) { - removeAttr(attrObj, nameAsString); - } else if ("class" == nameAsString) { - attrObj.initAttributes().define(nameAsString, val); - } else { - attrObj.setAttr(nameAsString, val); - } - } - } - - @TruffleBoundary - private static void removeAttr(RAttributable a, String name) { - a.removeAttr(name); - } - - public static RStringVector getClassHr(Object v) { - RStringVector result; - if (v instanceof RAttributable) { - result = ((RAttributable) v).getClassHierarchy(); - } else if (v instanceof Byte) { - result = RLogicalVector.implicitClassHeader; - } else if (v instanceof String) { - result = RStringVector.implicitClassHeader; - } else if (v instanceof Integer) { - result = RIntVector.implicitClassHeader; - } else if (v instanceof Double) { - result = RDoubleVector.implicitClassHeader; - } else if (v instanceof RComplex) { - result = RComplexVector.implicitClassHeader; - } else if (v instanceof RRaw) { - result = RRawVector.implicitClassHeader; - } else { - guaranteeInstanceOf(v, RNull.class); - result = RNull.implicitClassHeader; - } - return result; + if (tracing) { + RFFIUtils.traceUpCall("Rf_setAttrib", obj, name, val); + } + delegate.Rf_setAttrib(obj, name, val); } @Override public int Rf_inherits(Object x, Object clazz) { - if (tracer != null) { - tracer.Rf_inherits(x, clazz); + if (tracing) { + RFFIUtils.traceUpCall("Rf_inherits", x, clazz); } - int result = 0; - RStringVector hierarchy = getClassHr(x); - for (int i = 0; i < hierarchy.getLength(); i++) { - if (hierarchy.getDataAt(i).equals(clazz)) { - result = 1; - } - } - return result; + return delegate.Rf_inherits(x, clazz); } @Override public Object Rf_install(Object name) { - if (tracer != null) { - tracer.Rf_install(name); + if (tracing) { + RFFIUtils.traceUpCall("Rf_install", name); } - return RDataFactory.createSymbolInterned((String) name); + return delegate.Rf_install(name); } @Override public Object Rf_lengthgets(Object x, int newSize) { - if (tracer != null) { - tracer.Rf_lengthgets(x, newSize); + if (tracing) { + RFFIUtils.traceUpCall("Rf_lengthgets", x, newSize); } - RAbstractVector vec = (RAbstractVector) RRuntime.asAbstractVector(x); - return vec.resize(newSize); + return delegate.Rf_lengthgets(x, newSize); } @Override public int Rf_isString(Object x) { - if (tracer != null) { - tracer.Rf_isString(x); + if (tracing) { + RFFIUtils.traceUpCall("Rf_isString", x); } - return RRuntime.checkType(x, RType.Character) ? 1 : 0; + return delegate.Rf_isString(x); } @Override public int Rf_isNull(Object x) { - if (tracer != null) { - tracer.Rf_isNull(x); + if (tracing) { + RFFIUtils.traceUpCall("Rf_isNull", x); } - return x == RNull.instance ? 1 : 0; + return delegate.Rf_isNull(x); } @Override public Object Rf_PairToVectorList(Object x) { - if (tracer != null) { - tracer.Rf_PairToVectorList(x); - } - if (x == RNull.instance) { - return RDataFactory.createList(); + if (tracing) { + RFFIUtils.traceUpCall("Rf_PairToVectorList", x); } - RPairList pl = (RPairList) x; - return pl.toRList(); + return delegate.Rf_PairToVectorList(x); } @Override public void Rf_error(Object msg) { - if (tracer != null) { - tracer.Rf_error(msg); + if (tracing) { + RFFIUtils.traceUpCall("Rf_error", msg); } - throw RError.error(RError.SHOW_CALLER2, RError.Message.GENERIC, msg); + delegate.Rf_error(msg); } @Override public void Rf_warning(Object msg) { - if (tracer != null) { - tracer.Rf_warning(msg); + if (tracing) { + RFFIUtils.traceUpCall("Rf_warning", msg); } - RError.warning(RError.SHOW_CALLER2, RError.Message.GENERIC, msg); + delegate.Rf_warning(msg); } @Override public void Rf_warningcall(Object call, Object msg) { - if (tracer != null) { - tracer.Rf_warningcall(call, msg); + if (tracing) { + RFFIUtils.traceUpCall("Rf_warningcall", call, msg); } - RErrorHandling.warningcallRFFI(call, (String) msg); + delegate.Rf_warningcall(call, msg); } @Override public Object Rf_allocateVector(int mode, int n) { - if (tracer != null) { - tracer.Rf_allocateVector(mode, n); - } - SEXPTYPE type = SEXPTYPE.mapInt(mode); - if (n < 0) { - throw RError.error(RError.SHOW_CALLER2, RError.Message.NEGATIVE_LENGTH_VECTORS_NOT_ALLOWED); - // TODO check long vector - } - switch (type) { - case INTSXP: - return RDataFactory.createIntVector(new int[n], RDataFactory.COMPLETE_VECTOR); - case REALSXP: - return RDataFactory.createDoubleVector(new double[n], RDataFactory.COMPLETE_VECTOR); - case LGLSXP: - return RDataFactory.createLogicalVector(new byte[n], RDataFactory.COMPLETE_VECTOR); - case STRSXP: - return RDataFactory.createStringVector(new String[n], RDataFactory.COMPLETE_VECTOR); - case CPLXSXP: - return RDataFactory.createComplexVector(new double[2 * n], RDataFactory.COMPLETE_VECTOR); - case RAWSXP: - return RDataFactory.createRawVector(new byte[n]); - case VECSXP: - return RDataFactory.createList(n); - case LANGSXP: - return RDataFactory.createLangPairList(n); - default: - throw unimplemented("unexpected SEXPTYPE " + type); + if (tracing) { + RFFIUtils.traceUpCall("Rf_allocateVector", mode, n); } + return delegate.Rf_allocateVector(mode, n); } @Override public Object Rf_allocateArray(int mode, Object dimsObj) { - if (tracer != null) { - tracer.Rf_allocateArray(mode, dimsObj); - } - RIntVector dims = (RIntVector) dimsObj; - int n = 1; - int[] newDims = new int[dims.getLength()]; - // TODO check long vector - for (int i = 0; i < newDims.length; i++) { - newDims[i] = dims.getDataAt(i); - n *= newDims[i]; + if (tracing) { + RFFIUtils.traceUpCall("Rf_allocateArray", mode, dimsObj); } - RAbstractVector result = (RAbstractVector) Rf_allocateVector(mode, n); - setDims(newDims, result); - return result; - - } - - @TruffleBoundary - private static void setDims(int[] newDims, RAbstractVector result) { - result.setDimensions(newDims); + return null; } @Override public Object Rf_allocateMatrix(int mode, int nrow, int ncol) { - if (tracer != null) { - tracer.Rf_allocateMatrix(mode, ncol, nrow); - } - SEXPTYPE type = SEXPTYPE.mapInt(mode); - if (nrow < 0 || ncol < 0) { - throw RError.error(RError.SHOW_CALLER2, RError.Message.NEGATIVE_EXTENTS_TO_MATRIX); - } - // TODO check long vector - int[] dims = new int[]{nrow, ncol}; - switch (type) { - case INTSXP: - return RDataFactory.createIntVector(new int[nrow * ncol], RDataFactory.COMPLETE_VECTOR, dims); - case REALSXP: - return RDataFactory.createDoubleVector(new double[nrow * ncol], RDataFactory.COMPLETE_VECTOR, dims); - case LGLSXP: - return RDataFactory.createLogicalVector(new byte[nrow * ncol], RDataFactory.COMPLETE_VECTOR, dims); - case STRSXP: - return RDataFactory.createStringVector(new String[nrow * ncol], RDataFactory.COMPLETE_VECTOR, dims); - case CPLXSXP: - return RDataFactory.createComplexVector(new double[2 * (nrow * ncol)], RDataFactory.COMPLETE_VECTOR, dims); - default: - throw unimplemented(); + if (tracing) { + RFFIUtils.traceUpCall("Rf_allocateMatrix", mode, ncol, nrow); } + return delegate.Rf_allocateMatrix(mode, nrow, ncol); } @Override public int Rf_nrows(Object x) { - if (tracer != null) { - tracer.Rf_nrows(x); + if (tracing) { + RFFIUtils.traceUpCall("Rf_nrows", x); } - return RRuntime.nrows(x); + return delegate.Rf_nrows(x); } @Override public int Rf_ncols(Object x) { - if (tracer != null) { - tracer.Rf_ncols(x); + if (tracing) { + RFFIUtils.traceUpCall("Rf_ncols", x); } - return RRuntime.ncols(x); + return delegate.Rf_ncols(x); } @Override public int LENGTH(Object x) { - if (tracer != null) { - tracer.LENGTH(x); + if (tracing) { + RFFIUtils.traceUpCall("LENGTH", x); } - return (int) FFIUpCallRootNode.getCallTarget(RFFIUpCallMethod.LENGTH).call(x); + return delegate.LENGTH(x); } @Override public void SET_STRING_ELT(Object x, int i, Object v) { - if (tracer != null) { - tracer.SET_STRING_ELT(x, i, v); + if (tracing) { + RFFIUtils.traceUpCall("SET_STRING_ELT", x, i, v); } - RStringVector vector = guaranteeInstanceOf(x, RStringVector.class); - CharSXPWrapper element = guaranteeInstanceOf(v, CharSXPWrapper.class); - vector.setElement(i, element.getContents()); + delegate.SET_STRING_ELT(x, i, v); } @Override public void SET_VECTOR_ELT(Object x, int i, Object v) { - if (tracer != null) { - tracer.SET_VECTOR_ELT(x, i, v); + if (tracing) { + RFFIUtils.traceUpCall("SET_VECTOR_ELT", i, v); } - RList list = guaranteeInstanceOf(x, RList.class); - list.setElement(i, v); + delegate.SET_VECTOR_ELT(x, i, v); } @Override public Object RAW(Object x) { - if (tracer != null) { - tracer.RAW(x); - } - if (x instanceof RRawVector) { - return ((RRawVector) x).getDataWithoutCopying(); - } else if (x instanceof RRaw) { - return new byte[]{((RRaw) x).getValue()}; - } else { - throw unimplemented(); + if (tracing) { + RFFIUtils.traceUpCall("RAW", x); } + return delegate.RAW(x); } @Override public Object LOGICAL(Object x) { - if (tracer != null) { - tracer.LOGICAL(x); - } - if (x instanceof RLogicalVector) { - return ((RLogicalVector) x).getDataWithoutCopying(); - } else if (x instanceof Byte) { - return new byte[]{(Byte) x}; - } else { - throw unimplemented(); + if (tracing) { + RFFIUtils.traceUpCall("LOGICAL", x); } + return delegate.LOGICAL(x); } @Override public Object INTEGER(Object x) { - if (tracer != null) { - tracer.INTEGER(x); - } - if (x instanceof RIntVector) { - return ((RIntVector) x).getDataWithoutCopying(); - } else if (x instanceof RIntSequence) { - return ((RIntSequence) x).materialize().getDataWithoutCopying(); - } else if (x instanceof Integer) { - return new int[]{(Integer) x}; - } else if (x instanceof RLogicalVector) { - RLogicalVector vec = (RLogicalVector) x; - int[] result = new int[vec.getLength()]; - for (int i = 0; i < result.length; i++) { - result[i] = vec.getDataAt(i); - } - return result; - } else { - guaranteeInstanceOf(x, Byte.class); - return new int[]{(Byte) x}; + if (tracing) { + RFFIUtils.traceUpCall("INTEGER", x); } + return delegate.INTEGER(x); } @Override public Object REAL(Object x) { - if (tracer != null) { - tracer.REAL(x); - } - if (x instanceof RDoubleVector) { - return ((RDoubleVector) x).getDataWithoutCopying(); - } else if (x instanceof RDoubleSequence) { - return ((RDoubleSequence) x).materialize().getDataWithoutCopying(); - } else { - guaranteeInstanceOf(x, Double.class); - return new double[]{(Double) x}; + if (tracing) { + RFFIUtils.traceUpCall("REAL", x); } + return delegate.REAL(x); } @Override public Object STRING_ELT(Object x, int i) { - if (tracer != null) { - tracer.STRING_ELT(x, i); + if (tracing) { + RFFIUtils.traceUpCall("STRING_ELT", x, i); } - RAbstractStringVector vector = guaranteeInstanceOf(RRuntime.asAbstractVector(x), RAbstractStringVector.class); - return CharSXPWrapper.create(vector.getDataAt(i)); + return delegate.STRING_ELT(x, i); } @Override public Object VECTOR_ELT(Object x, int i) { - if (tracer != null) { - tracer.VECTOR_ELT(x, i); - } - Object vec = x; - if (vec instanceof RExpression) { - return ((RExpression) vec).getDataAt(i); + if (tracing) { + RFFIUtils.traceUpCall("VECTOR_ELT", x, i); } - RAbstractListVector list = guaranteeInstanceOf(RRuntime.asAbstractVector(vec), RAbstractListVector.class); - return list.getDataAt(i); + return delegate.VECTOR_ELT(x, i); } @Override public int NAMED(Object x) { - if (tracer != null) { - tracer.NAMED(x); - } - if (x instanceof RShareable) { - return ((RShareable) x).isShared() ? 1 : 0; - } else { - throw unimplemented(); + if (tracing) { + RFFIUtils.traceUpCall("NAMED", x); } + return delegate.NAMED(x); } @Override public Object SET_TYPEOF_FASTR(Object x, int v) { - if (tracer != null) { - tracer.SET_TYPEOF_FASTR(x, v); - } - int code = SEXPTYPE.gnuRCodeForObject(x); - if (code == SEXPTYPE.LISTSXP.code && v == SEXPTYPE.LANGSXP.code) { - return RLanguage.fromList(x, RLanguage.RepType.CALL); - } else { - throw unimplemented(); + if (tracing) { + RFFIUtils.traceUpCall("SET_TYPEOF_FASTR", x, v); } + return delegate.SET_TYPEOF_FASTR(x, v); } @Override public int TYPEOF(Object x) { - if (tracer != null) { - tracer.TYPEOF(x); - } - if (x instanceof CharSXPWrapper) { - return SEXPTYPE.CHARSXP.code; - } else { - return SEXPTYPE.gnuRCodeForObject(x); + if (tracing) { + RFFIUtils.traceUpCall("TYPEOF", x); } + return delegate.TYPEOF(x); } @Override - @TruffleBoundary public int OBJECT(Object x) { - if (tracer != null) { - tracer.OBJECT(x); - } - if (x instanceof RAttributable) { - return ((RAttributable) x).getAttr(RRuntime.CLASS_ATTR_KEY) == null ? 0 : 1; - } else { - return 0; + if (tracing) { + RFFIUtils.traceUpCall("OBJECT", x); } + return delegate.OBJECT(x); } @Override public Object Rf_duplicate(Object x, int deep) { - if (tracer != null) { - tracer.Rf_duplicate(x, deep); - } - guarantee(x != null, "unexpected type: null instead of " + x.getClass().getSimpleName()); - guarantee(x instanceof RShareable || x instanceof RSequence || x instanceof RExternalPtr, - "unexpected type: " + x + " is " + x.getClass().getSimpleName() + " instead of RShareable or RExternalPtr"); - if (x instanceof RShareable) { - return deep == 1 ? ((RShareable) x).deepCopy() : ((RShareable) x).copy(); - } else if (x instanceof RSequence) { - return ((RSequence) x).materializeToShareable(); - } else { - return ((RExternalPtr) x).copy(); + if (tracing) { + RFFIUtils.traceUpCall("Rf_duplicate", x, deep); } + return delegate.Rf_duplicate(x, deep); } @Override public int Rf_anyDuplicated(Object x, int fromLast) { - if (tracer != null) { - tracer.Rf_anyDuplicated(x, fromLast); - } - RAbstractVector vec = (RAbstractVector) x; - if (vec.getLength() == 0) { - return 0; - } else { - return DuplicationHelper.analyze(vec, null, true, fromLast != 0).getIndex(); + if (tracing) { + RFFIUtils.traceUpCall("Rf_anyDuplicated", x, fromLast); } + return delegate.Rf_anyDuplicated(x, fromLast); } @Override public Object PRINTNAME(Object x) { - if (tracer != null) { - tracer.PRINTNAME(x); + if (tracing) { + RFFIUtils.traceUpCall("PRINTNAME", x); } - guaranteeInstanceOf(x, RSymbol.class); - return CharSXPWrapper.create(((RSymbol) x).getName()); + return delegate.PRINTNAME(x); } @Override public Object TAG(Object e) { - if (tracer != null) { - tracer.TAG(e); - } - if (e instanceof RPairList) { - return ((RPairList) e).getTag(); - } else { - guaranteeInstanceOf(e, RExternalPtr.class); - // at the moment, this can only be used to null out the pointer - return ((RExternalPtr) e).getTag(); + if (tracing) { + RFFIUtils.traceUpCall("TAG", e); } + return delegate.TAG(e); } @Override public Object CAR(Object e) { - if (tracer != null) { - tracer.CAR(e); + if (tracing) { + RFFIUtils.traceUpCall("CAR", e); } - return FFIUpCallRootNode.getCallTarget(RFFIUpCallMethod.CAR).call(e); + return delegate.CAR(e); } @Override public Object CDR(Object e) { - if (tracer != null) { - tracer.CDR(e); + if (tracing) { + RFFIUtils.traceUpCall("CDR", e); } - return FFIUpCallRootNode.getCallTarget(RFFIUpCallMethod.CDR).call(e); + return delegate.CDR(e); } @Override public Object CADR(Object e) { - if (tracer != null) { - tracer.CADR(e); + if (tracing) { + RFFIUtils.traceUpCall("CADR", e); } - return FFIUpCallRootNode.getCallTarget(RFFIUpCallMethod.CADR).call(e); + return delegate.CADR(e); } @Override public Object CADDR(Object e) { - if (tracer != null) { - tracer.CADDR(e); + if (tracing) { + RFFIUtils.traceUpCall("CADDR", e); } - return FFIUpCallRootNode.getCallTarget(RFFIUpCallMethod.CADDR).call(e); + return delegate.CADDR(e); } @Override public Object CDDR(Object e) { - if (tracer != null) { - tracer.CDDR(e); + if (tracing) { + RFFIUtils.traceUpCall("CDDR", e); } - return FFIUpCallRootNode.getCallTarget(RFFIUpCallMethod.CDDR).call(e); + return delegate.CDDR(e); } @Override public Object SET_TAG(Object x, Object y) { - if (tracer != null) { - tracer.SET_TAG(x, y); - } - if (x instanceof RPairList) { - ((RPairList) x).setTag(y); - } else { - guaranteeInstanceOf(x, RExternalPtr.class); - // at the moment, this can only be used to null out the pointer - ((RExternalPtr) x).setTag(y); + if (tracing) { + RFFIUtils.traceUpCall("SET_TAG", x, y); } - return y; + return delegate.SET_TAG(x, y); } @Override public Object SETCAR(Object x, Object y) { - if (tracer != null) { - tracer.SETCAR(x, y); + if (tracing) { + RFFIUtils.traceUpCall("SETCAR", x, y); } - guaranteeInstanceOf(x, RPairList.class); - ((RPairList) x).setCar(y); - return y; + return delegate.SETCAR(x, y); } @Override public Object SETCDR(Object x, Object y) { - if (tracer != null) { - tracer.SETCDR(x, y); + if (tracing) { + RFFIUtils.traceUpCall("SETCDR", x, y); } - guaranteeInstanceOf(x, RPairList.class); - ((RPairList) x).setCdr(y); - return y; + return delegate.SETCDR(x, y); } @Override public Object SETCADR(Object x, Object y) { - if (tracer != null) { - tracer.SETCADR(x, y); + if (tracing) { + RFFIUtils.traceUpCall("SETCADR", x); } - SETCAR(CDR(x), y); - return y; + return delegate.SETCADR(x, y); } @Override public Object SYMVALUE(Object x) { - if (tracer != null) { - tracer.SYMVALUE(x); - } - if (!(x instanceof RSymbol)) { - throw RInternalError.shouldNotReachHere(); - } - Object res = REnvironment.baseEnv().get(((RSymbol) x).getName()); - if (res == null) { - return RUnboundValue.instance; - } else { - return res; + if (tracing) { + RFFIUtils.traceUpCall("SYMVALUE", x); } + return delegate.SYMVALUE(x); } @Override public void SET_SYMVALUE(Object x, Object v) { - if (tracer != null) { - tracer.SET_SYMVALUE(x, v); - } - if (!(x instanceof RSymbol)) { - throw RInternalError.shouldNotReachHere(); + if (tracing) { + RFFIUtils.traceUpCall("SET_SYMVALUE", x, v); } - REnvironment.baseEnv().safePut(((RSymbol) x).getName(), v); + delegate.SET_SYMVALUE(x, v); } @Override public int R_BindingIsLocked(Object sym, Object env) { - if (tracer != null) { - tracer.R_BindingIsLocked(sym, env); + if (tracing) { + RFFIUtils.traceUpCall("R_BindingIsLocked", sym, env); } - guaranteeInstanceOf(sym, RSymbol.class); - guaranteeInstanceOf(env, REnvironment.class); - return ((REnvironment) env).bindingIsLocked(((RSymbol) sym).getName()) ? 1 : 0; + return delegate.R_BindingIsLocked(sym, env); } @Override public Object R_FindNamespace(Object name) { - if (tracer != null) { - tracer.R_FindNamespace(name); + if (tracing) { + RFFIUtils.traceUpCall("R_FindNamespace", name); } - Object result = RContext.getInstance().stateREnvironment.getNamespaceRegistry().get(RRuntime.asString(name)); - return result; + return delegate.R_FindNamespace(name); } @Override public Object Rf_eval(Object expr, Object env) { - if (tracer != null) { - tracer.Rf_eval(expr, env); - } - guarantee(env instanceof REnvironment); - Object result; - if (expr instanceof RPromise) { - result = RContext.getRRuntimeASTAccess().forcePromise(null, expr); - } else if (expr instanceof RExpression) { - result = RContext.getEngine().eval((RExpression) expr, (REnvironment) env, RCaller.topLevel); - } else if (expr instanceof RLanguage) { - result = RContext.getEngine().eval((RLanguage) expr, (REnvironment) env, RCaller.topLevel); - } else if (expr instanceof RPairList) { - RPairList l = (RPairList) expr; - RFunction f = (RFunction) l.car(); - Object args = l.cdr(); - if (args == RNull.instance) { - result = RContext.getEngine().evalFunction(f, env == REnvironment.globalEnv() ? null : ((REnvironment) env).getFrame(), RCaller.topLevel, null, new Object[0]); - } else { - RList argsList = ((RPairList) args).toRList(); - result = RContext.getEngine().evalFunction(f, env == REnvironment.globalEnv() ? null : ((REnvironment) env).getFrame(), RCaller.topLevel, argsList.getNames(), - argsList.getDataNonShared()); - } - } else { - // just return value - result = expr; - } - return result; + if (tracing) { + RFFIUtils.traceUpCall("Rf_eval", expr, env); + } + return delegate.Rf_eval(expr, env); } @Override public Object Rf_findfun(Object symbolObj, Object envObj) { - if (tracer != null) { - tracer.Rf_findfun(symbolObj, envObj); - } - guarantee(envObj instanceof REnvironment); - REnvironment env = (REnvironment) envObj; - guarantee(symbolObj instanceof RSymbol); - RSymbol symbol = (RSymbol) symbolObj; - // Works but not remotely efficient - Source source = RSource.fromTextInternal("get(\"" + symbol.getName() + "\", mode=\"function\")", RSource.Internal.RF_FINDFUN); - try { - Object result = RContext.getEngine().parseAndEval(source, env.getFrame(), false); - return result; - } catch (ParseException ex) { - throw RInternalError.shouldNotReachHere(ex); + if (tracing) { + RFFIUtils.traceUpCall("Rf_findfun", symbolObj, envObj); } + return delegate.Rf_findfun(symbolObj, envObj); } @Override public Object Rf_GetOption1(Object tag) { - if (tracer != null) { - tracer.Rf_GetOption1(tag); + if (tracing) { + RFFIUtils.traceUpCall("Rf_GetOption1", tag); } - guarantee(tag instanceof RSymbol); - Object result = RContext.getInstance().stateROptions.getValue(((RSymbol) tag).getName()); - return result; + return delegate.Rf_GetOption1(tag); } @Override public void Rf_gsetVar(Object symbol, Object value, Object rho) { - if (tracer != null) { - tracer.Rf_gsetVar(symbol, value, rho); - } - guarantee(symbol instanceof RSymbol); - REnvironment baseEnv = RContext.getInstance().stateREnvironment.getBaseEnv(); - guarantee(rho == baseEnv); - try { - baseEnv.put(((RSymbol) symbol).getName(), value); - } catch (PutException e) { - e.printStackTrace(); + if (tracing) { + RFFIUtils.traceUpCall("Rf_gsetVar", symbol, value, rho); } + delegate.Rf_gsetVar(symbol, value, rho); } @Override public void DUPLICATE_ATTRIB(Object to, Object from) { - if (tracer != null) { - tracer.DUPLICATE_ATTRIB(to, from); + if (tracing) { + RFFIUtils.traceUpCall("DUPLICATE_ATTRIB", to, from); } - if (from instanceof RAttributable) { - guaranteeInstanceOf(to, RAttributable.class); - DynamicObject attributes = ((RAttributable) from).getAttributes(); - ((RAttributable) to).initAttributes(attributes == null ? null : RAttributesLayout.copy(attributes)); - } - // TODO: copy OBJECT? and S4 attributes + delegate.DUPLICATE_ATTRIB(to, from); } @Override public int R_computeIdentical(Object x, Object y, int flags) { - if (tracer != null) { - tracer.R_computeIdentical(x, y, flags); + if (tracing) { + RFFIUtils.traceUpCall("R_computeIdentical", x, y, flags); } - RFunction indenticalBuiltin = RContext.lookupBuiltin("identical"); - Object res = RContext.getEngine().evalFunction(indenticalBuiltin, null, null, null, x, y, RRuntime.asLogical((!((flags & 1) == 0))), - RRuntime.asLogical((!((flags & 2) == 0))), RRuntime.asLogical((!((flags & 4) == 0))), RRuntime.asLogical((!((flags & 8) == 0))), RRuntime.asLogical((!((flags & 16) == 0)))); - return (int) res; + return delegate.R_computeIdentical(x, y, flags); } @Override public void Rf_copyListMatrix(Object s, Object t, int byrow) { - if (tracer != null) { - tracer.Rf_copyListMatrix(s, t, byrow); + if (tracing) { + RFFIUtils.traceUpCall("Rf_copyListMatrix", t, byrow); } - throw unimplemented(); + delegate.Rf_copyListMatrix(s, t, byrow); } @Override public void Rf_copyMatrix(Object s, Object t, int byrow) { - if (tracer != null) { - tracer.Rf_copyMatrix(s, t, byrow); + if (tracing) { + RFFIUtils.traceUpCall("Rf_copyMatrix", t, byrow); } - throw unimplemented(); + delegate.Rf_copyMatrix(s, t, byrow); } @Override public Object R_tryEval(Object expr, Object env, boolean silent) { - if (tracer != null) { - tracer.R_tryEval(expr, env, silent); - } - Object handlerStack = RErrorHandling.getHandlerStack(); - Object restartStack = RErrorHandling.getRestartStack(); - try { - // TODO handle silent - RErrorHandling.resetStacks(); - Object result = Rf_eval(expr, env); - return result; - } catch (Throwable t) { - return null; - } finally { - RErrorHandling.restoreStacks(handlerStack, restartStack); + if (tracing) { + RFFIUtils.traceUpCall("R_tryEval", expr, env, silent); } + return delegate.R_tryEval(expr, env, silent); } - /** - * Helper function for {@code R_TopLevelExec} which is similar to {@code R_TryEval} except that - * a C function is invoked (in the native layer) instead of an R expression. assert: this is - * ONLY called from R_TopLevelExec prior to calling C function. - */ @Override public Object R_ToplevelExec() { - if (tracer != null) { - tracer.R_ToplevelExec(); + if (tracing) { + RFFIUtils.traceUpCall("R_TopLevelExec"); } - return RErrorHandling.resetAndGetHandlerStacks(); - } - - /** - * Helper function for {@code R_TopLevelExec}, see {@link #R_ToplevelExec()}, called after C - * function returns. - */ - public void R_ToplevelExecRestoreErrorHandlerStacks(Object stacks) { - RErrorHandling.HandlerStacks handlerStacks = guaranteeInstanceOf(stacks, RErrorHandling.HandlerStacks.class); - RErrorHandling.restoreHandlerStacks(handlerStacks); + return delegate.R_ToplevelExec(); } @Override public int RDEBUG(Object x) { - if (tracer != null) { - tracer.RDEBUG(x); - } - REnvironment env = guaranteeInstanceOf(x, REnvironment.class); - if (env instanceof REnvironment.Function) { - REnvironment.Function funcEnv = (REnvironment.Function) env; - RFunction func = RArguments.getFunction(funcEnv.getFrame()); - return RContext.getRRuntimeASTAccess().isDebugged(func) ? 1 : 0; - } else { - return 0; + if (tracing) { + RFFIUtils.traceUpCall("RDEBUG", x); } + return delegate.RDEBUG(x); } @Override public void SET_RDEBUG(Object x, int v) { - if (tracer != null) { - tracer.SET_RDEBUG(x, v); - } - REnvironment env = guaranteeInstanceOf(x, REnvironment.class); - if (env instanceof REnvironment.Function) { - REnvironment.Function funcEnv = (REnvironment.Function) env; - RFunction func = RArguments.getFunction(funcEnv.getFrame()); - if (v == 1) { - RContext.getRRuntimeASTAccess().enableDebug(func, false); - } else { - RContext.getRRuntimeASTAccess().disableDebug(func); - } + if (tracing) { + RFFIUtils.traceUpCall("SET_RDEBUG", x, v); } + delegate.SET_RDEBUG(x, v); } @Override public int RSTEP(Object x) { - if (tracer != null) { - tracer.RSTEP(x); + if (tracing) { + RFFIUtils.traceUpCall("RSTEP", x); } - @SuppressWarnings("unused") - REnvironment env = guaranteeInstanceOf(x, REnvironment.class); - throw RInternalError.unimplemented("RSTEP"); + return delegate.RSTEP(x); } @Override public void SET_RSTEP(Object x, int v) { - if (tracer != null) { - tracer.SET_RSTEP(x, v); + if (tracing) { + RFFIUtils.traceUpCall("SET_RSTEP", x, v); } - @SuppressWarnings("unused") - REnvironment env = guaranteeInstanceOf(x, REnvironment.class); - throw RInternalError.unimplemented("SET_RSTEP"); + delegate.SET_RSTEP(x, v); } @Override public Object ENCLOS(Object x) { - if (tracer != null) { - tracer.ENCLOS(x); - } - REnvironment env = guaranteeInstanceOf(x, REnvironment.class); - Object result = env.getParent(); - if (result == null) { - result = RNull.instance; + if (tracing) { + RFFIUtils.traceUpCall("ENCLOS", x); } - return result; + return delegate.ENCLOS(x); } @Override public Object PRVALUE(Object x) { - if (tracer != null) { - tracer.PRVALUE(x); + if (tracing) { + RFFIUtils.traceUpCall("PRVALUE", x); } - RPromise p = guaranteeInstanceOf(x, RPromise.class); - return p.isEvaluated() ? p.getValue() : RUnboundValue.instance; + return delegate.PRVALUE(x); } @Override public Object R_ParseVector(Object text, int n, Object srcFile) { - if (tracer != null) { - tracer.R_ParseVector(text, n, srcFile); - } - // TODO general case - assert n == 1; - assert srcFile == RNull.instance; - String textString = RRuntime.asString(text); - assert textString != null; - - try { - Source source = RSource.fromTextInternal(textString, RSource.Internal.R_PARSEVECTOR); - RExpression exprs = RContext.getEngine().parse(source); - return new ParseResult(ParseStatus.PARSE_OK.ordinal(), exprs); - } catch (ParseException ex) { - // TODO incomplete - return new ParseResult(ParseStatus.PARSE_ERROR.ordinal(), RNull.instance); + if (tracing) { + RFFIUtils.traceUpCall("R_ParseVector", text, n, srcFile); } + return delegate.R_ParseVector(text, n, srcFile); } @Override public Object R_lsInternal3(Object envArg, int allArg, int sortedArg) { - if (tracer != null) { - tracer.R_lsInternal3(envArg, allArg, sortedArg); + if (tracing) { + RFFIUtils.traceUpCall("R_lsInternal3", envArg, allArg, sortedArg); } - boolean sorted = sortedArg != 0; - boolean all = allArg != 0; - REnvironment env = guaranteeInstanceOf(envArg, REnvironment.class); - return env.ls(all, null, sorted); + return delegate.R_lsInternal3(envArg, allArg, sortedArg); } @Override public String R_HomeDir() { - if (tracer != null) { - tracer.R_HomeDir(); + if (tracing) { + RFFIUtils.traceUpCall("R_HomeDir"); } - return REnvVars.rHome(); + return delegate.R_HomeDir(); } @Override public void R_CleanUp(int sa, int status, int runlast) { - if (tracer != null) { - tracer.R_CleanUp(sa, status, runlast); + if (tracing) { + RFFIUtils.traceUpCall("R_Cleanup", sa, status, runlast); } - RCleanUp.stdCleanUp(SA_TYPE.values()[sa], status, runlast != 0); + delegate.R_CleanUp(sa, status, runlast); } @Override public Object R_GlobalContext() { - if (tracer != null) { - tracer.R_GlobalContext(); - } - Utils.warn("Potential memory leak (global context object)"); - Frame frame = Utils.getActualCurrentFrame(); - if (frame == null) { - return RCaller.topLevel; - } - if (RContext.getInstance().stateInstrumentation.getBrowserState().inBrowser()) { - return RContext.getInstance().stateInstrumentation.getBrowserState().getInBrowserCaller(); + if (tracing) { + RFFIUtils.traceUpCall("R_GlobalContext"); } - RCaller rCaller = RArguments.getCall(frame); - return rCaller == null ? RCaller.topLevel : rCaller; + return delegate.R_GlobalContext(); } @Override public Object R_GlobalEnv() { - if (tracer != null) { - tracer.R_GlobalEnv(); + if (tracing) { + RFFIUtils.traceUpCall("R_GlobalEnv"); } - return RContext.getInstance().stateREnvironment.getGlobalEnv(); + return delegate.R_GlobalEnv(); } @Override public Object R_BaseEnv() { - if (tracer != null) { - tracer.R_BaseEnv(); + if (tracing) { + RFFIUtils.traceUpCall("R_BaseEnv"); } - return RContext.getInstance().stateREnvironment.getBaseEnv(); + return delegate.R_BaseEnv(); } @Override public Object R_BaseNamespace() { - if (tracer != null) { - tracer.R_BaseNamespace(); + if (tracing) { + RFFIUtils.traceUpCall("R_BaseNamespace"); } - return RContext.getInstance().stateREnvironment.getBaseNamespace(); + return delegate.R_BaseNamespace(); } @Override public Object R_NamespaceRegistry() { - if (tracer != null) { - tracer.R_NamespaceRegistry(); + if (tracing) { + RFFIUtils.traceUpCall("R_NamespaceRegistry"); } - return RContext.getInstance().stateREnvironment.getNamespaceRegistry(); + return delegate.R_NamespaceRegistry(); } @Override public int R_Interactive() { - if (tracer != null) { - tracer.R_Interactive(); + if (tracing) { + RFFIUtils.traceUpCall("isInteractive"); } - return RContext.getInstance().isInteractive() ? 1 : 0; + return delegate.R_Interactive(); } @Override public int IS_S4_OBJECT(Object x) { - if (tracer != null) { - tracer.IS_S4_OBJECT(x); + if (tracing) { + RFFIUtils.traceUpCall("isS4Object"); } - return x instanceof RS4Object ? 1 : 0; + return delegate.IS_S4_OBJECT(x); } @Override public void Rprintf(Object message) { - if (tracer != null) { - tracer.Rprintf(message); + if (tracing) { + RFFIUtils.traceUpCall("Rprintf", message); } - RContext.getInstance().getConsoleHandler().print((String) message); + delegate.Rprintf(message); } @Override public void GetRNGstate() { - if (tracer != null) { - tracer.GetRNGstate(); + if (tracing) { + RFFIUtils.traceUpCall("GetRNGstate"); } - RRNG.getRNGState(); + delegate.GetRNGstate(); } @Override public void PutRNGstate() { - if (tracer != null) { - tracer.PutRNGstate(); + if (tracing) { + RFFIUtils.traceUpCall("PutRNGstate"); } - RRNG.putRNGState(); + delegate.PutRNGstate(); } @Override public double unif_rand() { - if (tracer != null) { - tracer.unif_rand(); + if (tracing) { + RFFIUtils.traceUpCall("unif_rand"); } - return RRNG.unifRand(); + return delegate.unif_rand(); } - // Checkstyle: stop method name check - @Override public Object R_getGlobalFunctionContext() { - if (tracer != null) { - tracer.R_getGlobalFunctionContext(); + if (tracing) { + RFFIUtils.traceUpCall("R_getGlobalFunctionContext"); } - Utils.warn("Potential memory leak (global function context object)"); - Frame frame = Utils.getActualCurrentFrame(); - if (frame == null) { - return RNull.instance; - } - RCaller currentCaller = RArguments.getCall(frame); - while (currentCaller != null) { - if (!currentCaller.isPromise() && currentCaller.isValidCaller() && currentCaller != RContext.getInstance().stateInstrumentation.getBrowserState().getInBrowserCaller()) { - break; - } - currentCaller = currentCaller.getParent(); - } - return currentCaller == null || currentCaller == RCaller.topLevel ? RNull.instance : currentCaller; + return delegate.R_getGlobalFunctionContext(); } @Override public Object R_getParentFunctionContext(Object c) { - if (tracer != null) { - tracer.R_getParentFunctionContext(c); - } - Utils.warn("Potential memory leak (parent function context object)"); - RCaller currentCaller = guaranteeInstanceOf(c, RCaller.class); - while (true) { - currentCaller = currentCaller.getParent(); - if (currentCaller == null || - (!currentCaller.isPromise() && currentCaller.isValidCaller() && currentCaller != RContext.getInstance().stateInstrumentation.getBrowserState().getInBrowserCaller())) { - break; - } + if (tracing) { + RFFIUtils.traceUpCall("R_getParentFunctionContext"); } - return currentCaller == null || currentCaller == RCaller.topLevel ? RNull.instance : currentCaller; + return delegate.R_getParentFunctionContext(c); } @Override public Object R_getContextEnv(Object c) { - if (tracer != null) { - tracer.R_getContextEnv(c); - } - RCaller rCaller = guaranteeInstanceOf(c, RCaller.class); - if (rCaller == RCaller.topLevel) { - return RContext.getInstance().stateREnvironment.getGlobalEnv(); - } - Frame frame = Utils.getActualCurrentFrame(); - if (RArguments.getCall(frame) == rCaller) { - return REnvironment.frameToEnvironment(frame.materialize()); - } else { - Object result = Utils.iterateRFrames(FrameAccess.READ_ONLY, new Function<Frame, Object>() { - - @Override - public Object apply(Frame f) { - RCaller currentCaller = RArguments.getCall(f); - if (currentCaller == rCaller) { - return REnvironment.frameToEnvironment(f.materialize()); - } else { - return null; - } - } - }); - return result; + if (tracing) { + RFFIUtils.traceUpCall("R_getContextEnv", c); } + return delegate.R_getContextEnv(c); } @Override public Object R_getContextFun(Object c) { - if (tracer != null) { - tracer.R_getContextFun(c); - } - RCaller rCaller = guaranteeInstanceOf(c, RCaller.class); - if (rCaller == RCaller.topLevel) { - return RNull.instance; - } - Frame frame = Utils.getActualCurrentFrame(); - if (RArguments.getCall(frame) == rCaller) { - return RArguments.getFunction(frame); - } else { - Object result = Utils.iterateRFrames(FrameAccess.READ_ONLY, new Function<Frame, Object>() { - - @Override - public Object apply(Frame f) { - RCaller currentCaller = RArguments.getCall(f); - if (currentCaller == rCaller) { - return RArguments.getFunction(f); - } else { - return null; - } - } - }); - return result; + if (tracing) { + RFFIUtils.traceUpCall("R_getContextFun", c); } + return delegate.R_getContextFun(c); } @Override public Object R_getContextCall(Object c) { - if (tracer != null) { - tracer.R_getContextCall(c); + if (tracing) { + RFFIUtils.traceUpCall("R_getContextCall", c); } - RCaller rCaller = guaranteeInstanceOf(c, RCaller.class); - if (rCaller == RCaller.topLevel) { - return RNull.instance; - } - return RContext.getRRuntimeASTAccess().getSyntaxCaller(rCaller); + return delegate.R_getContextCall(c); } @Override public Object R_getContextSrcRef(Object c) { - if (tracer != null) { - tracer.R_getContextSrcRef(c); - } - Object o = R_getContextFun(c); - if (!(o instanceof RFunction)) { - return RNull.instance; - } else { - RFunction f = (RFunction) o; - SourceSection ss = f.getRootNode().getSourceSection(); - String path = RSource.getPath(ss.getSource()); - // TODO: is it OK to pass "" if path is null? - return RSrcref.createLloc(ss, path == null ? "" : path); + if (tracing) { + RFFIUtils.traceUpCall("R_getContextSrcRef", c); } + return delegate.R_getContextSrcRef(c); } @Override public int R_insideBrowser() { - if (tracer != null) { - tracer.R_insideBrowser(); + if (tracing) { + RFFIUtils.traceUpCall("R_insideBrowser"); } - return RContext.getInstance().stateInstrumentation.getBrowserState().inBrowser() ? 1 : 0; + return delegate.R_insideBrowser(); } @Override public int R_isGlobal(Object c) { - if (tracer != null) { - tracer.R_isGlobal(c); + if (tracing) { + RFFIUtils.traceUpCall("R_isGlobal", c); } - RCaller rCaller = guaranteeInstanceOf(c, RCaller.class); - - return rCaller == RCaller.topLevel ? 1 : 0; + return delegate.R_isGlobal(c); } @Override public int R_isEqual(Object x, Object y) { - if (tracer != null) { - tracer.R_isEqual(x, y); + if (tracing) { + RFFIUtils.traceUpCall("isEqual", x, y); } - return x == y ? 1 : 0; + return delegate.R_isEqual(x, y); } @Override - @TruffleBoundary public Object Rf_classgets(Object x, Object y) { - if (tracer != null) { - tracer.Rf_classgets(x, y); + if (tracing) { + RFFIUtils.traceUpCall("Rf_classgets", x, y); } - RAbstractVector vector = guaranteeInstanceOf(x, RAbstractVector.class); - vector.setClassAttr(guaranteeInstanceOf(y, RStringVector.class)); - return RNull.instance; + return delegate.Rf_classgets(x, y); } @Override public RExternalPtr R_MakeExternalPtr(long addr, Object tag, Object prot) { - if (tracer != null) { - tracer.R_MakeExternalPtr(addr, tag, prot); + if (tracing) { + RFFIUtils.traceUpCall("R_MakeExternalPtr", addr, tag, prot); } - return RDataFactory.createExternalPtr(new SymbolHandle(addr), tag, prot); + return delegate.R_MakeExternalPtr(addr, tag, prot); } @Override public long R_ExternalPtrAddr(Object x) { - if (tracer != null) { - tracer.R_ExternalPtrAddr(x); + if (tracing) { + RFFIUtils.traceUpCall("R_ExternalPtrAddr", x); } - RExternalPtr p = guaranteeInstanceOf(x, RExternalPtr.class); - return p.getAddr().asAddress(); + return delegate.R_ExternalPtrAddr(x); } @Override public Object R_ExternalPtrTag(Object x) { - if (tracer != null) { - tracer.R_ExternalPtrTag(x); + if (tracing) { + RFFIUtils.traceUpCall("R_ExternalPtrTag", x); } - RExternalPtr p = guaranteeInstanceOf(x, RExternalPtr.class); - return p.getTag(); + return delegate.R_ExternalPtrTag(x); } @Override public Object R_ExternalPtrProt(Object x) { - if (tracer != null) { - tracer.R_ExternalPtrProt(x); + if (tracing) { + RFFIUtils.traceUpCall("R_ExternalPtrProt", x); } - RExternalPtr p = guaranteeInstanceOf(x, RExternalPtr.class); - return p.getProt(); + return delegate.R_ExternalPtrProt(x); } @Override public void R_SetExternalPtrAddr(Object x, long addr) { - if (tracer != null) { - tracer.R_SetExternalPtrAddr(x, addr); + if (tracing) { + RFFIUtils.traceUpCall("R_SetExternalPtrAddr", x); } - RExternalPtr p = guaranteeInstanceOf(x, RExternalPtr.class); - p.setAddr(new SymbolHandle(addr)); + delegate.R_SetExternalPtrAddr(x, addr); } @Override public void R_SetExternalPtrTag(Object x, Object tag) { - if (tracer != null) { - tracer.R_SetExternalPtrTag(x, tag); + if (tracing) { + RFFIUtils.traceUpCall("R_SetExternalPtrTag", x); } - RExternalPtr p = guaranteeInstanceOf(x, RExternalPtr.class); - p.setTag(tag); + delegate.R_SetExternalPtrTag(x, tag); } @Override public void R_SetExternalPtrProt(Object x, Object prot) { - if (tracer != null) { - tracer.R_SetExternalPtrProt(x, prot); + if (tracing) { + RFFIUtils.traceUpCall("R_ExternalPtrProt", x); } - RExternalPtr p = guaranteeInstanceOf(x, RExternalPtr.class); - p.setProt(prot); + delegate.R_SetExternalPtrProt(x, prot); } @Override public REnvironment R_NewHashedEnv(REnvironment parent, int initialSize) { - if (tracer != null) { - tracer.R_NewHashedEnv(parent, initialSize); + if (tracing) { + RFFIUtils.traceUpCall("R_NewHashedEnv", parent, initialSize); } - REnvironment env = RDataFactory.createNewEnv(REnvironment.UNNAMED, true, initialSize); - RArguments.initializeEnclosingFrame(env.getFrame(), parent.getFrame()); - return env; + return delegate.R_NewHashedEnv(parent, initialSize); } // Implementation specific support + /** + * Helper function for {@code R_TopLevelExec}, see {@link #R_ToplevelExec()}, called after C + * function returns. + */ + @SuppressWarnings("static-method") + public void R_ToplevelExecRestoreErrorHandlerStacks(Object stacks) { + RErrorHandling.HandlerStacks handlerStacks = guaranteeInstanceOf(stacks, RErrorHandling.HandlerStacks.class); + RErrorHandling.restoreHandlerStacks(handlerStacks); + } + /** * Called to possibly update the "complete" status on {@code x}. N.B. {@code x} may not be an * object with a concrete {@code setComplete} method, e.g. see {@link #INTEGER(Object)}. */ + @SuppressWarnings("static-method") public void setComplete(Object x, boolean complete) { // only care about concrete vectors if (x instanceof RVector) { @@ -1506,6 +954,7 @@ public class UpCallsRFFIImpl implements UpCallsRFFI { /** * Called when a {@link CharSXPWrapper} is expected and not found. */ + @SuppressWarnings("static-method") public void logNotCharSXPWrapper(Object x) { System.out.println("object " + x); System.out.println("class " + x.getClass()); diff --git a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_Call.java b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_Call.java index d7154d5a2c..b766682261 100644 --- a/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_Call.java +++ b/com.oracle.truffle.r.runtime.ffi/src/com/oracle/truffle/r/runtime/ffi/jni/JNI_Call.java @@ -27,8 +27,9 @@ import static com.oracle.truffle.r.nodes.ffi.RFFIUtils.traceDownCallReturn; import static com.oracle.truffle.r.nodes.ffi.RFFIUtils.traceEnabled; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.r.nodes.ffi.UpCallsRFFIImpl; +import com.oracle.truffle.r.nodes.ffi.JavaUpCallsRFFIImpl; import com.oracle.truffle.r.nodes.ffi.RFFIUtils; +import com.oracle.truffle.r.nodes.ffi.UpCallsRFFIImpl; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.ffi.CallRFFI; import com.oracle.truffle.r.runtime.ffi.NativeCallInfo; @@ -128,7 +129,7 @@ public class JNI_Call implements CallRFFI { traceDownCall("initialize"); } try { - initialize(new UpCallsRFFIImpl(), RFFIVariables.initialize()); + initialize(new UpCallsRFFIImpl(new JavaUpCallsRFFIImpl()), RFFIVariables.initialize()); } finally { if (traceEnabled()) { traceDownCallReturn("initialize", null); -- GitLab