diff --git a/ci.hocon b/ci.hocon index 7007030a80ffe1a6200d7ba0e5786c41e5a0bbb7..c2e5265dc7963abcab16d4213ac198b3a96c1a15 100644 --- a/ci.hocon +++ b/ci.hocon @@ -13,6 +13,7 @@ java8Downloads : { downloads : { EXTRA_JAVA_HOMES : { pathlist :[ ${java7} + ${java9} ]} JAVA_HOME : ${java8} } diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java index 52dd4f23b3776d046974c127c0aeb4970376fb79..371e16066c0e012dc4f5fc198061ad7b30226b0b 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java @@ -51,7 +51,6 @@ import com.oracle.truffle.r.launcher.StartupTiming; import com.oracle.truffle.r.library.graphics.RGraphics; import com.oracle.truffle.r.nodes.RASTBuilder; import com.oracle.truffle.r.nodes.RASTUtils; -import com.oracle.truffle.r.nodes.access.ConstantNode; import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinPackages; import com.oracle.truffle.r.nodes.control.BreakException; @@ -82,18 +81,16 @@ import com.oracle.truffle.r.runtime.RootWithBody; import com.oracle.truffle.r.runtime.ThreadTimings; import com.oracle.truffle.r.runtime.Utils; import com.oracle.truffle.r.runtime.Utils.DebugExitException; -import com.oracle.truffle.r.runtime.VirtualEvalFrame; import com.oracle.truffle.r.runtime.context.Engine; import com.oracle.truffle.r.runtime.context.RContext; -import com.oracle.truffle.r.runtime.data.Closure; import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; import com.oracle.truffle.r.runtime.data.RAttributable; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RExpression; import com.oracle.truffle.r.runtime.data.RFunction; -import com.oracle.truffle.r.runtime.data.RLanguage; import com.oracle.truffle.r.runtime.data.RMissing; 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.RSymbol; import com.oracle.truffle.r.runtime.data.RTypedValue; @@ -102,7 +99,6 @@ import com.oracle.truffle.r.runtime.env.REnvironment; import com.oracle.truffle.r.runtime.interop.R2Foreign; import com.oracle.truffle.r.runtime.interop.R2ForeignNodeGen; import com.oracle.truffle.r.runtime.nodes.RNode; -import com.oracle.truffle.r.runtime.nodes.RSyntaxElement; import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; /** @@ -434,8 +430,8 @@ final class REngine implements Engine, Engine.Timings { if (result == null) { throw RError.error(RError.SHOW_CALLER, RError.Message.ARGUMENT_MISSING, identifier); } - } else if (obj instanceof RLanguage) { - result = evalNode(((RLanguage) obj).getRep().asRSyntaxNode(), envir, caller); + } else if ((obj instanceof RPairList && ((RPairList) obj).isLanguage())) { + result = eval((RPairList) obj, envir, caller); } else { result = obj; } @@ -445,7 +441,8 @@ final class REngine implements Engine, Engine.Timings { @Override @TruffleBoundary - public Object eval(RLanguage expr, REnvironment envir, RCaller caller) { + public Object eval(RPairList expr, REnvironment envir, RCaller caller) { + assert expr.isLanguage(); return expr.getClosure().eval(envir, caller); } @@ -455,8 +452,8 @@ final class REngine implements Engine, Engine.Timings { Object result = null; for (int i = 0; i < expr.getLength(); i++) { result = expr.getDataAt(i); - if (result instanceof RLanguage) { - RLanguage lang = (RLanguage) result; + if ((result instanceof RPairList && ((RPairList) result).isLanguage())) { + RPairList lang = (RPairList) result; result = eval(lang, frame); } } @@ -464,15 +461,10 @@ final class REngine implements Engine, Engine.Timings { } @Override - public Object eval(RLanguage expr, MaterializedFrame frame) { + public Object eval(RPairList expr, MaterializedFrame frame) { + assert expr.isLanguage(); CompilerAsserts.neverPartOfCompilation(); - RNode n = (RNode) expr.getRep(); - // TODO perhaps this ought to be being checked earlier - if (n instanceof ConstantNode) { - return ((ConstantNode) n).getValue(); - } - Closure closure = expr.getClosure(); - return closure.eval(frame); + return expr.getClosure().eval(frame); } @Override @@ -505,31 +497,6 @@ final class REngine implements Engine, Engine.Timings { return CallRFunctionNode.executeSlowpath(func, rCaller, actualFrame, newArgs, reorderedArgs.getSignature(), null); } - private Object evalNode(RSyntaxElement exprRep, REnvironment envir, RCaller caller) { - // we need to copy the node, otherwise it (and its children) will specialized to a specific - // frame descriptor and will fail on subsequent re-executions - RSyntaxNode n = RContext.getASTBuilder().process(exprRep); - RootCallTarget callTarget = doMakeCallTarget(n.asRNode(), RSource.Internal.EVAL_WRAPPER.string, false, false); - return evalTarget(callTarget, caller, envir); - } - - /** - * This is tricky because the {@link Frame} "f" associated with {@code envir} has been - * materialized so we can't evaluate in it directly. Instead we create a new - * {@link VirtualEvalFrame} that behaves like "f" (delegates most calls to it) but has a - * slightly changed arguments array. - * - * N.B. The implementation should do its utmost to avoid calling this method as it is inherently - * inefficient. In particular, in the case where a {@link VirtualFrame} is available, then the - * {@code eval} methods that take such a {@link VirtualFrame} should be used in preference. - */ - private static Object evalTarget(RootCallTarget callTarget, RCaller call, REnvironment envir) { - // Here we create fake frame that wraps the original frame's context and has an only - // slightly changed arguments array (function and callSrc). - MaterializedFrame vFrame = VirtualEvalFrame.create(envir.getFrame(), (RFunction) null, call); - return callTarget.call(vFrame); - } - @Override public RootCallTarget makePromiseCallTarget(RNode body, String funName) { return doMakeCallTarget(body, funName, false, false); diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RRuntimeASTAccessImpl.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RRuntimeASTAccessImpl.java index 1e8fa828c18417547e78c25d7639c52e43615738..ba76e4063f61dd90997916bd5526997cb46a21fd 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RRuntimeASTAccessImpl.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/RRuntimeASTAccessImpl.java @@ -28,22 +28,17 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.frame.FrameInstance.FrameAccess; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.RootNode; -import com.oracle.truffle.api.object.DynamicObject; import com.oracle.truffle.r.launcher.RCommand; import com.oracle.truffle.r.launcher.RscriptCommand; import com.oracle.truffle.r.nodes.RASTUtils; import com.oracle.truffle.r.nodes.RRootNode; -import com.oracle.truffle.r.nodes.access.ConstantNode; import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinRootNode; @@ -57,19 +52,14 @@ import com.oracle.truffle.r.nodes.control.IfNode; import com.oracle.truffle.r.nodes.control.ReplacementDispatchNode; import com.oracle.truffle.r.nodes.function.ClassHierarchyNode; import com.oracle.truffle.r.nodes.function.FunctionDefinitionNode; -import com.oracle.truffle.r.nodes.function.FunctionExpressionNode; -import com.oracle.truffle.r.nodes.function.RCallBaseNode; import com.oracle.truffle.r.nodes.function.RCallNode; import com.oracle.truffle.r.nodes.instrumentation.RInstrumentation; -import com.oracle.truffle.r.runtime.Arguments; import com.oracle.truffle.r.runtime.ArgumentsSignature; import com.oracle.truffle.r.runtime.RArguments; import com.oracle.truffle.r.runtime.RCaller; import com.oracle.truffle.r.runtime.RDeparse; import com.oracle.truffle.r.runtime.RError; -import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.RRuntimeASTAccess; -import com.oracle.truffle.r.runtime.RSrcref; import com.oracle.truffle.r.runtime.RootWithBody; import com.oracle.truffle.r.runtime.Utils; import com.oracle.truffle.r.runtime.context.Engine; @@ -77,301 +67,30 @@ import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.context.TruffleRLanguage; import com.oracle.truffle.r.runtime.data.Closure; 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.RDataFactory; import com.oracle.truffle.r.runtime.data.RFunction; -import com.oracle.truffle.r.runtime.data.RLanguage; -import com.oracle.truffle.r.runtime.data.RList; 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.RStringVector; -import com.oracle.truffle.r.runtime.data.RSymbol; -import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; import com.oracle.truffle.r.runtime.nodes.InternalRSyntaxNodeChildren; import com.oracle.truffle.r.runtime.nodes.RBaseNode; -import com.oracle.truffle.r.runtime.nodes.RCodeBuilder; -import com.oracle.truffle.r.runtime.nodes.RCodeBuilder.Argument; import com.oracle.truffle.r.runtime.nodes.RInstrumentableNode; import com.oracle.truffle.r.runtime.nodes.RNode; -import com.oracle.truffle.r.runtime.nodes.RSourceSectionNode; -import com.oracle.truffle.r.runtime.nodes.RSyntaxCall; import com.oracle.truffle.r.runtime.nodes.RSyntaxElement; -import com.oracle.truffle.r.runtime.nodes.RSyntaxFunction; -import com.oracle.truffle.r.runtime.nodes.RSyntaxLookup; import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; /** - * Implementation of {@link RRuntimeASTAccess}. - * - * A note on the "list" aspects of {@link RLanguage}, specified by {@link RAbstractContainer}. In - * GnuR a language element (LANGSXP) is represented as a pairlist, so the length of the language - * element is defined to be the length of the pairlist. The goal of this implementation is to - * emulate the behavior of GnuR by walking the AST. - * - * The nodes we are interested in are {@link ReadVariableNode} (symbols), {@link ConstantNode} - * (constants) and {@link RCallNode} etc., (calls). However, the nodes that are not (but should be) - * represented as calls, e.g. {@link IfNode} have to be handled specially. - * - * Since the AST is a final field (and we assert) immutable in its syntactic essence, we can cache - * information such as the length here. A Truffle AST has many nodes that are not part of the - * syntactic essence and we ignore these. - * - * This implementation necessarily has to use a lot of {@code instanceof} checks on the node class. - * However, it is not important enough to warrant refactoring as an {@link RNode} method, (cf - * deparse). TODO reconsider this. - * - * Some examples: - * - * <pre> - * length(quote(f()) == 1 - * length(quote(f(a)) == 2 - * length(quote(a + b)) == 3 - * length(quote(a + f(b))) == 3 - * </pre> - * - * Note the last example in particular which shows that the length is not computed from the - * flattened tree. Rather indexing the third element would produce another language element of - * length 2. + * This class contains functions that need access to actual implementation classes but which are + * used in places where there is not dependency on the node project. */ class RRuntimeASTAccessImpl implements RRuntimeASTAccess { - @TruffleBoundary - @Override - public RLanguage.RepType getRepType(RLanguage rl) { - RSyntaxElement s = RASTUtils.unwrap(rl.getRep()).asRSyntaxNode(); - - if (s instanceof RSyntaxCall) { - return RLanguage.RepType.CALL; - } else if (s instanceof RSyntaxFunction) { - return RLanguage.RepType.FUNCTION; - } else { - throw RInternalError.shouldNotReachHere("unexpected type: " + s.getClass()); - } - } - - @TruffleBoundary - @Override - public int getLength(RLanguage rl) { - RSyntaxElement s = RASTUtils.unwrap(rl.getRep()).asRSyntaxNode(); - - if (s instanceof RSyntaxCall) { - return ((RSyntaxCall) s).getSyntaxSignature().getLength() + 1; - } else if (s instanceof RSyntaxFunction) { - return 4; - } else { - /* - * We do not expect RSyntaxConstant and RSyntaxLookup here (see getDataAtAsObject). - */ - throw RInternalError.shouldNotReachHere("unexpected type: " + s.getClass()); - } - } - - @TruffleBoundary - @Override - public Object getDataAtAsObject(RLanguage rl, final int index) { - // index has already been range checked based on getLength - RSyntaxElement s = RASTUtils.unwrap(rl.getRep()).asRSyntaxNode(); - - RSyntaxElement result; - if (s instanceof RSyntaxCall) { - RSyntaxCall call = (RSyntaxCall) s; - if (index == 0) { - result = call.getSyntaxLHS(); - } else { - result = call.getSyntaxArguments()[index - 1]; - if (result == null) { - result = RSyntaxLookup.createDummyLookup(RSyntaxNode.LAZY_DEPARSE, "", false); - } - } - } else if (s instanceof RSyntaxFunction) { - switch (index) { - case 0: - result = RSyntaxLookup.createDummyLookup(null, "function", true); - break; - case 1: - ArgumentsSignature sig = ((RSyntaxFunction) s).getSyntaxSignature(); - RSyntaxElement[] defaults = ((RSyntaxFunction) s).getSyntaxArgumentDefaults(); - - Object list = RNull.instance; - for (int i = sig.getLength() - 1; i >= 0; i--) { - list = RDataFactory.createPairList(defaults[i] == null ? RSymbol.MISSING : RASTUtils.createLanguageElement(defaults[i]), list, - RDataFactory.createSymbolInterned(sig.getName(i))); - } - return list; - case 2: - result = ((RSyntaxFunction) s).getSyntaxBody(); - break; - case 3: - // srcref - return RSrcref.createLloc(s.getLazySourceSection()); - default: - throw RInternalError.shouldNotReachHere(); - } - } else { - /* - * We do not expect RSyntaxConstant and RSyntaxLookup here: RSyntaxConstant should have - * been converted to the constant value, and RSyntaxLookup should have been converted to - * an RSymbol (see below). - */ - throw RInternalError.shouldNotReachHere("unexpected type: " + s.getClass()); - } - - /* - * Constants and lookups are converted to their intrinsic value: - */ - return RASTUtils.createLanguageElement(result); - } - - @Override - @TruffleBoundary - public Object createLanguageFromList(RList list, RLanguage.RepType repType) { - int length = list.getLength(); - if (length == 0) { - return RNull.instance; - } else if (repType == RLanguage.RepType.CALL) { - RStringVector formals = list.getNames(); - - List<RCodeBuilder.Argument<RSyntaxNode>> argList = new ArrayList<>(length - 1); - for (int i = 1; i < length; i++) { - String formal = formals == null ? null : formals.getDataAt(i); - RSyntaxNode syntaxArg = (RSyntaxNode) unwrapToRNode(list.getDataAtAsObject(i), false); - if (formal != null) { - argList.add(RCodeBuilder.argument(RSourceSectionNode.LAZY_DEPARSE, formal, syntaxArg)); - } else { - argList.add(RCodeBuilder.argument(syntaxArg)); - } - } - - RNode fn = unwrapToRNode(list.getDataAtAsObject(0), true); - RSyntaxNode call = RContext.getASTBuilder().call(RSourceSectionNode.LAZY_DEPARSE, fn.asRSyntaxNode(), argList); - RLanguage result = RDataFactory.createLanguage(Closure.createLanguageClosure(call.asRNode())); - if (formals != null && formals.getLength() > 0 && formals.getDataAt(0).length() > 0) { - result.setCallLHSName(formals.getDataAt(0)); - } - return addAttributes(result, list); - } else if (repType == RLanguage.RepType.FUNCTION) { - RAbstractContainer argsList = (RAbstractContainer) list.getDataAt(1); - RSyntaxNode body = (RSyntaxNode) unwrapToRNode(list.getDataAt(2), false); - List<Argument<RSyntaxNode>> resArgs = new LinkedList<>(); - RStringVector argsNames = argsList.getNames(); - for (int i = 0; i < argsList.getLength(); i++) { - String argName = argsNames == null ? null : argsNames.getDataAt(i); - Object argVal = argsList.getDataAtAsObject(i); - Argument<RSyntaxNode> arg = RCodeBuilder.argument(RSyntaxNode.LAZY_DEPARSE, argName, argVal == RSymbol.MISSING ? null : (RSyntaxNode) unwrapToRNode(argVal, false)); - resArgs.add(arg); - } - RootCallTarget rootCallTarget = RContext.getASTBuilder().rootFunction(RContext.getInstance().getLanguage(), RSyntaxNode.LAZY_DEPARSE, resArgs, body, null); - FunctionExpressionNode fnExprNode = FunctionExpressionNode.create(RSyntaxNode.LAZY_DEPARSE, rootCallTarget); - RLanguage result = RDataFactory.createLanguage(Closure.createLanguageClosure(fnExprNode)); - return addAttributes(result, list); - } else { - throw RInternalError.shouldNotReachHere("unexpected type"); - } - } - - private static Object addAttributes(RAttributable result, RList list) { - DynamicObject attrs = list.getAttributes(); - if (attrs != null && !attrs.isEmpty()) { - result.initAttributes(RAttributesLayout.copy(attrs)); - } - return result; - } - - private RNode unwrapToRNode(Object objArg, boolean functionLookup) { - Object obj = objArg; - // obj is RSymbol or a primitive value. - // A symbol needs to be converted back to a ReadVariableNode - if (obj instanceof RLanguage) { - return (RNode) RASTUtils.unwrap(((RLanguage) obj).getRep()); - } else if (obj instanceof RSymbol) { - return RContext.getASTBuilder().lookup(RSyntaxNode.LAZY_DEPARSE, ((RSymbol) obj).getName(), functionLookup).asRNode(); - } else if (obj instanceof RPromise) { - // Evaluate promise and return the result as constant. - return ConstantNode.create(forcePromise("unwrapToRNode", objArg)); - } else { - return ConstantNode.create(obj); - } - } - @Override - public RList asList(RLanguage rl) { - Object[] data = new Object[getLength(rl)]; - for (int i = 0; i < data.length; i++) { - data[i] = getDataAtAsObject(rl, i); - } - RStringVector names = getNames(rl); - if (names == null) { - return RDataFactory.createList(data); - } else { - return RDataFactory.createList(data, names); - } - } - - @Override - @TruffleBoundary - public RStringVector getNames(RLanguage rl) { - RBaseNode node = rl.getRep(); - if (node instanceof RCallNode) { - RCallNode call = (RCallNode) node; - /* - * If the function or any argument has a name, then all arguments (and the function) are - * given names, with unnamed arguments getting "". However, if no arguments have names, - * the result is NULL (null) - */ - boolean hasName = false; - String functionName = ""; - if (rl.getCallLHSName() != null) { - hasName = true; - functionName = rl.getCallLHSName(); - } - ArgumentsSignature sig = call.getSyntaxSignature(); - if (!hasName) { - for (int i = 0; i < sig.getLength(); i++) { - if (sig.getName(i) != null) { - hasName = true; - break; - } - } - } - if (!hasName) { - return null; - } - String[] data = new String[sig.getLength() + 1]; - data[0] = functionName; // function - for (int i = 0; i < sig.getLength(); i++) { - String name = sig.getName(i); - data[i + 1] = name == null ? "" : name; - } - return RDataFactory.createStringVector(data, RDataFactory.COMPLETE_VECTOR); - } else { - return null; - } - } - - @Override - @TruffleBoundary - public void setNames(RLanguage rl, RStringVector names) { - RNode node = (RNode) rl.getRep(); - if (node instanceof RCallBaseNode) { - RCallBaseNode call = (RCallBaseNode) node; - Arguments<RSyntaxNode> args = call.getArguments(); - ArgumentsSignature sig = args.getSignature(); - String[] newNames = new String[sig.getLength()]; - int argNamesLength = names.getLength() - 1; - if (argNamesLength > sig.getLength()) { - throw RError.error(RError.SHOW_CALLER2, RError.Message.ATTRIBUTE_VECTOR_SAME_LENGTH, "names", names.getLength(), sig.getLength() + 1); - } - for (int i = 0, j = 1; i < sig.getLength() && j <= argNamesLength; i++, j++) { - newNames[i] = names.getDataAt(j); - } - // copying is already handled by RShareable - RCallNode newCall = RCallNode.createCall(RSyntaxNode.INTERNAL, ((RCallBaseNode) node).getFunction(), ArgumentsSignature.get(newNames), args.getArguments()); - rl.setClosure(Closure.createLanguageClosure(newCall)); - } else { - throw RInternalError.shouldNotReachHere(); - } + public Object createLanguageElement(RSyntaxElement element) { + return RASTUtils.createLanguageElement(element); } @Override @@ -415,7 +134,7 @@ class RRuntimeASTAccessImpl implements RRuntimeASTAccess { } @Override - public RLanguage getSyntaxCaller(RCaller rl) { + public RPairList getSyntaxCaller(RCaller rl) { RCaller call = rl; while (call.isPromise()) { call = call.getParent(); @@ -442,10 +161,11 @@ class RRuntimeASTAccessImpl implements RRuntimeASTAccess { } @Override - public String getCallerSource(RLanguage rl) { + public String getCallerSource(RPairList rl) { + assert rl.isLanguage(); // This checks for the specific structure of replacements - RLanguage replacement = ReplacementDispatchNode.getRLanguage(rl); - RLanguage elem = replacement == null ? rl : replacement; + RPairList replacement = ReplacementDispatchNode.getRLanguage(rl); + RPairList elem = replacement == null ? rl : replacement; String string = RDeparse.deparse(elem, RDeparse.DEFAULT_CUTOFF, true, RDeparse.KEEPINTEGER, -1); return string.split("\n")[0]; } @@ -482,11 +202,6 @@ class RRuntimeASTAccessImpl implements RRuntimeASTAccess { } } - @Override - public RSyntaxFunction getSyntaxFunction(RFunction f) { - return (FunctionDefinitionNode) f.getTarget().getRootNode(); - } - private Object findCallerFromFrame(Frame frame) { if (frame != null && RArguments.isRFrame(frame)) { RCaller caller = RArguments.getCall(frame); diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ListMR.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ListMR.java index 17611a0c03a3d658dd229a03d5ae8dcd4802f329..d5fb9c194dd7275331aa0fb98f77dea85d495623 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ListMR.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/ListMR.java @@ -338,7 +338,7 @@ public class ListMR { @Cached("createKeyInfoNode()") ListKeyInfoImplNode keyInfo) { int info = keyInfo.execute(receiver, idx); if (unknownIdentifier.profile(!KeyInfo.isExisting(info))) { - throw UnknownIdentifierException.raise("" + idx); + throw UnknownIdentifierException.raise(String.valueOf(idx)); } initExtractNode(); // idx + 1 R is indexing from 1 @@ -355,7 +355,7 @@ public class ListMR { // let's be consistent at this place, the name should be known to the caller anyway int info = keyInfo.execute(receiver, field); if (unknownIdentifier.profile(!KeyInfo.isExisting(info))) { - throw UnknownIdentifierException.raise("" + field); + throw UnknownIdentifierException.raise(field); } initExtractNode(); Object value = extract.applyAccessField(receiver, field); @@ -365,7 +365,7 @@ public class ListMR { @Fallback protected Object read(@SuppressWarnings("unused") TruffleObject receiver, Object field) { - throw UnknownIdentifierException.raise("" + field); + throw UnknownIdentifierException.raise(String.valueOf(field)); } protected ListKeyInfoImplNode createKeyInfoNode() { @@ -426,23 +426,23 @@ public class ListMR { abstract static class ListKeyInfoImplNode extends Node { @Child private ExtractVectorNode extractNode; - private final ConditionProfile unknownIdentifier = ConditionProfile.createBinaryProfile(); - abstract int execute(TruffleObject receiver, Object idx); @Specialization protected int keyInfo(TruffleObject receiver, int idx, + @Cached("createBinaryProfile()") ConditionProfile outOfBounds, @Cached("createLengthNode()") RLengthNode lenghtNode) { - return keyInfo(receiver, (double) idx, lenghtNode); + return keyInfo(receiver, (double) idx, outOfBounds, lenghtNode); } @Specialization protected int keyInfo(TruffleObject receiver, double idx, + @Cached("createBinaryProfile()") ConditionProfile outOfBounds, @Cached("createLengthNode()") RLengthNode lengthNode) { int length = lengthNode.executeInteger(receiver); - if (unknownIdentifier.profile(idx < 0 || idx >= length)) { - return 0; + if (outOfBounds.profile(idx < 0 || idx >= length)) { + return KeyInfo.NONE; } initExtractNode(); return buildKeys(extractNode.apply(receiver, new Object[]{idx + 1}, RLogical.valueOf(false), RMissing.instance)); @@ -450,8 +450,13 @@ public class ListMR { @Specialization protected int keyInfo(TruffleObject receiver, String identifier, + @Cached("createBinaryProfile()") ConditionProfile noNames, + @Cached("createBinaryProfile()") ConditionProfile unknownIdentifier, @Cached("createNamesNode()") GetNamesAttributeNode namesNode) { RStringVector names = namesNode.getNames(receiver); + if (noNames.profile(names == null)) { + return KeyInfo.NONE; + } boolean exists = false; for (int i = 0; i < names.getLength(); i++) { if (identifier.equals(names.getDataAt(i))) { @@ -460,7 +465,7 @@ public class ListMR { } } if (unknownIdentifier.profile(!exists)) { - return 0; + return KeyInfo.NONE; } initExtractNode(); return buildKeys(extractNode.applyAccessField(receiver, identifier)); @@ -491,7 +496,7 @@ public class ListMR { @Fallback protected int access(@SuppressWarnings("unused") TruffleObject receiver, @SuppressWarnings("unused") Object field) { - return 0; + return KeyInfo.NONE; } } diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RForeignAccessFactoryImpl.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RForeignAccessFactoryImpl.java index ecf20060ba621a44f23f0cac080aa7e77d31d5c0..158e2dde6ee39bb4bfbc519097408be78fb09da3 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RForeignAccessFactoryImpl.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RForeignAccessFactoryImpl.java @@ -38,11 +38,10 @@ import com.oracle.truffle.r.runtime.data.RExternalPtr; import com.oracle.truffle.r.runtime.data.RFunction; import com.oracle.truffle.r.runtime.data.RInteger; import com.oracle.truffle.r.runtime.data.RInteropScalar; -import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RMissing; 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.RS4Object; @@ -105,8 +104,6 @@ public final class RForeignAccessFactoryImpl implements RForeignAccessFactory { return RPromiseMRForeign.ACCESS; } else if (obj instanceof RArgsValuesAndNames) { return RArgsValuesAndNamesMRForeign.ACCESS; - } else if (obj instanceof RLanguage) { - return RLanguageMRForeign.ACCESS; } else if (obj instanceof ActiveBinding) { return ActiveBindingMRForeign.ACCESS; } else if (obj instanceof RInteropScalar) { diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RLanguageMR.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RLanguageMR.java deleted file mode 100644 index d6f5b6b3f83dffb8e9d5df41452b598bc5e9a25f..0000000000000000000000000000000000000000 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/interop/RLanguageMR.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.r.engine.interop; - -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.Fallback; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.interop.CanResolve; -import com.oracle.truffle.api.interop.KeyInfo; -import com.oracle.truffle.api.interop.MessageResolution; -import com.oracle.truffle.api.interop.Resolve; -import com.oracle.truffle.api.interop.TruffleObject; -import com.oracle.truffle.api.interop.UnknownIdentifierException; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.profiles.ConditionProfile; -import com.oracle.truffle.r.nodes.access.vector.ElementAccessMode; -import com.oracle.truffle.r.nodes.access.vector.ExtractVectorNode; -import com.oracle.truffle.r.runtime.data.RLanguage; -import com.oracle.truffle.r.runtime.data.RLogical; -import com.oracle.truffle.r.runtime.data.RNull; -import com.oracle.truffle.r.runtime.data.RObject; -import com.oracle.truffle.r.runtime.interop.R2Foreign; -import com.oracle.truffle.r.runtime.interop.R2ForeignNodeGen; -import com.oracle.truffle.r.runtime.interop.RObjectNativeWrapper; - -@MessageResolution(receiverType = RLanguage.class) -public class RLanguageMR { - - @Resolve(message = "HAS_SIZE") - public abstract static class RLanguageHasSizeNode extends Node { - protected Object access(@SuppressWarnings("unused") RLanguage receiver) { - return true; - } - } - - @Resolve(message = "GET_SIZE") - public abstract static class RLanguageGetSizeNode extends Node { - protected Object access(RLanguage receiver) { - return receiver.getLength(); - } - } - - @Resolve(message = "READ") - public abstract static class RLanguageReadNode extends Node { - @Child private ReadNode readNode = RLanguageMRFactory.ReadNodeGen.create(); - - protected Object access(VirtualFrame frame, RLanguage receiver, Object identifier) { - return readNode.execute(frame, receiver, identifier); - } - } - - @Resolve(message = "KEY_INFO") - public abstract static class RLanguageNode extends Node { - @Node.Child private KeyInfoNode keyInfoNode = RLanguageMRFactory.KeyInfoNodeGen.create(); - - protected Object access(RLanguage receiver, Object obj) { - return keyInfoNode.execute(receiver, obj); - } - } - - @Resolve(message = "IS_POINTER") - public abstract static class IsPointerNode extends Node { - protected boolean access(@SuppressWarnings("unused") Object receiver) { - return false; - } - } - - @Resolve(message = "TO_NATIVE") - public abstract static class ToNativeNode extends Node { - protected Object access(RObject receiver) { - return new RObjectNativeWrapper(receiver); - } - } - - @CanResolve - public abstract static class RLanguageCheck extends Node { - - protected static boolean test(TruffleObject receiver) { - return receiver instanceof RLanguage; - } - } - - abstract static class ReadNode extends Node { - @Child private ExtractVectorNode extract; - @Child private R2Foreign r2Foreign; - - private final ConditionProfile unknownIdentifier = ConditionProfile.createBinaryProfile(); - - abstract Object execute(VirtualFrame frame, RLanguage receiver, Object identifier); - - @Specialization - protected Object access(RLanguage receiver, int idx, - @Cached("createKeyInfoNode()") KeyInfoNode keyInfo) { - - int info = keyInfo.execute(receiver, idx); - if (unknownIdentifier.profile(!KeyInfo.isExisting(info))) { - throw UnknownIdentifierException.raise("" + idx); - } - - if (extract == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - extract = insert(ExtractVectorNode.create(ElementAccessMode.SUBSCRIPT, true)); - } - Object value = extract.apply(receiver, new Object[]{idx + 1}, RLogical.TRUE, RLogical.TRUE); - if (value == null) { - return RNull.instance; - } - - if (r2Foreign == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - r2Foreign = insert(R2ForeignNodeGen.create()); - } - return r2Foreign.execute(value); - } - - @Fallback - protected Object access(@SuppressWarnings("unused") RLanguage receiver, Object identifier) { - throw UnknownIdentifierException.raise("" + identifier); - } - - protected static KeyInfoNode createKeyInfoNode() { - return RLanguageMRFactory.KeyInfoNodeGen.create(); - } - } - - abstract static class KeyInfoNode extends Node { - private final ConditionProfile unknownIdentifier = ConditionProfile.createBinaryProfile(); - - abstract int execute(RLanguage receiver, Object identifier); - - @Specialization - protected int access(RLanguage receiver, int idx) { - if (unknownIdentifier.profile(idx < 0 || idx >= receiver.getLength())) { - return 0; - } - // TODO what about writeble/invocable/... - return KeyInfo.READABLE; - } - - @Fallback - protected int access(@SuppressWarnings("unused") RLanguage receiver, @SuppressWarnings("unused") Object identifier) { - return 0; - } - } -} diff --git a/com.oracle.truffle.r.ffi.codegen/src/com/oracle/truffle/r/ffi/codegen/FFITestsCodeGen.java b/com.oracle.truffle.r.ffi.codegen/src/com/oracle/truffle/r/ffi/codegen/FFITestsCodeGen.java index b96c168f538357e4290e5d1f85f92b0bdf72c964..c20b778115b63f5f58be8b11efe363488509f9fb 100644 --- a/com.oracle.truffle.r.ffi.codegen/src/com/oracle/truffle/r/ffi/codegen/FFITestsCodeGen.java +++ b/com.oracle.truffle.r.ffi.codegen/src/com/oracle/truffle/r/ffi/codegen/FFITestsCodeGen.java @@ -37,16 +37,16 @@ import com.oracle.truffle.r.ffi.processor.RFFICstring; /** * Generates 1) C wrapper that calls each RFFI function and converts between SEXP and primitive * types, 2) sequence of calls to CALLDEF to register all those functions as ".Call" targets. - * + * * This creates R interface to all applicable RFFI functions. RFFI functions working with raw * pointers are excluded. - * + * * The generated code is to be used in testrffi package located in * "com.oracle.truffle.r.test.native/packages/testrffi/testrffi". */ public final class FFITestsCodeGen extends CodeGenBase { private static final String FUN_PREFIX = "api_"; - private static final HashSet<String> IGNORE_FUNS = new HashSet<>(Arrays.asList("Rf_duplicate", "SET_TYPEOF_FASTR", "R_ToplevelExec", "R_CleanUp", "R_ParseVector", "octsize", "R_NewHashedEnv")); + private static final HashSet<String> IGNORE_FUNS = new HashSet<>(Arrays.asList("Rf_duplicate", "R_ToplevelExec", "R_CleanUp", "R_ParseVector", "octsize", "R_NewHashedEnv")); public static void main(String[] args) { new FFITestsCodeGen().run(args); diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java index 071912314d8917df3734d2e043ee173d3c0ba41f..e874fcffe4d8e8b7a0048200f7445e1cd6039708 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java @@ -65,6 +65,7 @@ import com.oracle.truffle.r.runtime.context.Engine.ParseException; import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.CharSXPWrapper; import com.oracle.truffle.r.runtime.data.NativeDataAccess; +import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; import com.oracle.truffle.r.runtime.data.RAttributable; import com.oracle.truffle.r.runtime.data.RAttributesLayout; import com.oracle.truffle.r.runtime.data.RComplexVector; @@ -74,12 +75,11 @@ 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.RIntVector; -import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.runtime.data.RPairList; 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.RObject; -import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RPromise; import com.oracle.truffle.r.runtime.data.RPromise.EagerPromise; import com.oracle.truffle.r.runtime.data.RRawVector; @@ -231,7 +231,6 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI { } @Override - @TruffleBoundary public Object Rf_findVar(Object symbolArg, Object envArg) { return findVarInFrameHelper(envArg, symbolArg, true); } @@ -248,6 +247,7 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI { return findVarInFrameHelper(envArg, symbolArg, false); } + @TruffleBoundary 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); @@ -265,6 +265,9 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI { // env) should not show up return ((RPromise) value).getRawValue(); } + if (value instanceof RArgsValuesAndNames) { + return ((RArgsValuesAndNames) value).toPairlist(); + } return value; } if (!inherits) { @@ -434,8 +437,9 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI { return RDataFactory.createRawVector(new byte[ni]); case VECSXP: return RDataFactory.createList(ni); + case LISTSXP: case LANGSXP: - return RDataFactory.createLangPairList(ni); + return RDataFactory.createPairList(ni, type); default: throw unimplemented("unexpected SEXPTYPE " + type); } @@ -588,14 +592,8 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI { } @Override - @TruffleBoundary - 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(); - } + public void SET_TYPEOF(Object x, int v) { + guaranteeInstanceOf(x, RPairList.class).setType(SEXPTYPE.mapInt(v)); } @Override @@ -715,8 +713,7 @@ public abstract class JavaUpCallsRFFIImpl implements UpCallsRFFI { @Override public Object SETCDR(Object x, Object y) { - guaranteeInstanceOf(x, RPairList.class); - ((RPairList) x).setCdr(y); + guaranteeInstanceOf(x, RPairList.class).setCdr(y); return y; } diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/AttributesAccessNodes.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/AttributesAccessNodes.java index 272b93ca537ee356b208279ffb1957407812f559..4ea02bcd09038c0dfab6c2ebf7043416f62d74a4 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/AttributesAccessNodes.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/AttributesAccessNodes.java @@ -55,7 +55,6 @@ import com.oracle.truffle.r.runtime.data.RAttributeStorage; import com.oracle.truffle.r.runtime.data.RAttributesLayout; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RExternalPtr; -import com.oracle.truffle.r.runtime.data.RLanguage; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RPairList; @@ -214,12 +213,6 @@ public final class AttributesAccessNodes { return SetAttribNodeGen.create(); } - @Specialization - protected Object doLanguage(RSharingAttributeStorage target, RLanguage attributes, - @Cached("create()") SetAttributeNode setAttribNode) { - return doIt(target, getPairList(attributes), setAttribNode); - } - @Specialization protected Object doIt(RSharingAttributeStorage target, RPairList attributes, @Cached("create()") SetAttributeNode setAttribNode) { @@ -247,10 +240,5 @@ public final class AttributesAccessNodes { private static void clearAttrs(RSharingAttributeStorage target) { target.initAttributes(RAttributesLayout.createRAttributes()); } - - @TruffleBoundary - private static RPairList getPairList(RLanguage attributes) { - return attributes.getPairList(); - } } } diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/CoerceNodes.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/CoerceNodes.java index 43df7a5efb42a8f754b79b15a2dbe7920b6f0e20..a42c04d1756434feb0298de6f14d5594dfcb975a 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/CoerceNodes.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/CoerceNodes.java @@ -58,39 +58,51 @@ import com.oracle.truffle.r.runtime.gnur.SEXPTYPE; public final class CoerceNodes { - public abstract static class VectorToPairListNode extends FFIUpCallNode.Arg1 { + public static final class VectorToPairListNode extends FFIUpCallNode.Arg1 { - @Child private CopyOfRegAttributesNode copyRegAttributesNode; - @Child private GetNamesAttributeNode getNamesAttributeNode; + @Child private CastPairListNode cast = CastPairListNode.create(SEXPTYPE.LISTSXP); + + @Override + public Object executeObject(Object value) { + return cast.doCast(value); + } + + public static VectorToPairListNode create() { + return new VectorToPairListNode(); + } + } + + public abstract static class CastPairListNode extends CastNode { + + private final SEXPTYPE type; + + @Child private CopyOfRegAttributesNode copyRegAttributesNode = CopyOfRegAttributesNode.create(); + @Child private GetNamesAttributeNode getNamesAttributeNode = GetNamesAttributeNode.create(); + + protected CastPairListNode(SEXPTYPE type) { + this.type = type; + } @Specialization protected Object convert(RAbstractVector v) { - RStringVector names = getNamesAttributeNode.getNames(v); SEXPTYPE gnurType = SEXPTYPE.gnuRTypeForObject(v); - RPairList head = null; - RPairList prev = null; + Object current = RNull.instance; assert names == null || names.getLength() == v.getLength(); - for (int i = 0; i < v.getLength(); i++) { + for (int i = v.getLength() - 1; i >= 0; i--) { Object element = v.getDataAtAsObject(i); adjustSharing(v, element); - RPairList cur = RDataFactory.createPairList(element, RNull.instance, names != null ? RDataFactory.createSymbol(names.getDataAt(i)) : RNull.instance, gnurType); - - if (prev == null) { - assert head == null; - head = cur; - } else { - prev.setCdr(cur); - } - prev = cur; + current = RDataFactory.createPairList(element, current, names != null ? RDataFactory.createSymbol(names.getDataAt(i)) : RNull.instance, gnurType); } - if (head != null) { + if (current != RNull.instance) { // also copy regular attributes - copyRegAttributesNode.execute(v, head); - return head; + RPairList pl = (RPairList) current; + copyRegAttributesNode.execute(v, pl); + pl.setType(type); + pl.allowClosure(); } - return RNull.instance; + return current; } private static void adjustSharing(RAbstractVector origin, Object element) { @@ -110,8 +122,8 @@ public final class CoerceNodes { } } - public static VectorToPairListNode create() { - return CoerceNodesFactory.VectorToPairListNodeGen.create(); + public static CastPairListNode create(SEXPTYPE type) { + return CoerceNodesFactory.CastPairListNodeGen.create(type); } private static int getSharingLevel(RShareable r) { @@ -234,9 +246,8 @@ public final class CoerceNodes { case NILSXP: return new CastNullNode(); case LISTSXP: - throw RInternalError.unimplemented("Rf_coerceVector unimplemented for PairLists."); case LANGSXP: - throw RInternalError.unimplemented("Rf_coerceVector unimplemented for RLanguage."); + return CastPairListNode.create(type); case ENVSXP: return new EnvironmentCast(); case VECSXP: diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/ListAccessNodes.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/ListAccessNodes.java index d33dce24251486421bac34e98ff080935c1f10e0..62b743b4f544ed3809dd455a1a94ee73fdccb4f6 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/ListAccessNodes.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/ListAccessNodes.java @@ -35,10 +35,9 @@ import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.data.CharSXPWrapper; import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; import com.oracle.truffle.r.runtime.data.RDataFactory; -import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RNull; -import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.RSymbol; import com.oracle.truffle.r.runtime.data.RTypes; @@ -56,11 +55,6 @@ public final class ListAccessNodes { return pl.car(); } - @Specialization - protected Object car(RLanguage lang) { - return lang.getDataAtAsObject(0); - } - @Specialization protected Object car(RArgsValuesAndNames args) { if (args.isEmpty()) { @@ -101,15 +95,10 @@ public final class ListAccessNodes { return pl.cdr(); } - @Specialization - protected Object cdr(RLanguage lang) { - RPairList l = lang.getPairList(); - return l.cdr(); - } - @Specialization protected Object cdr(RArgsValuesAndNames args) { - return args.toPairlist().cdr(); + // TODO: this is too late - "..." should be converted to pairlist earlier + return ((RPairList) args.toPairlist()).cdr(); } @Specialization @@ -177,8 +166,8 @@ public final class ListAccessNodes { @TypeSystemReference(RTypes.class) public static final class SETCADDRNode extends FFIUpCallNode.Arg2 { - @Child CDDRNode cddr = CDDRNode.create(); - @Child SETCARNode setcarNode = SETCARNode.create(); + @Child private CDDRNode cddr = CDDRNode.create(); + @Child private SETCARNode setcarNode = SETCARNode.create(); @Override public Object executeObject(Object x, Object val) { @@ -192,8 +181,8 @@ public final class ListAccessNodes { @TypeSystemReference(RTypes.class) public static final class SETCADDDRNode extends FFIUpCallNode.Arg2 { - @Child CDDDRNode cdddr = CDDDRNode.create(); - @Child SETCARNode setcarNode = SETCARNode.create(); + @Child private CDDDRNode cdddr = CDDDRNode.create(); + @Child private SETCARNode setcarNode = SETCARNode.create(); @Override public Object executeObject(Object x, Object val) { @@ -207,9 +196,9 @@ public final class ListAccessNodes { @TypeSystemReference(RTypes.class) public static final class SETCAD4RNode extends FFIUpCallNode.Arg2 { - @Child CDDDRNode cdddr = CDDDRNode.create(); - @Child CDRNode cdr = CDRNode.create(); - @Child SETCARNode setcarNode = SETCARNode.create(); + @Child private CDDDRNode cdddr = CDDDRNode.create(); + @Child private CDRNode cdr = CDRNode.create(); + @Child private SETCARNode setcarNode = SETCARNode.create(); @Override public Object executeObject(Object x, Object val) { @@ -227,12 +216,6 @@ public final class ListAccessNodes { return SETCARNodeGen.create(); } - @Specialization - protected Object doRLang(RLanguage x, Object y) { - x.getPairList().setCar(y); - return y; - } - @Specialization protected Object doRPairList(RPairList x, Object y) { x.setCar(y); @@ -340,8 +323,8 @@ public final class ListAccessNodes { @TypeSystemReference(RTypes.class) public static final class CDDDRNode extends FFIUpCallNode.Arg1 { - @Child CDDRNode cddr = CDDRNode.create(); - @Child CDRNode cdr = CDRNode.create(); + @Child private CDDRNode cddr = CDDRNode.create(); + @Child private CDRNode cdr = CDRNode.create(); @Override public Object executeObject(Object x) { diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/RfEvalNode.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/RfEvalNode.java index a3dd1b686b35e0e3b06c884c2855745ce61812df..cd6d41817b4d91f61a22c6ba51876a49930b52da 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/RfEvalNode.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/RfEvalNode.java @@ -41,10 +41,9 @@ import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.RExpression; import com.oracle.truffle.r.runtime.data.RFunction; -import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RList; 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.RSymbol; import com.oracle.truffle.r.runtime.env.REnvironment; @@ -76,9 +75,9 @@ public abstract class RfEvalNode extends FFIUpCallNode.Arg2 { return RContext.getEngine().eval(expr, getEnv(envArg), null); } - @Specialization + @Specialization(guards = "expr.isLanguage()") @TruffleBoundary - Object handleLanguage(RLanguage expr, Object envArg) { + Object handleLanguage(RPairList expr, Object envArg) { return RContext.getEngine().eval(expr, getEnv(envArg), null); } @@ -93,7 +92,7 @@ public abstract class RfEvalNode extends FFIUpCallNode.Arg2 { return result; } - @Specialization + @Specialization(guards = "!l.isLanguage()") Object handlePairList(RPairList l, Object envArg, @Cached("createBinaryProfile()") ConditionProfile isPromiseProfile, @Cached("createBinaryProfile()") ConditionProfile noArgsProfile) { @@ -142,7 +141,11 @@ public abstract class RfEvalNode extends FFIUpCallNode.Arg2 { if (envIsNullProfile.profile(envArg == RNull.instance)) { return REnvironment.globalEnv(RContext.getInstance()); } else if (envArg instanceof REnvironment) { - return (REnvironment) envArg; + REnvironment env = (REnvironment) envArg; + if (env == REnvironment.emptyEnv()) { + return RContext.getInstance().stateREnvironment.getEmptyDummy(); + } + return env; } CompilerDirectives.transferToInterpreter(); throw RError.error(RError.NO_CALLER, ARGUMENT_NOT_ENVIRONMENT); diff --git a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java index e9bbeb09d1c1dce2218199897ece6acd1f77f8a7..c9ba7f60d1362ef3381c342fdf1ff63410142f83 100644 --- a/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java +++ b/com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java @@ -273,7 +273,7 @@ public interface StdUpCallsRFFI { void SET_NAMED_FASTR(Object x, int v); - Object SET_TYPEOF_FASTR(Object x, int v); + void SET_TYPEOF(Object x, int v); int TYPEOF(Object x); diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/graphics/RGridGraphicsAdapter.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/graphics/RGridGraphicsAdapter.java index 9c2cce59df625173faf89f9847d7fe9208b3901e..e30a62ce54dca40dfb1bad6ae8a66db7bf7f669f 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/graphics/RGridGraphicsAdapter.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/fastrGrid/graphics/RGridGraphicsAdapter.java @@ -8,7 +8,7 @@ * Copyright (c) 1998--2014, The R Core Team * Copyright (c) 2002--2010, The R Foundation * Copyright (C) 2005--2006, Morten Welinder - * Copyright (c) 2014, 2017, Oracle and/or its affiliates + * Copyright (c) 2014, 2018, Oracle and/or its affiliates * * All rights reserved. */ @@ -90,7 +90,7 @@ public final class RGridGraphicsAdapter { public static RPairList fixupDevicesVariable() { REnvironment baseEnv = REnvironment.baseEnv(); Object devices = baseEnv.get(DOT_DEVICES); - if (devices instanceof RPairList) { + if ((devices instanceof RPairList && !((RPairList) devices).isLanguage())) { return (RPairList) devices; } if (devices instanceof RList) { @@ -151,11 +151,11 @@ public final class RGridGraphicsAdapter { public static int getDevicesCount() { Object dotDevices = REnvironment.baseEnv().get(DOT_DEVICES); - return dotDevices instanceof RPairList ? ((RPairList) dotDevices).getLength() : 0; + return (dotDevices instanceof RPairList && !((RPairList) dotDevices).isLanguage()) ? ((RPairList) dotDevices).getLength() : 0; } private static boolean contains(Object devices, String name) { - if (!(devices instanceof RPairList)) { + if (!((devices instanceof RPairList && !((RPairList) devices).isLanguage()))) { return false; } for (RPairList dev : (RPairList) devices) { diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/MethodsListDispatch.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/MethodsListDispatch.java index 18e39decc0796987fb30decfd71ae8d5bd9b3c07..351de044af320e907df5f8260c5f0d94467fd47c 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/MethodsListDispatch.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/MethodsListDispatch.java @@ -55,7 +55,7 @@ import com.oracle.truffle.r.runtime.data.RAttributable; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RExternalPtr; import com.oracle.truffle.r.runtime.data.RFunction; -import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RPromise; import com.oracle.truffle.r.runtime.data.RS4Object; @@ -66,6 +66,7 @@ import com.oracle.truffle.r.runtime.env.frame.FrameSlotChangeMonitor; import com.oracle.truffle.r.runtime.ffi.DLL; import com.oracle.truffle.r.runtime.nodes.RBaseNode; import com.oracle.truffle.r.runtime.nodes.RNode; +import com.oracle.truffle.r.runtime.nodes.RSyntaxCall; import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; // Transcribed (unless otherwise noted) from src/library/methods/methods_list_dispatch.c @@ -451,9 +452,9 @@ public class MethodsListDispatch { Casts.noCasts(R_nextMethodCall.class); } - @Specialization + @Specialization(guards = "matchedCall.isLanguage()") @TruffleBoundary - protected Object nextMethodCall(RLanguage matchedCall, REnvironment ev) { + protected Object nextMethodCall(RPairList matchedCall, REnvironment ev) { // TODO: we can't create LocalReadVariableNode-s once and for all because ev may change // leading to a problem if contains a different frame; should we finesse implementation // of LocalReadVariableNode to handle this? @@ -468,18 +469,18 @@ public class MethodsListDispatch { if (primCase) { throw RInternalError.unimplemented(); } - if (!(matchedCall.getRep() instanceof RCallNode)) { + if (!(matchedCall.getSyntaxElement() instanceof RSyntaxCall)) { throw RInternalError.unimplemented(); } - RCallNode callNode = (RCallNode) matchedCall.getRep(); + RSyntaxCall callNode = (RSyntaxCall) matchedCall.getSyntaxElement(); RNode f = RContext.getASTBuilder().lookup(RSyntaxNode.SOURCE_UNAVAILABLE, RRuntime.R_DOT_NEXT_METHOD, false).asRNode(); ArgumentsSignature sig = callNode.getSyntaxSignature(); RSyntaxNode[] args = new RSyntaxNode[sig.getLength()]; for (int i = 0; i < args.length; i++) { args[i] = RContext.getASTBuilder().lookup(RSyntaxNode.SOURCE_UNAVAILABLE, sig.getName(i), false); } - RLanguage newCall = RDataFactory.createLanguage(Closure.createLanguageClosure(RCallNode.createCall(RSyntaxNode.SOURCE_UNAVAILABLE, f, sig, args))); + RPairList newCall = RDataFactory.createLanguage(Closure.createLanguageClosure(RCallNode.createCall(RSyntaxNode.SOURCE_UNAVAILABLE, f, sig, args))); Object res = RContext.getEngine().eval(newCall, ev.getFrame()); return res; } diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/SubstituteDirect.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/SubstituteDirect.java index 20ee2cb8d6d4a1dcce0713f845b96264a5973f43..f203baea0f964643fe6aacdf9ca6dd51713dba2a 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/SubstituteDirect.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/methods/SubstituteDirect.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2018, 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 @@ -35,7 +35,7 @@ import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RSubstitute; import com.oracle.truffle.r.runtime.data.RDataFactory; -import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.model.RAbstractListVector; import com.oracle.truffle.r.runtime.env.REnvironment; @@ -56,9 +56,9 @@ public abstract class SubstituteDirect extends RExternalBuiltinNode.Arg2 { @Specialization @TruffleBoundary protected Object substituteDirect(Object object, REnvironment env) { - if (object instanceof RLanguage) { - RLanguage lang = (RLanguage) object; - return RASTUtils.createLanguageElement(RSubstitute.substitute(env, lang.getRep(), getRLanguage())); + if ((object instanceof RPairList && ((RPairList) object).isLanguage())) { + RPairList lang = (RPairList) object; + return RASTUtils.createLanguageElement(RSubstitute.substitute(env, lang.getSyntaxElement(), getRLanguage())); } else { return object; } diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/CompleteCases.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/CompleteCases.java index c0183e5841ef8b80453f77a7ce2e3332e32d2d49..90e7af268e83e2f6e680679a14ee6f4a4f2a8b32 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/CompleteCases.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/CompleteCases.java @@ -5,7 +5,7 @@ * * Copyright (c) 1995, 1996 Robert Gentleman and Ross Ihaka * Copyright (c) 1997-2013, The R Core Team - * Copyright (c) 2015, 2017, Oracle and/or its affiliates + * Copyright (c) 2015, 2018, Oracle and/or its affiliates * * All rights reserved. */ @@ -70,7 +70,7 @@ public final class CompleteCases extends RExternalBuiltinNode { Object arg = args.getArgument(i); if (arg instanceof RNull) { // nothing to do - } else if (arg instanceof RPairList) { + } else if ((arg instanceof RPairList && !((RPairList) arg).isLanguage())) { for (Object t = ((RPairList) arg).car(); t != RNull.instance; t = ((RPairList) t).cdr()) { len = checkAbstractVectorLength(len, ((RPairList) t).car()); } @@ -103,7 +103,7 @@ public final class CompleteCases extends RExternalBuiltinNode { for (int i = 0; i < args.getLength(); i++) { Object arg = args.getArgument(i); - if (arg instanceof RPairList) { + if ((arg instanceof RPairList && !((RPairList) arg).isLanguage())) { for (Object t = ((RPairList) arg).car(); t != RNull.instance; t = ((RPairList) t).cdr()) { Object entry = ((RPairList) t).car(); iterateAbstractVectorContents(len, result, entry); diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/deriv/D.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/deriv/D.java index f0d059510dfd53f75059882ad3365224b3d6d9dc..50b06a20e909d40c2d9a3a1bc0fa8e226110b892 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/deriv/D.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/deriv/D.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2018, 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 @@ -34,13 +34,12 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.r.nodes.RASTUtils; -import com.oracle.truffle.r.nodes.access.ConstantNode; import com.oracle.truffle.r.nodes.builtin.RExternalBuiltinNode; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.RExpression; -import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RSymbol; import com.oracle.truffle.r.runtime.nodes.RSyntaxElement; import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; @@ -50,7 +49,7 @@ public abstract class D extends RExternalBuiltinNode.Arg2 { static { Casts casts = new Casts(D.class); - casts.arg(0, "expr").mustBe(instanceOf(RExpression.class).or(instanceOf(RLanguage.class)).or(instanceOf(RSymbol.class)).or(numericValue()).or(complexValue()), + casts.arg(0, "expr").mustBe(instanceOf(RExpression.class).or(instanceOf(RPairList.class)).or(instanceOf(RSymbol.class)).or(numericValue()).or(complexValue()), RError.Message.INVALID_EXPRESSION_TYPE, typeName()); casts.arg(1, "namevec").mustBe(stringValue()).asStringVector().mustBe(notEmpty(), RError.Message.GENERIC, "variable must be a character string").shouldBe(size(1), RError.Message.ONLY_FIRST_VARIABLE_NAME).findFirst(); @@ -61,13 +60,13 @@ public abstract class D extends RExternalBuiltinNode.Arg2 { } protected static boolean isConstant(Object expr) { - return !(expr instanceof RLanguage || expr instanceof RExpression || expr instanceof RSymbol); + return !((expr instanceof RPairList && ((RPairList) expr).isLanguage()) || expr instanceof RExpression || expr instanceof RSymbol); } @Specialization(guards = "isConstant(expr)") @TruffleBoundary protected Object doD(Object expr, String var) { - return doD(ConstantNode.create(expr), var); + return doD(RContext.getASTBuilder().constant(RSyntaxNode.LAZY_DEPARSE, expr), var); } @Specialization @@ -76,10 +75,10 @@ public abstract class D extends RExternalBuiltinNode.Arg2 { return doD(RContext.getASTBuilder().lookup(RSyntaxNode.LAZY_DEPARSE, expr.getName(), false), var); } - @Specialization + @Specialization(guards = "expr.isLanguage()") @TruffleBoundary - protected Object doD(RLanguage expr, String var) { - return doD((RSyntaxElement) expr.getRep(), var); + protected Object doD(RPairList expr, String var) { + return doD(expr.getSyntaxElement(), var); } @Specialization diff --git a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/deriv/Deriv.java b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/deriv/Deriv.java index 0c225227f7a5983c1b23bf0c70bbe37b2419bdcd..5bb5eee3326b747a2287785ccb695571ad491566 100644 --- a/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/deriv/Deriv.java +++ b/com.oracle.truffle.r.library/src/com/oracle/truffle/r/library/stats/deriv/Deriv.java @@ -5,7 +5,7 @@ * * Copyright (c) 1995, 1996 Robert Gentleman and Ross Ihaka * Copyright (c) 1997-2013, The R Core Team - * Copyright (c) 2015, 2017, Oracle and/or its affiliates + * Copyright (c) 2015, 2018, Oracle and/or its affiliates * * All rights reserved. */ @@ -53,13 +53,12 @@ import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.REmpty; import com.oracle.truffle.r.runtime.data.RExpression; import com.oracle.truffle.r.runtime.data.RFunction; -import com.oracle.truffle.r.runtime.data.RLanguage; import com.oracle.truffle.r.runtime.data.RMissing; import com.oracle.truffle.r.runtime.data.RNull; +import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RSymbol; import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; import com.oracle.truffle.r.runtime.env.frame.FrameSlotChangeMonitor; -import com.oracle.truffle.r.runtime.nodes.RBaseNode; import com.oracle.truffle.r.runtime.nodes.RCodeBuilder; import com.oracle.truffle.r.runtime.nodes.RCodeBuilder.Argument; import com.oracle.truffle.r.runtime.nodes.RNode; @@ -113,12 +112,12 @@ public abstract class Deriv extends RExternalBuiltinNode { return DerivNodeGen.create(); } - public abstract Object execute(VirtualFrame frame, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5); + public abstract Object execute(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5); @Override public Object call(VirtualFrame frame, RArgsValuesAndNames args) { checkLength(args, 5); - return execute(frame, castArg(args, 0), castArg(args, 1), castArg(args, 2), castArg(args, 3), castArg(args, 4)); + return execute(castArg(args, 0), castArg(args, 1), castArg(args, 2), castArg(args, 3), castArg(args, 4)); } @Override @@ -127,43 +126,38 @@ public abstract class Deriv extends RExternalBuiltinNode { } protected static boolean isConstant(Object expr) { - return !(expr instanceof RLanguage || expr instanceof RExpression || expr instanceof RSymbol); + return !((expr instanceof RPairList && ((RPairList) expr).isLanguage()) || expr instanceof RExpression || expr instanceof RSymbol); } @Specialization(guards = "isConstant(expr)") - protected Object derive(VirtualFrame frame, Object expr, RAbstractStringVector names, Object functionArg, String tag, boolean hessian) { - return derive(frame.materialize(), createConstant(expr), names, functionArg, tag, hessian); - } - - @TruffleBoundary - private static ConstantNode createConstant(Object expr) { - return ConstantNode.create(expr); + protected Object derive(Object expr, RAbstractStringVector names, Object functionArg, String tag, boolean hessian) { + return deriveInternal(RSyntaxConstant.createDummyConstant(RSyntaxNode.INTERNAL, expr), names, functionArg, tag, hessian); } @Specialization - protected Object derive(VirtualFrame frame, RSymbol expr, RAbstractStringVector names, Object functionArg, String tag, boolean hessian) { - return derive(frame.materialize(), createLookup(expr), names, functionArg, tag, hessian); - } - - @TruffleBoundary - private static RBaseNode createLookup(RSymbol expr) { - return (RBaseNode) RContext.getASTBuilder().lookup(RSyntaxNode.LAZY_DEPARSE, expr.getName(), false); + protected Object derive(RSymbol expr, RAbstractStringVector names, Object functionArg, String tag, boolean hessian) { + return deriveInternal(RSyntaxLookup.createDummyLookup(RSyntaxNode.INTERNAL, expr.getName(), false), names, functionArg, tag, hessian); } @Specialization - protected Object derive(VirtualFrame frame, RExpression expr, RAbstractStringVector names, Object functionArg, String tag, boolean hessian, + protected Object derive(RExpression expr, RAbstractStringVector names, Object functionArg, String tag, boolean hessian, @Cached("create()") Deriv derivNode) { - return derivNode.execute(frame, expr.getDataAt(0), names, functionArg, tag, hessian); + return derivNode.execute(expr.getDataAt(0), names, functionArg, tag, hessian); } - @Specialization - protected Object derive(VirtualFrame frame, RLanguage expr, RAbstractStringVector names, Object functionArg, String tag, boolean hessian) { - return derive(frame.materialize(), expr.getRep(), names, functionArg, tag, hessian); + @Specialization(guards = "expr.isLanguage()") + protected Object derive(RPairList expr, RAbstractStringVector names, Object functionArg, String tag, boolean hessian) { + return deriveInternal(getSyntaxElement(expr), names, functionArg, tag, hessian); + } + + @TruffleBoundary + private static RSyntaxElement getSyntaxElement(RPairList expr) { + return expr.getSyntaxElement(); } @TruffleBoundary - private Object derive(MaterializedFrame frame, RBaseNode elem, RAbstractStringVector names, Object functionArg, String tag, boolean hessian) { - return findDerive(elem, names, functionArg, tag, hessian).getResult(frame.materialize(), getRLanguage()); + private Object deriveInternal(RSyntaxElement elem, RAbstractStringVector names, Object functionArg, String tag, boolean hessian) { + return findDerive(elem, names, functionArg, tag, hessian).getResult(getRLanguage(), functionArg); } private static final class DerivResult { @@ -183,10 +177,11 @@ public abstract class Deriv extends RExternalBuiltinNode { result = null; } - private Object getResult(MaterializedFrame frame, TruffleRLanguage language) { + private Object getResult(TruffleRLanguage language, Object functionArg) { if (result != null) { return result; } + MaterializedFrame frame = functionArg instanceof RFunction ? ((RFunction) functionArg).getEnclosingFrame() : RContext.getInstance().stateREnvironment.getGlobalFrame(); RootCallTarget callTarget = RContext.getASTBuilder().rootFunction(language, RSyntaxNode.LAZY_DEPARSE, targetArgs, blockCall, null); FrameSlotChangeMonitor.initializeEnclosingFrame(callTarget.getRootNode().getFrameDescriptor(), frame); return RDataFactory.createFunction(RFunction.NO_NAME, RFunction.NO_NAME, callTarget, null, frame); @@ -194,7 +189,7 @@ public abstract class Deriv extends RExternalBuiltinNode { } @TruffleBoundary - private DerivResult findDerive(RBaseNode elem, RAbstractStringVector names, Object functionArg, String tag, boolean hessian) { + private DerivResult findDerive(RSyntaxElement elem, RAbstractStringVector names, Object functionArg, String tag, boolean hessian) { LinkedList<RSyntaxNode> exprlist = new LinkedList<>(); int fIndex = findSubexpression(elem, exprlist, tag); @@ -202,12 +197,12 @@ public abstract class Deriv extends RExternalBuiltinNode { int[] dIndex = new int[nderiv]; int[] d2Index = hessian ? new int[(nderiv * (1 + nderiv)) / 2] : null; for (int i = 0, k = 0; i < nderiv; i++) { - RBaseNode dExpr = d(elem, names.getDataAt(i)); + RSyntaxElement dExpr = d(elem, names.getDataAt(i)); dIndex[i] = findSubexpression(dExpr, exprlist, tag); if (hessian) { for (int j = i; j < nderiv; j++) { - RBaseNode d2Expr = d(dExpr, names.getDataAt(j)); + RSyntaxElement d2Expr = d(dExpr, names.getDataAt(j)); d2Index[k] = findSubexpression(d2Expr, exprlist, tag); k++; } @@ -219,7 +214,7 @@ public abstract class Deriv extends RExternalBuiltinNode { if (fIndex > 0) { exprlist.add(createLookup(tag + fIndex)); } else { - exprlist.add(cloneElement(elem.asRSyntaxNode())); + exprlist.add(cloneElement(elem)); } exprlist.add(null); @@ -232,7 +227,7 @@ public abstract class Deriv extends RExternalBuiltinNode { exprlist.add(createLookup(tag + dIndex[i])); if (hessian) { - RBaseNode dExpr = d(elem, names.getDataAt(i)); + RSyntaxElement dExpr = d(elem, names.getDataAt(i)); for (int j = i; j < nderiv; j++) { if (d2Index[k] > 0) { exprlist.add(createLookup(tag + d2Index[k])); @@ -245,7 +240,7 @@ public abstract class Deriv extends RExternalBuiltinNode { } else { // the first derivative is constant or simple variable // TODO: do not call the d twice - RBaseNode dExpr = d(elem, names.getDataAt(i)); + RSyntaxElement dExpr = d(elem, names.getDataAt(i)); exprlist.add((RSyntaxNode) dExpr); if (hessian) { @@ -253,8 +248,8 @@ public abstract class Deriv extends RExternalBuiltinNode { if (d2Index[k] > 0) { exprlist.add(createLookup(tag + d2Index[k])); } else { - RBaseNode d2Expr = d(dExpr, names.getDataAt(j)); - if (isZero((RSyntaxElement) d2Expr)) { + RSyntaxElement d2Expr = d(dExpr, names.getDataAt(j)); + if (isZero(d2Expr)) { exprlist.add(null); } else { exprlist.add((RSyntaxNode) d2Expr); @@ -357,17 +352,13 @@ public abstract class Deriv extends RExternalBuiltinNode { return new DerivResult(blockCall, targetArgs); } else { - RLanguage lan = RDataFactory.createLanguage(Closure.createLanguageClosure(blockCall.asRNode())); + RPairList lan = RDataFactory.createLanguage(Closure.createLanguageClosure(blockCall.asRNode())); RExpression res = RDataFactory.createExpression(new Object[]{lan}); return new DerivResult(res); } } - private int findSubexpression(RBaseNode expr, List<RSyntaxNode> exprlist, String tag) { - if (!(expr instanceof RSyntaxElement)) { - throw RError.error(RError.SHOW_CALLER, RError.Message.INVALID_EXPRESSION, "FindSubexprs"); - } - + private int findSubexpression(RSyntaxElement expr, List<RSyntaxNode> exprlist, String tag) { RSyntaxVisitor<Integer> vis = new RSyntaxVisitor<Integer>() { @Override protected Integer visit(RSyntaxCall call) { @@ -404,7 +395,7 @@ public abstract class Deriv extends RExternalBuiltinNode { throw RError.error(RError.SHOW_CALLER, RError.Message.INVALID_EXPRESSION, "FindSubexprs"); } }; - return vis.accept((RSyntaxElement) expr); + return vis.accept(expr); } private static int checkConstant(Object val) { @@ -490,13 +481,8 @@ public abstract class Deriv extends RExternalBuiltinNode { return RContext.getASTBuilder().process(element); } - private static RBaseNode d(RBaseNode expr, String var) { - if (!(expr instanceof RSyntaxElement)) { - throw RError.error(RError.SHOW_CALLER, RError.Message.INVALID_EXPRESSION, "FindSubexprs"); - } - - RSyntaxVisitor<RSyntaxElement> vis = new DerivVisitor(var); - return (RBaseNode) vis.accept((RSyntaxElement) expr); + private static RSyntaxElement d(RSyntaxElement expr, String var) { + return new DerivVisitor(var).accept(expr); } private static int argsLength(RSyntaxElement elem) { diff --git a/com.oracle.truffle.r.native/fficall/src/common/inlined_fastr.c b/com.oracle.truffle.r.native/fficall/src/common/inlined_fastr.c index 4d6ac072c5ba151c2f0ca47ad22df74a74ad5413..55b83d7b6229fb2825cf549ef0b61c5c67662d2a 100644 --- a/com.oracle.truffle.r.native/fficall/src/common/inlined_fastr.c +++ b/com.oracle.truffle.r.native/fficall/src/common/inlined_fastr.c @@ -6,7 +6,7 @@ * Copyright (c) 1995, 1996, 1997 Robert Gentleman and Ross Ihaka * Copyright (c) 1995-2014, The R Core Team * Copyright (c) 2002-2008, The R Foundation - * Copyright (c) 2015, 2017, Oracle and/or its affiliates + * Copyright (c) 2015, 2018, Oracle and/or its affiliates * * All rights reserved. */ @@ -178,9 +178,6 @@ INLINE_FUN SEXP listAppend(SEXP s, SEXP t) return s; } - -SEXP SET_TYPEOF_FASTR(SEXP x, int v); - /* Language based list constructs. These are identical to the list */ /* constructs, but the results can be evaluated. */ @@ -189,7 +186,8 @@ SEXP SET_TYPEOF_FASTR(SEXP x, int v); INLINE_FUN SEXP lcons(SEXP car, SEXP cdr) { SEXP e = cons(car, cdr); - return SET_TYPEOF_FASTR(e, LANGSXP); + SET_TYPEOF(e, LANGSXP); + return e; } INLINE_FUN SEXP lang1(SEXP s) diff --git a/com.oracle.truffle.r.native/fficall/src/common/rffi_upcalls.h b/com.oracle.truffle.r.native/fficall/src/common/rffi_upcalls.h index c6a6da14a046f9657d850d3ed40e7e8ba5ad780b..04906b42fe95a278277427fc455adb8828c57d3c 100644 --- a/com.oracle.truffle.r.native/fficall/src/common/rffi_upcalls.h +++ b/com.oracle.truffle.r.native/fficall/src/common/rffi_upcalls.h @@ -196,7 +196,6 @@ typedef int (*call_NAMED)(SEXP x); typedef int (*call_REFCNT)(SEXP x); typedef void (*call_SET_OBJECT)(SEXP x, int v); typedef void (*call_SET_TYPEOF)(SEXP x, int v); -typedef SEXP (*call_SET_TYPEOF_FASTR)(SEXP x, int v); typedef void (*call_SET_NAMED)(SEXP x, int v); typedef void (*call_SET_ATTRIB)(SEXP x, SEXP v); typedef void (*call_DUPLICATE_ATTRIB)(SEXP to, SEXP from); diff --git a/com.oracle.truffle.r.native/fficall/src/common/rffi_upcallsindex.h b/com.oracle.truffle.r.native/fficall/src/common/rffi_upcallsindex.h index 28b3d41c7bd2e56a88e9affddb86e9781905b421..71610473d392af86a17fbb8edeb8978174fd9bfb 100644 --- a/com.oracle.truffle.r.native/fficall/src/common/rffi_upcallsindex.h +++ b/com.oracle.truffle.r.native/fficall/src/common/rffi_upcallsindex.h @@ -262,7 +262,7 @@ #define SET_STRING_ELT_x 256 #define SET_SYMVALUE_x 257 #define SET_TAG_x 258 -#define SET_TYPEOF_FASTR_x 259 +#define SET_TYPEOF_x 259 #define SET_VECTOR_ELT_x 260 #define STRING_ELT_x 261 #define SYMVALUE_x 262 diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_common/Rinternals_truffle_common.h b/com.oracle.truffle.r.native/fficall/src/truffle_common/Rinternals_truffle_common.h index c1e44d5c68a2208a070b400e6a0ab110b3017c3f..8a0a2f31a0f4b84dcbcff439b9e2d00925e4aee7 100644 --- a/com.oracle.truffle.r.native/fficall/src/truffle_common/Rinternals_truffle_common.h +++ b/com.oracle.truffle.r.native/fficall/src/truffle_common/Rinternals_truffle_common.h @@ -1223,15 +1223,8 @@ void SET_OBJECT(SEXP x, int v) { void SET_TYPEOF(SEXP x, int v) { TRACE0(); - // TODO: we will be able to implement this for RLanguage <-> RPairList once they are unified in one Java class - unimplemented("SET_TYPEOF"); -} - -SEXP SET_TYPEOF_FASTR(SEXP x, int v) { - TRACE0(); - SEXP result = ((call_SET_TYPEOF_FASTR) callbacks[SET_TYPEOF_FASTR_x])(x, v); + ((call_SET_TYPEOF) callbacks[SET_TYPEOF_x])(x, v); checkExitCall(); - return result; } void SET_NAMED(SEXP x, int v) { diff --git a/com.oracle.truffle.r.native/fficall/src/truffle_nfi/Rembedded.c b/com.oracle.truffle.r.native/fficall/src/truffle_nfi/Rembedded.c index 770deeca724b7c9b8a1a43f6fea0058e6e6bbab6..945eba892a2e1d21f660bf3db44fd89c97ca5a23 100644 --- a/com.oracle.truffle.r.native/fficall/src/truffle_nfi/Rembedded.c +++ b/com.oracle.truffle.r.native/fficall/src/truffle_nfi/Rembedded.c @@ -60,7 +60,7 @@ static void setupOverrides(void); static void *dlopen_jvmlib(char *libpath); static JNIEnv* getEnv(); static jmethodID checkGetMethodID(JNIEnv *env, jclass klass, const char *name, const char *sig, int isStatic); -static jclass checkFindClass(JNIEnv *env, const char *name); +static jclass checkFindClass(JNIEnv *env, const char *name, const char* vm_cp); static int process_vmargs(int argc, char *argv[], char *vmargv[], char *uargv[]); static char **update_environ_with_java_home(void); static void print_environ(char **env); @@ -224,9 +224,9 @@ static int initializeFastR(int argc, char *argv[], int setupRmainloop) { return 1; } - rInterfaceCallbacksClass = checkFindClass(jniEnv, "com/oracle/truffle/r/runtime/RInterfaceCallbacks"); - rembeddedClass = checkFindClass(jniEnv, "com/oracle/truffle/r/engine/shell/REmbedded"); - jclass stringClass = checkFindClass(jniEnv, "java/lang/String"); + rInterfaceCallbacksClass = checkFindClass(jniEnv, "com/oracle/truffle/r/runtime/RInterfaceCallbacks", vm_cp); + rembeddedClass = checkFindClass(jniEnv, "com/oracle/truffle/r/engine/shell/REmbedded", vm_cp); + jclass stringClass = checkFindClass(jniEnv, "java/lang/String", vm_cp); jmethodID initializeMethod = checkGetMethodID(jniEnv, rembeddedClass, "initializeR", "([Ljava/lang/String;Z)V", 1); jobjectArray argsArray = (*jniEnv)->NewObjectArray(jniEnv, argc, stringClass, NULL); for (int i = 0; i < argc; i++) { @@ -578,13 +578,16 @@ static jmethodID checkGetMethodID(JNIEnv *env, jclass klass, const char *name, c return methodID; } -static jclass checkFindClass(JNIEnv *env, const char *name) { +static jclass checkFindClass(JNIEnv *env, const char *name, const char* vm_cp) { jclass klass = (*env)->FindClass(env, name); if (klass == NULL) { - char buf[1024]; + char buf[16384]; strcpy(buf, "failed to find class "); strcat(buf, name); + strcat(buf, " in classpath "); + strcat(buf, vm_cp); strcat(buf, ".\nDid you set R_HOME to the correct location?"); + (*env)->ExceptionDescribe(env); (*env)->FatalError(env, buf); } return (*env)->NewGlobalRef(env, klass); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AllNames.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AllNames.java index 7a73125009e2d2c99480dfcbc6ecb84440a15b55..97779f7aba1e2797c26e0c442a8f2c27dc3d02ef 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AllNames.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AllNames.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2018, 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 @@ -31,13 +31,12 @@ import java.util.HashSet; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.r.nodes.RASTUtils; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RExpression; -import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.RSymbol; import com.oracle.truffle.r.runtime.nodes.RSyntaxCall; @@ -66,19 +65,19 @@ public abstract class AllNames extends RBuiltinNode.Arg4 { Object expr = exprs.getDataAt(i); if (expr instanceof RSymbol) { visitor.accept(RSyntaxLookup.createDummyLookup(null, ((RSymbol) expr).getName(), false)); - } else if (expr instanceof RLanguage) { - RLanguage lang = (RLanguage) expr; - visitor.accept(RASTUtils.unwrap(lang.getRep()).asRSyntaxNode()); + } else if ((expr instanceof RPairList && ((RPairList) expr).isLanguage())) { + RPairList lang = (RPairList) expr; + visitor.accept(lang.getSyntaxElement()); } } return visitor.getResult(); } - @Specialization + @Specialization(guards = "expr.isLanguage()") @TruffleBoundary - protected Object doAllNames(RLanguage expr, byte functions, int maxNames, byte unique) { + protected Object doAllNames(RPairList expr, byte functions, int maxNames, byte unique) { AllNamesVisitor visitor = new AllNamesVisitor(functions == RRuntime.LOGICAL_TRUE, maxNames, unique == RRuntime.LOGICAL_TRUE); - visitor.accept(RASTUtils.unwrap(expr.getRep()).asRSyntaxNode()); + visitor.accept(expr.getSyntaxElement()); return visitor.getResult(); } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCall.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCall.java index 7139930df041522007009b725c638afec6a756a6..df7305df9eef1c4aec2251aa40c3352db670e801 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCall.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCall.java @@ -32,15 +32,15 @@ import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.nodes.RASTUtils; import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNamesAttributeNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; -import com.oracle.truffle.r.nodes.function.RCallBaseNode; import com.oracle.truffle.r.runtime.ArgumentsSignature; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RError.Message; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; import com.oracle.truffle.r.runtime.data.model.RAbstractListBaseVector; +import com.oracle.truffle.r.runtime.gnur.SEXPTYPE; import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; @RBuiltin(name = "as.call", kind = PRIMITIVE, parameterNames = {"x"}, behavior = PURE) @@ -55,9 +55,9 @@ public abstract class AsCall extends RBuiltinNode.Arg1 { @Specialization @TruffleBoundary - protected RLanguage asCallFunction(RAbstractListBaseVector x) { + protected RPairList asCallFunction(RAbstractListBaseVector x) { if (x.getLength() == 0) { - error(Message.INVALID_LEN_0_ARG); + throw error(Message.INVALID_LEN_0_ARG); } // separate the first element (call target) from the rest (arguments) @@ -88,13 +88,13 @@ public abstract class AsCall extends RBuiltinNode.Arg1 { } } - protected boolean containsCall(RLanguage l) { - return l.getRep() instanceof RCallBaseNode; - } - - @Specialization(guards = "containsCall(l)") - protected RLanguage asCall(RLanguage l) { - return l; + @Specialization + protected Object asCall(RPairList l) { + if (l.isLanguage()) { + return l; + } else { + return RPairList.asPairList(l, SEXPTYPE.LANGSXP); + } } @Fallback diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsFunction.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsFunction.java index f996bc6bb45487328c1a51db140550f3f37c045a..998befd07a407ff900566fce99ddb6ba0b2d7a2a 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsFunction.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsFunction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2018, 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 @@ -48,7 +48,7 @@ import com.oracle.truffle.r.runtime.data.RAttributable; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RExpression; import com.oracle.truffle.r.runtime.data.RFunction; -import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RMissing; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RStringVector; @@ -96,8 +96,8 @@ public abstract class AsFunction extends RBuiltinNode.Arg2 { defaultValue = null; } else if (arg == RNull.instance) { defaultValue = RContext.getASTBuilder().constant(RSyntaxNode.LAZY_DEPARSE, RNull.instance).asRNode(); - } else if (arg instanceof RLanguage) { - defaultValue = (RNode) ((RLanguage) arg).getRep(); + } else if ((arg instanceof RPairList && ((RPairList) arg).isLanguage())) { + defaultValue = ((RPairList) arg).createNode().asRNode(); } else if (arg instanceof RSymbol) { RSymbol symbol = (RSymbol) arg; if (symbol.isMissing()) { @@ -128,8 +128,8 @@ public abstract class AsFunction extends RBuiltinNode.Arg2 { RBaseNode body; Object bodyObject = x.getDataAtAsObject(x.getLength() - 1); - if (bodyObject instanceof RLanguage) { - body = (RBaseNode) RContext.getASTBuilder().process(((RLanguage) x.getDataAtAsObject(x.getLength() - 1)).getRep().asRSyntaxNode()); + if ((bodyObject instanceof RPairList && ((RPairList) bodyObject).isLanguage())) { + body = RContext.getASTBuilder().process(((RPairList) x.getDataAtAsObject(x.getLength() - 1)).getSyntaxElement()).asRNode(); } else if (bodyObject instanceof RSymbol) { body = RContext.getASTBuilder().lookup(RSyntaxNode.LAZY_DEPARSE, ((RSymbol) bodyObject).getName(), false).asRNode(); } else { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java index b6747d6c4872dd37c96b7619bc22588fd4c2ac50..3a0a601b0894573b2601b650d3c2ea53c89302c8 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java @@ -70,7 +70,6 @@ import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.data.RAttributesLayout; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RExpression; -import com.oracle.truffle.r.runtime.data.RLanguage; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RS4Object; @@ -184,9 +183,13 @@ public abstract class AsVector extends RBuiltinNode.Arg2 { throw RError.error(RError.SHOW_CALLER, Message.CANNOT_COERCE, RType.Environment.getName(), type != null ? type.getName() : mode); } + protected static boolean isREnvironment(Object value) { + return value instanceof REnvironment; + } + // there should never be more than ~12 specializations @SuppressWarnings("unused") - @Specialization(limit = "99", guards = {"!isEnv(x)", "matchesMode(mode, cachedMode)"}) + @Specialization(limit = "99", guards = {"!isREnvironment(x)", "matchesMode(mode, cachedMode)"}) protected Object asVector(Object x, String mode, @Cached("mode") String cachedMode, @Cached("fromMode(cachedMode)") RType type, @@ -198,11 +201,7 @@ public abstract class AsVector extends RBuiltinNode.Arg2 { if (!RRuntime.isForeignObject(o)) { return cast == null ? o : cast.doCast(o); } - if (type == RType.List) { - throw RError.error(RError.SHOW_CALLER, RError.Message.CANNOT_COERCE_EXTERNAL_OBJECT_TO_VECTOR, "list"); - } else { - throw RError.error(RError.SHOW_CALLER, RError.Message.CANNOT_COERCE_EXTERNAL_OBJECT_TO_VECTOR, "vector"); - } + throw RError.error(RError.SHOW_CALLER, RError.Message.CANNOT_COERCE_EXTERNAL_OBJECT_TO_VECTOR, type == RType.List ? "list" : "vector"); } Object result = x; if (x instanceof RS4Object) { @@ -211,10 +210,6 @@ public abstract class AsVector extends RBuiltinNode.Arg2 { return drop.execute(result, cast == null ? x : cast.doCast(result)); } - static boolean isEnv(Object x) { - return x instanceof REnvironment; - } - private Object getS4DataSlot(RS4Object o) { if (getS4DataSlotNode == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); @@ -260,8 +255,8 @@ public abstract class AsVector extends RBuiltinNode.Arg2 { return profile.profile(o.getAttributes() != null) ? o.copyDropAttributes() : o; } - @Specialization(guards = "o.getAttributes() != null") - protected RLanguage drop(@SuppressWarnings("unused") Object original, RLanguage o) { + @Specialization(guards = {"o.isLanguage()", "o.getAttributes() != null"}) + protected RPairList drop(@SuppressWarnings("unused") Object original, RPairList o) { switch (targetType) { case Any: case PairList: @@ -277,7 +272,7 @@ public abstract class AsVector extends RBuiltinNode.Arg2 { } @Specialization(guards = "pairList.getAttributes() != null") - protected Object drop(@SuppressWarnings("unused") Object original, RPairList pairList) { + protected Object dropPairList(@SuppressWarnings("unused") Object original, RPairList pairList) { // dropping already done in the cast node CastPairListNode below return pairList; } @@ -334,15 +329,8 @@ public abstract class AsVector extends RBuiltinNode.Arg2 { } @Specialization - @TruffleBoundary - protected Object doPairList(RPairList list) { - return list.copy(); - } - - @Specialization - protected Object doRLanguage(RLanguage language) { - // GNUR just let's language be language... - return language; + protected Object doRLanguage(RPairList pairlist) { + return pairlist; } @Fallback diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Call.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Call.java index 466d405fd046abc956319982b7ce2e2b0a8b77ca..c603e2fc90eed41f694873549c2ef4be7f3375ab 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Call.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Call.java @@ -40,15 +40,16 @@ import com.oracle.truffle.r.runtime.context.TruffleRLanguage; import com.oracle.truffle.r.runtime.data.Closure; import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; import com.oracle.truffle.r.runtime.data.RDataFactory; -import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RMissing; +import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.nodes.RCodeBuilder; import com.oracle.truffle.r.runtime.nodes.RNode; import com.oracle.truffle.r.runtime.nodes.RSyntaxLookup; import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; /** - * Construct a call object ({@link RLanguage}) from a name and optional arguments. + * Construct a call object ({@link RPairList}) from a name and optional arguments. * * Does not perform argument matching for first parameter "name". */ @@ -67,14 +68,15 @@ public abstract class Call extends RBuiltinNode.Arg2 { @Specialization @TruffleBoundary - protected RLanguage call(String name, RArgsValuesAndNames args) { + protected RPairList call(String name, RArgsValuesAndNames args) { return makeCall(getRLanguage(), RContext.getASTBuilder().lookup(RSyntaxNode.LAZY_DEPARSE, name, true), args.getArguments(), args.getSignature()); } @TruffleBoundary - public static RLanguage makeCall(TruffleRLanguage language, RSyntaxNode target, Object[] arguments, ArgumentsSignature signature) { + public static RPairList makeCall(TruffleRLanguage language, RSyntaxNode target, Object[] arguments, ArgumentsSignature signature) { assert arguments.length == signature.getLength(); - if (target instanceof RSyntaxLookup && "function".equals(((RSyntaxLookup) target).getIdentifier()) && arguments.length == 2) { + if (target instanceof RSyntaxLookup && "function".equals(((RSyntaxLookup) target).getIdentifier()) && arguments.length >= 2 && + (arguments[1] == RNull.instance || arguments[1] instanceof RPairList)) { // this optimization is not strictly necessary, `function` builtin is functional too. FunctionExpressionNode function = FunctionBuiltin.createFunctionExpressionNode(language, arguments[0], arguments[1]); return RDataFactory.createLanguage(Closure.createLanguageClosure(function.asRNode())); @@ -84,7 +86,7 @@ public abstract class Call extends RBuiltinNode.Arg2 { } @TruffleBoundary - private static RLanguage makeCall0(RSyntaxNode target, Object[] arguments, ArgumentsSignature signature) { + private static RPairList makeCall0(RSyntaxNode target, Object[] arguments, ArgumentsSignature signature) { RSyntaxNode[] args = new RSyntaxNode[arguments.length]; for (int i = 0; i < arguments.length; i++) { args[i] = (RSyntaxNode) RASTUtils.createNodeForValue(arguments[i]); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Cat.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Cat.java index c1002705f1527f1de76d9b2759a3f7fd9b165218..a6f99d109689b7196e1029a581c1db854c1d0682 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Cat.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Cat.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2018, 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 @@ -52,7 +52,7 @@ import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.REmpty; import com.oracle.truffle.r.runtime.data.RExpression; -import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RMissing; import com.oracle.truffle.r.runtime.data.RNull; @@ -209,7 +209,7 @@ public abstract class Cat extends RBuiltinNode.Arg6 { } private void validateType(int argIndex, Object obj) { - if (obj instanceof RList || obj instanceof RLanguage || obj instanceof RExpression) { + if (obj instanceof RList || (obj instanceof RPairList && ((RPairList) obj).isLanguage()) || obj instanceof RExpression) { RTypedValue rType = (RTypedValue) obj; throw error(Message.CAT_ARGUMENT_OF_TYPE, argIndex, rType.getRType().getName()); } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Combine.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Combine.java index c67f195568f87887e16278c1827f7472ef09b915..5f9940f9c0ef0e4ea6ca562a5f07d25f0222946d 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Combine.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Combine.java @@ -71,7 +71,7 @@ import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; import com.oracle.truffle.r.runtime.data.RAttributesLayout; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RFunction; -import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RS4Object; @@ -121,7 +121,7 @@ public abstract class Combine extends RBuiltinNode.Arg2 { !(args.getArgument(0) instanceof RAbstractVector) && !(args.getArgument(0) instanceof REnvironment) && !(args.getArgument(0) instanceof RFunction) && - !(args.getArgument(0) instanceof RLanguage) && + !(args.getArgument(0) instanceof RPairList) && !(args.getArgument(0) instanceof RSymbol) && !(args.getArgument(0) instanceof RS4Object) && !RRuntime.isForeignObject(args.getArgument(0)); @@ -238,7 +238,7 @@ public abstract class Combine extends RBuiltinNode.Arg2 { for (int i = 0; i < elements.length; i++) { CombineInputCast inputCast = getCast(i); Object value = args[i]; - Object element = (exprListPrecedence && value instanceof RLanguage) ? value : cast.doCast(inputCast.cast(value)); + Object element = (exprListPrecedence && (value instanceof RPairList && ((RPairList) value).isLanguage())) ? value : cast.doCast(inputCast.cast(value)); element = inputCast.valueProfile.profile(element); elements[i] = element; size += getElementSize(element); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DoCall.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DoCall.java index 289fadac02fa12812e51ce2975fe7fcd3d1c499d..5d56afcee2c928d467ea8394658de6d6351dd47c 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DoCall.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DoCall.java @@ -72,8 +72,8 @@ import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.REmpty; import com.oracle.truffle.r.runtime.data.RFunction; -import com.oracle.truffle.r.runtime.data.RLanguage; import com.oracle.truffle.r.runtime.data.RList; +import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RPromise; import com.oracle.truffle.r.runtime.data.RPromise.PromiseState; import com.oracle.truffle.r.runtime.data.RSymbol; @@ -226,8 +226,8 @@ public abstract class DoCall extends RBuiltinNode.Arg4 implements InternalRSynta } else { argValues[i] = createLookupPromise(promiseFrame, symbol.getName()); } - } else if (arg instanceof RLanguage) { - argValues[i] = createLanguagePromise(promiseFrame, (RLanguage) arg); + } else if ((arg instanceof RPairList && ((RPairList) arg).isLanguage())) { + argValues[i] = createLanguagePromise(promiseFrame, (RPairList) arg); } } } @@ -236,9 +236,8 @@ public abstract class DoCall extends RBuiltinNode.Arg4 implements InternalRSynta } @TruffleBoundary - private RPromise createLanguagePromise(MaterializedFrame promiseFrame, RLanguage arg) { - Closure closure = languagesClosureCache.getOrCreatePromiseClosure(arg.getRep()); - return RDataFactory.createPromise(PromiseState.Supplied, closure, promiseFrame); + private RPromise createLanguagePromise(MaterializedFrame promiseFrame, RPairList arg) { + return RDataFactory.createPromise(PromiseState.Supplied, arg.getClosure(languagesClosureCache), promiseFrame); } @TruffleBoundary diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EnvFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EnvFunctions.java index 6e8e3aec40fa299d74c4e6a173908e8895098393..324249e38dd0faea4957f0c13ce9ccb2e940f4f1 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EnvFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EnvFunctions.java @@ -49,7 +49,6 @@ import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.profiles.BranchProfile; -import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.nodes.RRootNode; import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode; import com.oracle.truffle.r.nodes.attributes.GetFixedAttributeNode; @@ -58,7 +57,6 @@ import com.oracle.truffle.r.nodes.builtin.EnvironmentNodes.GetFunctionEnvironmen import com.oracle.truffle.r.nodes.builtin.EnvironmentNodes.RList2EnvNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.builtin.base.EnvFunctionsFactory.CopyNodeGen; -import com.oracle.truffle.r.nodes.function.ClassHierarchyNode; import com.oracle.truffle.r.nodes.function.GetCallerFrameNode; import com.oracle.truffle.r.nodes.function.PromiseHelperNode; import com.oracle.truffle.r.nodes.function.PromiseHelperNode.PromiseDeoptimizeFrameNode; @@ -75,10 +73,10 @@ import com.oracle.truffle.r.runtime.data.RAttributesLayout; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RExternalPtr; import com.oracle.truffle.r.runtime.data.RFunction; -import com.oracle.truffle.r.runtime.data.RLanguage; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RMissing; 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.RS4Object; import com.oracle.truffle.r.runtime.data.RStringVector; @@ -340,9 +338,6 @@ public class EnvFunctions { @RBuiltin(name = "environment", kind = INTERNAL, parameterNames = {"fun"}, behavior = COMPLEX) public abstract static class Environment extends RBuiltinNode.Arg1 { - private final ConditionProfile attributable = ConditionProfile.createBinaryProfile(); - @Child private GetFixedAttributeNode getEnvAttrNode; - static { Casts.noCasts(Environment.class); } @@ -367,34 +362,21 @@ public class EnvFunctions { return getEnv.getEnvironment(fun); } - @Specialization + protected static GetFixedAttributeNode createDotEnv() { + return GetFixedAttributeNode.create(RRuntime.DOT_ENVIRONMENT); + } + + @Specialization(guards = "!isRFunction(value)") @TruffleBoundary - protected Object environmentLanguage(RLanguage value) { - if (ClassHierarchyNode.hasClass(value, RRuntime.FORMULA_CLASS)) { - if (getEnvAttrNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - getEnvAttrNode = insert(GetFixedAttributeNode.create(RRuntime.DOT_ENVIRONMENT)); - } - Object result = getEnvAttrNode.execute(value); - return result == null ? RNull.instance : result; - } else { - return environment(value); - } + protected Object environmentLanguage(RAttributable value, + @Cached("createDotEnv()") GetFixedAttributeNode getEnvAttrNode) { + Object result = getEnvAttrNode.execute(value); + return result == null ? RNull.instance : result; } - @Specialization(guards = {"!isRNull(value)", "!isRFunction(value)", "!isRLanguage(value)"}) - protected Object environment(Object value) { - if (attributable.profile(value instanceof RAttributable)) { - if (getEnvAttrNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - getEnvAttrNode = insert(GetFixedAttributeNode.create(RRuntime.DOT_ENVIRONMENT)); - } - Object attr = getEnvAttrNode.execute(value); - return attr == null ? RNull.instance : attr; - } else { - // Not an error according to GnuR - return RNull.instance; - } + @Fallback + protected Object environment(@SuppressWarnings("unused") Object value) { + return RNull.instance; } } @@ -747,8 +729,8 @@ public class EnvFunctions { return v.copy(); } - @Specialization - RLanguage copy(RLanguage l) { + @Specialization(guards = "l.isLanguage()") + RPairList copy(RPairList l) { return l.copy(); } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Eval.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Eval.java index 12c2f8e4103696ec9f8fdae8fc157655946cae49..b77b22bbce02f925a39c56ba46a4edfbf855f7bf 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Eval.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Eval.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2018, 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 @@ -58,11 +58,10 @@ import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; import com.oracle.truffle.r.runtime.data.RExpression; -import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RMissing; import com.oracle.truffle.r.runtime.data.RNull; -import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RSymbol; import com.oracle.truffle.r.runtime.env.REnvironment; import com.oracle.truffle.r.runtime.nodes.RBaseNode; @@ -119,7 +118,7 @@ public abstract class Eval extends RBuiltinNode.Arg3 { return rList2EnvNode.execute(list, null, null, enclos); } - @Specialization + @Specialization(guards = "!list.isLanguage()") protected REnvironment cast(RPairList list, REnvironment enclos) { lazyCreateRList2EnvNode(); return rList2EnvNode.execute(list.toRList(), null, null, enclos); @@ -133,7 +132,7 @@ public abstract class Eval extends RBuiltinNode.Arg3 { return rList2EnvNode.execute(list, null, null, REnvironment.baseEnv()); } - @Specialization + @Specialization(guards = "!list.isLanguage()") protected REnvironment cast(RPairList list, @SuppressWarnings("unused") RNull enclos) { lazyCreateRList2EnvNode(); @@ -171,8 +170,8 @@ public abstract class Eval extends RBuiltinNode.Arg3 { casts.arg("enclos").allowNull().mustBe(REnvironment.class); } - @Specialization - protected Object doEval(VirtualFrame frame, RLanguage expr, Object envir, Object enclos) { + @Specialization(guards = "expr.isLanguage()") + protected Object doEval(VirtualFrame frame, RPairList expr, Object envir, Object enclos) { REnvironment environment = envCast.execute(frame, envir, enclos); RCaller rCaller = getCaller(frame, environment); try { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Expression.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Expression.java index c58f3020137ad9a68eaede21ba87a484355e5688..883333d5b764d031f5de8503dfd5ad5fd4487aad 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Expression.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Expression.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2018, 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 @@ -40,7 +40,7 @@ import com.oracle.truffle.r.runtime.data.RPromise; public abstract class Expression extends RBuiltinNode.Arg1 { /* * Owing to the nonEvalArgs, all arguments are RPromise, but an expression may contain - * non-RLanguage elements. + * non-RPairList elements. */ private final ConditionProfile isEvaluatedProfile = ConditionProfile.createBinaryProfile(); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FrameFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FrameFunctions.java index 3ec9be5ccfee7e492d9ce5d8f13779eb1488f683..9cc46a846c6409de9e221fff7a041e45ddc4c7ac 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FrameFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/FrameFunctions.java @@ -72,9 +72,8 @@ import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RExpression; import com.oracle.truffle.r.runtime.data.RFunction; import com.oracle.truffle.r.runtime.data.RIntVector; -import com.oracle.truffle.r.runtime.data.RLanguage; -import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RPairList; +import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RPromise; import com.oracle.truffle.r.runtime.env.REnvironment; import com.oracle.truffle.r.runtime.env.frame.FrameSlotChangeMonitor; @@ -234,18 +233,18 @@ public class FrameFunctions { static { Casts casts = new Casts(MatchCall.class); casts.arg("definition").mustBe(RFunction.class); - casts.arg("call").mustBe(RLanguage.class); + casts.arg("call").mustBe(RPairList.class); casts.arg("expand.dots").asLogicalVector().findFirst(); casts.arg("envir").mustBe(REnvironment.class, Message.MUST_BE_ENVIRON, "envir"); } @Specialization - protected RLanguage matchCall(RFunction definition, Object callObj, byte expandDotsL, REnvironment env) { + protected RPairList matchCall(RFunction definition, Object callObj, byte expandDotsL, REnvironment env) { /* * definition==null in the standard (default) case, in which case we get the RFunction * from the calling frame */ - RLanguage call = checkCall(callObj); + RPairList call = checkCall(callObj); if (expandDotsL == RRuntime.LOGICAL_NA) { throw error(RError.Message.INVALID_ARGUMENT, "expand.dots"); } @@ -255,19 +254,19 @@ public class FrameFunctions { } @TruffleBoundary - private static RLanguage doMatchCall(MaterializedFrame cframe, RFunction definition, RLanguage call, boolean expandDots) { + private static RPairList doMatchCall(MaterializedFrame cframe, RFunction definition, RPairList call, boolean expandDots) { /* * We have to ensure that all parameters are named, in the correct order, and deal with * "...". This process has a lot in common with MatchArguments, which we use as a * starting point */ - RCallNode callNode = (RCallNode) RASTUtils.unwrap(call.getRep()); + RCallNode callNode = (RCallNode) call.getSyntaxElement(); CallArgumentsNode callArgs = callNode.createArguments(null, false, true); ArgumentsSignature inputVarArgSignature = callArgs.containsVarArgsSymbol() ? CallArgumentsNode.getVarargsAndNames(cframe).getSignature() : null; RNode[] matchedArgNodes = ArgumentMatcher.matchArguments((RRootNode) definition.getRootNode(), callArgs, inputVarArgSignature, null, null, true).getArguments(); ArgumentsSignature sig = ((HasSignature) definition.getRootNode()).getSignature(); // expand any varargs - ArrayList<RNode> nodes = new ArrayList<>(); + ArrayList<RSyntaxNode> nodes = new ArrayList<>(); ArrayList<String> names = new ArrayList<>(); FrameSlot varArgSlot = cframe.getFrameDescriptor().findFrameSlot(ArgumentsSignature.VARARG_NAME); @@ -300,7 +299,7 @@ public class FrameFunctions { if (expandDots) { for (int i2 = 0; i2 < varArgNodes.length; i2++) { - nodes.add(varArgNodes[i2]); + nodes.add(varArgNodes[i2].asRSyntaxNode()); names.add(varArgSignature.getName(i2)); } } else { @@ -329,10 +328,10 @@ public class FrameFunctions { names.add(ArgumentsSignature.VARARG_NAME); } } else if (arg instanceof PromiseNode) { - nodes.add(((PromiseNode) arg).getPromiseExpr().asRNode()); + nodes.add(((PromiseNode) arg).getPromiseExpr()); names.add(sig.getName(i)); } else { - nodes.add(arg); + nodes.add(arg.asRSyntaxNode()); names.add(sig.getName(i)); } } @@ -377,21 +376,17 @@ public class FrameFunctions { @Specialization @SuppressWarnings("unused") - protected RLanguage matchCall(Object definition, Object call, Object expandDots, Object envir) { + protected RPairList matchCall(Object definition, Object call, Object expandDots, Object envir) { throw error(RError.Message.INVALID_OR_UNIMPLEMENTED_ARGUMENTS); } - private RLanguage checkCall(Object obj) throws RError { + private RPairList checkCall(Object obj) throws RError { Object callObj = obj; while (callObj instanceof RExpression) { callObj = ((RExpression) callObj).getDataAt(0); } - if (callObj instanceof RLanguage) { - RLanguage call = (RLanguage) callObj; - RNode node = (RNode) RASTUtils.unwrap(call.getRep()); - if (node instanceof RCallNode) { - return call; - } + if ((callObj instanceof RPairList && ((RPairList) callObj).isLanguage())) { + return (RPairList) callObj; } throw error(RError.Message.INVALID_ARGUMENT, "call"); } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/HiddenInternalFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/HiddenInternalFunctions.java index 938fc86868755f44f9c7bff182d27f84938a8856..0cdb82aa469d4247cdc8bea6e8709c1b8bebab0e 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/HiddenInternalFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/HiddenInternalFunctions.java @@ -24,6 +24,7 @@ import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.nio.ByteBuffer; +import java.util.ArrayList; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; @@ -33,8 +34,6 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.LoopNode; -import com.oracle.truffle.r.nodes.RASTUtils; -import com.oracle.truffle.r.nodes.access.ConstantNode; import com.oracle.truffle.r.nodes.access.variables.ReadVariableNode; import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetClassAttributeNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; @@ -42,6 +41,7 @@ import com.oracle.truffle.r.nodes.function.PromiseHelperNode; import com.oracle.truffle.r.nodes.function.RCallNode; import com.oracle.truffle.r.nodes.function.call.CallRFunctionCachedNode; import com.oracle.truffle.r.nodes.function.call.CallRFunctionCachedNodeGen; +import com.oracle.truffle.r.runtime.ArgumentsSignature; import com.oracle.truffle.r.runtime.RCaller; import com.oracle.truffle.r.runtime.RCompression; import com.oracle.truffle.r.runtime.RError; @@ -56,9 +56,9 @@ import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RExternalPtr; import com.oracle.truffle.r.runtime.data.RFunction; 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.RNull; +import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RPromise; import com.oracle.truffle.r.runtime.data.RPromise.PromiseState; import com.oracle.truffle.r.runtime.data.RStringVector; @@ -67,6 +67,11 @@ import com.oracle.truffle.r.runtime.env.REnvironment; import com.oracle.truffle.r.runtime.env.REnvironment.PutException; import com.oracle.truffle.r.runtime.ffi.DLL; import com.oracle.truffle.r.runtime.ffi.DLL.DLLInfo; +import com.oracle.truffle.r.runtime.nodes.RCodeBuilder; +import com.oracle.truffle.r.runtime.nodes.RCodeBuilder.Argument; +import com.oracle.truffle.r.runtime.nodes.RSyntaxCall; +import com.oracle.truffle.r.runtime.nodes.RSyntaxElement; +import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; /** * Private, undocumented, {@code .Internal} and {@code .Primitive} functions transcribed from GnuR, @@ -103,9 +108,9 @@ public class HiddenInternalFunctions { * {@code names}. The value for the name stored as a {@link RPromise} to evaluate the * modified call in the {@code eenv} environment. */ - @Specialization + @Specialization(guards = "expr.isLanguage()") @TruffleBoundary - protected RNull doMakeLazy(RAbstractStringVector names, RList values, RLanguage expr, REnvironment eenv, REnvironment aenv) { + protected RNull doMakeLazy(RAbstractStringVector names, RList values, RPairList expr, REnvironment eenv, REnvironment aenv) { initEval(); for (int i = 0; i < names.getLength(); i++) { String name = names.getDataAt(i); @@ -113,9 +118,19 @@ public class HiddenInternalFunctions { // GnuR does an eval but we short cut since intVec evaluates to itself. // What happens next a pretty gross - we replace the "key" argument variable read // in expr with a constant that is the value of intVec - RCallNode callNode = (RCallNode) RASTUtils.unwrap(expr.getRep()); - ConstantNode vecNode = ConstantNode.create(intVec); - RCallNode expr0 = RCallNode.createCloneReplacingArgs(callNode, vecNode); + + RSyntaxCall element = (RSyntaxCall) expr.getSyntaxElement(); + RSyntaxElement[] arguments = element.getSyntaxArguments(); + ArgumentsSignature signature = element.getSyntaxSignature(); + + RCodeBuilder<RSyntaxNode> builder = RContext.getASTBuilder(); + ArrayList<Argument<RSyntaxNode>> args = new ArrayList<>(arguments.length); + args.add(RCodeBuilder.argument(RSyntaxNode.INTERNAL, signature.getName(i), builder.constant(RSyntaxNode.INTERNAL, intVec))); + for (int j = 1; j < arguments.length; j++) { + args.add(RCodeBuilder.argument(arguments[j] == null ? null : arguments[j].getLazySourceSection(), signature.getName(j), + arguments[j] == null ? null : builder.process(arguments[j]))); + } + RCallNode expr0 = (RCallNode) builder.call(element.getLazySourceSection(), builder.process(element.getSyntaxLHS()), args).asRNode(); try { // We want this call to have a SourceSection aenv.put(name, RDataFactory.createPromise(PromiseState.Explicit, Closure.createPromiseClosure(expr0), eenv.getFrame())); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Identical.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Identical.java index ce13c56a758c09b8b6b29cb56b52ea0c23f27872..31f0ac35210691cbe97075186576185c06b82111 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Identical.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Identical.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2018, 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 @@ -32,8 +32,8 @@ import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.object.DynamicObject; import com.oracle.truffle.api.interop.TruffleObject; +import com.oracle.truffle.api.object.DynamicObject; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.nodes.attributes.IterableAttributeNode; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; @@ -46,7 +46,6 @@ import com.oracle.truffle.r.runtime.data.RAttributesLayout; import com.oracle.truffle.r.runtime.data.RExternalPtr; import com.oracle.truffle.r.runtime.data.RFunction; import com.oracle.truffle.r.runtime.data.RInteropScalar; -import com.oracle.truffle.r.runtime.data.RLanguage; import com.oracle.truffle.r.runtime.data.RListBase; import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RS4Object; @@ -164,14 +163,45 @@ public abstract class Identical extends RBuiltinNode.Arg8 { } private byte identicalAttr(RAttributable x, RAttributable y, boolean numEq, boolean singleNA, boolean attribAsSet, boolean ignoreBytecode, boolean ignoreEnvironment, boolean ignoreSrcref) { - // TODO interpret attribAsSet correctly DynamicObject xAttributes = x.getAttributes(); DynamicObject yAttributes = y.getAttributes(); - if (xAttributes == null && yAttributes == null) { + int xSize = xAttributes == null ? 0 : xAttributes.size(); + int ySize = yAttributes == null ? 0 : yAttributes.size(); + if (xSize == 0 && ySize == 0) { return RRuntime.LOGICAL_TRUE; - } else if (xAttributes == null || yAttributes == null) { + } else if (xSize != ySize) { return RRuntime.LOGICAL_FALSE; - } else if (xAttributes.size() == yAttributes.size()) { + } else { + return identicalAttrInternal(numEq, singleNA, attribAsSet, ignoreBytecode, ignoreEnvironment, ignoreSrcref, xAttributes, yAttributes); + } + } + + @TruffleBoundary + private byte identicalAttrInternal(boolean numEq, boolean singleNA, boolean attribAsSet, boolean ignoreBytecode, boolean ignoreEnvironment, boolean ignoreSrcref, DynamicObject xAttributes, + DynamicObject yAttributes) { + if (attribAsSet) { + // make sure all attributes from x are in y, with identical values + Iterator<RAttributesLayout.RAttribute> xIter = attrIterNodeX.execute(xAttributes).iterator(); + while (xIter.hasNext()) { + RAttributesLayout.RAttribute xAttr = xIter.next(); + Object yValue = yAttributes.get(xAttr.getName()); + if (yValue == null) { + return RRuntime.LOGICAL_FALSE; + } + byte res = identicalRecursiveAttr(xAttr.getValue(), yValue, numEq, singleNA, attribAsSet, ignoreBytecode, ignoreEnvironment, ignoreSrcref); + if (res == RRuntime.LOGICAL_FALSE) { + return RRuntime.LOGICAL_FALSE; + } + } + // make sure all attributes from y are in x + Iterator<RAttributesLayout.RAttribute> yIter = attrIterNodeY.execute(yAttributes).iterator(); + while (xIter.hasNext()) { + RAttributesLayout.RAttribute yAttr = yIter.next(); + if (!xAttributes.containsKey(yAttr.getName())) { + return RRuntime.LOGICAL_FALSE; + } + } + } else { Iterator<RAttributesLayout.RAttribute> xIter = attrIterNodeX.execute(xAttributes).iterator(); Iterator<RAttributesLayout.RAttribute> yIter = attrIterNodeY.execute(yAttributes).iterator(); while (xIter.hasNext()) { @@ -185,9 +215,8 @@ public abstract class Identical extends RBuiltinNode.Arg8 { return RRuntime.LOGICAL_FALSE; } } - return RRuntime.LOGICAL_TRUE; } - return RRuntime.LOGICAL_FALSE; + return RRuntime.LOGICAL_TRUE; } @SuppressWarnings("unused") @@ -204,20 +233,6 @@ public abstract class Identical extends RBuiltinNode.Arg8 { return RRuntime.asLogical(x.getName() == y.getName()); } - @Specialization - @TruffleBoundary - protected byte doInternalIdentical(RLanguage x, RLanguage y, boolean numEq, boolean singleNA, boolean attribAsSet, boolean ignoreBytecode, boolean ignoreEnvironment, boolean ignoreSrcref) { - if (x == y) { - return RRuntime.LOGICAL_TRUE; - } - RSyntaxNode xNode = x.getRep().asRSyntaxNode(); - RSyntaxNode yNode = y.getRep().asRSyntaxNode(); - if (!new IdenticalVisitor().accept(xNode, yNode)) { - return RRuntime.LOGICAL_FALSE; - } - return identicalAttr(x, y, numEq, singleNA, attribAsSet, ignoreBytecode, ignoreEnvironment, ignoreSrcref); - } - @Specialization byte doInternalIdentical(RFunction x, RFunction y, boolean numEq, boolean singleNA, boolean attribAsSet, boolean ignoreBytecode, boolean ignoreEnvironment, boolean ignoreSrcref) { if (x == y) { @@ -300,48 +315,64 @@ public abstract class Identical extends RBuiltinNode.Arg8 { } @Specialization + @TruffleBoundary protected byte doInternalIdenticalGeneric(RPairList x, RPairList y, boolean numEq, boolean singleNA, boolean attribAsSet, boolean ignoreBytecode, boolean ignoreEnvironment, boolean ignoreSrcref) { - if (identicalRecursive(x.car(), y.car(), numEq, singleNA, attribAsSet, ignoreBytecode, ignoreEnvironment, ignoreSrcref) == RRuntime.LOGICAL_FALSE) { - return RRuntime.LOGICAL_FALSE; + if (x == y) { + return RRuntime.LOGICAL_TRUE; } - Object tmpXCdr = x.cdr(); - Object tmpYCdr = y.cdr(); - while (true) { - if (RPairList.isNull(tmpXCdr) && RPairList.isNull(tmpYCdr)) { - break; - } else if (RPairList.isNull(tmpXCdr) || RPairList.isNull(tmpYCdr)) { + boolean xHasClosure = x.hasClosure(); + boolean yHasClosure = y.hasClosure(); + try { + if (identicalRecursive(x.car(), y.car(), numEq, singleNA, attribAsSet, ignoreBytecode, ignoreEnvironment, ignoreSrcref) == RRuntime.LOGICAL_FALSE) { return RRuntime.LOGICAL_FALSE; - } else { - RPairList xSubList = (RPairList) tmpXCdr; - RPairList ySubList = (RPairList) tmpYCdr; - - if (RPairList.isNull(xSubList.getTag()) && RPairList.isNull(ySubList.getTag())) { + } + Object tmpXCdr = x.cdr(); + Object tmpYCdr = y.cdr(); + while (true) { + if (RPairList.isNull(tmpXCdr) && RPairList.isNull(tmpYCdr)) { break; - } else if (RPairList.isNull(xSubList.getTag()) || RPairList.isNull(ySubList.getTag())) { + } else if (RPairList.isNull(tmpXCdr) || RPairList.isNull(tmpYCdr)) { return RRuntime.LOGICAL_FALSE; } else { - if (xSubList.getTag() instanceof RSymbol && ySubList.getTag() instanceof RSymbol) { - String xTagName = ((RSymbol) xSubList.getTag()).getName(); - String yTagName = ((RSymbol) ySubList.getTag()).getName(); - assert Utils.isInterned(xTagName) && Utils.isInterned(yTagName); - if (xTagName != yTagName) { - return RRuntime.LOGICAL_FALSE; - } + RPairList xSubList = (RPairList) tmpXCdr; + RPairList ySubList = (RPairList) tmpYCdr; + + if (RPairList.isNull(xSubList.getTag()) && RPairList.isNull(ySubList.getTag())) { + // continue + } else if (RPairList.isNull(xSubList.getTag()) || RPairList.isNull(ySubList.getTag())) { + return RRuntime.LOGICAL_FALSE; } else { - RInternalError.unimplemented("non-RNull and non-RSymbol pairlist tags are not currently supported"); + if (xSubList.getTag() instanceof RSymbol && ySubList.getTag() instanceof RSymbol) { + String xTagName = ((RSymbol) xSubList.getTag()).getName(); + String yTagName = ((RSymbol) ySubList.getTag()).getName(); + assert Utils.isInterned(xTagName) && Utils.isInterned(yTagName); + if (xTagName != yTagName) { + return RRuntime.LOGICAL_FALSE; + } + } else { + throw RInternalError.unimplemented("non-RNull and non-RSymbol pairlist tags are not currently supported"); + } } + if (identicalRecursive(xSubList.car(), ySubList.car(), numEq, singleNA, attribAsSet, ignoreBytecode, ignoreEnvironment, ignoreSrcref) == RRuntime.LOGICAL_FALSE) { + return RRuntime.LOGICAL_FALSE; + } + if (xSubList.getAttributes() != null || ySubList.getAttributes() != null) { + throw RInternalError.unimplemented("attributes of internal pairlists are not currently supported"); + } + tmpXCdr = ((RPairList) tmpXCdr).cdr(); + tmpYCdr = ((RPairList) tmpYCdr).cdr(); } - if (identicalRecursive(xSubList.car(), ySubList.car(), numEq, singleNA, attribAsSet, ignoreBytecode, ignoreEnvironment, ignoreSrcref) == RRuntime.LOGICAL_FALSE) { - return RRuntime.LOGICAL_FALSE; - } - if (xSubList.getAttributes() != null || ySubList.getAttributes() != null) { - RInternalError.unimplemented("attributes of internal pairlists are not currently supported"); - } - tmpXCdr = ((RPairList) tmpXCdr).cdr(); - tmpYCdr = ((RPairList) tmpYCdr).cdr(); + } + return identicalAttr(x, y, numEq, singleNA, attribAsSet, ignoreBytecode, ignoreEnvironment, ignoreSrcref); + } finally { + // if they were closures before, they can still be afterwards + if (xHasClosure) { + x.allowClosure(); + } + if (yHasClosure) { + y.allowClosure(); } } - return identicalAttr(x, y, numEq, singleNA, attribAsSet, ignoreBytecode, ignoreEnvironment, ignoreSrcref); } @SuppressWarnings("unused") diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsTypeFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsTypeFunctions.java index dee51d150d82e3b75710a984716eb785e812ae04..7497a64aeea4d55b8f3beedb75f86997c422f179 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsTypeFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsTypeFunctions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2018, 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 @@ -49,16 +49,13 @@ import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.RType; import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.data.RAttributable; -import com.oracle.truffle.r.runtime.data.RComplex; 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.RLanguage; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RListBase; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RPairList; -import com.oracle.truffle.r.runtime.data.RRaw; import com.oracle.truffle.r.runtime.data.RSymbol; import com.oracle.truffle.r.runtime.data.model.RAbstractAtomicVector; import com.oracle.truffle.r.runtime.data.model.RAbstractComplexVector; @@ -97,7 +94,7 @@ public class IsTypeFunctions { return RRuntime.asLogical(isArrayProfile.profile(getDim.isArray(vector))); } - @Specialization(guards = {"!isRMissing(value)", "!isRAbstractVector(value)"}) + @Fallback protected byte isType(@SuppressWarnings("unused") Object value) { return RRuntime.LOGICAL_FALSE; } @@ -173,11 +170,11 @@ public class IsTypeFunctions { } @Specialization - protected byte isType(@SuppressWarnings("unused") RLanguage lang) { - return RRuntime.LOGICAL_TRUE; + protected byte isType(RPairList lang) { + return RRuntime.asLogical(lang.isLanguage()); } - @Specialization(guards = {"!isRLanguage(value)"}) + @Fallback protected byte isType(@SuppressWarnings("unused") Object value) { return RRuntime.LOGICAL_FALSE; } @@ -195,11 +192,7 @@ public class IsTypeFunctions { return RRuntime.LOGICAL_TRUE; } - protected static boolean isAnyCharacter(Object value) { - return value instanceof String || value instanceof RAbstractStringVector; - } - - @Specialization(guards = {"!isRMissing(value)", "!isAnyCharacter(value)"}) + @Fallback protected byte isType(@SuppressWarnings("unused") Object value) { return RRuntime.LOGICAL_FALSE; } @@ -217,11 +210,7 @@ public class IsTypeFunctions { return RRuntime.LOGICAL_TRUE; } - protected static boolean isAnyComplex(Object value) { - return value instanceof RComplex || value instanceof RAbstractComplexVector; - } - - @Specialization(guards = {"!isRMissing(value)", "!isAnyComplex(value)"}) + @Fallback protected byte isType(@SuppressWarnings("unused") Object value) { return RRuntime.LOGICAL_FALSE; } @@ -239,11 +228,7 @@ public class IsTypeFunctions { return RRuntime.LOGICAL_TRUE; } - protected static boolean isAnyDouble(Object value) { - return value instanceof Double || value instanceof RAbstractDoubleVector; - } - - @Specialization(guards = {"!isRMissing(value)", "!isAnyDouble(value)"}) + @Fallback protected byte isType(@SuppressWarnings("unused") Object value) { return RRuntime.LOGICAL_FALSE; } @@ -261,7 +246,7 @@ public class IsTypeFunctions { return RRuntime.LOGICAL_TRUE; } - @Specialization(guards = {"!isRMissing(value)", "!isRExpression(value)"}) + @Fallback protected byte isType(@SuppressWarnings("unused") Object value) { return RRuntime.LOGICAL_FALSE; } @@ -279,7 +264,7 @@ public class IsTypeFunctions { return RRuntime.LOGICAL_TRUE; } - @Specialization(guards = {"!isRMissing(value)", "!isRFunction(value)"}) + @Fallback protected byte isType(@SuppressWarnings("unused") Object value) { return RRuntime.LOGICAL_FALSE; } @@ -297,11 +282,7 @@ public class IsTypeFunctions { return RRuntime.LOGICAL_TRUE; } - protected static boolean isAnyInteger(Object value) { - return value instanceof Integer || value instanceof RAbstractIntVector; - } - - @Specialization(guards = {"!isRMissing(value)", "!isAnyInteger(value)"}) + @Fallback protected byte isType(@SuppressWarnings("unused") Object value) { return RRuntime.LOGICAL_FALSE; } @@ -325,11 +306,11 @@ public class IsTypeFunctions { } @Specialization - protected byte isType(@SuppressWarnings("unused") RLanguage value) { - return RRuntime.LOGICAL_TRUE; + protected byte isType(RPairList value) { + return RRuntime.asLogical(value.isLanguage()); } - @Specialization(guards = {"!isRMissing(value)", "!isRSymbol(value)", "!isRExpression(value)", "!isRLanguage(value)"}) + @Fallback protected byte isType(@SuppressWarnings("unused") Object value) { return RRuntime.LOGICAL_FALSE; } @@ -350,11 +331,11 @@ public class IsTypeFunctions { } @Specialization - protected byte isType(@SuppressWarnings("unused") RPairList pl) { - return RRuntime.LOGICAL_TRUE; + protected byte isType(RPairList pl) { + return RRuntime.asLogical(!pl.isLanguage()); } - @Specialization(guards = {"!isRMissing(value)", "!isRList(value)", "!isRPairList(value)"}) + @Fallback protected byte isType(@SuppressWarnings("unused") Object value) { return RRuntime.LOGICAL_FALSE; } @@ -372,11 +353,7 @@ public class IsTypeFunctions { return RRuntime.LOGICAL_TRUE; } - protected static boolean isAnyLogical(Object value) { - return value instanceof Byte || value instanceof RAbstractLogicalVector; - } - - @Specialization(guards = {"!isRMissing(value)", "!isAnyLogical(value)"}) + @Fallback protected byte isType(@SuppressWarnings("unused") Object value) { return RRuntime.LOGICAL_FALSE; } @@ -397,7 +374,7 @@ public class IsTypeFunctions { return RRuntime.asLogical(isMatrixProfile.profile(getDim.isMatrix(vector))); } - @Specialization(guards = {"!isRMissing(value)", "!isRAbstractVector(value)"}) + @Fallback protected byte isType(@SuppressWarnings("unused") Object value) { return RRuntime.LOGICAL_FALSE; } @@ -415,7 +392,7 @@ public class IsTypeFunctions { return RRuntime.LOGICAL_TRUE; } - @Specialization(guards = {"!isRMissing(value)", "!isRSymbol(value)"}) + @Fallback protected byte isType(@SuppressWarnings("unused") Object value) { return RRuntime.LOGICAL_FALSE; } @@ -434,14 +411,10 @@ public class IsTypeFunctions { return inheritsCheck.execute(o); } - @Specialization(guards = "!isFactor(value)") - protected byte isType(@SuppressWarnings("unused") RAbstractIntVector value) { - return RRuntime.LOGICAL_TRUE; - } - - @Specialization(guards = "isFactor(value)") - protected byte isTypeFactor(@SuppressWarnings("unused") RAbstractIntVector value) { - return RRuntime.LOGICAL_FALSE; + @Specialization + protected byte isType(RAbstractIntVector value, + @Cached("createBinaryProfile()") ConditionProfile profile) { + return RRuntime.asLogical(!profile.profile(isFactor(value))); } @Specialization @@ -449,10 +422,6 @@ public class IsTypeFunctions { return RRuntime.LOGICAL_TRUE; } - protected static boolean isAnyNumeric(Object value) { - return value instanceof Integer || value instanceof Double || value instanceof RAbstractIntVector || value instanceof RAbstractDoubleVector; - } - @Fallback protected byte isType(@SuppressWarnings("unused") Object value) { return RRuntime.LOGICAL_FALSE; @@ -471,7 +440,7 @@ public class IsTypeFunctions { return RRuntime.LOGICAL_TRUE; } - @Specialization(guards = {"!isRMissing(value)", "!isRNull(value)"}) + @Fallback protected byte isType(@SuppressWarnings("unused") Object value) { return RRuntime.LOGICAL_FALSE; } @@ -500,7 +469,7 @@ public class IsTypeFunctions { return RRuntime.asLogical(getClassNode.isObject(arg)); } - @Specialization(guards = {"!isRMissing(value)", "!isRAttributable(value)"}) + @Fallback protected byte isType(@SuppressWarnings("unused") Object value) { return RRuntime.LOGICAL_FALSE; } @@ -519,11 +488,11 @@ public class IsTypeFunctions { } @Specialization - protected byte isType(@SuppressWarnings("unused") RPairList value) { - return RRuntime.LOGICAL_TRUE; + protected byte isType(RPairList value) { + return RRuntime.asLogical(!value.isLanguage()); } - @Specialization(guards = {"!isRMissing(value)", "!isRNull(value)", "!isRPairList(value)"}) + @Fallback protected byte isType(@SuppressWarnings("unused") Object value) { return RRuntime.LOGICAL_FALSE; } @@ -541,11 +510,7 @@ public class IsTypeFunctions { return RRuntime.LOGICAL_TRUE; } - protected static boolean isAnyRaw(Object value) { - return value instanceof RRaw || value instanceof RAbstractRawVector; - } - - @Specialization(guards = {"!isRMissing(value)", "!isAnyRaw(value)"}) + @Fallback protected byte isType(@SuppressWarnings("unused") Object value) { return RRuntime.LOGICAL_FALSE; } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LoadSaveFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LoadSaveFunctions.java index 9d7e4eec318c1bfc3eecdda2e843d47cff737805..4f4766c142e1c830f75d33b8cdc4c7d63fd4778e 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LoadSaveFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/LoadSaveFunctions.java @@ -6,7 +6,7 @@ * Copyright (c) 1995, 1996, 1997 Robert Gentleman and Ross Ihaka * Copyright (c) 1995-2014, The R Core Team * Copyright (c) 2002-2008, The R Foundation - * Copyright (c) 2014, 2017, Oracle and/or its affiliates + * Copyright (c) 2014, 2018, Oracle and/or its affiliates * * All rights reserved. */ @@ -73,7 +73,7 @@ public class LoadSaveFunctions { if (o == RNull.instance) { return RDataFactory.createEmptyStringVector(); } - if (!(o instanceof RPairList)) { + if (!((o instanceof RPairList && !((RPairList) o).isLanguage()))) { throw error(RError.Message.GENERIC, "loaded data is not in pair list form"); } RPairList vars = (RPairList) o; diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Parse.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Parse.java index 953d92bd68749e0dfa19d9e1cfac95283dac0dd9..b35736e7e3754999eb003298b92533a89245a6ae 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Parse.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Parse.java @@ -67,13 +67,12 @@ import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.REmpty; import com.oracle.truffle.r.runtime.data.RExpression; import com.oracle.truffle.r.runtime.data.RIntVector; -import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RMissing; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RSymbol; import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; import com.oracle.truffle.r.runtime.env.REnvironment; -import com.oracle.truffle.r.runtime.nodes.RBaseNode; import com.oracle.truffle.r.runtime.nodes.RSyntaxCall; import com.oracle.truffle.r.runtime.nodes.RSyntaxConstant; import com.oracle.truffle.r.runtime.nodes.RSyntaxElement; @@ -260,9 +259,8 @@ public abstract class Parse extends RBuiltinNode.Arg6 { Object[] srcrefData = new Object[exprs.getLength()]; for (int i = 0; i < srcrefData.length; i++) { Object data = exprs.getDataAt(i); - if (data instanceof RLanguage) { - RBaseNode node = ((RLanguage) data).getRep(); - SourceSection ss = node.asRSyntaxNode().getSourceSection(); + if ((data instanceof RPairList && ((RPairList) data).isLanguage())) { + SourceSection ss = ((RPairList) data).getSourceSection(); srcrefData[i] = RSrcref.createLloc(ss, srcFile); } else if (data instanceof RSymbol) { srcrefData[i] = RNull.instance; @@ -462,10 +460,9 @@ public abstract class Parse extends RBuiltinNode.Arg6 { List<OctetNode> rootOctets = new ArrayList<>(); for (int i = 0; i < exprLen; i++) { Object x = exprs.getDataAt(i); - if (x instanceof RLanguage) { - RBaseNode rep = ((RLanguage) x).getRep(); - assert rep instanceof RSyntaxElement; - rootOctets.add(accept((RSyntaxElement) rep)); + if ((x instanceof RPairList && ((RPairList) x).isLanguage())) { + RSyntaxElement rep = ((RPairList) x).getSyntaxElement(); + rootOctets.add(accept(rep)); } else if (x instanceof RSymbol) { rootOctets.add(newOctet((RSymbol) x, OctetNode.NO_CHILDREN)); } else { @@ -541,9 +538,11 @@ public abstract class Parse extends RBuiltinNode.Arg6 { List<OctetNode> children = new ArrayList<>(); RSyntaxElement[] args = element.getSyntaxArguments(); for (int i = from; i < Math.min(args.length, to); i++) { - OctetNode argOctet = accept(args[i]); - if (argOctet != null) { - children.add(argOctet); + if (args[i] != null) { + OctetNode argOctet = accept(args[i]); + if (argOctet != null) { + children.add(argOctet); + } } } return children; @@ -559,6 +558,8 @@ public abstract class Parse extends RBuiltinNode.Arg6 { tt = TokenType.NUM_CONST; } else if (value instanceof String) { tt = TokenType.STR_CONST; + } else if (value instanceof RComplex) { + tt = TokenType.NUM_CONST; } else if (value == REmpty.instance || value == RMissing.instance) { return null; // ignored } else { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/RecordGraphics.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/RecordGraphics.java index 5e744ad5e899f66506406b3ffa0c9536c57a450c..8d57bb6fbb8a91315a6432fadec0932240097aea 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/RecordGraphics.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/RecordGraphics.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2018, 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 @@ -35,7 +35,7 @@ import com.oracle.truffle.r.runtime.RCaller; import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.RExpression; -import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.env.REnvironment; @@ -55,7 +55,7 @@ public abstract class RecordGraphics extends RBuiltinNode.Arg3 { static { Casts casts = new Casts(RecordGraphics.class); - casts.arg("expr").mustBe(instanceOf(RLanguage.class).or(instanceOf(RExpression.class))); + casts.arg("expr").mustBe(instanceOf(RPairList.class).or(instanceOf(RExpression.class))); casts.arg("list").mustBe(instanceOf(RList.class)); casts.arg("env").mustBe(instanceOf(REnvironment.class)); } @@ -64,8 +64,8 @@ public abstract class RecordGraphics extends RBuiltinNode.Arg3 { return RecordGraphicsNodeGen.create(); } - @Specialization - protected Object doEval(VirtualFrame frame, RLanguage expr, RList list, REnvironment env) { + @Specialization(guards = "expr.isLanguage()") + protected Object doEval(VirtualFrame frame, RPairList expr, RList list, REnvironment env) { RCaller rCaller = RCaller.create(frame, getOriginalCall()); try { return RContext.getEngine().eval(expr, createEnv(list, env), rCaller); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Substitute.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Substitute.java index b36d37b4337ef084bfe0f07a1def52c089b4e6e9..ad80f28418e303f69342b31b8faa3706b22beea1 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Substitute.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Substitute.java @@ -38,10 +38,10 @@ import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.control.IfNode; import com.oracle.truffle.r.runtime.RSubstitute; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RLanguage; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RMissing; 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.RSymbol; import com.oracle.truffle.r.runtime.data.model.RAbstractListVector; @@ -98,7 +98,7 @@ public abstract class Substitute extends RBuiltinNode.Arg2 { * @param expr * @param env {@code null} if the {@code env} argument was {@code RMissing} to avoid always * materializing the current frame. - * @return in general an {@link RLanguage} instance, but simple cases could be a constant value + * @return in general an {@link RPairList} instance, but simple cases could be a constant value * or {@link RSymbol} */ private Object doSubstituteWithEnv(RPromise expr, REnvironment env) { @@ -114,7 +114,7 @@ public abstract class Substitute extends RBuiltinNode.Arg2 { // The "expr" promise comes from the no-evalarg aspect of the builtin, // so get the actual expression (AST) from that - return RASTUtils.createLanguageElement(RSubstitute.substitute(env, expr.getRep(), getRLanguage())); + return RASTUtils.createLanguageElement(RSubstitute.substitute(env, expr.getClosure().getSyntaxElement(), getRLanguage())); } protected static RList2EnvNode createList2EnvNode() { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Unlist.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Unlist.java index 3d79c24d362d9fe64208b872ee71a1675a179680..4ec423b9483099075021813f059797da88376c90 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Unlist.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Unlist.java @@ -48,10 +48,9 @@ import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.RComplex; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RFunction; -import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RNull; -import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RRaw; import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.RSymbol; @@ -89,8 +88,8 @@ public abstract class Unlist extends RBuiltinNode.Arg3 { @Child private RLengthNode lengthNode; - @Specialization - protected int getLength(@SuppressWarnings("unused") RLanguage l) { + @Specialization(guards = "l.isLanguage()") + protected int getLength(@SuppressWarnings("unused") RPairList l) { // language object do not get expanded - as such their length for the purpose of unlist // is 1 return 1; @@ -131,8 +130,8 @@ public abstract class Unlist extends RBuiltinNode.Arg3 { return 0; } - @Specialization - protected int getLength(@SuppressWarnings("unused") RLanguage l) { + @Specialization(guards = "l.isLanguage()") + protected int getLength(@SuppressWarnings("unused") RPairList l) { // language object do not get expanded - as such their length for the purpose of unlist // is 1 return 1; @@ -167,7 +166,7 @@ public abstract class Unlist extends RBuiltinNode.Arg3 { return vector instanceof RList; } - @Specialization + @Specialization(guards = "!list.isLanguage()") protected int getLengthPairList(RPairList list) { int totalSize = 0; for (RPairList item : list) { @@ -276,12 +275,6 @@ public abstract class Unlist extends RBuiltinNode.Arg3 { return RNull.instance; } - @SuppressWarnings("unused") - @Specialization(guards = "isEmpty(list)") - protected RNull unlistEmptyList(RPairList list, boolean recursive, boolean useNames) { - return RNull.instance; - } - // TODO: initially unlist was on the slow path - hence initial recursive implementation is on // the slow path as well; ultimately we may consider (non-recursive) optimization @Specialization(guards = "!isEmpty(list)") @@ -305,8 +298,9 @@ public abstract class Unlist extends RBuiltinNode.Arg3 { } } - @Specialization(guards = "!isEmpty(list)") + @Specialization(guards = "!list.isLanguage()") protected Object unlistPairList(RPairList list, boolean recursive, boolean useNames) { + assert !isEmpty(list) : "pairlist should never be empty"; // TODO: unlist((pairlist(pairlist(1)), recursive=FALSE), see unit tests // Note: currently, we convert to list any pair-list that we encounter along the way, this // is sub-optimal, but the assumption is that pair-lists do not show up a lot @@ -1054,6 +1048,6 @@ public abstract class Unlist extends RBuiltinNode.Arg3 { } private static Object handlePairList(Object o) { - return o instanceof RPairList ? ((RPairList) o).toRList() : o; + return (o instanceof RPairList && !((RPairList) o).isLanguage()) ? ((RPairList) o).toRList() : o; } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Vector.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Vector.java index cb883dd4d41421465ce4b4ed4a00c8d28e6e8e35..b2130321c4f8f4dff4b3f44a77286d58b43d4b4f 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Vector.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Vector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2018, 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 @@ -36,6 +36,7 @@ import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RType; import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.data.RDataFactory; +import com.oracle.truffle.r.runtime.gnur.SEXPTYPE; @RBuiltin(name = "vector", kind = INTERNAL, parameterNames = {"mode", "length"}, behavior = PURE) public abstract class Vector extends RBuiltinNode.Arg2 { @@ -76,7 +77,7 @@ public abstract class Vector extends RBuiltinNode.Arg2 { // RAbstractVector. Note2: pair list of size == 0 is RNull -> we have to return Object. private static Object createType(RType type, int length) { if (type == RType.PairList) { - return RDataFactory.createPairList(length); + return RDataFactory.createPairList(length, SEXPTYPE.LISTSXP); } return type.create(length, false); } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/AccessField.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/AccessField.java index adc9076fd6b91177070fe04b597ced131219d695..36d6177e4497ba1e0d34aba3b4c20f0974ffa431 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/AccessField.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/AccessField.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2018, 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 @@ -42,7 +42,6 @@ import com.oracle.truffle.r.nodes.helpers.AccessListField; import com.oracle.truffle.r.runtime.ArgumentsSignature; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RError.Message; -import com.oracle.truffle.r.runtime.RType; import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.builtins.RSpecialFactory; import com.oracle.truffle.r.runtime.data.RList; @@ -87,7 +86,7 @@ public abstract class AccessField extends RBuiltinNode.Arg2 { static { Casts casts = new Casts(AccessField.class); - casts.arg(1).defaultError(Message.INVALID_SUBSCRIPT_TYPE, RType.Language.getName()).mustBe(stringValue()).asStringVector().findFirst(); + casts.arg(1).defaultError(Message.INVALID_SUBSCRIPT_TYPE, "language").mustBe(stringValue()).asStringVector().findFirst(); } public static RNode createSpecial(ArgumentsSignature signature, RNode[] arguments, @SuppressWarnings("unused") boolean inReplacement) { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/Tilde.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/Tilde.java index e5366c429bcfca8aaab5c7cfd18b306064f37039..918c3e637c1145ffcce156adccfc9e8ea6f2887f 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/Tilde.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/infix/Tilde.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2018, 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 @@ -39,7 +39,7 @@ import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.Closure; import com.oracle.truffle.r.runtime.data.RDataFactory; -import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RMissing; import com.oracle.truffle.r.runtime.data.RPromise; import com.oracle.truffle.r.runtime.data.RStringVector; @@ -75,7 +75,7 @@ public abstract class Tilde extends RBuiltinNode.Arg2 { } @Specialization - protected RLanguage tilde(VirtualFrame frame, Object x, Object y) { + protected RPairList tilde(VirtualFrame frame, Object x, Object y) { if (setEnvAttrNode == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); @@ -85,7 +85,7 @@ public abstract class Tilde extends RBuiltinNode.Arg2 { RCallNode call = createCall(x, y); // Do not cache the closure because formulas are usually not evaluated. - RLanguage lang = RDataFactory.createLanguage(Closure.createLanguageClosure(call)); + RPairList lang = RDataFactory.createLanguage(Closure.createLanguageClosure(call)); setClassAttrNode.execute(lang, FORMULA_CLASS); REnvironment env = REnvironment.frameToEnvironment(frame.materialize()); setEnvAttrNode.execute(lang, env); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/LanguagePrinter.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/LanguagePrinter.java index bc050bed9d46661b295b32889e4b192304e8daa8..401b28c2f0aee0b9fb88d8dff4699ee7cc52f4cb 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/LanguagePrinter.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/LanguagePrinter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2018, 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 @@ -26,9 +26,9 @@ import java.io.IOException; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.r.runtime.RDeparse; -import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.runtime.data.RPairList; -final class LanguagePrinter extends AbstractValuePrinter<RLanguage> { +final class LanguagePrinter extends AbstractValuePrinter<RPairList> { static final LanguagePrinter INSTANCE = new LanguagePrinter(); @@ -38,7 +38,7 @@ final class LanguagePrinter extends AbstractValuePrinter<RLanguage> { @Override @TruffleBoundary - protected void printValue(RLanguage language, PrintContext printCtx) throws IOException { + protected void printValue(RPairList language, PrintContext printCtx) throws IOException { printCtx.output().print(RDeparse.deparse(language, RDeparse.DEFAULT_CUTOFF, true, RDeparse.KEEPINTEGER, -1)); } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ListPrinter.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ListPrinter.java index 4fa95a508ed285bc4b6c9a80ccd6183c0d5d2677..305d7ad9bcf8ad14042613b1452e9d6a1f683dcd 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ListPrinter.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ListPrinter.java @@ -25,7 +25,7 @@ import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.RAttributable; import com.oracle.truffle.r.runtime.data.RDataFactory; -import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.model.RAbstractComplexVector; @@ -128,7 +128,7 @@ final class ListPrinter extends AbstractValuePrinter<RAbstractListVector> { pbuf = "Raw," + ((RAbstractRawVector) (tmp)).getLength(); } else if (tmp instanceof RAbstractListVector) { pbuf = "List," + ((RAbstractListVector) (tmp)).getLength(); - } else if (tmp instanceof RLanguage) { + } else if ((tmp instanceof RPairList && ((RPairList) tmp).isLanguage())) { pbuf = "Expression"; } else { pbuf = "?"; diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/PairListPrinter.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/PairListPrinter.java index c73fabdda712ae98656ae584182d7289738e7341..d6e624ff9c392ea4da395f71878a3fe7093a7c43 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/PairListPrinter.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/PairListPrinter.java @@ -5,7 +5,7 @@ * * Copyright (c) 1995, 1996 Robert Gentleman and Ross Ihaka * Copyright (c) 1997-2013, The R Core Team - * Copyright (c) 2016, 2017, Oracle and/or its affiliates + * Copyright (c) 2016, 2018, Oracle and/or its affiliates * * All rights reserved. */ @@ -16,9 +16,8 @@ import java.io.IOException; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.data.RDataFactory; -import com.oracle.truffle.r.runtime.data.RLanguage; -import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RPairList; +import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.model.RAbstractComplexVector; import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; @@ -68,7 +67,7 @@ final class PairListPrinter extends AbstractValuePrinter<RPairList> { pbuf = "Raw," + ((RAbstractContainer) tmp).getLength(); } else if (tmp instanceof RAbstractListVector) { pbuf = "List," + ((RAbstractContainer) tmp).getLength(); - } else if (tmp instanceof RLanguage) { + } else if ((tmp instanceof RPairList && ((RPairList) tmp).isLanguage())) { pbuf = "Expression"; } else { pbuf = "?"; diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ValuePrinters.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ValuePrinters.java index c3278b4310ed49742d6456bf8a5c006b1a26d6b3..7636090ea9eecd705efebf9ac1348c80062cb45a 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ValuePrinters.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ValuePrinters.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2018, 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 @@ -37,7 +37,6 @@ 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.RInteropScalar; -import com.oracle.truffle.r.runtime.data.RLanguage; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RS4Object; @@ -63,10 +62,8 @@ final class ValuePrinters implements ValuePrinter<Object> { printers.put(RSymbol.class, SymbolPrinter.INSTANCE); printers.put(RFunction.class, FunctionPrinter.INSTANCE); printers.put(RExpression.class, ExpressionPrinter.INSTANCE); - printers.put(RLanguage.class, LanguagePrinter.INSTANCE); printers.put(RExternalPtr.class, ExternalPtrPrinter.INSTANCE); printers.put(RS4Object.class, S4ObjectPrinter.INSTANCE); - printers.put(RPairList.class, PairListPrinter.INSTANCE); } @SuppressWarnings({"rawtypes", "unchecked"}) @@ -106,6 +103,8 @@ final class ValuePrinters implements ValuePrinter<Object> { printer = RArgsValuesAndNamesPrinter.INSTANCE; } else if (x instanceof REnvironment) { printer = EnvironmentPrinter.INSTANCE; + } else if (x instanceof RPairList) { + printer = ((RPairList) x).isLanguage() ? LanguagePrinter.INSTANCE : PairListPrinter.INSTANCE; } else if (x instanceof TruffleObject) { assert !(x instanceof RTypedValue); printer = TruffleObjectPrinter.INSTANCE; diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRSourceInfo.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRSourceInfo.java index fd2d891411ccaa621e96578318781d76e32cebbb..fa4f21a4b9914092bad1f0052d195550dcf4b3f3 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRSourceInfo.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRSourceInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2018, 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 @@ -29,15 +29,14 @@ import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.source.SourceSection; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.builtins.RBehavior; import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.data.RFunction; -import com.oracle.truffle.r.runtime.data.RLanguage; import com.oracle.truffle.r.runtime.data.RNull; +import com.oracle.truffle.r.runtime.data.RPairList; /** * Allows to show the actual location of the source section of a provided function. @@ -47,30 +46,30 @@ public abstract class FastRSourceInfo extends RBuiltinNode.Arg1 { static { Casts casts = new Casts(FastRSourceInfo.class); - casts.arg("fun").defaultError(RError.Message.GENERIC, "Only functions are allowed.").mustBe(instanceOf(RFunction.class).or(instanceOf(RLanguage.class))); + casts.arg("fun").defaultError(RError.Message.GENERIC, "Only functions are allowed.").mustBe(instanceOf(RFunction.class).or(instanceOf(RPairList.class))); } @Specialization + @TruffleBoundary public Object srcInfo(RFunction fun) { - return srcInfo(fun.getRootNode()); + return syntaxSrcInfo(fun.getRootNode().getSourceSection()); } - @Specialization - public Object srcInfo(RLanguage fun) { - return srcInfo(fun.getRep()); + @Specialization(guards = "fun.isLanguage()") + @TruffleBoundary + public Object srcInfo(RPairList fun) { + return syntaxSrcInfo(fun.getSourceSection()); } - @TruffleBoundary - private static Object srcInfo(Node fun) { - SourceSection ss = fun.getSourceSection(); - if (ss != null) { - String path = ss.getSource().getPath(); + private static Object syntaxSrcInfo(SourceSection source) { + if (source != null) { + String path = source.getSource().getPath(); if (path != null) { - return path + "#" + ss.getStartLine(); - } else if (ss.getSource().getURI() != null) { - return ss.getSource().getURI() + "#" + ss.getStartLine(); + return path + "#" + source.getStartLine(); + } else if (source.getSource().getURI() != null) { + return source.getSource().getURI() + "#" + source.getStartLine(); } else { - return ss.getSource().getName(); + return source.getSource().getName(); } } return RNull.instance; diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRTrace.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRTrace.java index 437fa5d89b4e6599a42719f10aed54d698d520ca..c37917e34bd629c8ccc6fb4eebdb979ec3cf16a8 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRTrace.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRTrace.java @@ -55,7 +55,7 @@ import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.data.Closure; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RFunction; -import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RMissing; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.nodes.RBaseNode; @@ -168,16 +168,15 @@ public class FastRTrace { return Utils.toString(func); } - @SuppressWarnings("unused") @TruffleBoundary - private void complexCase(RFunction func, Object tracerObj, Object exit, Object at, boolean print, Object signature) { + private void complexCase(RFunction func, Object tracerObj, @SuppressWarnings("unused") Object exit, Object at, boolean print, @SuppressWarnings("unused") Object signature) { // the complex case - RLanguage tracer; + RPairList tracer; if (tracerObj instanceof RFunction) { Closure closure = Closure.createLanguageClosure(RASTUtils.createCall(tracerObj, false, ArgumentsSignature.empty(0)).asRNode()); tracer = RDataFactory.createLanguage(closure); - } else if (tracerObj instanceof RLanguage) { - tracer = (RLanguage) tracerObj; + } else if ((tracerObj instanceof RPairList && ((RPairList) tracerObj).isLanguage())) { + tracer = (RPairList) tracerObj; } else { throw error(RError.Message.GENERIC, "tracer is unexpected type"); } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/helpers/TraceHandling.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/helpers/TraceHandling.java index bdf06d0ff098aa05d5d622e729821934a8df48c3..72c99139236f988e32c49eb8cf47458bedabe009 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/helpers/TraceHandling.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/helpers/TraceHandling.java @@ -44,7 +44,7 @@ import com.oracle.truffle.r.runtime.RSuicide; import com.oracle.truffle.r.runtime.conn.StdConnections; import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.RFunction; -import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RMissing; /** @@ -95,7 +95,7 @@ public class TraceHandling { } } - public static boolean enableStatementTrace(RFunction func, RLanguage tracer, Object at, boolean print) { + public static boolean enableStatementTrace(RFunction func, RPairList tracer, Object at, boolean print) { @SuppressWarnings("unchecked") EventBinding<TraceEventListener> binding = (EventBinding<TraceEventListener>) RContext.getInstance().stateInstrumentation.getTraceBinding(RInstrumentation.getSourceSection(func)); if (binding != null) { @@ -198,10 +198,10 @@ public class TraceHandling { * entry. */ private static class TracerFunctionEntryEventListener extends TraceEventListener { - private final RLanguage tracer; + private final RPairList tracer; private final boolean print; - TracerFunctionEntryEventListener(RLanguage tracer, boolean print) { + TracerFunctionEntryEventListener(RPairList tracer, boolean print) { this.tracer = tracer; this.print = print; } diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/castsTests/ResultTypesAnalyserTest.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/castsTests/ResultTypesAnalyserTest.java index c275686083061f5b5670e5f9068ff438b60a71fb..efad5a55a6231d6fcd0530ed593b43717a2fa75e 100644 --- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/castsTests/ResultTypesAnalyserTest.java +++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/castsTests/ResultTypesAnalyserTest.java @@ -75,7 +75,6 @@ import com.oracle.truffle.r.runtime.data.RAttributable; import com.oracle.truffle.r.runtime.data.RComplex; import com.oracle.truffle.r.runtime.data.RComplexVector; import com.oracle.truffle.r.runtime.data.RDouble; -import com.oracle.truffle.r.runtime.data.RDoubleSequence; import com.oracle.truffle.r.runtime.data.RDoubleVector; import com.oracle.truffle.r.runtime.data.RFunction; import com.oracle.truffle.r.runtime.data.RIntSequence; diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/DefaultArgsExtractor.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/DefaultArgsExtractor.java index 1debf3f9419d4dffcc5897a8297af5e66d683c32..66ee87d6d1e734a7d5e5ee0a149c8cb83fa88991 100644 --- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/DefaultArgsExtractor.java +++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/DefaultArgsExtractor.java @@ -32,9 +32,8 @@ import com.oracle.truffle.r.nodes.casts.Samples; import com.oracle.truffle.r.runtime.RDeparse; import com.oracle.truffle.r.runtime.RSource; import com.oracle.truffle.r.runtime.context.RContext.ContextKind; -import com.oracle.truffle.r.runtime.data.RLanguage; -import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RPairList; +import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.RSymbol; import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; @@ -74,7 +73,7 @@ class DefaultArgsExtractor { String name = names.getDataAt(i); Object defVal = formals.getDataAtAsObject(i); - if (defVal instanceof RLanguage) { + if ((defVal instanceof RPairList && ((RPairList) defVal).isLanguage())) { String deparsedDefVal = RDeparse.deparse(defVal); try { Value eval = context.eval(FastRSession.createSource(deparsedDefVal, RSource.Internal.UNIT_TEST.string)); diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/SpecialCallTest.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/SpecialCallTest.java index a6d4cfd2fc01d32062205eb99598bfdda1c20858..243a5e9e83510806ab7a5f15bc398e09c7b1d9f3 100644 --- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/SpecialCallTest.java +++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/SpecialCallTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2018, 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 @@ -33,13 +33,16 @@ import com.oracle.truffle.r.runtime.ArgumentsSignature; import com.oracle.truffle.r.runtime.FastROptions; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RootWithBody; +import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.RExpression; -import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.runtime.data.RPairList; +import com.oracle.truffle.r.runtime.nodes.RCodeBuilder; import com.oracle.truffle.r.runtime.nodes.RSyntaxCall; import com.oracle.truffle.r.runtime.nodes.RSyntaxConstant; import com.oracle.truffle.r.runtime.nodes.RSyntaxElement; import com.oracle.truffle.r.runtime.nodes.RSyntaxFunction; import com.oracle.truffle.r.runtime.nodes.RSyntaxLookup; +import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; import com.oracle.truffle.r.runtime.nodes.RSyntaxVisitor; public class SpecialCallTest extends TestBase { @@ -291,8 +294,9 @@ public class SpecialCallTest extends TestBase { RExpression testExpression = testVMContext.getThisEngine().parse(testSource); assert setupExpression.getLength() == 1; assert testExpression.getLength() == 1; - RootCallTarget setupCallTarget = testVMContext.getThisEngine().makePromiseCallTarget(((RLanguage) setupExpression.getDataAt(0)).getRep().asRSyntaxNode().asRNode(), "test"); - RootCallTarget testCallTarget = testVMContext.getThisEngine().makePromiseCallTarget(((RLanguage) testExpression.getDataAt(0)).getRep().asRSyntaxNode().asRNode(), "test"); + RCodeBuilder<RSyntaxNode> builder = RContext.getASTBuilder(); + RootCallTarget setupCallTarget = testVMContext.getThisEngine().makePromiseCallTarget(builder.process(((RPairList) setupExpression.getDataAt(0)).getSyntaxElement()).asRNode(), "test"); + RootCallTarget testCallTarget = testVMContext.getThisEngine().makePromiseCallTarget(builder.process(((RPairList) testExpression.getDataAt(0)).getSyntaxElement()).asRNode(), "test"); try { CountCallsVisitor count1 = new CountCallsVisitor(testCallTarget); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTBuilder.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTBuilder.java index b682b1268a7c728e81af732e330ffea1e96c43bc..f10eff707bcacd3482af60843bcabd72fc4eb580 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTBuilder.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTBuilder.java @@ -200,7 +200,7 @@ public final class RASTBuilder implements RCodeBuilder<RSyntaxNode> { @Override public ArrayList<Argument<RSyntaxNode>> getFunctionExprArgs(Object args) { CompilerAsserts.neverPartOfCompilation(); - if (!(args instanceof RPairList || args == RNull.instance)) { + if (!((args instanceof RPairList && !((RPairList) args).isLanguage()) || args == RNull.instance)) { throw RError.error(RError.SHOW_CALLER, Message.INVALID_FORMAL_ARG_LIST, "function"); } ArrayList<Argument<RSyntaxNode>> finalArgs = new ArrayList<>(); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTUtils.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTUtils.java index ed58d2311b2c90105134cad2a1fd45e97ce7c9cd..f51c7bb75cc27e76c61672816d6c3f539bfb79d6 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTUtils.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RASTUtils.java @@ -56,10 +56,9 @@ import com.oracle.truffle.r.runtime.data.RAttributable; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.REmpty; import com.oracle.truffle.r.runtime.data.RFunction; -import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RMissing; 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.RSymbol; import com.oracle.truffle.r.runtime.env.frame.FrameSlotChangeMonitor; @@ -206,24 +205,7 @@ public final class RASTUtils { } return RASTUtils.cloneNode(promiseRep); } else { - return createNodeForRValue(value); - } - } - - @TruffleBoundary - public static RBaseNode createNodeForRValue(Object value) { - if (value instanceof RSymbol) { - RSymbol symbol = (RSymbol) value; - if (symbol.isMissing()) { - return RContext.getASTBuilder().constant(RSyntaxNode.SOURCE_UNAVAILABLE, REmpty.instance).asRNode(); - } else { - return RContext.getASTBuilder().lookup(RSyntaxNode.SOURCE_UNAVAILABLE, symbol.getName(), false).asRNode(); - } - } else if (value instanceof RLanguage) { - return RASTUtils.cloneNode(((RLanguage) value).getRep()); - } else { - assert value instanceof String || value instanceof Integer || value instanceof Double || value instanceof Byte || value instanceof TruffleObject; - return ConstantNode.create(value); + return createSyntaxNodeForRValue(value).asRNode(); } } @@ -236,11 +218,11 @@ public final class RASTUtils { } else { return RContext.getASTBuilder().lookup(RSyntaxNode.SOURCE_UNAVAILABLE, symbol.getName(), false); } - } else if (value instanceof RLanguage) { - return RContext.getASTBuilder().process(((RLanguage) value).getSyntaxElement()); + } else if ((value instanceof RPairList && ((RPairList) value).isLanguage())) { + return RContext.getASTBuilder().process(((RPairList) value).getSyntaxElement()); } else { assert value instanceof String || value instanceof Integer || value instanceof Double || value instanceof Byte || value instanceof TruffleObject; - return ConstantNode.create(value); + return RContext.getASTBuilder().constant(RSyntaxNode.SOURCE_UNAVAILABLE, value); } } @@ -303,7 +285,7 @@ public final class RASTUtils { defaultValue = null; } else if (arg == RNull.instance) { defaultValue = RContext.getASTBuilder().constant(RSyntaxNode.LAZY_DEPARSE, RNull.instance); - } else if (arg instanceof RLanguage) { + } else if ((arg instanceof RPairList && ((RPairList) arg).isLanguage())) { defaultValue = RASTUtils.createSyntaxNodeForRValue(arg); } else if (arg instanceof RSymbol) { RSymbol symbol = (RSymbol) arg; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedExtractVectorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedExtractVectorNode.java index 381690d7202e9c2238c7482b2f34194e52f1b87c..989c45541a3e2e5d48a5d292a85f5c52a53c05d3 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedExtractVectorNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedExtractVectorNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2018, 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 @@ -24,7 +24,6 @@ package com.oracle.truffle.r.nodes.access.vector; import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.nodes.ExplodeLoop; @@ -44,13 +43,12 @@ import com.oracle.truffle.r.nodes.profile.AlwaysOnBranchProfile; import com.oracle.truffle.r.nodes.profile.VectorLengthProfile; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.RType; -import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.RAttributesLayout; import com.oracle.truffle.r.runtime.data.RDataFactory; -import com.oracle.truffle.r.runtime.data.RLanguage; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RLogical; import com.oracle.truffle.r.runtime.data.RNull; +import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RString; import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.RTypedValue; @@ -180,7 +178,8 @@ final class CachedExtractVectorNode extends CachedVectorNode { switch (vectorType) { case Language: - return materializeLanguage(extractedVector); + case PairList: + return ((RPairList) originalVector).isLanguage() ? RPairList.asPairList(extractedVector, ((RPairList) originalVector).getType()) : extractedVector; default: return trySubsetPrimitive(extractedVector); } @@ -221,11 +220,6 @@ final class CachedExtractVectorNode extends CachedVectorNode { return numberOfDimensions == 1 && positionsCheckNode.isMissing(); } - @TruffleBoundary - private static Object materializeLanguage(RAbstractVector extractedVector) { - return RContext.getRRuntimeASTAccess().createLanguageFromList((RList) extractedVector, RLanguage.RepType.CALL); - } - private Object extract(int dimensionIndex, RAbstractStringVector vector, Object pos, PositionProfile profile) { if (extractDimNames == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); @@ -435,7 +429,7 @@ final class CachedExtractVectorNode extends CachedVectorNode { // usual case container.initAttributes(RAttributesLayout.createNames(newNames1)); } else { - // from an RLanguage extraction that set a name + // from an RPairList extraction that set a name RStringVector oldNames = (RStringVector) namesAttrGetter.execute(container.getAttributes()); assert oldNames.getLength() == newNames.getLength(); assert oldNames.toString().equals(newNames1.toString()); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/ExtractVectorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/ExtractVectorNode.java index ee74036ba299c2a123f3cd6a74c7fdc23a9f8bf4..55e0a68fa0e4f6cac82e6a4dc0a3538fd00858c4 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/ExtractVectorNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/ExtractVectorNode.java @@ -49,7 +49,7 @@ import com.oracle.truffle.r.nodes.unary.FirstStringNode; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.RType; -import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RLogical; import com.oracle.truffle.r.runtime.data.RMissing; import com.oracle.truffle.r.runtime.data.RNull; @@ -136,7 +136,7 @@ public abstract class ExtractVectorNode extends RBaseNode { } private boolean isRecursiveSubscript(Object vector, Object[] positions) { - return !recursive && !ignoreRecursive && mode.isSubscript() && (vector instanceof RAbstractListVector || vector instanceof RLanguage) && positions.length == 1; + return !recursive && !ignoreRecursive && mode.isSubscript() && (vector instanceof RAbstractListVector || vector instanceof RPairList) && positions.length == 1; } @Specialization(limit = "CACHE_LIMIT", guards = {"!isForeignObject(vector)", "cached != null", "cached.isSupported(vector, positions, exact, dropDimensions)"}) diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/RecursiveExtractSubscriptNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/RecursiveExtractSubscriptNode.java index a50f0a2da30620dca6d5dffeb8d6e752b93180a4..10e6d61e912ef14f0fd3dc565799bf9654514366 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/RecursiveExtractSubscriptNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/RecursiveExtractSubscriptNode.java @@ -26,7 +26,7 @@ import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.data.RInteger; -import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RLogical; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; @@ -73,7 +73,7 @@ abstract class RecursiveExtractSubscriptNode extends RecursiveSubscriptNode { for (int i = 1; i < positionLength; i++) { Object selection = getPositionExtract.apply(firstPosition, new Object[]{RInteger.valueOf(i)}, RLogical.TRUE, RLogical.TRUE); try { - if (!(currentVector instanceof RAbstractListVector || currentVector instanceof RLanguage)) { + if (!(currentVector instanceof RAbstractListVector || currentVector instanceof RPairList)) { throw indexingFailed(i); } currentVector = recursiveSubscriptExtract.apply(currentVector, new Object[]{selection}, exact, dropDimensions); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/ReplaceVectorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/ReplaceVectorNode.java index 86bfe74041bc4c902f63d135acd8d3261005a66c..5dfaade26ba9128699e04c2f9ad137ac7448fbc0 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/ReplaceVectorNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/ReplaceVectorNode.java @@ -35,7 +35,7 @@ import com.oracle.truffle.api.interop.KeyInfo; import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.interop.java.JavaInterop; import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.object.DynamicObject; +import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.nodes.access.vector.ExtractVectorNode.AccessElementNode; import com.oracle.truffle.r.nodes.access.vector.ExtractVectorNode.ExtractSingleName; import com.oracle.truffle.r.nodes.access.vector.ExtractVectorNode.ReadElementNode; @@ -49,10 +49,6 @@ import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.RType; -import com.oracle.truffle.r.runtime.context.RContext; -import com.oracle.truffle.r.runtime.data.RAttributesLayout; -import com.oracle.truffle.r.runtime.data.RLanguage; -import com.oracle.truffle.r.runtime.data.RLanguage.RepType; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RPairList; @@ -212,24 +208,13 @@ public abstract class ReplaceVectorNode extends RBaseNode { } @Specialization - @TruffleBoundary - protected Object doReplacementLanguage(RLanguage vector, Object[] positions, Object value, - @Cached("createForContainerTypes()") ReplaceVectorNode replace) { - RepType repType = RContext.getRRuntimeASTAccess().getRepType(vector); - RList result = RContext.getRRuntimeASTAccess().asList(vector); - DynamicObject attrs = vector.getAttributes(); - if (attrs != null && !attrs.isEmpty()) { - result.initAttributes(RAttributesLayout.copy(attrs)); - } - result = (RList) replace.execute(result, positions, value); - return RContext.getRRuntimeASTAccess().createLanguageFromList(result, repType); - } - - @Specialization - @TruffleBoundary protected Object doReplacementPairList(RPairList vector, Object[] positions, Object value, - @Cached("createForContainerTypes()") ReplaceVectorNode replace) { - return replace.execute(vector.toRList(), positions, value); + @Cached("createForContainerTypes()") ReplaceVectorNode replace, + @Cached("createBinaryProfile()") ConditionProfile isLanguage) { + RList result = vector.toRList(); + result = (RList) replace.execute(result, positions, value); + // whether the result is list or pairlist depends on mode and the type of the pairlist + return mode != ElementAccessMode.SUBSET || isLanguage.profile(vector.isLanguage()) ? RPairList.asPairList(result, vector.getType()) : result; } protected static GenericVectorReplaceNode createGeneric() { @@ -254,18 +239,20 @@ public abstract class ReplaceVectorNode extends RBaseNode { private RecursiveReplaceSubscriptNode getRecursive(ReplaceVectorNode node, Object vector, Object[] positions) { CompilerAsserts.neverPartOfCompilation(); - if (cachedRecursive == null || !cachedRecursive.isSupported(vector, positions)) { - cachedRecursive = insert(node.createRecursiveCache(vector, positions)); + RecursiveReplaceSubscriptNode current = cachedRecursive; + if (current == null || !current.isSupported(vector, positions)) { + return cachedRecursive = insert(node.createRecursiveCache(vector, positions)); } - return cachedRecursive; + return current; } private CachedReplaceVectorNode get(ReplaceVectorNode node, RAbstractVector vector, Object[] positions, Object value) { CompilerAsserts.neverPartOfCompilation(); - if (cached == null || !cached.isSupported(vector, positions, value)) { - cached = insert(node.createDefaultCached(vector, positions, value)); + CachedReplaceVectorNode current = cached; + if (current == null || !current.isSupported(vector, positions, value)) { + return cached = insert(node.createDefaultCached(vector, positions, value)); } - return cached; + return current; } } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/GetAttributesNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/GetAttributesNode.java index 2adbdc699b35da9b5e02328daa83978848b89403..addb986a7c68bf74713f48ae02a7138bb0915357 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/GetAttributesNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/GetAttributesNode.java @@ -38,10 +38,9 @@ import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.data.RAttributable; import com.oracle.truffle.r.runtime.data.RAttributesLayout; import com.oracle.truffle.r.runtime.data.RDataFactory; -import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RNull; -import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; @@ -67,32 +66,28 @@ public abstract class GetAttributesNode extends RBaseNode { public abstract Object execute(RAttributable attributable); - @Specialization(guards = "!isPairList(container)") + @Specialization(guards = "!isRPairList(container)") protected Object attributesNull(RAbstractContainer container, @Cached("createBinaryProfile()") ConditionProfile hasAttributesProfile) { if (hasAttributesProfile.profile(hasAttributes(container))) { - return createResult(container, container instanceof RLanguage, null); + return createResult(container, (container instanceof RPairList && ((RPairList) container).isLanguage()), null); } else { return RNull.instance; } } @Specialization - @TruffleBoundary - protected Object attributesPairList(RPairList pairList) { + protected Object attributesPairList(RPairList pairList, + @Cached("createBinaryProfile()") ConditionProfile hasNamesProfile) { RStringVector names = pairList.getNames(); if (hasAttributes(pairList)) { return createResult(pairList, false, names); - } else if (names != null) { + } else if (hasNamesProfile.profile(names != null)) { return RDataFactory.createList(new Object[]{names}, RDataFactory.createStringVector(RRuntime.NAMES_ATTR_KEY)); } return RNull.instance; } - protected static boolean isPairList(RAbstractContainer x) { - return x instanceof RPairList; - } - /** * Unusual cases that it is not worth specializing on as they are not performance-centric, * basically any type that is not an {@link RAbstractContainer} but is {@link RAttributable}, diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SpecialAttributesFunctions.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SpecialAttributesFunctions.java index d14aeadf41029b784ae396b003383ab6f2b8771b..2bc9d5391665d106625ac4a92bb0c6415b6f1252 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SpecialAttributesFunctions.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SpecialAttributesFunctions.java @@ -39,12 +39,10 @@ import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.Utils; -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.RDataFactory; 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.RNull; import com.oracle.truffle.r.runtime.data.RPairList; @@ -307,18 +305,6 @@ public final class SpecialAttributesFunctions { } } - @Specialization(insertBefore = "setAttrInAttributable") - protected void setNamesInLanguage(RLanguage x, RStringVector newNames, - @Cached("createBinaryProfile()") ConditionProfile pairListProfile) { - RPairList pl = x.getPairListInternal(); - if (pairListProfile.profile(pl == null)) { - /* See getNames */ - RContext.getRRuntimeASTAccess().setNames(x, newNames); - } else { - pl.setNames(newNames); - } - } - @Specialization(insertBefore = "setAttrInAttributable") protected void resetDimNames(RAbstractContainer x, @SuppressWarnings("unused") RNull rnull, @Cached("create()") RemoveNamesAttributeNode removeNamesAttrNode) { @@ -415,25 +401,6 @@ public final class SpecialAttributesFunctions { return null; } - @Specialization(insertBefore = "getAttrFromAttributable") - protected Object getLanguageNames(RLanguage x, - @Cached("createBinaryProfile()") ConditionProfile pairListProfile) { - RPairList pl = x.getPairListInternal(); - if (pairListProfile.profile(pl == null)) { - /* - * "names" for a language object is a special case, that is applicable to calls and - * returns the names of the actual arguments, if any. E.g. f(x=1, 3) would return - * c("", "x", ""). GnuR defines it as returning the "tag" values on the pairlist - * that represents the call. Well, we don't have a pairlist, (we could get one by - * serializing the expression), so we do it by AST walking. - */ - RStringVector names = RContext.getRRuntimeASTAccess().getNames(x); - return names; - } else { - return pl.getNames(); - } - } - @Specialization(insertBefore = "getAttrFromAttributable") protected Object getVectorNames(RAbstractVector x, @Cached("create()") BranchProfile attrNullProfile, @@ -625,7 +592,6 @@ public final class SpecialAttributesFunctions { public abstract static class GetDimAttributeNode extends GetFixedAttributeNode { - private final BranchProfile isLanguageProfile = BranchProfile.create(); private final BranchProfile isPairListProfile = BranchProfile.create(); private final ConditionProfile nullDimsProfile = ConditionProfile.createBinaryProfile(); private final ConditionProfile nonEmptyDimsProfile = ConditionProfile.createBinaryProfile(); @@ -648,10 +614,6 @@ public final class SpecialAttributesFunctions { public final int[] getDimensions(Object x) { // Let's handle the following two types directly so as to avoid wrapping and unwrapping // RIntVector. The getContainerDims spec would be invoked otherwise. - if (x instanceof RLanguage) { - isLanguageProfile.enter(); - return ((RLanguage) x).getDimensions(); - } if (x instanceof RPairList) { isPairListProfile.enter(); return ((RPairList) x).getDimensions(); @@ -780,19 +742,7 @@ public final class SpecialAttributesFunctions { } @Specialization(insertBefore = "setAttrInAttributable") - protected void setDimNamesInLanguage(RLanguage x, RAbstractVector newDimNames, - @Cached("createBinaryProfile()") ConditionProfile pairListProfile, - @Cached("create()") BranchProfile attrNullProfile, - @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile, - @Cached("createClassProfile()") ValueProfile typeProfile, - @Cached("create()") ShareObjectNode updateRefCountNode) { - RPairList pl = x.getPairListInternal(); - RAttributable attr = pairListProfile.profile(pl == null) ? x : pl; - setAttrInAttributable(attr, newDimNames, attrNullProfile, attrStorageProfile, typeProfile, updateRefCountNode); - } - - @Specialization(insertBefore = "setAttrInAttributable") - protected void setDimNamesInVector(RVector<?> x, RList newDimNames, + protected void setDimNamesInVector(RAbstractContainer x, RList newDimNames, @Cached("create()") GetDimAttributeNode getDimNode, @Cached("createCountingProfile()") LoopConditionProfile loopProfile, @Cached("create()") BranchProfile nullDimProfile, @@ -850,14 +800,6 @@ public final class SpecialAttributesFunctions { int len = x.getLength(); return len == 0 || len == expectedDim; } - - @Specialization(insertBefore = "setAttrInAttributable") - @TruffleBoundary - protected void setDimNamesInContainer(RAbstractContainer x, RList dimNames, - @Cached("createClassProfile()") ValueProfile contClassProfile) { - RAbstractContainer xProfiled = contClassProfile.profile(x); - xProfiled.setDimNames(dimNames); - } } public abstract static class RemoveDimNamesAttributeNode extends RemoveSpecialAttributeNode { @@ -893,37 +835,12 @@ public final class SpecialAttributesFunctions { } @Specialization(insertBefore = "getAttrFromAttributable") - protected Object getVectorDimNames(@SuppressWarnings("unused") RPairList x) { - return null; - } - - @Specialization(insertBefore = "getAttrFromAttributable") - protected Object getLanguageDimNames(RLanguage x, - @Cached("createBinaryProfile()") ConditionProfile pairListProfile, - @Cached("create()") BranchProfile attrNullProfile, - @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile, - @Cached("createClassProfile()") ValueProfile xTypeProfile, - @Cached("createBinaryProfile()") ConditionProfile nullRowNamesProfile) { - RPairList pl = x.getPairListInternal(); - RAttributable attr = pairListProfile.profile(pl == null) ? x : pl; - Object res = super.getAttrFromAttributable(attr, attrNullProfile, attrStorageProfile, xTypeProfile); - return nullRowNamesProfile.profile(res == null) ? RNull.instance : res; - } - - @Specialization(insertBefore = "getAttrFromAttributable") - protected Object getVectorDimNames(RAbstractVector x, + protected Object getVectorDimNames(RAbstractContainer x, @Cached("create()") BranchProfile attrNullProfile, @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile, @Cached("createClassProfile()") ValueProfile xTypeProfile) { return super.getAttrFromAttributable(x, attrNullProfile, attrStorageProfile, xTypeProfile); } - - @Specialization(insertBefore = "getAttrFromAttributable", guards = "!isRAbstractVector(x)") - @TruffleBoundary - protected Object getVectorDimNames(RAbstractContainer x, - @Cached("createClassProfile()") ValueProfile xTypeProfile) { - return xTypeProfile.profile(x).getDimNames(); - } } public abstract static class ExtractDimNamesAttributeNode extends RBaseNode { @@ -1083,19 +1000,7 @@ public final class SpecialAttributesFunctions { } @Specialization(insertBefore = "setAttrInAttributable") - protected void setRowNamesInLanguage(RLanguage x, RAbstractVector newRowNames, - @Cached("createBinaryProfile()") ConditionProfile pairListProfile, - @Cached("create()") BranchProfile attrNullProfile, - @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile, - @Cached("createClassProfile()") ValueProfile typeProfile, - @Cached("create()") ShareObjectNode updateRefCountNode) { - RPairList pl = x.getPairListInternal(); - RAttributable attr = pairListProfile.profile(pl == null) ? x : pl; - setAttrInAttributable(attr, newRowNames, attrNullProfile, attrStorageProfile, typeProfile, updateRefCountNode); - } - - @Specialization(insertBefore = "setAttrInAttributable") - protected void setRowNamesInVector(RAbstractVector x, RAbstractVector newRowNames, + protected void setRowNamesInVector(RAbstractContainer x, RAbstractVector newRowNames, @Cached("create()") BranchProfile attrNullProfile, @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile, @Cached("createClassProfile()") ValueProfile xTypeProfile, @@ -1108,14 +1013,6 @@ public final class SpecialAttributesFunctions { } setAttrInAttributable(x, newRowNames, attrNullProfile, attrStorageProfile, xTypeProfile, updateRefCountNode); } - - @Specialization(insertBefore = "setAttrInAttributable", guards = "!isRAbstractVector(x)") - @TruffleBoundary - protected void setRowNamesInContainer(RAbstractContainer x, RAbstractVector rowNames, - @Cached("createClassProfile()") ValueProfile contClassProfile) { - RAbstractContainer xProfiled = contClassProfile.profile(x); - xProfiled.setRowNames(rowNames); - } } public abstract static class RemoveRowNamesAttributeNode extends RemoveSpecialAttributeNode { @@ -1160,20 +1057,7 @@ public final class SpecialAttributesFunctions { } @Specialization(insertBefore = "getAttrFromAttributable") - protected Object getLanguageRowNames(RLanguage x, - @Cached("createBinaryProfile()") ConditionProfile pairListProfile, - @Cached("create()") BranchProfile attrNullProfile, - @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile, - @Cached("createBinaryProfile()") ConditionProfile nullRowNamesProfile, - @Cached("createClassProfile()") ValueProfile xTypeProfile) { - RPairList pl = x.getPairListInternal(); - RAttributable attr = pairListProfile.profile(pl == null) ? x : pl; - Object res = super.getAttrFromAttributable(attr, attrNullProfile, attrStorageProfile, xTypeProfile); - return nullRowNamesProfile.profile(res == null) ? RNull.instance : res; - } - - @Specialization(insertBefore = "getAttrFromAttributable") - protected Object getVectorRowNames(RAbstractVector x, + protected Object getVectorRowNames(RAbstractContainer x, @Cached("create()") BranchProfile attrNullProfile, @Cached("createBinaryProfile()") ConditionProfile attrStorageProfile, @Cached("createBinaryProfile()") ConditionProfile nullRowNamesProfile, @@ -1181,12 +1065,6 @@ public final class SpecialAttributesFunctions { Object res = super.getAttrFromAttributable(x, attrNullProfile, attrStorageProfile, xTypeProfile); return nullRowNamesProfile.profile(res == null) ? RNull.instance : res; } - - @Specialization(insertBefore = "getAttrFromAttributable") - @TruffleBoundary - protected Object getVectorRowNames(RAbstractContainer x) { - return x.getRowNames(); - } } public abstract static class SetClassAttributeNode extends SetSpecialAttributeNode { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryBooleanNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryBooleanNode.java index 5212cec1c120efb55f0b211612033bfadf9836e6..55b020c0676a7c3abc2ea5535dfc6430f91c0197 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryBooleanNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryBooleanNode.java @@ -43,7 +43,7 @@ import com.oracle.truffle.r.runtime.data.RComplex; import com.oracle.truffle.r.runtime.data.RComplexVector; import com.oracle.truffle.r.runtime.data.RDoubleVector; import com.oracle.truffle.r.runtime.data.RIntVector; -import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RLogicalVector; import com.oracle.truffle.r.runtime.data.RRaw; import com.oracle.truffle.r.runtime.data.RRawVector; @@ -146,7 +146,7 @@ public abstract class BinaryBooleanNode extends RBuiltinNode.Arg2 { } protected static boolean isSymbolOrLang(Object obj) { - return obj instanceof RSymbol || obj instanceof RLanguage; + return obj instanceof RSymbol || (obj instanceof RPairList && ((RPairList) obj).isLanguage()); } @Specialization(guards = {"isSymbolOrLang(left) || isSymbolOrLang(right)"}) diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementDispatchNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementDispatchNode.java index 73dc64dc5bcea713f28d0b61a19733c6e962e122..68bcacaf66946a1768f5de4ef356a4f89919a3bf 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementDispatchNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementDispatchNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2018, 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 @@ -38,7 +38,7 @@ import com.oracle.truffle.r.runtime.ArgumentsSignature; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.RRuntime; -import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.nodes.RNode; import com.oracle.truffle.r.runtime.nodes.RSyntaxCall; @@ -186,12 +186,14 @@ public final class ReplacementDispatchNode extends OperatorNode { * Encapsulates check for the specific structure of replacements, to display the replacement * instead of the "internal" form (with *tmp*, etc.) of the update call. */ - public static RLanguage getRLanguage(RLanguage language) { - RSyntaxNode sn = (RSyntaxNode) language.getRep(); - Node parent = RASTUtils.unwrapParent(sn.asNode()); - if (parent instanceof WriteVariableNode) { - WriteVariableNode wvn = (WriteVariableNode) parent; - return ReplacementNode.getLanguage(wvn); + public static RPairList getRLanguage(RPairList language) { + RSyntaxElement sn = language.getSyntaxElement(); + if (sn instanceof Node) { + Node parent = RASTUtils.unwrapParent((Node) sn); + if (parent instanceof WriteVariableNode) { + WriteVariableNode wvn = (WriteVariableNode) parent; + return ReplacementNode.getLanguage(wvn); + } } return null; } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementNode.java index 1a992180308ec43e27011b9cdef129492e16edbd..9dda30204060503f615b018dd05030e1374762b6 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/ReplacementNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2018, 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 @@ -44,7 +44,7 @@ import com.oracle.truffle.r.runtime.builtins.RSpecialFactory.FullCallNeededExcep import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.Closure; import com.oracle.truffle.r.runtime.data.RDataFactory; -import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.nodes.RCodeBuilder; import com.oracle.truffle.r.runtime.nodes.RCodeBuilder.CodeBuilderContext; import com.oracle.truffle.r.runtime.nodes.RNode; @@ -157,7 +157,7 @@ abstract class ReplacementNode extends OperatorNode { return RCallSpecialNode.createCallInReplace(source, newSyntaxLHS.asRNode(), ArgumentsSignature.get(names), argNodes, 0, argNodes.length - 1).asRNode(); } - static RLanguage getLanguage(WriteVariableNode wvn) { + static RPairList getLanguage(WriteVariableNode wvn) { Node parent = wvn.getParent(); if (parent instanceof ReplacementNode) { return RDataFactory.createLanguage(Closure.createLanguageClosure((ReplacementNode) parent)); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ArgumentStatePush.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ArgumentStatePush.java index 4c9b9aa0b6fbede742e9f3141231321d94a845b6..3b0f05c72fe2d6bb4b201a1149e6207c3bef0a60 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ArgumentStatePush.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ArgumentStatePush.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2018, 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 @@ -34,7 +34,7 @@ import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.runtime.FastROptions; import com.oracle.truffle.r.runtime.RArguments; import com.oracle.truffle.r.runtime.data.RFunction; -import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RShareable; import com.oracle.truffle.r.runtime.data.RSharingAttributeStorage; import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; @@ -63,7 +63,7 @@ public abstract class ArgumentStatePush extends Node { protected int createWriteArgMask(VirtualFrame frame, RShareable shareable) { if (shareable instanceof RAbstractContainer) { - if (shareable instanceof RLanguage || ((RAbstractContainer) shareable).getLength() < REF_COUNT_SIZE_THRESHOLD) { + if ((shareable instanceof RPairList && ((RPairList) shareable).isLanguage()) || ((RAbstractContainer) shareable).getLength() < REF_COUNT_SIZE_THRESHOLD) { // don't decrement ref count for small objects or language objects- this // is pretty conservative and can be further finessed return -1; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/PromiseNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/PromiseNode.java index adb31fe1b3da2c65c83c82b723655ac7d6fd04ea..49c8ef078df2dd19ce9cd6b9278014d0344a1f31 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/PromiseNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/PromiseNode.java @@ -528,9 +528,10 @@ public abstract class PromiseNode extends RNode { } private int evaluateArguments(VirtualFrame frame, Object[] evaluatedArgs) { - if (evaluatedArgs.length <= 32) { + if (evaluatedArgs.length <= 64) { return evaluateArgumentsExplode(frame, evaluatedArgs); } + return evaluateArgumentsLoop(frame, evaluatedArgs); } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallNode.java index 18abff07e0105d05e2ffa2ce5536b1abcbec6238..84fb2f06e21b2fb8e65bcec9db896f3cce97e87f 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallNode.java @@ -750,20 +750,6 @@ public abstract class RCallNode extends RCallBaseNode implements RSyntaxNode, RS return CallArgumentsNode.create(modeChange, modeChangeAppliesToAll, args, signature, varArgIndexes); } - /** - * Creates a modified call in which the first N arguments are replaced by - * {@code replacementArgs}. This is only used to support - * {@code HiddenInternalFunctions.MakeLazy}. - */ - @TruffleBoundary - public static RCallNode createCloneReplacingArgs(RCallNode call, RSyntaxNode... replacementArgs) { - RSyntaxNode[] args = new RSyntaxNode[call.arguments.length]; - for (int i = 0; i < args.length; i++) { - args[i] = i < replacementArgs.length ? replacementArgs[i] : call.arguments[i]; - } - return RCallNodeGen.create(call.getLazySourceSection(), args, call.signature, RASTUtils.cloneNode(call.getFunction())); - } - /** * The standard way to create a call to {@code function} with given arguments. If * {@code src == RSyntaxNode.EAGER_DEPARSE} we force a deparse. diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastComplexNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastComplexNode.java index 34dbaafbe58523b337c5df400c84910fa3ec88cc..2d090b4a654604710acaf7f0a34eb7880b33b061 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastComplexNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastComplexNode.java @@ -266,7 +266,7 @@ public abstract class CastComplexNode extends CastBaseNode { return ret; } - @Specialization + @Specialization(guards = "!pairList.isLanguage()") protected RComplexVector doPairList(RPairList pairList) { return doList(pairList.toRList()); } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleNode.java index 7ffe25f55cc859ff56f853f37925eb69cdd916bb..25f98c0075c43bd8f6cc7aaf0fdb98f410ce54c8 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleNode.java @@ -223,7 +223,7 @@ public abstract class CastDoubleNode extends CastDoubleBaseNode { return ret; } - @Specialization + @Specialization(guards = "!pairList.isLanguage()") protected RDoubleVector doPairList(RPairList pairList) { return doList(pairList.toRList()); } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerNode.java index 1ede1d748c1ee6ecb03f1fb779e3d8ae87756721..a11b5b0defcf48dcb49b9849e483a80ac54c67f9 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerNode.java @@ -231,7 +231,7 @@ public abstract class CastIntegerNode extends CastIntegerBaseNode { return ret; } - @Specialization + @Specialization(guards = "!pairList.isLanguage()") protected RIntVector doPairList(RPairList pairList) { return doList(pairList.toRList()); } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java index 32314a0227f25ed9c53f1aea6f5e8896f0340883..a84cc5a885946ba875aba03b60ea89df0fbeb298 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2018, 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,25 +22,17 @@ */ package com.oracle.truffle.r.nodes.unary; -import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.interop.TruffleObject; -import com.oracle.truffle.api.object.DynamicObject; import com.oracle.truffle.api.profiles.ValueProfile; -import com.oracle.truffle.r.nodes.attributes.ArrayAttributeNode; -import com.oracle.truffle.r.nodes.attributes.SetAttributeNode; import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetClassAttributeNode; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.RType; -import com.oracle.truffle.r.runtime.context.RContext; -import com.oracle.truffle.r.runtime.data.RAttributesLayout; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RFunction; import com.oracle.truffle.r.runtime.data.RInteropScalar; -import com.oracle.truffle.r.runtime.data.RLanguage; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RPairList; @@ -102,32 +94,6 @@ public abstract class CastListNode extends CastBaseNode { } @Specialization - protected RList doLanguage(RLanguage operand, - @Cached("create()") ArrayAttributeNode attrAttrAccess, - @Cached("create()") SetAttributeNode setAttrNode) { - RList result = RContext.getRRuntimeASTAccess().asList(operand); - DynamicObject operandAttrs = operand.getAttributes(); - if (operandAttrs != null) { - // result may already have names, so can't call RVector.copyAttributesFrom - for (RAttributesLayout.RAttribute attr : attrAttrAccess.execute(operandAttrs)) { - if (attr.getName().equals(RRuntime.CLASS_ATTR_KEY)) { - - if (setClassAttrNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - setClassAttrNode = insert(SetClassAttributeNode.create()); - } - - setClassAttrNode.execute(result, attr.getValue()); - } else { - setAttrNode.execute(result, attr.getName(), attr.getValue()); - } - } - } - return result; - } - - @Specialization - @TruffleBoundary protected RList doPairList(RPairList pl) { return pl.toRList(); } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastLogicalNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastLogicalNode.java index 8df91e8627608a45b6875e452dd81e057981c25e..cc36f7a8d95b76be4b519269a9d68d6ed708e08e 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastLogicalNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastLogicalNode.java @@ -189,7 +189,7 @@ public abstract class CastLogicalNode extends CastLogicalBaseNode { return ret; } - @Specialization + @Specialization(guards = "!pairList.isLanguage()") protected RLogicalVector doPairList(RPairList pairList) { return doList(pairList.toRList()); } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastRawNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastRawNode.java index 361383031470940faba47fde77d7cd07f19587c7..fd644286c9590ee90f01756f885a1010552b3bf1 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastRawNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastRawNode.java @@ -314,7 +314,7 @@ public abstract class CastRawNode extends CastBaseNode { return result; } - @Specialization + @Specialization(guards = "!pairList.isLanguage()") protected RRawVector doPairList(RPairList pairList) { return doList(pairList.toRList()); } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastStringNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastStringNode.java index 31acd91b95dc99fee391f1d863f254d57bad5d35..13ba94958a26aa5c85f208bcd23d9257e03d41e4 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastStringNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastStringNode.java @@ -34,7 +34,7 @@ import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RIntSequence; -import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RStringSequence; import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.RSymbol; @@ -95,7 +95,7 @@ public abstract class CastStringNode extends CastStringBaseNode { // conversions to character will not introduce new NAs for (int i = 0; i < operand.getLength(); i++) { Object o = operand.getDataAtAsObject(i); - if (isLanguageProfile.profile(o instanceof RLanguage)) { + if (isLanguageProfile.profile((o instanceof RPairList && ((RPairList) o).isLanguage()))) { sdata[i] = RDeparse.deparse(o); } else { sdata[i] = toString(o); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/DuplicateNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/DuplicateNode.java index 9e94fc4d50e99526d4c6f1e8b0707ffa5c9cdbee..e20c343977a5ada3bde68468f66b1b71ece65aa5 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/DuplicateNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/DuplicateNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2018, 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 @@ -27,7 +27,7 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.data.RExternalPtr; import com.oracle.truffle.r.runtime.data.RFunction; -import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RS4Object; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; import com.oracle.truffle.r.runtime.env.REnvironment; @@ -64,8 +64,8 @@ public abstract class DuplicateNode extends RBaseNode { return p.copy(); } - @Specialization - protected RLanguage duplicate(RLanguage l) { + @Specialization(guards = "l.isLanguage()") + protected RPairList duplicate(RPairList l) { return l.copy(); } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/PrecedenceNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/PrecedenceNode.java index 8515ffef861c03f83bd5e7e310f4c4d91dbc5a81..9207a1a2eb2a01f28ab2a9b9c9595da69ed28947 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/PrecedenceNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/PrecedenceNode.java @@ -44,10 +44,9 @@ import com.oracle.truffle.r.runtime.data.RExpression; import com.oracle.truffle.r.runtime.data.RForeignListWrapper; import com.oracle.truffle.r.runtime.data.RFunction; import com.oracle.truffle.r.runtime.data.RInteropScalar; -import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RNull; -import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RS4Object; import com.oracle.truffle.r.runtime.data.RSymbol; import com.oracle.truffle.r.runtime.data.model.RAbstractAtomicVector; @@ -176,7 +175,7 @@ public abstract class PrecedenceNode extends RBaseNode { return precedence; } - @Specialization(guards = "recursive") + @Specialization(guards = {"recursive", "!list.isLanguage()"}) protected int doPairListRecursive(RPairList list, boolean recursive, @Cached("createRecursive()") PrecedenceNode precedenceNode) { int precedence = -1; @@ -202,7 +201,7 @@ public abstract class PrecedenceNode extends RBaseNode { return LIST_PRECEDENCE; } - @Specialization(guards = "!recursive") + @Specialization(guards = {"!recursive", "!val.isLanguage()"}) @SuppressWarnings("unused") protected int doPairList(RPairList val, boolean recursive) { return LIST_PRECEDENCE; @@ -214,9 +213,9 @@ public abstract class PrecedenceNode extends RBaseNode { return EXPRESSION_PRECEDENCE; } - @Specialization + @Specialization(guards = "val.isLanguage()") @SuppressWarnings("unused") - protected int doExpression(RLanguage val, boolean recursive) { + protected int doExpression(RPairList val, boolean recursive) { return LIST_PRECEDENCE; } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RChannel.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RChannel.java index b397cfb419199e8468f60a30ff2c39419721de2f..e6bdb0224112d037f25ec8d81a0e6894e5baa1cc 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RChannel.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RChannel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2018, 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 @@ -40,7 +40,7 @@ import com.oracle.truffle.r.runtime.data.RAttributeStorage; import com.oracle.truffle.r.runtime.data.RAttributesLayout; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RFunction; -import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RPromise; @@ -495,7 +495,7 @@ public class RChannel { } private static boolean serializeObject(Object o) { - return o instanceof REnvironment || o instanceof RConnection || o instanceof RLanguage; + return o instanceof REnvironment || o instanceof RConnection || (o instanceof RPairList && ((RPairList) o).isLanguage()); } private Object convertPrivate(Object o) throws IOException { diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RDeparse.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RDeparse.java index 8138ab7f7a1f538e2f3af7a126b2ee2b72386296..206c8683f3095de874b75464e44a717f6112a76f 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RDeparse.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RDeparse.java @@ -48,11 +48,10 @@ 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.RLanguage; +import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RMissing; 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.RPromise.EagerPromise; import com.oracle.truffle.r.runtime.data.RRaw; @@ -788,7 +787,7 @@ public class RDeparse { append(") "); appendFunctionBody(function.getSyntaxBody()); } - } else if (value instanceof RPairList) { + } else if ((value instanceof RPairList && !((RPairList) value).isLanguage())) { RPairList arglist = (RPairList) value; append("pairlist("); int i = 0; @@ -927,8 +926,8 @@ public class RDeparse { RSyntaxElement element; if (value instanceof RSymbol) { element = RSyntaxLookup.createDummyLookup(RSyntaxNode.INTERNAL, ((RSymbol) value).getName(), false); - } else if (value instanceof RLanguage) { - element = ((RLanguage) value).getRep().asRSyntaxNode(); + } else if ((value instanceof RPairList && ((RPairList) value).isLanguage())) { + element = ((RPairList) value).getSyntaxElement(); } else if (value instanceof RMissing) { element = RSyntaxLookup.createDummyLookup(null, "", false); } else { diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RErrorHandling.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RErrorHandling.java index 51d1e1e52ae6956275c16e6fd62b0d46d95ce34f..c39997c6f30b58bb1d3df9230a08fd5fbff15d29 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RErrorHandling.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RErrorHandling.java @@ -25,11 +25,10 @@ import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RExpression; import com.oracle.truffle.r.runtime.data.RFunction; -import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RMissing; import com.oracle.truffle.r.runtime.data.RNull; -import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RString; import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; @@ -53,7 +52,7 @@ import com.oracle.truffle.r.runtime.nodes.RBaseNode; * passed as an argument. For better or worse, we use an {@link RPairList}. We handle the * {@code deparse} special case explicitly in our implementation of {@code deparse}. * <p> - * TODO Consider using an {@link RLanguage} object to denote the call (somehow). + * TODO Consider using an {@link RPairList} object to denote the call (somehow). */ public class RErrorHandling { @@ -469,11 +468,11 @@ public class RErrorHandling { /** * Check a {@code call} value. * - * @param call Either {@link RNull#instance} or an {@link RLanguage}. - * @return {@code null} iff {@code call == RNull.instance} else cast to {@link RLanguage}. + * @param call Either {@link RNull#instance} or an {@link RPairList}. + * @return {@code null} iff {@code call == RNull.instance} else cast to {@link RPairList}. */ private static Object fromCall(Object call) { - if (!(call == RNull.instance || call instanceof RLanguage)) { + if (!(call == RNull.instance || (call instanceof RPairList && ((RPairList) call).isLanguage()))) { throw RInternalError.shouldNotReachHere(); } return call; @@ -539,9 +538,9 @@ public class RErrorHandling { } } RContext.getEngine().evalFunction(errorFunction, null, null, true, null, evaluatedArgs); - } else if (errorExpr instanceof RLanguage || errorExpr instanceof RExpression) { - if (errorExpr instanceof RLanguage) { - RContext.getEngine().eval((RLanguage) errorExpr, materializedFrame); + } else if ((errorExpr instanceof RPairList && ((RPairList) errorExpr).isLanguage()) || errorExpr instanceof RExpression) { + if ((errorExpr instanceof RPairList && ((RPairList) errorExpr).isLanguage())) { + RContext.getEngine().eval((RPairList) errorExpr, materializedFrame); } else if (errorExpr instanceof RExpression) { RContext.getEngine().eval((RExpression) errorExpr, materializedFrame); } @@ -635,7 +634,7 @@ public class RErrorHandling { } Object s = RContext.getInstance().stateROptions.getValue("warning.expression"); if (s != RNull.instance) { - if (!(s instanceof RLanguage || s instanceof RExpression)) { + if (!((s instanceof RPairList && ((RPairList) s).isLanguage()) || s instanceof RExpression)) { // TODO } throw RInternalError.unimplemented(); @@ -742,7 +741,7 @@ public class RErrorHandling { } private static void printWarningMessage(String prefix, Warning warning, int maxLen) { - String callString = RContext.getRRuntimeASTAccess().getCallerSource((RLanguage) warning.call); + String callString = RContext.getRRuntimeASTAccess().getCallerSource((RPairList) warning.call); String message = warning.message; int firstLineLength = message.contains("\n") ? message.indexOf('\n') : message.length(); @@ -795,13 +794,13 @@ public class RErrorHandling { private static String createKindMessage(String kind, Object call, String formattedMsg) { String preamble = kind; String errorMsg = null; - assert call instanceof RNull || call instanceof RLanguage; + assert call instanceof RNull || (call instanceof RPairList && ((RPairList) call).isLanguage()); if (call == RNull.instance) { // generally means top-level of shell or similar preamble += ": "; errorMsg = preamble + formattedMsg; } else { - RLanguage rl = (RLanguage) call; + RPairList rl = (RPairList) call; preamble += " in " + RContext.getRRuntimeASTAccess().getCallerSource(rl) + " :"; errorMsg = wrapMessage(preamble, formattedMsg); } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ROptions.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ROptions.java index 57860a82591b1eca7b7c0855efd1a209ce2400a1..ba250c7d6bdfb1dac6a3416cbed6e5dce0ea3755 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ROptions.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ROptions.java @@ -5,7 +5,7 @@ * * Copyright (c) 1995-2012, The R Core Team * Copyright (c) 2003, The R Foundation - * Copyright (c) 2015, 2017, Oracle and/or its affiliates + * Copyright (c) 2015, 2018, Oracle and/or its affiliates * * All rights reserved. */ @@ -27,10 +27,9 @@ import com.oracle.truffle.r.runtime.data.RDoubleVector; import com.oracle.truffle.r.runtime.data.RExpression; import com.oracle.truffle.r.runtime.data.RFunction; import com.oracle.truffle.r.runtime.data.RIntVector; -import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.runtime.data.RPairList; 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.RStringVector; import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; import com.oracle.truffle.r.runtime.env.REnvironment; @@ -285,7 +284,7 @@ public class ROptions { } case "warning.expression": { - if (!(value instanceof RLanguage || value instanceof RExpression)) { + if (!((value instanceof RPairList && ((RPairList) value).isLanguage()) || value instanceof RExpression)) { throw OptionsException.createInvalid(name); } break; @@ -313,7 +312,7 @@ public class ROptions { } case "error": { - if (!(value == RNull.instance || value instanceof RFunction || value instanceof RLanguage || value instanceof RExpression)) { + if (!(value == RNull.instance || value instanceof RFunction || (value instanceof RPairList && ((RPairList) value).isLanguage()) || value instanceof RExpression)) { throw OptionsException.createInvalid(name); } break; diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntimeASTAccess.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntimeASTAccess.java index cda344489795bd1c53400e6741bf16cb43d66dfc..5e4df87fd91f809ec6daf78593dc58df3ea03b18 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntimeASTAccess.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntimeASTAccess.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2018, 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 @@ -30,68 +30,25 @@ import com.oracle.truffle.r.runtime.context.TruffleRLanguage; import com.oracle.truffle.r.runtime.data.RAttributable; import com.oracle.truffle.r.runtime.data.RComplex; import com.oracle.truffle.r.runtime.data.RFunction; -import com.oracle.truffle.r.runtime.data.RLanguage; -import com.oracle.truffle.r.runtime.data.RList; 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.RStringVector; -import com.oracle.truffle.r.runtime.data.RSymbol; import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; import com.oracle.truffle.r.runtime.nodes.RBaseNode; -import com.oracle.truffle.r.runtime.nodes.RSyntaxFunction; +import com.oracle.truffle.r.runtime.nodes.RSyntaxElement; import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; /** * A collection of methods that need access to the AST types, needed by code that resides in the * runtime project, which does not have direct access, as it would introduce project circularities. - * */ public interface RRuntimeASTAccess { - /** - * Retrieves a type of RLanguage object's representation. - */ - RLanguage.RepType getRepType(RLanguage rl); - - /** - * Computes the "length" of the language element as per the R specification. - */ - int getLength(RLanguage rl); - - /** - * Returns the object ({@link RSymbol}, {@link RLanguage} or scalar value (e.g. {@link Double}) - * at index {@code index}. - */ - Object getDataAtAsObject(RLanguage rl, int index); - - /** - * Converts {@code rl} to a {@link RList}. - */ - RList asList(RLanguage rl); - - /** - * If {@code list} is empty return {@link RNull#instance} else create an {@link RLanguage} - * object whose rep is a {@code RCallNode} with the first list element as the function and the - * remainder as the arguments, or a {@code RFunction} (as determined by repType). - */ - Object createLanguageFromList(RList list, RLanguage.RepType repType); - - /** - * Get the "names" attribute for an {@link RLanguage} object, or {@code null} if none. - */ - RStringVector getNames(RLanguage rl); - - /** - * Set the "names" attribute for an {@link RLanguage} object. - */ - void setNames(RLanguage rl, RStringVector names); - - RSyntaxFunction getSyntaxFunction(RFunction f); /** * Returns the real caller associated with {@code rl}, by locating the {@code RSyntaxNode} * associated with the node stored with {@code rl}. */ - RLanguage getSyntaxCaller(RCaller rl); + RPairList getSyntaxCaller(RCaller rl); /** * Gets {@code TruffleRLanguage} avoiding project circularity. @@ -102,13 +59,13 @@ public interface RRuntimeASTAccess { * Returns a string for a call as represented by {@code rl}, returned originally by * {@link #getSyntaxCaller}. */ - String getCallerSource(RLanguage rl); + String getCallerSource(RPairList rl); /** * Used by error/warning handling to try to find the call that provoked the error/warning. * * If there is no caller, return {@link RNull#instance}, e.g. "call" of a builtin from the - * global env, otherwise return an {@code RLanguage} instance that represents the call. + * global env, otherwise return an {@code RPairList} instance that represents the call. * * @param call may be {@code null} or it may be the {@link Node} that was executing when the * error.warning was generated (builtin or associated node). @@ -205,4 +162,6 @@ public interface RRuntimeASTAccess { RAbstractStringVector getClassHierarchy(RAttributable value); RContext getCurrentContext(); + + Object createLanguageElement(RSyntaxElement element); } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java index 7289839a040ab3c413fa47aa2ae85ec5e8ad6f5e..8fb4c1e47e9fdbd6b7c20700f2e3e1a675c4889b 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java @@ -57,11 +57,10 @@ import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.REmpty; import com.oracle.truffle.r.runtime.data.RExternalPtr; import com.oracle.truffle.r.runtime.data.RFunction; -import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RMissing; 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.RPromise.PromiseState; import com.oracle.truffle.r.runtime.data.RScalar; @@ -607,7 +606,7 @@ public class RSerialize { * for LANGSXP when specifying a formula */ if (langDepth == 0) { - RLanguage lang = PairlistDeserializer.processLanguage(carItem, cdrItem, tagItem); + RPairList lang = PairlistDeserializer.processLanguage(carItem, cdrItem, tagItem); if (attrItem != RNull.instance) { setAttributes(lang, attrItem); } @@ -1482,7 +1481,7 @@ public class RSerialize { stream.writeInt(specialType.code); return; } - SEXPTYPE type = SEXPTYPE.typeForClass(obj.getClass()); + SEXPTYPE type = SEXPTYPE.typeForClass(obj); SEXPTYPE gnuRType = SEXPTYPE.gnuRType(type, obj); int refIndex; if ((refIndex = getRefIndex(obj)) != -1) { @@ -1653,7 +1652,6 @@ public class RSerialize { RFunction fun = (RFunction) obj; RPairList pl = (RPairList) serializeLanguageObject(state, fun); assert pl != null; - state.convertUnboundValues(pl); if (FastROptions.debugMatches("printWclosure")) { Debug.printClosure(pl); } @@ -1666,7 +1664,6 @@ public class RSerialize { case PROMSXP: { RPairList pl = (RPairList) serializeLanguageObject(state, obj); assert pl != null; - state.convertUnboundValues(pl); if (pl.getTag() != RNull.instance) { writeItem(pl.getTag()); } @@ -1687,7 +1684,6 @@ public class RSerialize { case LANGSXP: { RPairList pl = (RPairList) serializeLanguageObject(state, obj); - state.convertUnboundValues(pl); writeItem(pl.car()); obj = pl.cdr(); break; @@ -1737,7 +1733,7 @@ public class RSerialize { if (hook == null) { return RNull.instance; } - switch (SEXPTYPE.typeForClass(obj.getClass())) { + switch (SEXPTYPE.typeForClass(obj)) { case WEAKREFSXP: case EXTPTRSXP: break; @@ -2205,11 +2201,11 @@ public class RSerialize { } private static SEXPTYPE type(Object obj) { - if (obj instanceof RPairList) { + if ((obj instanceof RPairList && !((RPairList) obj).isLanguage())) { SEXPTYPE s = ((RPairList) obj).getType(); return s == null ? SEXPTYPE.LISTSXP : s; } else { - return SEXPTYPE.typeForClass(obj.getClass()); + return SEXPTYPE.typeForClass(obj); } } @@ -2430,12 +2426,23 @@ public class RSerialize { } private static Object serializeLanguageObject(RSerialize.State state, Object obj) { - if (obj instanceof RFunction) { - return RSerialize.serializeFunction(state, (RFunction) obj); - } else if (obj instanceof RLanguage) { - return RSerialize.serializeLanguage(state, (RLanguage) obj); + if (obj instanceof RPairList) { + RPairList list = (RPairList) obj; + if (list.isLanguage() && list.hasClosure()) { + RPairList result = (RPairList) RSerialize.serializeLanguage(state, list); + state.convertUnboundValues(result); + return result; + } else { + return list; + } + } else if (obj instanceof RFunction) { + RPairList result = (RPairList) RSerialize.serializeFunction(state, (RFunction) obj); + state.convertUnboundValues(result); + return result; } else if (obj instanceof RPromise) { - return RSerialize.serializePromise(state, (RPromise) obj); + RPairList result = (RPairList) RSerialize.serializePromise(state, (RPromise) obj); + state.convertUnboundValues(result); + return result; } else { throw RInternalError.unimplemented("serialize"); } @@ -2512,8 +2519,8 @@ public class RSerialize { return null; } - private static Object serializeLanguage(State state, RLanguage lang) { - RSyntaxElement element = lang.getRep().asRSyntaxNode(); + private static Object serializeLanguage(State state, RPairList lang) { + RSyntaxElement element = lang.getSyntaxElement(); state.openPairList(SEXPTYPE.LANGSXP); new SerializeVisitor(state).accept(element); return state.closePairList(); @@ -2566,7 +2573,7 @@ public class RSerialize { return func; } - public static RLanguage processLanguage(Object car, Object cdr, Object tag) { + public static RPairList processLanguage(Object car, Object cdr, Object tag) { Closure closure = Closure.createLanguageClosure(processCall(car, cdr, tag, null).asRNode()); return RDataFactory.createLanguage(closure); } @@ -2594,12 +2601,11 @@ public class RSerialize { case CLOSXP: return processFunctionExpression(pl.car(), pl.cdr(), pl.getTag(), name); default: - throw RInternalError.shouldNotReachHere("unexpected SXP type: " + pl.getType()); + // other pairlists: include as constants + return RContext.getASTBuilder().constant(RSyntaxNode.LAZY_DEPARSE, unwrapScalarValues(value)); } } else { assert !(value instanceof RMissing) : "should be handled outside"; - assert !(value instanceof RLanguage) : "unexpected RLanguage constant in unserialize"; - return RContext.getASTBuilder().constant(RSyntaxNode.LAZY_DEPARSE, unwrapScalarValues(value)); } } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSubstitute.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSubstitute.java index 61744df37aa6cd22b847eda8271f01f45e5c7962..f140db79bdad71065b2a4d04cb018c71830fbec6 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSubstitute.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSubstitute.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2018, 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 @@ -33,13 +33,12 @@ import com.oracle.truffle.r.runtime.RError.Message; import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.context.TruffleRLanguage; import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; -import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RMissing; import com.oracle.truffle.r.runtime.data.RPromise; import com.oracle.truffle.r.runtime.data.RPromise.EagerPromise; import com.oracle.truffle.r.runtime.data.RSymbol; import com.oracle.truffle.r.runtime.env.REnvironment; -import com.oracle.truffle.r.runtime.nodes.RBaseNode; import com.oracle.truffle.r.runtime.nodes.RCodeBuilder; import com.oracle.truffle.r.runtime.nodes.RCodeBuilder.Argument; import com.oracle.truffle.r.runtime.nodes.RSyntaxCall; @@ -67,8 +66,8 @@ public class RSubstitute { } else if (val instanceof RPromise) { RPromise promise = (RPromise) val; return substitutePromise(promise, builder); - } else if (val instanceof RLanguage) { - return ((RLanguage) val).getRep().asRSyntaxNode(); + } else if ((val instanceof RPairList && ((RPairList) val).isLanguage())) { + return ((RPairList) val).getSyntaxElement(); } else if (val instanceof RSymbol) { return RSyntaxLookup.createDummyLookup(RSyntaxNode.LAZY_DEPARSE, ((RSymbol) val).getName(), false); } else if (val instanceof RArgsValuesAndNames) { @@ -216,7 +215,7 @@ public class RSubstitute { } @TruffleBoundary - public static RSyntaxNode substitute(REnvironment env, RBaseNode node, TruffleRLanguage language) { - return substitute(RContext.getASTBuilder(), node.asRSyntaxNode(), env, language); + public static RSyntaxNode substitute(REnvironment env, RSyntaxElement node, TruffleRLanguage language) { + return substitute(RContext.getASTBuilder(), node, env, language); } } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/Utils.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/Utils.java index 35a969fc4628dbc0ebe423b0838fa8d59734bde8..93541e43987bcaad7c8924fe5ad099008f40698b 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/Utils.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/Utils.java @@ -53,7 +53,6 @@ import com.oracle.truffle.r.runtime.conn.StdConnections; import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.context.RContext.ConsoleIO; import com.oracle.truffle.r.runtime.data.RDataFactory; -import com.oracle.truffle.r.runtime.data.RLanguage; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RStringVector; @@ -61,7 +60,6 @@ import com.oracle.truffle.r.runtime.data.RTypedValue; import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; import com.oracle.truffle.r.runtime.env.frame.FrameSlotChangeMonitor.MultiSlotData; import com.oracle.truffle.r.runtime.ffi.BaseRFFI; -import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; public final class Utils { @@ -488,15 +486,14 @@ public final class Utils { skip--; return null; } - RLanguage rl = RContext.getRRuntimeASTAccess().getSyntaxCaller(call); - RSyntaxNode sn = (RSyntaxNode) rl.getRep(); - SourceSection ss = sn != null ? sn.getSourceSection() : null; + RPairList rl = RContext.getRRuntimeASTAccess().getSyntaxCaller(call); + SourceSection section = rl.getSourceSection(); // fabricate a srcref attribute from ss - Source source = ss != null ? ss.getSource() : null; + Source source = section != null ? section.getSource() : null; String path = RSource.getPath(source); RStringVector callerSource = RDataFactory.createStringVectorFromScalar(RContext.getRRuntimeASTAccess().getCallerSource(call)); if (path != null) { - callerSource.setAttr(RRuntime.R_SRCREF, RSrcref.createLloc(ss, path)); + callerSource.setAttr(RRuntime.R_SRCREF, RSrcref.createLloc(section, path)); } RPairList pl = RDataFactory.createPairList(callerSource); if (prev != null) { @@ -598,7 +595,7 @@ public final class Utils { str.append(text.length() < 256 ? text : text.substring(0, 256) + "..."); } } catch (Throwable t) { - // RLanguage values may not react kindly to getLength() calls + // RPairList values may not react kindly to getLength() calls str.append("<exception ").append(t.getClass().getSimpleName()).append(" while printing value of type ").append( value == null ? "null" : value.getClass().getSimpleName()).append('>'); } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/Engine.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/Engine.java index 998f2e895d819e4bfaff297aaa4242f2361e9039..92777dd9a6d24b59e0a64fa79269e87395d433ae 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/Engine.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/Engine.java @@ -43,7 +43,7 @@ import com.oracle.truffle.r.runtime.RSource; import com.oracle.truffle.r.runtime.context.RContext.ConsoleIO; import com.oracle.truffle.r.runtime.data.RExpression; import com.oracle.truffle.r.runtime.data.RFunction; -import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.env.REnvironment; import com.oracle.truffle.r.runtime.nodes.RNode; @@ -207,7 +207,7 @@ public interface Engine { * Variant of {@link #eval(RExpression, REnvironment, RCaller)} for a single language element. * If the {@code caller} argument is null, it is taken from the environment's frame. */ - Object eval(RLanguage expr, REnvironment envir, RCaller caller); + Object eval(RPairList expr, REnvironment envir, RCaller caller); /** * Evaluate {@code expr} in {@code frame}. @@ -217,10 +217,10 @@ public interface Engine { /** * Variant of {@link #eval(RExpression, MaterializedFrame)} for a single language element. */ - Object eval(RLanguage expr, MaterializedFrame frame); + Object eval(RPairList expr, MaterializedFrame frame); /** - * Variant of {@link #eval(RLanguage, MaterializedFrame)} where we already have the + * Variant of {@link #eval(RPairList, MaterializedFrame)} where we already have the * {@link RFunction} and the evaluated arguments. {@code frame} may be {@code null} in which * case the current frame is used). In many cases {@code frame} may not represent the current * call stack, for example many S4-related evaluations set {@code frame} to the {@code methods} diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/Closure.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/Closure.java index 158df899f7ac1edde853e90625af4225df428486..4fefd8d73a76cde9ac314b0a34f61971227426d4 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/Closure.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/Closure.java @@ -25,9 +25,11 @@ package com.oracle.truffle.r.runtime.data; import java.util.WeakHashMap; import com.oracle.truffle.api.CompilerAsserts; +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.api.frame.FrameDescriptor; import com.oracle.truffle.api.frame.MaterializedFrame; +import com.oracle.truffle.r.runtime.ArgumentsSignature; import com.oracle.truffle.r.runtime.RCaller; import com.oracle.truffle.r.runtime.Utils; import com.oracle.truffle.r.runtime.VirtualEvalFrame; @@ -36,6 +38,7 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; import com.oracle.truffle.r.runtime.env.REnvironment; import com.oracle.truffle.r.runtime.nodes.RBaseNode; import com.oracle.truffle.r.runtime.nodes.RNode; +import com.oracle.truffle.r.runtime.nodes.RSyntaxCall; import com.oracle.truffle.r.runtime.nodes.RSyntaxConstant; import com.oracle.truffle.r.runtime.nodes.RSyntaxElement; import com.oracle.truffle.r.runtime.nodes.RSyntaxLookup; @@ -49,14 +52,22 @@ public final class Closure { public static final String PROMISE_CLOSURE_WRAPPER_NAME = new String("<promise>"); public static final String LANGUAGE_CLOSURE_WRAPPER_NAME = new String("<language>"); + private static final RStringVector NULL_MARKER = new RStringVector(new String[0], true); + private final RBaseNode expr; private final String symbol; private final String stringConstant; private final String closureName; - private Closure(String closureName, RBaseNode expr) { + // the first entry in the "names" attribute (special case for pairlist representation) + private final String syntaxLHSName; + + private RStringVector namesVector; // may be null if never queried + + private Closure(String closureName, RBaseNode expr, String syntaxLHSName) { this.closureName = closureName; this.expr = expr; + this.syntaxLHSName = syntaxLHSName; if (expr.asRSyntaxNode() instanceof RSyntaxLookup) { this.symbol = Utils.intern(((RSyntaxLookup) expr.asRSyntaxNode()).getIdentifier()); } else { @@ -77,15 +88,23 @@ public final class Closure { } public static Closure createPromiseClosure(RBaseNode expr) { - return new Closure(PROMISE_CLOSURE_WRAPPER_NAME, expr); + return new Closure(PROMISE_CLOSURE_WRAPPER_NAME, expr, null); + } + + public static Closure createLanguageClosure(RBaseNode expr, String lhsName) { + return new Closure(LANGUAGE_CLOSURE_WRAPPER_NAME, expr, lhsName); } public static Closure createLanguageClosure(RBaseNode expr) { - return new Closure(LANGUAGE_CLOSURE_WRAPPER_NAME, expr); + return new Closure(LANGUAGE_CLOSURE_WRAPPER_NAME, expr, null); } public static Closure create(String name, RBaseNode expr) { - return new Closure(name, expr); + return new Closure(name, expr, null); + } + + public String getSyntaxLHSName() { + return syntaxLHSName; } private synchronized RootCallTarget getCallTarget(FrameDescriptor desc, boolean canReuseExpr) { @@ -152,4 +171,52 @@ public final class Closure { public String asStringConstant() { return stringConstant; } + + public RStringVector getNamesVector() { + if (namesVector == null) { + initializeNamesVector(); + } + return namesVector == NULL_MARKER ? null : namesVector; + } + + @TruffleBoundary + private void initializeNamesVector() { + RSyntaxElement node = getSyntaxElement(); + if (node instanceof RSyntaxCall) { + RSyntaxCall call = (RSyntaxCall) node; + /* + * If the function or any argument has a name, then all arguments (and the function) are + * given names, with unnamed arguments getting "". However, if no arguments have names, + * the result is NULL (null) + */ + boolean hasName = false; + String functionName = ""; + if (getSyntaxLHSName() != null) { + hasName = true; + functionName = getSyntaxLHSName(); + } + ArgumentsSignature sig = call.getSyntaxSignature(); + if (!hasName) { + for (int i = 0; i < sig.getLength(); i++) { + if (sig.getName(i) != null) { + hasName = true; + break; + } + } + } + if (!hasName) { + namesVector = NULL_MARKER; + } else { + String[] data = new String[sig.getLength() + 1]; + data[0] = functionName; // function + for (int i = 0; i < sig.getLength(); i++) { + String name = sig.getName(i); + data[i + 1] = name == null ? "" : name; + } + namesVector = RDataFactory.getPermanent().createStringVector(data, RDataFactory.COMPLETE_VECTOR); + } + } else { + namesVector = NULL_MARKER; + } + } } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RArgsValuesAndNames.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RArgsValuesAndNames.java index f0182160856b72173b12e5dd533ec35f7ad2f186..479a3fcc90c99a64ceb8347ef0876ca7b0a0d0cc 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RArgsValuesAndNames.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RArgsValuesAndNames.java @@ -103,22 +103,16 @@ public final class RArgsValuesAndNames extends RObject implements RTypedValue { return str.toString(); } - public RPairList toPairlist() { - RPairList head = null; - assert signature.getLength() == getLength(); - for (int i = 0; i < getLength(); i++) { - String name = signature.getName(i); - RPairList cur = RDataFactory.createPairList(getArgument(i), RNull.instance, name != null ? RDataFactory.createSymbol(name) : RNull.instance, SEXPTYPE.DOTSXP); - - if (head == null) { - head = cur; - } else { - head.appendToEnd(cur); - } + public Object toPairlist() { + // special case: empty lists are represented by "missing" + if (isEmpty()) { + return RMissing.instance; } - if (head != null) { - return head; + Object current = RNull.instance; + for (int i = getLength() - 1; i >= 0; i--) { + String name = signature.getName(i); + current = RDataFactory.createPairList(getArgument(i), current, name != null ? RDataFactory.createSymbol(name) : RNull.instance, SEXPTYPE.DOTSXP); } - return RDataFactory.createPairList(RNull.instance); + return current; } } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java index 131261bdbcadb195a67839841f5e971ac0f5ee19..b56d627468b78ae6b4bd74702c8e9b18f1ede5c0 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java @@ -629,8 +629,8 @@ public final class RDataFactory { return createSymbol(Utils.intern(name)); } - public final RLanguage createLanguage(Closure closure) { - return traceDataCreated(new RLanguage(closure)); + public final RPairList createLanguage(Closure closure) { + return traceDataCreated(new RPairList(closure)); } public final RPromise createPromise(PromiseState state, Closure closure, MaterializedFrame env) { @@ -662,19 +662,11 @@ public final class RDataFactory { return traceDataCreated(new RPromise.EagerPromise(PromiseState.Promised, exprClosure, eagerValue, notChangedNonLocally, targetFrame, feedback, -1, execFrame)); } - public final Object createLangPairList(int size) { + public final Object createPairList(int size, SEXPTYPE type) { if (size == 0) { return RNull.instance; } else { - return traceDataCreated(RPairList.create(size, SEXPTYPE.LANGSXP)); - } - } - - public final Object createPairList(int size) { - if (size == 0) { - return RNull.instance; - } else { - return traceDataCreated(RPairList.create(size)); + return traceDataCreated(RPairList.create(size, type)); } } @@ -683,7 +675,6 @@ public final class RDataFactory { } public final RPairList createPairList(Object car) { - return traceDataCreated(new RPairList(car, RNull.instance, RNull.instance, null)); } @@ -1208,8 +1199,8 @@ public final class RDataFactory { return createSymbol(Utils.intern(name)); } - public static RLanguage createLanguage(Closure closure) { - return traceDataCreated(new RLanguage(closure)); + public static RPairList createLanguage(Closure closure) { + return traceDataCreated(new RPairList(closure)); } public static RPromise createPromise(PromiseState state, Closure closure, MaterializedFrame env) { @@ -1241,19 +1232,11 @@ public final class RDataFactory { return traceDataCreated(new RPromise.EagerPromise(PromiseState.Promised, exprClosure, eagerValue, notChangedNonLocally, targetFrame, feedback, -1, execFrame)); } - public static Object createLangPairList(int size) { + public static Object createPairList(int size, SEXPTYPE type) { if (size == 0) { return RNull.instance; } else { - return traceDataCreated(RPairList.create(size, SEXPTYPE.LANGSXP)); - } - } - - public static Object createPairList(int size) { - if (size == 0) { - return RNull.instance; - } else { - return traceDataCreated(RPairList.create(size)); + return traceDataCreated(RPairList.create(size, type)); } } @@ -1262,7 +1245,6 @@ public final class RDataFactory { } public static RPairList createPairList(Object car) { - return traceDataCreated(new RPairList(car, RNull.instance, RNull.instance, null)); } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLanguage.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLanguage.java deleted file mode 100644 index db8f3209f189cf5c114d30a0e5085f27b103d5f2..0000000000000000000000000000000000000000 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RLanguage.java +++ /dev/null @@ -1,334 +0,0 @@ -/* - * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.truffle.r.runtime.data; - -import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.CompilerDirectives.ValueType; -import com.oracle.truffle.r.runtime.RInternalError; -import com.oracle.truffle.r.runtime.RRuntime; -import com.oracle.truffle.r.runtime.RType; -import com.oracle.truffle.r.runtime.context.RContext; -import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; -import com.oracle.truffle.r.runtime.data.model.RAbstractVector; -import com.oracle.truffle.r.runtime.data.nodes.FastPathVectorAccess.FastPathFromListAccess; -import com.oracle.truffle.r.runtime.data.nodes.SlowPathVectorAccess.SlowPathFromListAccess; -import com.oracle.truffle.r.runtime.data.nodes.VectorAccess; -import com.oracle.truffle.r.runtime.nodes.RBaseNode; -import com.oracle.truffle.r.runtime.nodes.RSyntaxElement; - -/** - * Denotes an (unevaluated) R language element. It is equivalent to a LANGSXP value in GnuR. It - * would be more correct to be named {@code RCall} since all LANGSXP values in (Gnu)R are in fact - * function calls (although not currently in FastR). Therefore a {@code call} is represented by an - * instance of this type, and an {@code expression} ({@link RExpression}) is a list of such - * instances. R allows a language element to be treated as a list, hence the support for - * {@link RAbstractContainer}, which is implemented via AST walk operations. - * - * {@link RLanguage} instances are almost completely immutable, <i>except</i> for the ability for - * {@code}names} updates which manifests itself as actually transforming the AST. S we do have to - * implement the {@link RShareable} interface. - * - * - */ -@ValueType -public final class RLanguage extends RSharingAttributeStorage implements RAbstractContainer { - - /* - * Used for RLanguage construction from separate AST components. - */ - public enum RepType { - CALL, - FUNCTION, - UNKNOWN - } - - private RPairList list; - private String callLHSName; - - /** - * Lazily computed value. - */ - private int length = -1; - private Closure closure; - - RLanguage(Closure closure) { - this.closure = closure; - } - - private RLanguage(Closure closure, int length) { - this.closure = closure; - this.length = length; - } - - @Override - public Object getInternalStore() { - return this; - } - - @TruffleBoundary - public static Object fromList(Object o, RLanguage.RepType type) { - RList l; - if (o instanceof RPairList) { - l = ((RPairList) o).toRList(); - } else { - l = (RList) o; - } - return RContext.getRRuntimeASTAccess().createLanguageFromList(l, type); - } - - private void regenerateFromList() { - if (list != null) { - // we could rest rep but we keep it around to remember type of the language object - assert closure.getExpr() != null; - // list must be reset before rep type is obtained - RPairList oldList = this.list; - this.list = null; - RLanguage newLang = (RLanguage) fromList(oldList, RContext.getRRuntimeASTAccess().getRepType(this)); - assert newLang.list == null; - this.closure = newLang.closure; - this.length = newLang.length; - this.attributes = newLang.attributes; - } - } - - public Closure getClosure() { - regenerateFromList(); - return closure; - } - - public RBaseNode getRep() { - regenerateFromList(); - return closure.getExpr(); - } - - public void setClosure(Closure closure) { - this.closure = closure; - this.list = null; - } - - public String getCallLHSName() { - return callLHSName; - } - - public void setCallLHSName(String callLHSName) { - this.callLHSName = callLHSName; - } - - @Override - public RType getRType() { - return RType.Language; - } - - @Override - public boolean isComplete() { - return true; - } - - @Override - public int getLength() { - // if list representation is present, it takes priority as it might have been updated - if (list == null) { - if (length < 0) { - length = RContext.getRRuntimeASTAccess().getLength(this); - } - return length; - } else { - return list.getLength(); - } - } - - @Override - public RAbstractContainer resize(int size) { - throw RInternalError.shouldNotReachHere(); - } - - @Override - public boolean hasDimensions() { - // TODO - return false; - } - - @Override - public int[] getDimensions() { - // TODO - return null; - } - - @Override - public void setDimensions(int[] newDimensions) { - throw RInternalError.unimplemented(); - } - - @Override - public RLanguage materialize() { - // TODO is copy necessary? - return copy(); - } - - @Override - public Object getDataAtAsObject(int index) { - if (list == null) { - return RContext.getRRuntimeASTAccess().getDataAtAsObject(this, index); - } else { - return list.getDataAtAsObject(index); - } - } - - @Override - public RStringVector getNames() { - if (list == null) { - /* - * "names" for a language object is a special case, that is applicable to calls and - * returns the names of the actual arguments, if any. E.g. f(x=1, 3) would return c("", - * "x", ""). GnuR defines it as returning the "tag" values on the pairlist that - * represents the call. Well, we don't have a pairlist, (we could get one by serializing - * the expression), so we do it by AST walking. - */ - RStringVector names = RContext.getRRuntimeASTAccess().getNames(this); - return names; - } else { - return list.getNames(); - } - } - - @Override - public void setNames(RStringVector newNames) { - if (list == null) { - /* See getNames */ - RContext.getRRuntimeASTAccess().setNames(this, newNames); - } else { - setNamesOnPairList(newNames); - } - } - - @Override - public RList getDimNames() { - RAttributable attr = list == null ? this : list; - return (RList) attr.getAttr(RRuntime.DIMNAMES_ATTR_KEY); - } - - @Override - public void setDimNames(RList newDimNames) { - RAttributable attr = list == null ? this : list; - attr.setAttr(RRuntime.DIMNAMES_ATTR_KEY, newDimNames); - } - - @Override - public Object getRowNames() { - RAttributable attr = list == null ? this : list; - return attr.getAttr(RRuntime.ROWNAMES_ATTR_KEY); - } - - @Override - public void setRowNames(RAbstractVector rowNames) { - RAttributable attr = list == null ? this : list; - attr.setAttr(RRuntime.ROWNAMES_ATTR_KEY, rowNames); - } - - @Override - public RLanguage copy() { - RLanguage l = new RLanguage(closure, length); - if (this.attributes != null) { - l.initAttributes(RAttributesLayout.copy(attributes)); - } - l.setTypedValueInfo(getTypedValueInfo()); - return l; - } - - @Override - public String toString() { - return String.format("RLanguage(rep=%s)", getRep()); - } - - public RPairList getPairListInternal() { - return this.list; - } - - public RPairList getPairList() { - if (list == null) { - Object obj = RNull.instance; - for (int i = getLength() - 1; i >= 0; i--) { - Object element = RContext.getRRuntimeASTAccess().getDataAtAsObject(this, i); - obj = RDataFactory.createPairList(element, obj); - } - // names have to be taken before list is assigned - RStringVector names = RContext.getRRuntimeASTAccess().getNames(this); - list = (RPairList) obj; - if (names != null) { - setNamesOnPairList(names); - } - } - return list; - } - - @TruffleBoundary - private void setNamesOnPairList(RStringVector names) { - list.setNames(names); - } - - private static final class FastPathAccess extends FastPathFromListAccess { - - FastPathAccess(RAbstractContainer value) { - super(value); - } - - @Override - public RType getType() { - return RType.Language; - } - - @TruffleBoundary - @Override - protected Object getListElement(Object store, int index) { - return ((RLanguage) store).getDataAtAsObject(index); - } - } - - @Override - public VectorAccess access() { - return new FastPathAccess(this); - } - - private static final SlowPathFromListAccess SLOW_PATH_ACCESS = new SlowPathFromListAccess() { - @Override - public RType getType() { - return RType.Language; - } - - @TruffleBoundary - @Override - protected Object getListElement(Object store, int index) { - return ((RLanguage) store).getDataAtAsObject(index); - } - }; - - @Override - public VectorAccess slowPathAccess() { - return SLOW_PATH_ACCESS; - } - - public RSyntaxElement getSyntaxElement() { - regenerateFromList(); - return closure.getSyntaxElement(); - } -} diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RObjectSize.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RObjectSize.java index 0745ec8434ac2880fa45be53e703976f35dc9311..0fd18057ad65be7e1224ef3ef96f7c55c8d46138 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RObjectSize.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RObjectSize.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2018, 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 @@ -160,7 +160,7 @@ public class RObjectSize { } // Individual RTypedValues: if (obj instanceof RPromise || obj instanceof REnvironment || obj instanceof RExternalPtr || obj instanceof RFunction || obj instanceof RSymbol || obj instanceof RPairList || - obj instanceof RLanguage || obj instanceof RS4Object) { + obj instanceof RS4Object) { // promise: there is no value allocated yet, we may use the size of the closure return OBJECT_HEADER_SIZE + attributesSize; } else if (obj instanceof RStringSequence) { diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java index b729095f5df82ea0face701e2c98ccf540b0eb45..82b98b73542ad9d18000a9ca25dab46e5bcf8d4d 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java @@ -27,51 +27,85 @@ import java.util.Iterator; import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.object.DynamicObject; +import com.oracle.truffle.api.source.SourceSection; +import com.oracle.truffle.r.runtime.ArgumentsSignature; +import com.oracle.truffle.r.runtime.RDeparse; +import com.oracle.truffle.r.runtime.RError; +import com.oracle.truffle.r.runtime.RError.Message; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.RRuntime; +import com.oracle.truffle.r.runtime.RSrcref; import com.oracle.truffle.r.runtime.RType; -import com.oracle.truffle.r.runtime.Utils; +import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.RDataFactory.BaseVectorFactory; import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; -import com.oracle.truffle.r.runtime.data.model.RAbstractVector; import com.oracle.truffle.r.runtime.data.nodes.FastPathVectorAccess.FastPathFromListAccess; import com.oracle.truffle.r.runtime.data.nodes.SlowPathVectorAccess.SlowPathFromListAccess; import com.oracle.truffle.r.runtime.data.nodes.VectorAccess; import com.oracle.truffle.r.runtime.gnur.SEXPTYPE; +import com.oracle.truffle.r.runtime.nodes.RBaseNode; +import com.oracle.truffle.r.runtime.nodes.RNode; +import com.oracle.truffle.r.runtime.nodes.RSyntaxCall; +import com.oracle.truffle.r.runtime.nodes.RSyntaxConstant; +import com.oracle.truffle.r.runtime.nodes.RSyntaxElement; +import com.oracle.truffle.r.runtime.nodes.RSyntaxFunction; +import com.oracle.truffle.r.runtime.nodes.RSyntaxLookup; +import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; /** - * Denotes the (rarely seen) {@code pairlist} type in R. - * - * {@code null} is never allowed as a value for the tag, car or cdr, only the type. + * RPairList objects can represent both "normal" pairlists (which are rarely used from R directly) + * and language objects. They are unified in one implementation class because native code often + * changes the type of these in-place. */ public final class RPairList extends RSharingAttributeStorage implements RAbstractContainer, Iterable<RPairList> { + + private static final RSymbol FUNCTION_SYMBOL = RSymbol.install("function"); + /** - * Data of the current pair list cell. + * Data of the current pair list cell (can never be {@code null}). */ - private Object car = RNull.instance; + private Object car; + /** - * Link to the next {@link RPairList} cell or {@link RNull} if last. + * Link to the next {@link RPairList} cell or {@link RNull} if last (can never be {@code null}). */ - private Object cdr = RNull.instance; + private Object cdr; + /** * Externally, i.e., when serialized, this is either a SYMSXP ({@link RSymbol}) or an - * {@link RNull}. Internally it may take on other, non-null, values. + * {@link RNull}. Internally it may take on other values (can never be {@code null}). */ - private Object tag = RNull.instance; + private Object tag; /** * Denotes the (GnuR) type of entity that the pairlist represents. (Internal use only). */ private SEXPTYPE type; + /** + * A closure representing the language pairlist. If this is non-null, then car/cdr/tag are + * uninitialized and were never accessed. + */ + private Closure closure; + + /** + * If this is {@code true}, then the car/cdr/tag fields were not accessed yet, and thus the + * closure field can be initialized. + */ + private boolean mayBeClosure; + /** * Uninitialized pairlist. */ RPairList() { + // defaults to the uninitialized list case + this.car = RNull.instance; + this.cdr = RNull.instance; + this.tag = RNull.instance; } /** - * Variant used in unserialization to record the GnuR type the pairlist denotes. + * Normal pairlist with values for car, cdr, tag and type. */ RPairList(Object car, Object cdr, Object tag, SEXPTYPE type) { assert car != null; @@ -83,42 +117,119 @@ public final class RPairList extends RSharingAttributeStorage implements RAbstra this.type = type; } - @Override - public Object getInternalStore() { - return this; + /** + * A "language" pairlist that is initialized with an AST (and which will be deconstructed into a + * real pairlist if needed). + */ + RPairList(Closure closure) { + assert assertClosure(closure); + this.closure = closure; + this.type = SEXPTYPE.LANGSXP; + this.mayBeClosure = true; + } + + private static boolean assertClosure(Closure closure) { + RBaseNode node = closure.getExpr(); + if (node instanceof RSyntaxCall) { + RSyntaxCall call = (RSyntaxCall) node; + if (call.getSyntaxLHS() instanceof RSyntaxLookup && ((RSyntaxLookup) call.getSyntaxLHS()).getIdentifier().equals("function")) { + boolean valid = true; + valid &= call.getSyntaxSignature().getLength() >= 2; + if (valid) { + RSyntaxElement argList = call.getSyntaxArguments()[1]; + valid &= argList instanceof RSyntaxConstant; + if (valid) { + Object list = ((RSyntaxConstant) argList).getValue(); + valid &= list instanceof RNull || list instanceof RPairList; + } + } + assert !valid : "valid calls to 'function' should be instances of RSyntaxFunction"; + } + } else { + assert node instanceof RSyntaxFunction : "invalid contents of 'language' pairlist: " + node; + } + return true; } /** - * Creates a new pair list of given size > 0. Note: pair list of size 0 is NULL. + * Converts the given vector to a pairlist of the given type. This will apply the "names" + * attribute by putting the names into tags, and copy all other attributes. */ - public static RPairList create(int size) { - return create(size, null); + @TruffleBoundary + public static Object asPairList(RAbstractContainer vector, SEXPTYPE type) { + BaseVectorFactory dataFactory = RDataFactory.getInstance(); + Object result = RNull.instance; + RStringVector names = vector.getNames(); + for (int i = vector.getLength() - 1; i >= 0; i--) { + result = dataFactory.createPairList(vector.getDataAtAsObject(i), result, names != null ? RSymbol.install(names.getDataAt(i)) : RNull.instance, SEXPTYPE.LISTSXP); + } + if (result != RNull.instance) { + RPairList list = (RPairList) result; + list.mayBeClosure = true; + list.setType(type); + DynamicObject attrs = vector.getAttributes(); + if (attrs != null) { + DynamicObject resultAttrs = list.initAttributes(); + Iterator<RAttributesLayout.RAttribute> iter = RAttributesLayout.asIterable(attrs).iterator(); + while (iter.hasNext()) { + RAttributesLayout.RAttribute attr = iter.next(); + String attrName = attr.getName(); + if (!(attrName.equals(RRuntime.NAMES_ATTR_KEY) || attrName.equals(RRuntime.DIM_ATTR_KEY) || attrName.equals(RRuntime.DIMNAMES_ATTR_KEY))) { + resultAttrs.define(attrName, attr.getValue()); + } + } + } + list.setTypedValueInfo(vector.getTypedValueInfo()); + } + return result; } + /** + * Creates a new pair list of given size and type. + */ @TruffleBoundary - public static RPairList create(int size, SEXPTYPE type) { + static RPairList create(int size, SEXPTYPE type) { assert size > 0 : "a pair list of size = 0 does not exist, it should be NULL"; RPairList result = new RPairList(); for (int i = 1; i < size; i++) { RPairList tmp = result; result = new RPairList(); - result.cdr = tmp; - } - if (type != null) { - result.type = type; + result.setCdr(tmp); } + result.setType(type); return result; } + public boolean isLanguage() { + return type == SEXPTYPE.LANGSXP; + } + @Override public RType getRType() { - return RType.PairList; + return isLanguage() ? RType.Language : RType.PairList; + } + + /** + * Can be called after constructing a new pairlist to signal that the individual elements are + * not referenced and thus the closure field can be initialized. + */ + public void allowClosure() { + this.mayBeClosure = true; + } + + @Override + public Object getInternalStore() { + return this; } @Override public String toString() { CompilerAsserts.neverPartOfCompilation(); - return String.format("type=%s, tag=%s, car=%s, cdr=%s", type, tag, toStringHelper(car), toStringHelper(cdr)); + if (isLanguage()) { + return String.format("language(%s)", RDeparse.deparseSyntaxElement(getSyntaxElement())); + } else { + return String.format("pairlist(type=%s, tag=%s, car=%s, cdr=%s)", type, tag, toStringHelper(car), toStringHelper(cdr)); + } } private static String toStringHelper(Object obj) { @@ -126,10 +237,13 @@ public final class RPairList extends RSharingAttributeStorage implements RAbstra } /** - * Convert to a {@link RList}. + * Creates an RList from this pairlist. */ @TruffleBoundary public RList toRList() { + /** + * Convert to a {@link RList}. + */ int len = 0; boolean named = false; for (RPairList item : this) { @@ -140,9 +254,9 @@ public final class RPairList extends RSharingAttributeStorage implements RAbstra String[] names = named ? new String[len] : null; int i = 0; for (RPairList plt : this) { - data[i] = plt.car; + data[i] = plt.car(); if (named) { - Object ptag = plt.tag; + Object ptag = plt.getTag(); if (isNull(ptag)) { names[i] = RRuntime.NAMES_ATTR_EMPTY_VALUE; } else if (ptag instanceof RSymbol) { @@ -171,54 +285,75 @@ public final class RPairList extends RSharingAttributeStorage implements RAbstra } public Object car() { + if (closure != null) { + // TODO: maybe we need to wipe the closure here? + return getDataAtAsObject(0); + } + ensurePairList(); return car; } - public Object cdr() { - return cdr; - } - public void setCar(Object newCar) { + ensurePairList(); assert newCar != null; car = newCar; } + public Object cdr() { + ensurePairList(); + return cdr; + } + public void setCdr(Object newCdr) { + ensurePairList(); assert newCdr != null; cdr = newCdr; } public Object cadr() { - RPairList cdrpl = (RPairList) cdr; - return cdrpl.car; + ensurePairList(); + return ((RPairList) cdr).car(); } public Object cddr() { - RPairList cdrpl = (RPairList) cdr; - return cdrpl.cdr; + ensurePairList(); + return ((RPairList) cdr).cdr(); } public Object caddr() { - RPairList pl = (RPairList) cddr(); - return pl.car; + ensurePairList(); + RPairList pl = (RPairList) ((RPairList) cdr).cdr(); + return pl.car(); } public Object getTag() { - return tag; + if (closure != null) { + return closure.getSyntaxLHSName() == null ? RNull.instance : closure.getSyntaxLHSName(); + } else { + return tag; + } } public void setTag(Object newTag) { + ensurePairList(); assert newTag != null; this.tag = newTag; } public void setType(SEXPTYPE type) { - assert this.type == null || this.type.equals(type); - this.type = type; + if (type != this.type) { + ensurePairList(); + assert type == null || type.equals(type); + this.type = type; + } } public boolean isNullTag() { - return tag == RNull.instance; + if (closure != null) { + return closure.getSyntaxLHSName() == null; + } else { + return tag == RNull.instance; + } } public SEXPTYPE getType() { @@ -229,6 +364,7 @@ public final class RPairList extends RSharingAttributeStorage implements RAbstra * Appends given value as the last element of the pairlist. */ public void appendToEnd(RPairList value) { + ensurePairList(); RPairList last = null; for (RPairList item : this) { last = item; @@ -238,21 +374,31 @@ public final class RPairList extends RSharingAttributeStorage implements RAbstra @Override public boolean isComplete() { - // TODO: is it important to get more precise information here? return false; } @Override + @TruffleBoundary public int getLength() { - int result = 1; - Object tcdr = cdr; - while (!isNull(tcdr)) { - if (tcdr instanceof RPairList) { - tcdr = ((RPairList) tcdr).cdr; + if (closure != null) { + RSyntaxElement s = closure.getSyntaxElement(); + if (s instanceof RSyntaxCall) { + return ((RSyntaxCall) s).getSyntaxSignature().getLength() + 1; + } else { + assert s instanceof RSyntaxFunction : "unexpected type: " + s.getClass(); + return 4; + } + } else { + int result = 1; + Object tcdr = cdr(); + while (!isNull(tcdr)) { + if (tcdr instanceof RPairList) { + tcdr = ((RPairList) tcdr).cdr(); + } + result++; } - result++; + return result; } - return result; } @Override @@ -262,12 +408,16 @@ public final class RPairList extends RSharingAttributeStorage implements RAbstra @Override public boolean hasDimensions() { - return true; + return isLanguage() ? false : true; } @Override public int[] getDimensions() { - return new int[]{1}; + if (isLanguage()) { + return null; + } else { + return new int[]{1}; + } } @Override @@ -275,39 +425,65 @@ public final class RPairList extends RSharingAttributeStorage implements RAbstra throw RInternalError.shouldNotReachHere(); } + @Override @TruffleBoundary - public RPairList copy(boolean keepAttributes) { - BaseVectorFactory dataFactory = RDataFactory.getInstance(); - RPairList curr = dataFactory.createPairList(); - RPairList result = curr; - Object original = this; - while (true) { - RPairList origList = (RPairList) original; - curr.car = origList.car; - curr.tag = origList.tag; - original = origList.cdr; - if (isNull(original)) { - curr.cdr = RNull.instance; - break; + public RPairList copy() { + if (closure != null) { + RPairList result = new RPairList(closure); + if (getAttributes() != null) { + result.initAttributes(RAttributesLayout.copy(getAttributes())); } - curr.cdr = dataFactory.createPairList(); - curr = (RPairList) curr.cdr; - } - if (keepAttributes && getAttributes() != null) { - result.initAttributes(RAttributesLayout.copy(getAttributes())); + result.setTypedValueInfo(getTypedValueInfo()); + return result; + } else { + BaseVectorFactory dataFactory = RDataFactory.getInstance(); + RPairList curr = dataFactory.createPairList(); + RPairList result = curr; + Object original = this; + while (true) { + RPairList origList = (RPairList) original; + curr.setCar(origList.car()); + curr.setTag(origList.getTag()); + curr.setType(origList.getType()); + original = origList.cdr(); + if (isNull(original)) { + curr.setCdr(RNull.instance); + break; + } + curr.setCdr(dataFactory.createPairList()); + curr = (RPairList) curr.cdr(); + } + if (getAttributes() != null) { + result.initAttributes(RAttributesLayout.copy(getAttributes())); + } + result.allowClosure(); + result.setTypedValueInfo(getTypedValueInfo()); + return result; } - return result; - } - - @Override - public RPairList copy() { - return copy(true); } @Override + @TruffleBoundary public RShareable deepCopy() { - RInternalError.shouldNotReachHere(); - return null; + if (closure != null) { + return copy(); + } else { + RPairList result = copy(); + RPairList current = result; + while (true) { + Object c = current.car(); + if (c instanceof RShareable) { + current.setCar(((RShareable) c).deepCopy()); + } + Object next = current.cdr(); + if (next == RNull.instance) { + break; + } + current = (RPairList) next; + } + result.allowClosure(); + return result; + } } @Override @@ -316,14 +492,19 @@ public final class RPairList extends RSharingAttributeStorage implements RAbstra } @Override + @TruffleBoundary public Object getDataAtAsObject(int index) { - RPairList pl = this; - int i = 0; - while (!isNull(pl) && i < index) { - pl = (RPairList) pl.cdr; - i++; + if (closure != null) { + return getClosureDataAtAsObject(index); + } else { + RPairList pl = this; + int i = 0; + while (!isNull(pl) && i < index) { + pl = (RPairList) pl.cdr(); + i++; + } + return pl.car(); } - return pl.car; } public static boolean isNull(Object obj) { @@ -331,59 +512,62 @@ public final class RPairList extends RSharingAttributeStorage implements RAbstra } @Override + @TruffleBoundary public RStringVector getNames() { - if (this.tag == RNull.instance) { - return null; - } - int l = getLength(); - String[] data = new String[l]; - RPairList pl = this; - boolean complete = RDataFactory.COMPLETE_VECTOR; - int i = 0; - while (true) { - data[i] = Utils.toString(pl.tag); - complete &= data[i] != RRuntime.STRING_NA; - if (isNull(pl.cdr)) { - break; + if (closure != null) { + return closure.getNamesVector(); + } else { + boolean hasNames = false; + int length = 1; + RPairList current = this; + while (true) { + if (current.getTag() != RNull.instance) { + hasNames = true; + } + Object next = current.cdr(); + if (isNull(next)) { + break; + } + current = (RPairList) next; + length++; } - pl = (RPairList) pl.cdr; - i++; + if (!hasNames) { + return null; + } + String[] data = new String[length]; + current = this; + int i = 0; + while (true) { + Object name = current.getTag(); + assert name == RNull.instance || name instanceof RSymbol; + data[i] = name == RNull.instance ? "" : ((RSymbol) name).getName(); + Object next = current.cdr(); + if (isNull(next)) { + break; + } + current = (RPairList) next; + i++; + } + // there can never be NAs in the names + return RDataFactory.createStringVector(data, true); } - return RDataFactory.createStringVector(data, complete); } @Override + @TruffleBoundary public void setNames(RStringVector newNames) { + ensurePairList(); Object p = this; for (int i = 0; i < newNames.getLength() && !isNull(p); i++) { RPairList pList = (RPairList) p; - pList.tag = RDataFactory.createSymbol(newNames.getDataAt(i)); - p = pList.cdr; + pList.setTag(RDataFactory.createSymbol(newNames.getDataAt(i))); + p = pList.cdr(); } } - @Override - public RList getDimNames() { - return null; - } - - @Override - public void setDimNames(RList newDimNames) { - throw RInternalError.unimplemented(); - } - - @Override - public void setRowNames(RAbstractVector rowNames) { - throw RInternalError.unimplemented(); - } - - @Override - public boolean isObject() { - return false; - } - @Override public Iterator<RPairList> iterator() { + ensurePairList(); return new Iterator<RPairList>() { private Object plt = RPairList.this; @@ -394,17 +578,283 @@ public final class RPairList extends RSharingAttributeStorage implements RAbstra @Override public RPairList next() { - if (plt instanceof RLanguage) { - plt = ((RLanguage) plt).getPairList(); - } assert plt instanceof RPairList; RPairList curr = (RPairList) plt; - plt = curr.cdr; + plt = curr.cdr(); return curr; } }; } + /** + * Returns a new node that contains the code represented by this language pairlist. This node is + * not used anywhere else and can be executed. + */ + public RSyntaxNode createNode() { + assert isLanguage(); + return RContext.getASTBuilder().process(getSyntaxElement()); + } + + private static RSyntaxElement unwrapToRSyntaxElement(Object obj, boolean functionLookup) { + if ((obj instanceof RPairList && ((RPairList) obj).isLanguage())) { + return ((RPairList) obj).getSyntaxElement(); + } else if (obj instanceof RSymbol) { + return RContext.getASTBuilder().lookup(RSyntaxNode.LAZY_DEPARSE, ((RSymbol) obj).getName(), functionLookup); + } else if (obj instanceof RPromise) { + // Evaluate promise and return the result as constant. + return RContext.getASTBuilder().constant(RSyntaxNode.LAZY_DEPARSE, RContext.getRRuntimeASTAccess().forcePromise("unwrapToRNode", obj)); + } else { + return RContext.getASTBuilder().constant(RSyntaxNode.LAZY_DEPARSE, obj); + } + } + + public SourceSection getLazySourceSection() { + return getSyntaxElement().getLazySourceSection(); + } + + public SourceSection getSourceSection() { + return getSyntaxElement().getSourceSection(); + } + + public RSyntaxElement getSyntaxElement() { + CompilerAsserts.neverPartOfCompilation(); + assert isLanguage(); + if (closure != null) { + return closure.getSyntaxElement(); + } else { + final int length = getLength(); + if (car == FUNCTION_SYMBOL) { + if (length < 3) { + throw RError.error(RError.SHOW_CALLER, Message.BAD_FUNCTION_EXPR); + } + Object argsList = cadr(); + if (!(argsList instanceof RPairList || argsList == RNull.instance)) { + throw RError.error(RError.SHOW_CALLER, Message.BAD_FUNCTION_EXPR); + } + return new RSyntaxFunction() { + @Override + public SourceSection getSourceSection() { + return RSyntaxNode.INTERNAL; + } + + @Override + public SourceSection getLazySourceSection() { + return RSyntaxNode.INTERNAL; + } + + @Override + public void setSourceSection(SourceSection source) { + // ignored + } + + @Override + public ArgumentsSignature getSyntaxSignature() { + if (argsList == RNull.instance) { + return ArgumentsSignature.empty(0); + } + RStringVector argsNames = ((RPairList) argsList).getNames(); + return ArgumentsSignature.get(argsNames.getReadonlyData()); + } + + @Override + public RSyntaxElement[] getSyntaxArgumentDefaults() { + if (argsList == RNull.instance) { + return new RSyntaxElement[0]; + } + RPairList current = (RPairList) argsList; + int argsLength = current.getLength(); + RSyntaxElement[] result = new RSyntaxElement[argsLength]; + int i = 0; + while (true) { + result[i] = unwrapToRSyntaxElement(current.car(), false); + Object next = current.cdr(); + if (next == RNull.instance) { + break; + } + current = (RPairList) next; + i++; + } + return result; + } + + @Override + public RSyntaxElement getSyntaxBody() { + return unwrapToRSyntaxElement(caddr(), false); + } + + @Override + public String getSyntaxDebugName() { + return null; + } + }; + } else { + return new RSyntaxCall() { + + @Override + public SourceSection getSourceSection() { + return RSyntaxNode.INTERNAL; + } + + @Override + public SourceSection getLazySourceSection() { + return RSyntaxNode.INTERNAL; + } + + @Override + public void setSourceSection(SourceSection source) { + // ignored + } + + @Override + public RSyntaxElement getSyntaxLHS() { + return unwrapToRSyntaxElement(getDataAtAsObject(0), true); + } + + @Override + public ArgumentsSignature getSyntaxSignature() { + RStringVector names = getNames(); + if (names == null) { + return ArgumentsSignature.empty(length - 1); + } else { + String[] signature = new String[length - 1]; + for (int i = 0; i < names.getLength() && i < (length - 1); i++) { + signature[i] = names.getDataAt(i + 1); + } + return ArgumentsSignature.get(signature); + } + } + + @Override + public RSyntaxElement[] getSyntaxArguments() { + RSyntaxElement[] result = new RSyntaxElement[length - 1]; + for (int i = 1; i < length; i++) { + result[i - 1] = unwrapToRSyntaxElement(getDataAtAsObject(i), false); + } + return result; + } + }; + } + } + } + + /** + * Used mainly for serialization (because it has special handling for converting nodes to + * pairlists). + */ + public boolean hasClosure() { + return closure != null; + } + + public Closure getClosure(ClosureCache<RBaseNode> cache) { + if (closure != null) { + return closure; + } else { + return createClosure(cache); + } + } + + @TruffleBoundary + private Closure createClosure(ClosureCache<RBaseNode> cache) { + RNode node = createNode().asRNode(); + Closure result = cache == null ? Closure.createLanguageClosure(node) : cache.getOrCreateLanguageClosure(node); + if (mayBeClosure) { + closure = result; + } + return result; + } + + public Closure getClosure() { + return getClosure(null); + } + + @TruffleBoundary + public Object getClosureDataAtAsObject(int index) { + assert closure != null; + // index has already been range checked based on getLength + RSyntaxElement s = closure.getSyntaxElement(); + + RSyntaxElement result; + if (s instanceof RSyntaxCall) { + RSyntaxCall call = (RSyntaxCall) s; + if (index == 0) { + result = call.getSyntaxLHS(); + } else { + result = call.getSyntaxArguments()[index - 1]; + if (result == null) { + return RSymbol.MISSING; + } + } + } else { + /* + * We do not expect RSyntaxConstant and RSyntaxLookup here: RSyntaxConstant should have + * been converted to the constant value, and RSyntaxLookup should have been converted to + * an RSymbol (see below). + */ + assert s instanceof RSyntaxFunction; + + RSyntaxFunction function = (RSyntaxFunction) s; + switch (index) { + case 0: + return RDataFactory.createSymbol("function"); + case 1: + ArgumentsSignature sig = function.getSyntaxSignature(); + RSyntaxElement[] defaults = function.getSyntaxArgumentDefaults(); + + Object lst = RNull.instance; + for (int i = sig.getLength() - 1; i >= 0; i--) { + lst = RDataFactory.createPairList(defaults[i] == null ? RSymbol.MISSING : RContext.getRRuntimeASTAccess().createLanguageElement(defaults[i]), lst, + RDataFactory.createSymbolInterned(sig.getName(i))); + } + return lst; + case 2: + result = function.getSyntaxBody(); + break; + case 3: + // srcref + return RSrcref.createLloc(s.getLazySourceSection()); + default: + throw RInternalError.shouldNotReachHere(); + } + } + + /* + * Constants and lookups are converted to their intrinsic value: + */ + return RContext.getRRuntimeASTAccess().createLanguageElement(result); + } + + /** + * Ensures that the car, cdr and tag fields are initialized from the contents of closure if + * necessary. + */ + private void ensurePairList() { + mayBeClosure = false; + if (closure != null) { + convertToPairList(); + } + } + + @TruffleBoundary + private void convertToPairList() { + RStringVector names = getNames(); + + Object obj = RNull.instance; + for (int i = getLength() - 1; i > 0; i--) { + obj = RDataFactory.createPairList(getDataAtAsObject(i), obj); + } + this.car = getDataAtAsObject(0); + this.cdr = obj; + // names have to be taken before list is assigned + closure = null; + mayBeClosure = false; + if (names != null) { + setNames(names); + } else { + // needs to be initialized + this.tag = RNull.instance; + } + } + private static final class FastPathAccess extends FastPathFromListAccess { FastPathAccess(RAbstractContainer value) { diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RTypes.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RTypes.java index 582b9366c70bc6a0cdd69ba8e82cba861b652241..8e782899b0f16c3ccdc89262f67ce1e9a6c900af 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RTypes.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RTypes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2018, 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 @@ -69,7 +69,6 @@ import com.oracle.truffle.r.runtime.nodes.RNode; RMissing.class, RPairList.class, RSymbol.class, - RLanguage.class, RFunction.class, REnvironment.class, RAbstractContainer.class, diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/REnvironment.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/REnvironment.java index 1253a0a8091e54e81e3e8f2c06ff270a0cab5b43..190728124225092bfda16e1990049e4a3ca6a66a 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/REnvironment.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/env/REnvironment.java @@ -124,8 +124,12 @@ public abstract class REnvironment extends RAttributeStorage { @CompilationFinal private SearchPath searchPath; @CompilationFinal private MaterializedFrame parentGlobalFrame; // SHARED_PARENT_RW only + @CompilationFinal private REnvironment emptyDummy; // used when evaluating in emptyenv + private ContextStateImpl(MaterializedFrame globalFrame) { this.globalFrame = globalFrame; + this.emptyDummy = RDataFactory.createNewEnv(null, false, 0); + RArguments.initializeEnclosingFrame(this.emptyDummy.getFrame(), null); } public REnvironment getGlobalEnv() { @@ -144,6 +148,10 @@ public abstract class REnvironment extends RAttributeStorage { return baseEnv; } + public REnvironment getEmptyDummy() { + return emptyDummy; + } + public REnvironment getBaseNamespace() { return baseEnv.getNamespace(); } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/gnur/SEXPTYPE.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/gnur/SEXPTYPE.java index 977cc6c1a7a9fabd532de93fb4957c0cd5e142f7..873ade3ce5a1c5b684b38373ad167d244df71682 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/gnur/SEXPTYPE.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/gnur/SEXPTYPE.java @@ -5,7 +5,7 @@ * * Copyright (c) 1995-2012, The R Core Team * Copyright (c) 2003, The R Foundation - * Copyright (c) 2013, 2017, Oracle and/or its affiliates + * Copyright (c) 2013, 2018, Oracle and/or its affiliates * * All rights reserved. */ @@ -23,12 +23,11 @@ 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.RPairList; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RLogicalVector; import com.oracle.truffle.r.runtime.data.RMissing; 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.RPromise.EagerPromise; import com.oracle.truffle.r.runtime.data.RRaw; @@ -46,11 +45,11 @@ public enum SEXPTYPE { NILSXP(0, RNull.class), /* nil ()NULL */ SYMSXP(1, RSymbol.class), /* symbols */ - LISTSXP(2, RPairList.class), /* lists of dotted pairs */ - CLOSXP(3, RPairList.class), /* closures */ + LISTSXP(2), /* lists of dotted pairs */ + CLOSXP(3), /* closures */ ENVSXP(4, REnvironment.class), /* environments */ PROMSXP(5, RPromise.class, EagerPromise.class), /* promises: [un]evaluated closure arguments */ - LANGSXP(6, RLanguage.class), /* language constructs (special lists) */ + LANGSXP(6), /* language constructs (special lists) */ SPECIALSXP(7), /* special forms */ BUILTINSXP(8), /* builtin non-special forms */ CHARSXP(9), /* "scalar" string type (GnuR internal only) */ @@ -119,7 +118,11 @@ public enum SEXPTYPE { * ints, e.g. {@code DeParse}. N.B. This is not unique for {@link RPairList}, so the * {@code type} field on the {@link RPairList} has to be consulted. */ - public static SEXPTYPE typeForClass(Class<?> fastRClass) { + public static SEXPTYPE typeForClass(Object value) { + if (value instanceof RPairList) { + return ((RPairList) value).isLanguage() ? LANGSXP : LISTSXP; + } + Class<?> fastRClass = value.getClass(); for (SEXPTYPE type : values()) { for (Class<?> clazz : type.fastRClasses) { if (fastRClass == clazz) { @@ -147,7 +150,7 @@ public enum SEXPTYPE { * Accessed from FFI layer. */ public static SEXPTYPE gnuRTypeForObject(Object obj) { - SEXPTYPE type = typeForClass(obj.getClass()); + SEXPTYPE type = typeForClass(obj); return gnuRType(type, obj); } @@ -166,7 +169,7 @@ public enum SEXPTYPE { } case LISTSXP: RPairList pl = (RPairList) obj; - if (pl.getType() != null && pl.getType() == SEXPTYPE.LANGSXP) { + if (pl.getType() == SEXPTYPE.LANGSXP) { return SEXPTYPE.LANGSXP; } else { return type; diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/RBaseNode.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/RBaseNode.java index 694a5de17e9537f7086c2f69b57c029243c7d1c3..ba05196b72aee87a2ed14685e38548139afda0f6 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/RBaseNode.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/RBaseNode.java @@ -41,11 +41,10 @@ import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; import com.oracle.truffle.r.runtime.data.RAttributable; import com.oracle.truffle.r.runtime.data.RExpression; import com.oracle.truffle.r.runtime.data.RFunction; -import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RMissing; 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.RSymbol; import com.oracle.truffle.r.runtime.data.model.RAbstractComplexVector; @@ -257,10 +256,6 @@ public abstract class RBaseNode extends Node { return value instanceof RPromise; } - protected static boolean isRLanguage(Object value) { - return value instanceof RLanguage; - } - protected static boolean isRExpression(Object value) { return value instanceof RExpression; } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/RSyntaxVisitor.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/RSyntaxVisitor.java index 5ffdf75dfd26a2aeff48b2b9eb135c702214d3f6..6a374229ef0f001a55d243f2f88f57981f2a1aa5 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/RSyntaxVisitor.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/RSyntaxVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2018, 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 @@ -44,7 +44,7 @@ public abstract class RSyntaxVisitor<T> { } else if (element instanceof RSyntaxFunction) { return visit((RSyntaxFunction) element); } else { - throw RInternalError.shouldNotReachHere("unexpected RSyntaxElement: " + element.getClass().getCanonicalName()); + throw RInternalError.shouldNotReachHere("unexpected RSyntaxElement: " + element == null ? "null" : element.getClass().getCanonicalName()); } } diff --git a/com.oracle.truffle.r.test.native/embedded/src/embedded.c b/com.oracle.truffle.r.test.native/embedded/src/embedded.c index 84d129e2e60419537abee49a0e88030dc519ea12..82c52bc4b32674ed668196d942521e6a12486af4 100644 --- a/com.oracle.truffle.r.test.native/embedded/src/embedded.c +++ b/com.oracle.truffle.r.test.native/embedded/src/embedded.c @@ -188,7 +188,7 @@ int main(int argc, char **argv) { printf("Calling R_getEmbeddingDllInfo...\n"); DllInfo *eDllInfo = R_getEmbeddingDllInfo(); R_CallMethodDef CallEntries[] = { - CALLDEF(twice, 2), + CALLDEF(twice, 1), {NULL, NULL, 0} }; R_registerRoutines(eDllInfo, NULL, CallEntries, NULL, NULL); diff --git a/com.oracle.truffle.r.test.native/embedded/src/embedded.expected.output b/com.oracle.truffle.r.test.native/embedded/src/embedded.expected.output index 4a76493713e8e62a45def473e837b219739b5b95..298ea4e37b57c92299c44d6417c7afde268eb3c8 100644 --- a/com.oracle.truffle.r.test.native/embedded/src/embedded.expected.output +++ b/com.oracle.truffle.r.test.native/embedded/src/embedded.expected.output @@ -13,24 +13,12 @@ Caught an error calling sqrt(). Try again with a different argument. Sourcing 'foo.R'... Calling foo with named arguments... Printing the expression to be eval'ed... -[[1]] -function(...) -{ +function (...) { args <- list(...) print(args) print(names(args)) TRUE -} - -$pch -[1] "+" - -$id -[1] 123 - -[[4]] -[1] TRUE FALSE - +}(pch = "+", id = 123L, c(TRUE, FALSE)) Eval'ing the expression... $pch [1] "+" @@ -43,18 +31,7 @@ $id [1] "pch" "id" "" Printing the expression to be tryEval'ed... -[[1]] -foo - -$pch -[1] "+" - -$id -[1] 123 - -[[4]] -[1] TRUE FALSE - +foo(pch = "+", id = 123L, c(TRUE, FALSE)) TryEval'ing the expression... $pch [1] "+" @@ -70,6 +47,6 @@ Calling R_getEmbeddingDllInfo... Sourcing 'embedding.R'... getDLLRegisteredRoutines('(embedding)'): .Call .Call.numParameters -1 twice 2 +1 twice 1 [1] 2 4 6 8 10 DONE diff --git a/com.oracle.truffle.r.test.native/embedded/test.sh b/com.oracle.truffle.r.test.native/embedded/test.sh index 38f05584f494acff07adee9bf307abfa9a166f20..8dc334a042fa48e4b83487752095f7e4485c6e35 100755 --- a/com.oracle.truffle.r.test.native/embedded/test.sh +++ b/com.oracle.truffle.r.test.native/embedded/test.sh @@ -40,6 +40,11 @@ dir="$( cd -P "$( dirname "$source" )" && pwd )" : ${R_HOME?"R_HOME must point to FastR directory"} : ${NFI_LIB?"NFI_LIB must point to libtrufflenfi.so located in mxbuild directory of Truffle"} +echo "R_HOME: $R_HOME" +echo "NFI_LIB: $NFI_LIB" +echo "Rclasspath: " +$dir/../../bin/execRextras/Rclasspath + echo "Testing 'main' embedding example..." (cd $dir/bin; ./main -Dtruffle.nfi.library=$NFI_LIB --vanilla < $dir/src/main.input > $dir/main.actual.output 2>&1) if ! diff -q $dir/main.actual.output $dir/src/main.expected.output > /dev/null 2>&1; then diff --git a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/R/api.R b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/R/api.R index 433e496efc9b16392eed16ca689b4115271b0140..cb2bc78eb92f67e735a71ca421edf5b6231b3a7d 100644 --- a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/R/api.R +++ b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/R/api.R @@ -3,17 +3,18 @@ # All the generated files in testrffi can be regenerated by running 'mx testrfficodegen' # R wrappers for all the generated RFFI C wrappers +api.OBJECT <- function(...) .Call(C_api_OBJECT, ...) +api.Rf_cons <- function(...) .Call(C_api_Rf_cons, ...) +api.Rf_ScalarInteger <- function(...) .Call(C_api_Rf_ScalarInteger, ...) +api.Rf_ScalarLogical <- function(...) .Call(C_api_Rf_ScalarLogical, ...) api.Rf_ScalarReal <- function(...) .Call(C_api_Rf_ScalarReal, ...) api.Rf_ScalarString <- function(...) .Call(C_api_Rf_ScalarString, ...) -api.Rf_ScalarLogical <- function(...) .Call(C_api_Rf_ScalarLogical, ...) -api.Rf_ScalarInteger <- function(...) .Call(C_api_Rf_ScalarInteger, ...) api.Rf_asInteger <- function(...) .Call(C_api_Rf_asInteger, ...) api.Rf_asReal <- function(...) .Call(C_api_Rf_asReal, ...) api.Rf_asLogical <- function(...) .Call(C_api_Rf_asLogical, ...) api.Rf_asChar <- function(...) .Call(C_api_Rf_asChar, ...) api.Rf_coerceVector <- function(...) .Call(C_api_Rf_coerceVector, ...) api.Rf_mkCharLenCE <- function(...) .Call(C_api_Rf_mkCharLenCE, ...) -api.Rf_cons <- function(...) .Call(C_api_Rf_cons, ...) api.Rf_defineVar <- function(...) .Call(C_api_Rf_defineVar, ...) api.R_getClassDef <- function(...) .Call(C_api_R_getClassDef, ...) api.R_do_MAKE_CLASS <- function(...) .Call(C_api_R_do_MAKE_CLASS, ...) @@ -49,6 +50,7 @@ api.VECTOR_ELT <- function(...) .Call(C_api_VECTOR_ELT, ...) api.NAMED <- function(...) .Call(C_api_NAMED, ...) api.SET_OBJECT <- function(...) .Call(C_api_SET_OBJECT, ...) api.SET_NAMED <- function(...) .Call(C_api_SET_NAMED, ...) +api.SET_TYPEOF <- function(...) .Call(C_api_SET_TYPEOF, ...) api.TYPEOF <- function(...) .Call(C_api_TYPEOF, ...) api.Rf_any_duplicated <- function(...) .Call(C_api_Rf_any_duplicated, ...) api.Rf_any_duplicated3 <- function(...) .Call(C_api_Rf_any_duplicated3, ...) @@ -228,4 +230,3 @@ api.Rf_match <- function(...) .Call(C_api_Rf_match, ...) api.Rf_NonNullStringMatch <- function(...) .Call(C_api_Rf_NonNullStringMatch, ...) api.R_has_slot <- function(...) .Call(C_api_R_has_slot, ...) api.Rf_PrintValue <- function(...) .Call(C_api_Rf_PrintValue, ...) -api.OBJECT <- function(...) .Call(C_api_OBJECT, ...) diff --git a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/init_api.h b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/init_api.h index 345fc0f7b540cf39b1acfeee4e02d545ccdbd18a..cadf77e0a2b1dc27ebb381b71574e019d23e44d2 100644 --- a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/init_api.h +++ b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/init_api.h @@ -27,8 +27,17 @@ // The definitions of the C functions could be generated by the same Java class (but run without any option) // RFFI functions that take/return C pointers are ignored // This code is '#included' into init.c -CALLDEF(api_Rf_ScalarInteger, 1), +CALLDEF(api_OBJECT, 1), +CALLDEF(api_LENGTH, 1), +CALLDEF(api_Rf_error, 1), +CALLDEF(api_NAMED, 1), +CALLDEF(api_Rf_ncols, 1), +CALLDEF(api_TYPEOF, 1), +CALLDEF(api_Rf_nrows, 1), +CALLDEF(api_ATTRIB, 1), CALLDEF(api_Rf_ScalarLogical, 1), +CALLDEF(api_Rf_cons, 2), +CALLDEF(api_Rf_ScalarInteger, 1), CALLDEF(api_Rf_ScalarReal, 1), CALLDEF(api_Rf_ScalarString, 1), CALLDEF(api_Rf_asInteger, 1), @@ -37,7 +46,6 @@ CALLDEF(api_Rf_asLogical, 1), CALLDEF(api_Rf_asChar, 1), CALLDEF(api_Rf_coerceVector, 2), CALLDEF(api_Rf_mkCharLenCE, 3), -CALLDEF(api_Rf_cons, 2), CALLDEF(api_Rf_defineVar, 3), CALLDEF(api_R_getClassDef, 1), CALLDEF(api_R_do_MAKE_CLASS, 1), @@ -45,7 +53,6 @@ CALLDEF(api_R_do_new_object, 1), CALLDEF(api_Rf_findVar, 2), CALLDEF(api_Rf_findVarInFrame, 2), CALLDEF(api_Rf_findVarInFrame3, 3), -CALLDEF(api_ATTRIB, 1), CALLDEF(api_Rf_getAttrib, 2), CALLDEF(api_Rf_setAttrib, 3), CALLDEF(api_Rf_inherits, 2), @@ -55,25 +62,20 @@ CALLDEF(api_Rf_lengthgets, 2), CALLDEF(api_Rf_isString, 1), CALLDEF(api_Rf_isNull, 1), CALLDEF(api_Rf_PairToVectorList, 1), -CALLDEF(api_Rf_error, 1), CALLDEF(api_Rf_warning, 1), CALLDEF(api_Rf_warningcall, 2), CALLDEF(api_Rf_errorcall, 2), CALLDEF(api_Rf_allocVector, 2), CALLDEF(api_Rf_allocArray, 2), CALLDEF(api_Rf_allocMatrix, 3), -CALLDEF(api_Rf_nrows, 1), -CALLDEF(api_Rf_ncols, 1), -CALLDEF(api_LENGTH, 1), CALLDEF(api_SET_STRING_ELT, 3), CALLDEF(api_SET_VECTOR_ELT, 3), CALLDEF(api_SET_ATTRIB, 2), CALLDEF(api_STRING_ELT, 2), CALLDEF(api_VECTOR_ELT, 2), -CALLDEF(api_NAMED, 1), CALLDEF(api_SET_OBJECT, 2), CALLDEF(api_SET_NAMED, 2), -CALLDEF(api_TYPEOF, 1), +CALLDEF(api_SET_TYPEOF, 2), CALLDEF(api_Rf_any_duplicated, 2), CALLDEF(api_Rf_any_duplicated3, 3), CALLDEF(api_PRINTNAME, 1), @@ -252,5 +254,4 @@ CALLDEF(api_Rf_match, 3), CALLDEF(api_Rf_NonNullStringMatch, 2), CALLDEF(api_R_has_slot, 2), CALLDEF(api_Rf_PrintValue, 1), -CALLDEF(api_OBJECT, 1), // ---- end of generated code diff --git a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/rffiwrappers.c b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/rffiwrappers.c index c9bf742466e25cf3a81e165e1d763a169ddd938b..8f5204897749ac82d69cc571620a8681aac7b78b 100644 --- a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/rffiwrappers.c +++ b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/rffiwrappers.c @@ -43,6 +43,18 @@ #pragma GCC diagnostic ignored "-Wincompatible-pointer-types" +SEXP api_OBJECT(SEXP x) { + return ScalarInteger(OBJECT(x)); +} + +SEXP api_ATTRIB(SEXP obj) { + return ATTRIB(obj); +} + +SEXP api_Rf_cons(SEXP car, SEXP cdr) { + return Rf_cons(car, cdr); +} + SEXP api_Rf_ScalarInteger(SEXP value) { return Rf_ScalarInteger(INTEGER_VALUE(value)); } @@ -83,10 +95,6 @@ SEXP api_Rf_mkCharLenCE(SEXP bytes, SEXP len, SEXP encoding) { return Rf_mkCharLenCE(R_CHAR(STRING_ELT(bytes, 0)), INTEGER_VALUE(len), INTEGER_VALUE(encoding)); } -SEXP api_Rf_cons(SEXP car, SEXP cdr) { - return Rf_cons(car, cdr); -} - SEXP api_Rf_defineVar(SEXP symbolArg, SEXP value, SEXP envArg) { Rf_defineVar(symbolArg, value, envArg); return R_NilValue; @@ -116,10 +124,6 @@ SEXP api_Rf_findVarInFrame3(SEXP envArg, SEXP symbolArg, SEXP doGet) { return Rf_findVarInFrame3(envArg, symbolArg, INTEGER_VALUE(doGet)); } -SEXP api_ATTRIB(SEXP obj) { - return ATTRIB(obj); -} - SEXP api_Rf_getAttrib(SEXP obj, SEXP name) { return Rf_getAttrib(obj, name); } @@ -238,6 +242,11 @@ SEXP api_SET_NAMED(SEXP x, SEXP v) { return R_NilValue; } +SEXP api_SET_TYPEOF(SEXP x, SEXP v) { + SET_TYPEOF(x, INTEGER_VALUE(v)); + return R_NilValue; +} + SEXP api_TYPEOF(SEXP x) { return ScalarInteger(TYPEOF(x)); } @@ -977,9 +986,5 @@ SEXP api_Rf_PrintValue(SEXP value) { return R_NilValue; } -SEXP api_OBJECT(SEXP x) { - return ScalarInteger(OBJECT(x)); -} - #pragma GCC diagnostic pop #pragma GCC diagnostic pop diff --git a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/rffiwrappers.h b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/rffiwrappers.h index f59eb727b14a0abc1bb8cd43a771e8f8fd6a6967..60f794a162816d0bc05b0aa0c9cce9e75145f83f 100644 --- a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/rffiwrappers.h +++ b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/src/rffiwrappers.h @@ -34,18 +34,22 @@ #include <R_ext/Connections.h> #include <Rmath.h> -SEXP api_Rf_ScalarInteger(SEXP value); - -SEXP api_Rf_ScalarLogical(SEXP value); +SEXP api_OBJECT(SEXP x); SEXP api_Rf_ScalarReal(SEXP value); -SEXP api_Rf_ScalarString(SEXP value); +SEXP api_Rf_cons(SEXP car, SEXP cdr); SEXP api_Rf_asInteger(SEXP x); SEXP api_Rf_asReal(SEXP x); +SEXP api_Rf_ScalarString(SEXP value); + +SEXP api_Rf_ScalarInteger(SEXP value); + +SEXP api_Rf_ScalarLogical(SEXP value); + SEXP api_Rf_asLogical(SEXP x); SEXP api_Rf_asChar(SEXP x); @@ -54,8 +58,6 @@ SEXP api_Rf_coerceVector(SEXP x, SEXP mode); SEXP api_Rf_mkCharLenCE(SEXP bytes, SEXP len, SEXP encoding); -SEXP api_Rf_cons(SEXP car, SEXP cdr); - SEXP api_Rf_defineVar(SEXP symbolArg, SEXP value, SEXP envArg); SEXP api_R_getClassDef(SEXP clazz); @@ -126,6 +128,8 @@ SEXP api_SET_OBJECT(SEXP x, SEXP flag); SEXP api_SET_NAMED(SEXP x, SEXP v); +SEXP api_SET_TYPEOF(SEXP x, SEXP v); + SEXP api_TYPEOF(SEXP x); SEXP api_Rf_any_duplicated(SEXP x, SEXP fromLast); @@ -484,5 +488,3 @@ SEXP api_R_has_slot(SEXP container, SEXP name); SEXP api_Rf_PrintValue(SEXP value); -SEXP api_OBJECT(SEXP x); - diff --git a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/tests/pairlists.R b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/tests/pairlists.R index 8260d0d90eadf62d3367a3bf8101ae1792500977..5511b2bd64ed4f2255e17f128654dc79b87efde7 100644 --- a/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/tests/pairlists.R +++ b/com.oracle.truffle.r.test.native/packages/testrffi/testrffi/tests/pairlists.R @@ -9,3 +9,24 @@ invisible(foo(a=4, b=6)) foo <- function(...) api.CDR(get('...')) is.null(foo(a=3)) names(foo(a=4, b=6)) + +someFunction <- function(a,b,c,d=100) a + b + d +l <- quote(someFunction(a=1,122,c=x+foo)) +api.TYPEOF(l) +api.CAR(l) +api.CDR(l) +l +eval(l) +api.SET_TYPEOF(l, 2) # LISTSXP +l +eval(l) +api.SET_TYPEOF(l, 6) # LANGSXP + +l <- pairlist(a=as.symbol("sum"), foo=123L,1233) +api.TYPEOF(l) +api.CAR(l) +api.CDR(l) +l +api.SET_TYPEOF(l, 6) # LANGSXP +l +eval(l) diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test index 57f734463d8a4bb4bd387d9254e61ccf87fe0e94..dc4af52603c82f1790d5d045015e208a0eb9c442 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test @@ -528,7 +528,7 @@ Use showMethods("gen") for currently available ones. [1] 42 [1] 42 -##com.oracle.truffle.r.test.S4.TestS4.testMethods#Ignored.OutputFormatting# +##com.oracle.truffle.r.test.S4.TestS4.testMethods# #{ setClass("foo"); setMethod("diag<-", "foo", function(x, value) 42); removeMethod("diag<-", "foo"); removeGeneric("diag<-"); removeClass("foo") } Creating a generic function for ‘diag<-’ from package ‘base’ in the global environment [1] TRUE @@ -549,7 +549,7 @@ Note: method with signature ‘A2#A1’ chosen for function ‘foo’, #{ setClass('A1', representation(a='numeric')); setMethod('length', 'A1', function(x) x@a); obj <- new('A1'); obj@a <- 10; length(obj) } [1] 10 -##com.oracle.truffle.r.test.S4.TestS4.testMethods#Ignored.OutputFormatting# +##com.oracle.truffle.r.test.S4.TestS4.testMethods# #{ setClass('A2', representation(a = 'numeric')); setMethod('rep', 'A2', function(x, a, b, c) { c(x@a, a, b, c) }); setMethod('ifelse', c(yes = 'A2'), function(test, yes, no) print(test)) } Creating a generic function for ‘ifelse’ from package ‘base’ in the global environment [1] "ifelse" @@ -21412,6 +21412,18 @@ attr(,"gradient") x [1,] NaN +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testEnvironment# +#environment(deriv((y ~ sin(cos(x) * y)), c('x','y'), func = TRUE)) +<environment: R_GlobalEnv> + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testEnvironment# +#environment(local(deriv((y ~ sin(cos(x) * y)), c('x','y'), func = TRUE))) +<environment: R_GlobalEnv> + +##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testEnvironment# +#environment(local(deriv((y ~ sin(cos(x) * y)), c('x','y'), func = deriv))) +<environment: namespace:stats> + ##com.oracle.truffle.r.test.builtins.TestBuiltin_deriv.testFunctionGenereration#Output.IgnoreWhitespace# #(df <- deriv(~x^2*sin(x), "x", function.arg=TRUE));df(0) function (x) @@ -28269,7 +28281,7 @@ Error: atomic vector arguments only function (x = 4) x + 1 -##com.oracle.truffle.r.test.builtins.TestBuiltin_function.testFunctionFunction#Output.IgnoreErrorContext# +##com.oracle.truffle.r.test.builtins.TestBuiltin_function.testFunctionFunction#Output.MayIgnoreErrorContext# #eval(call('function', 1, expression(x + 1)[[1]])) Error in eval(call("function", 1, expression(x + 1)[[1]])) : invalid formal argument list for "function" @@ -29823,7 +29835,7 @@ attr(,"Rd_tag") ##com.oracle.truffle.r.test.builtins.TestBuiltin_icuSetCollate.testicuSetCollate1#Ignored.Unimplemented# # .Internal(icuSetCollate()) -##com.oracle.truffle.r.test.builtins.TestBuiltin_identical.testAttrOrder#Ignored.ImplementationError# +##com.oracle.truffle.r.test.builtins.TestBuiltin_identical.testAttrOrder# #x <- 1; y <- 1; attr(x, "f") <- 2; attr(x, "g") <- 1; attr(y, "g") <- 1; attr(y, "f") <- 2; identical(x, y) [1] TRUE @@ -29891,6 +29903,34 @@ attr(,"Rd_tag") #identical(NaN, NaN, num.eq=T, single.NA=T) [1] TRUE +##com.oracle.truffle.r.test.builtins.TestBuiltin_identical.testIdentical# +#a <- quote(a(100)); b <- quote(a(100)); attr(a[[2]], 'foo') <- 'bar'; b[[2]] <- a[[2]]; identical(a,b) +[1] TRUE + +##com.oracle.truffle.r.test.builtins.TestBuiltin_identical.testIdentical# +#a <- quote(a(100)); b <- quote(a(100)); attr(a[[2]], 'foo') <- 'bar'; identical(a,b) +[1] FALSE + +##com.oracle.truffle.r.test.builtins.TestBuiltin_identical.testIdentical# +#a <- quote(a(100)); b <- quote(a(100)); attr(b[[2]], 'foo') <- 'bar'; attr(a[[2]], 'foo') <- 'bar'; identical(a,b) +[1] TRUE + +##com.oracle.truffle.r.test.builtins.TestBuiltin_identical.testIdentical# +#a <- quote(a(100)); b <- quote(a(100)); attr(b[[2]], 'foo') <- 'baz'; attr(a[[2]], 'foo') <- 'bar'; identical(a,b) +[1] FALSE + +##com.oracle.truffle.r.test.builtins.TestBuiltin_identical.testIdentical# +#a <- quote(a(100)); b <- quote(a(100)); identical(a,b) +[1] TRUE + +##com.oracle.truffle.r.test.builtins.TestBuiltin_identical.testIdentical# +#a <- quote(a(100)); b <- quote(a(101)); identical(a,b) +[1] FALSE + +##com.oracle.truffle.r.test.builtins.TestBuiltin_identical.testIdentical# +#identical(pairlist(1, pairlist('foo')), pairlist(1, pairlist('bar'))) +[1] FALSE + ##com.oracle.truffle.r.test.builtins.TestBuiltin_identical.testIdentical# #{ f1 <- function() {}; f2 <- function() {}; identical(f1, f2) } [1] TRUE @@ -41536,7 +41576,7 @@ NULL #{ x <- c(10, 20); names(x) <- c('ahoj', 'svete'); y <- c(1,2); z <- choose(x,y); names(z)[[1]] <- 'onlyinz'; names(x) } [1] "ahoj" "svete" -##com.oracle.truffle.r.test.builtins.TestBuiltin_names.testNames#Ignored.ImplementationError# +##com.oracle.truffle.r.test.builtins.TestBuiltin_names.testNames# #{ x <- parse(text='x+y')[[1]]; names(x) <- c('a','b','c'); names(x); } [1] "a" "b" "c" @@ -68361,6 +68401,14 @@ integer(0) [26] 09 00 00 00 01 2b 00 00 00 02 00 00 00 01 00 04 00 09 00 00 00 01 61 00 00 [51] 00 02 00 00 00 01 00 04 00 09 00 00 00 01 62 00 00 00 fe +##com.oracle.truffle.r.test.builtins.TestBuiltin_serialize.testserialize# +#options(keep.source=FALSE); serialize(quote(b + xxxx(yyyy=1)), connection=NULL) + [1] 58 0a 00 00 00 02 00 03 04 00 00 02 03 00 00 00 00 06 00 00 00 01 00 04 00 + [26] 09 00 00 00 01 2b 00 00 00 02 00 00 00 01 00 04 00 09 00 00 00 01 62 00 00 + [51] 00 02 00 00 00 06 00 00 00 01 00 04 00 09 00 00 00 04 78 78 78 78 00 00 04 + [76] 02 00 00 00 01 00 04 00 09 00 00 00 04 79 79 79 79 00 00 00 0e 00 00 00 01 +[101] 3f f0 00 00 00 00 00 00 00 00 00 fe 00 00 00 fe + ##com.oracle.truffle.r.test.builtins.TestBuiltin_serialize.testserialize# #options(keep.source=FALSE); serialize(quote(f(g)$h.i), connection=NULL) [1] 58 0a 00 00 00 02 00 03 04 00 00 02 03 00 00 00 00 06 00 00 00 01 00 04 00 @@ -68583,6 +68631,12 @@ integer(0) [1] 58 0a 00 00 00 02 00 03 04 00 00 02 03 00 00 00 00 01 00 04 00 09 00 00 00 [26] 01 78 +##com.oracle.truffle.r.test.builtins.TestBuiltin_serialize.testserialize# +#options(keep.source=FALSE); serialize(quote(xxxx(yyyy=1)), connection=NULL) + [1] 58 0a 00 00 00 02 00 03 04 00 00 02 03 00 00 00 00 06 00 00 00 01 00 04 00 +[26] 09 00 00 00 04 78 78 78 78 00 00 04 02 00 00 00 01 00 04 00 09 00 00 00 04 +[51] 79 79 79 79 00 00 00 0e 00 00 00 01 3f f0 00 00 00 00 00 00 00 00 00 fe + ##com.oracle.truffle.r.test.builtins.TestBuiltin_serialize.testserialize# #options(keep.source=FALSE); serialize(quote({ foo(a,b,c) }), connection=NULL) [1] 58 0a 00 00 00 02 00 03 04 00 00 02 03 00 00 00 00 06 00 00 00 01 00 04 00 @@ -132293,6 +132347,22 @@ Error in x[["a", "d"]] : subscript out of bounds Error in match(x, table, nomatch = 0L) : 'match' requires vector arguments +##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testLanguageIndex# +#f <- function(x) x[[1]]; l <- as.pairlist(c('a','b')); f(l); l <- quote(a+b); f(l) +[1] "a" +`+` + +##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testLanguageIndex# +#l <- quote(a+b+c); l[[c(2,2)]]; l[[c(2,3)]]; l[[c(2,2)]]; l[[c(3)]]; l <- as.pairlist(c('+','x','c')); l[[2]] <- as.pairlist(c('+','a','b')); l[[c(2,2)]]; l[[c(2,3)]]; l[[c(2,2)]]; l[[c(3)]] +a +b +a +c +[1] "a" +[1] "b" +[1] "a" +[1] "c" + ##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testLanguageIndex# #{ e <- quote(f(x=a, b)); names(e) } [1] "" "x" "" @@ -137408,6 +137478,69 @@ Error in `[[.default`(x, "z", exact = TRUE) : subscript out of bounds [1] b Levels: a b +##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testPairList# +#l <- as.pairlist(c(1,2,3,4)); l2 <- l; typeof(l); l[[3]] <- 123; typeof(l); l +[1] "pairlist" +[1] "pairlist" +[[1]] +[1] 1 + +[[2]] +[1] 2 + +[[3]] +[1] 123 + +[[4]] +[1] 4 + + +##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testPairList# +#l <- as.pairlist(c(1,2,3,4)); typeof(l); l[[3]] <- 123; typeof(l); l +[1] "pairlist" +[1] "pairlist" +[[1]] +[1] 1 + +[[2]] +[1] 2 + +[[3]] +[1] 123 + +[[4]] +[1] 4 + + +##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testPairList# +#l <- pairlist("a","b",1,4,3); typeof(l); typeof(l[[1]]); typeof(l[1]); typeof(l[1:5]); typeof(l[4:5]); l[4:5] +[1] "pairlist" +[1] "character" +[1] "list" +[1] "list" +[1] "list" +[[1]] +[1] 4 + +[[2]] +[1] 3 + + +##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testPairList# +#l <- quote(a("b",1,4,3)); typeof(l); typeof(l[[1]]); typeof(l[1]); typeof(l[1:5]); typeof(l[4:5]); l[4:5] +[1] "language" +[1] "symbol" +[1] "language" +[1] "language" +[1] "language" +4(3) + +##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testPairList# +#x <- as.pairlist(list(7,42)); x[[1]] <- list(); typeof(x); x$foo <- 123; typeof(x); x[1] <- list(1); typeof(x) +[1] "pairlist" +[1] "pairlist" +[1] "list" + ##com.oracle.truffle.r.test.library.base.TestSimpleVectors.testPrint# #{ mp<-getOption("max.print"); options(max.print=3); x<-c(1,2,3,4,5); attr(x, "foo")<-"foo"; print(x); options(max.print=mp) } [1] 1 2 3 diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/S4/TestS4.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/S4/TestS4.java index d660c79947e21c355d7ccf9d95220e8a66c8e9a9..5653770c6af61e4610411b9ae957cc356f42a7cc 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/S4/TestS4.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/S4/TestS4.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2018, 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 @@ -121,8 +121,7 @@ public class TestS4 extends TestRBase { assertEval("{ setGeneric(\"gen\", function(o) standardGeneric(\"gen\")); res<-print(setGeneric(\"gen\", function(o) standardGeneric(\"gen\"))); removeGeneric(\"gen\"); res }"); - assertEval(Ignored.OutputFormatting, - "{ setClass(\"foo\"); setMethod(\"diag<-\", \"foo\", function(x, value) 42); removeMethod(\"diag<-\", \"foo\"); removeGeneric(\"diag<-\"); removeClass(\"foo\") }"); + assertEval("{ setClass(\"foo\"); setMethod(\"diag<-\", \"foo\", function(x, value) 42); removeMethod(\"diag<-\", \"foo\"); removeGeneric(\"diag<-\"); removeClass(\"foo\") }"); assertEval("{ setClass('A'); setClass('A1', contains = 'A'); setClass('A2', contains = 'A1'); setGeneric('foo', function(a, b) standardGeneric('foo')); setMethod('foo', signature('A1', 'A2'), function(a, b) '1-2'); setMethod('foo', signature('A2', 'A1'), function(a, b) '2-1'); foo(new('A2'), new('A2')) }"); @@ -130,8 +129,7 @@ public class TestS4 extends TestRBase { assertEval("{ setClass('A1', representation(a='numeric')); setMethod('length', 'A1', function(x) x@a); obj <- new('A1'); obj@a <- 10; length(obj) }"); - assertEval(Ignored.OutputFormatting, - "{ setClass('A2', representation(a = 'numeric')); setMethod('rep', 'A2', function(x, a, b, c) { c(x@a, a, b, c) }); setMethod('ifelse', c(yes = 'A2'), function(test, yes, no) print(test)) }"); + assertEval("{ setClass('A2', representation(a = 'numeric')); setMethod('rep', 'A2', function(x, a, b, c) { c(x@a, a, b, c) }); setMethod('ifelse', c(yes = 'A2'), function(test, yes, no) print(test)) }"); } @Test diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_asvector.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_asvector.java index cf1870d917f8e864e10595f84d29df46ad3d391a..4d7e4426ab547509ff0e964e012b3012e3e703ea 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_asvector.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_asvector.java @@ -474,7 +474,7 @@ public class TestBuiltin_asvector extends TestRBase { "c(T, F, T)", "c(1+i, 2+i, 4+i)", "parse(text='x; y; z')", - // TODO: "parse(text='x+y')[[1]]", -- problem with UpdateNames and RLanguage... + // TODO: "parse(text='x+y')[[1]]", -- problem with UpdateNames and RPairList... // TODO: "function() 42", }; diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_deriv.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_deriv.java index 190994eb998d501c5da8846af11c57e576a8af11..8f7446063da37bf958c9bcab9f89573442d596b0 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_deriv.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_deriv.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2018, 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 @@ -190,6 +190,13 @@ public class TestBuiltin_deriv extends TestBase { assertEval(Output.IgnoreWhitespace, "(df <- deriv(~x^2*sin(x), \"x\", function.arg=function(x)NULL));df(0)"); } + @Test + public void testEnvironment() { + assertEval("environment(deriv((y ~ sin(cos(x) * y)), c('x','y'), func = TRUE))"); + assertEval("environment(local(deriv((y ~ sin(cos(x) * y)), c('x','y'), func = TRUE)))"); + assertEval("environment(local(deriv((y ~ sin(cos(x) * y)), c('x','y'), func = deriv)))"); + } + @Test public void testUnusualExprs() { assertEval("(df <- deriv(expression(x^2*sin(x)), \"x\"));df(0)"); diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_function.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_function.java index eac9c3629d63f0921183400c3ad3b3ba025206dc..f9c4e95e618610267cd4f62fad74102955418962 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_function.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_function.java @@ -30,7 +30,7 @@ import com.oracle.truffle.r.test.TestBase; public class TestBuiltin_function extends TestBase { @Test public void testFunctionFunction() { - assertEval(Output.IgnoreErrorContext, "eval(call('function', 1, expression(x + 1)[[1]]))"); + assertEval(Output.MayIgnoreErrorContext, "eval(call('function', 1, expression(x + 1)[[1]]))"); assertEval("eval(call('function', as.pairlist(list(x=4)), expression(x + 1)[[1]]))"); assertEval("do.call('function', list(as.pairlist(list(x=4)), expression(x + 1)[[1]]))"); } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_identical.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_identical.java index ecb854a29ac5e63c7d73d1ea071155f655d4ab3c..d9e8d9df8e8cf413e2485220111a7a477c76ab2a 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_identical.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_identical.java @@ -4,7 +4,7 @@ * http://www.gnu.org/licenses/gpl-2.0.html * * Copyright (c) 2012-2014, Purdue University - * Copyright (c) 2013, 2017, Oracle and/or its affiliates + * Copyright (c) 2013, 2018, Oracle and/or its affiliates * * All rights reserved. */ @@ -202,7 +202,7 @@ public class TestBuiltin_identical extends TestBase { @Test public void testAttrOrder() { - assertEval(Ignored.ImplementationError, "x <- 1; y <- 1; attr(x, \"f\") <- 2; attr(x, \"g\") <- 1; attr(y, \"g\") <- 1; attr(y, \"f\") <- 2; identical(x, y)"); + assertEval("x <- 1; y <- 1; attr(x, \"f\") <- 2; attr(x, \"g\") <- 1; attr(y, \"g\") <- 1; attr(y, \"f\") <- 2; identical(x, y)"); } @Test @@ -258,6 +258,19 @@ public class TestBuiltin_identical extends TestBase { assertEval("{ f1 <- function() {}; f2 <- function() {}; identical(f1, f2) }"); assertEval("{ identical(function() 42, function() 42) }"); + + // pairlists + + assertEval("identical(pairlist(1, pairlist('foo')), pairlist(1, pairlist('bar')))"); + + // language + + assertEval("a <- quote(a(100)); b <- quote(a(101)); identical(a,b)"); + assertEval("a <- quote(a(100)); b <- quote(a(100)); identical(a,b)"); + assertEval("a <- quote(a(100)); b <- quote(a(100)); attr(a[[2]], 'foo') <- 'bar'; identical(a,b)"); + assertEval("a <- quote(a(100)); b <- quote(a(100)); attr(a[[2]], 'foo') <- 'bar'; b[[2]] <- a[[2]]; identical(a,b)"); + assertEval("a <- quote(a(100)); b <- quote(a(100)); attr(b[[2]], 'foo') <- 'baz'; attr(a[[2]], 'foo') <- 'bar'; identical(a,b)"); + assertEval("a <- quote(a(100)); b <- quote(a(100)); attr(b[[2]], 'foo') <- 'bar'; attr(a[[2]], 'foo') <- 'bar'; identical(a,b)"); } @Test diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_names.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_names.java index 147f9137f9ae7786841967d1d25194d966a49e6a..39cc1c3415710f3779c56175291c2df9c12192bf 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_names.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_names.java @@ -206,8 +206,7 @@ public class TestBuiltin_names extends TestBase { assertEval("{ y<-c(d=\"e\"); attr(y, \"foo\")<-\"foo\"; x<-c(42); names(x)<-y; attributes(names(x)) }"); assertEval("{ x <- c(10, 20); names(x) <- c('ahoj', 'svete'); y <- c(1,2); z <- choose(x,y); names(z)[[1]] <- 'onlyinz'; names(x) }"); assertEval("{ e <- new.env(); names(e) <- c('a'); }"); - // FIXME: set names on language does not set the first name - assertEval(Ignored.ImplementationError, "{ x <- parse(text='x+y')[[1]]; names(x) <- c('a','b','c'); names(x); }"); + assertEval("{ x <- parse(text='x+y')[[1]]; names(x) <- c('a','b','c'); names(x); }"); assertEval("names(pairlist(a=3, b=4))"); assertEval("names(pairlist(1,2,3))"); assertEval("names(pairlist(a=1,2,q=3))"); diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_serialize.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_serialize.java index 07b12af333d27fd0cff34d59e59c3c151129a8fd..c758a995ec59630a9ed6b937539c333ced6851d3 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_serialize.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_serialize.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2018, 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 @@ -72,6 +72,8 @@ public class TestBuiltin_serialize extends TestBase { assertEval("options(keep.source=FALSE); serialize(quote(if ({a}) {b} else {c}), connection=NULL)"); assertEval("options(keep.source=FALSE); serialize(quote(while (a) b), connection=NULL)"); assertEval("options(keep.source=FALSE); serialize(quote(repeat {b; if (c) next else break}), connection=NULL)"); + assertEval("options(keep.source=FALSE); serialize(quote(xxxx(yyyy=1)), connection=NULL)"); + assertEval("options(keep.source=FALSE); serialize(quote(b + xxxx(yyyy=1)), connection=NULL)"); assertEval("options(keep.source=FALSE); serialize(quote(if (a * 2 < 199) b + foo(x,y,foo=z+1,bar=)), connection=NULL)"); assertEval("options(keep.source=FALSE); serialize(quote(\"bar\"), connection=NULL)"); assertEval("options(keep.source=FALSE); serialize(quote('baz'), connection=NULL)"); diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/AbstractMRTest.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/AbstractMRTest.java index 9fcf40ab9e89f21c660e35e441c8bafffc5b9d14..8f884c1764b258a17918ede70dd4be90edcbf03d 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/AbstractMRTest.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/AbstractMRTest.java @@ -45,7 +45,6 @@ import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.interop.UnknownIdentifierException; import com.oracle.truffle.api.interop.UnsupportedMessageException; import com.oracle.truffle.api.interop.UnsupportedTypeException; -import com.oracle.truffle.r.test.generate.FastRSession; public abstract class AbstractMRTest { @@ -54,17 +53,16 @@ public abstract class AbstractMRTest { @BeforeClass public static void before() { context = Context.newBuilder("R", "llvm").build(); + context.eval("R", "1"); // initialize context + context.enter(); } @AfterClass public static void after() { + context.leave(); context.close(); } - protected void execInContext(Callable<Object> c) { - FastRSession.execInContext(context, c); - } - @Before public void beforeMethod() { /** @@ -116,93 +114,75 @@ public abstract class AbstractMRTest { @Test public void testIsNull() throws Exception { - execInContext(() -> { - for (TruffleObject obj : createTruffleObjects()) { - assertEquals(isNull(obj), ForeignAccess.sendIsNull(Message.IS_NULL.createNode(), obj)); - } - return null; - }); + for (TruffleObject obj : createTruffleObjects()) { + assertEquals(isNull(obj), ForeignAccess.sendIsNull(Message.IS_NULL.createNode(), obj)); + } } @Test public void testExecutable() throws Exception { - execInContext(() -> { - for (TruffleObject obj : createTruffleObjects()) { - try { - // TODO if the need appears, also provide for args for execute - ForeignAccess.sendExecute(Message.createExecute(0).createNode(), obj); - assertEquals(obj.getClass().getSimpleName() + " " + obj + " IS_EXECUTABLE", true, ForeignAccess.sendIsExecutable(Message.IS_EXECUTABLE.createNode(), obj)); - } catch (UnsupportedTypeException | ArityException e) { - throw e; - } catch (UnsupportedMessageException e) { - assertEquals(obj.getClass().getSimpleName() + " " + obj + " IS_EXECUTABLE", false, ForeignAccess.sendIsExecutable(Message.IS_EXECUTABLE.createNode(), obj)); - } + for (TruffleObject obj : createTruffleObjects()) { + try { + // TODO if the need appears, also provide for args for execute + ForeignAccess.sendExecute(Message.createExecute(0).createNode(), obj); + assertEquals(obj.getClass().getSimpleName() + " " + obj + " IS_EXECUTABLE", true, ForeignAccess.sendIsExecutable(Message.IS_EXECUTABLE.createNode(), obj)); + } catch (UnsupportedTypeException | ArityException e) { + throw e; + } catch (UnsupportedMessageException e) { + assertEquals(obj.getClass().getSimpleName() + " " + obj + " IS_EXECUTABLE", false, ForeignAccess.sendIsExecutable(Message.IS_EXECUTABLE.createNode(), obj)); } - return null; - }); + } } @Test public void testInstantiable() throws Exception { - execInContext(() -> { - for (TruffleObject obj : createTruffleObjects()) { - try { - // TODO if the need appears, also provide for args for new - ForeignAccess.sendNew(Message.createNew(0).createNode(), obj); - assertEquals(obj.getClass().getSimpleName() + " " + obj + " IS_INSTANTIABLE", true, ForeignAccess.sendIsInstantiable(Message.IS_INSTANTIABLE.createNode(), obj)); - } catch (UnsupportedTypeException | ArityException e) { - throw e; - } catch (UnsupportedMessageException e) { - assertEquals(obj.getClass().getSimpleName() + " " + obj + " IS_INSTANTIABLE", false, ForeignAccess.sendIsInstantiable(Message.IS_INSTANTIABLE.createNode(), obj)); - } + for (TruffleObject obj : createTruffleObjects()) { + try { + // TODO if the need appears, also provide for args for new + ForeignAccess.sendNew(Message.createNew(0).createNode(), obj); + assertEquals(obj.getClass().getSimpleName() + " " + obj + " IS_INSTANTIABLE", true, ForeignAccess.sendIsInstantiable(Message.IS_INSTANTIABLE.createNode(), obj)); + } catch (UnsupportedTypeException | ArityException e) { + throw e; + } catch (UnsupportedMessageException e) { + assertEquals(obj.getClass().getSimpleName() + " " + obj + " IS_INSTANTIABLE", false, ForeignAccess.sendIsInstantiable(Message.IS_INSTANTIABLE.createNode(), obj)); } - return null; - }); + } } @Test public void testAsNativePointer() throws Exception { - execInContext(() -> { - for (TruffleObject obj : createTruffleObjects()) { - try { - assertNotNull(obj.getClass().getSimpleName(), ForeignAccess.sendToNative(Message.AS_POINTER.createNode(), obj)); - assertEquals(obj.getClass().getSimpleName() + " " + obj + " IS_POINTER", true, ForeignAccess.sendIsPointer(Message.IS_POINTER.createNode(), obj)); - } catch (UnsupportedMessageException e) { - assertEquals(obj.getClass().getSimpleName() + " " + obj + " IS_POINTER", false, ForeignAccess.sendIsPointer(Message.IS_POINTER.createNode(), obj)); - } + for (TruffleObject obj : createTruffleObjects()) { + try { + assertNotNull(obj.getClass().getSimpleName(), ForeignAccess.sendToNative(Message.AS_POINTER.createNode(), obj)); + assertEquals(obj.getClass().getSimpleName() + " " + obj + " IS_POINTER", true, ForeignAccess.sendIsPointer(Message.IS_POINTER.createNode(), obj)); + } catch (UnsupportedMessageException e) { + assertEquals(obj.getClass().getSimpleName() + " " + obj + " IS_POINTER", false, ForeignAccess.sendIsPointer(Message.IS_POINTER.createNode(), obj)); } - return null; - }); + } } @Test public void testNativePointer() throws Exception { - execInContext(() -> { - for (TruffleObject obj : createTruffleObjects()) { - if (!testToNative(obj)) { - continue; - } - try { - assertTrue(obj.getClass().getSimpleName(), ForeignAccess.sendToNative(Message.TO_NATIVE.createNode(), obj) != obj); - } catch (UnsupportedMessageException e) { - } + for (TruffleObject obj : createTruffleObjects()) { + if (!testToNative(obj)) { + continue; + } + try { + assertTrue(obj.getClass().getSimpleName(), ForeignAccess.sendToNative(Message.TO_NATIVE.createNode(), obj) != obj); + } catch (UnsupportedMessageException e) { } - return null; - }); + } } @Test public void testSize() throws Exception { - execInContext(() -> { - for (TruffleObject obj : createTruffleObjects()) { - testSize(obj); - } - TruffleObject empty = createEmptyTruffleObject(); - if (empty != null) { - testSize(empty); - } - return null; - }); + for (TruffleObject obj : createTruffleObjects()) { + testSize(obj); + } + TruffleObject empty = createEmptyTruffleObject(); + if (empty != null) { + testSize(empty); + } } private void testSize(TruffleObject obj) { @@ -217,16 +197,13 @@ public abstract class AbstractMRTest { @Test public void testBoxed() throws Exception { - execInContext(() -> { - for (TruffleObject obj : createTruffleObjects()) { - testUnboxed(obj); - } - TruffleObject empty = createEmptyTruffleObject(); - if (empty != null) { - testUnboxed(empty); - } - return null; - }); + for (TruffleObject obj : createTruffleObjects()) { + testUnboxed(obj); + } + TruffleObject empty = createEmptyTruffleObject(); + if (empty != null) { + testUnboxed(empty); + } } private void testUnboxed(TruffleObject obj) { @@ -241,16 +218,13 @@ public abstract class AbstractMRTest { @Test public void testKeys() throws Exception { - execInContext(() -> { - for (TruffleObject obj : createTruffleObjects()) { - testKeys(obj); - } - TruffleObject empty = createEmptyTruffleObject(); - if (empty != null) { - testKeys(empty); - } - return null; - }); + for (TruffleObject obj : createTruffleObjects()) { + testKeys(obj); + } + TruffleObject empty = createEmptyTruffleObject(); + if (empty != null) { + testKeys(empty); + } } private void testKeys(TruffleObject obj) throws UnknownIdentifierException { @@ -276,27 +250,27 @@ public abstract class AbstractMRTest { } protected void assertInteropException(Callable<Object> c, Class<? extends InteropException> expectedClazz) { - boolean ie = false; try { c.call(); } catch (InteropException ex) { if (expectedClazz != null && ex.getClass() != expectedClazz) { + ex.printStackTrace(); Assert.fail(expectedClazz + " was expected but got instead: " + ex); } - ie = true; + return; } catch (Exception ex) { if (expectedClazz != null && ex.getClass() != expectedClazz) { + ex.printStackTrace(); Assert.fail(expectedClazz + " was expected but got instead: " + ex); } else { - Assert.fail("InteropException was expected but got insteat: " + ex); + ex.printStackTrace(); + Assert.fail("InteropException was expected but got instead: " + ex); } } - if (!ie) { - if (expectedClazz != null) { - Assert.fail(expectedClazz + " was expected"); - } else { - Assert.fail("InteropException was expected"); - } + if (expectedClazz != null) { + Assert.fail(expectedClazz + " was expected"); + } else { + Assert.fail("InteropException was expected"); } } } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/ListMRTest.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/ListMRTest.java index 29d48191b221e2143876dce368f6e3935e2f09af..47ed7023d29d834be14f7b9881bcae632f6ad893 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/ListMRTest.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/ListMRTest.java @@ -55,45 +55,42 @@ public class ListMRTest extends AbstractMRTest { } @Test - public void testKeysReadWrite() { + public void testKeysReadWrite() throws Exception { testKeysReadWrite("list"); testKeysReadWrite("pairlist"); } - private void testKeysReadWrite(String createFun) { - execInContext(() -> { - RAbstractContainer l = create(createFun, testValues); + private void testKeysReadWrite(String createFun) throws Exception { + RAbstractContainer l = create(createFun, testValues); - assertEquals(1, ForeignAccess.sendRead(Message.READ.createNode(), l, "i")); - assertEquals(2.1, ForeignAccess.sendRead(Message.READ.createNode(), l, "d")); - assertEquals(true, ForeignAccess.sendRead(Message.READ.createNode(), l, "b")); - assertTrue(ForeignAccess.sendRead(Message.READ.createNode(), l, "n") instanceof RNull); + assertEquals(1, ForeignAccess.sendRead(Message.READ.createNode(), l, "i")); + assertEquals(2.1, ForeignAccess.sendRead(Message.READ.createNode(), l, "d")); + assertEquals(true, ForeignAccess.sendRead(Message.READ.createNode(), l, "b")); + assertTrue(ForeignAccess.sendRead(Message.READ.createNode(), l, "n") instanceof RNull); - assertEquals(1, ForeignAccess.sendRead(Message.READ.createNode(), l, 0)); - assertEquals(2.1, ForeignAccess.sendRead(Message.READ.createNode(), l, 1)); - assertEquals(4d, ForeignAccess.sendRead(Message.READ.createNode(), l, 5d)); - assertEquals(true, ForeignAccess.sendRead(Message.READ.createNode(), l, 2)); - assertTrue(ForeignAccess.sendRead(Message.READ.createNode(), l, 4) instanceof RNull); + assertEquals(1, ForeignAccess.sendRead(Message.READ.createNode(), l, 0)); + assertEquals(2.1, ForeignAccess.sendRead(Message.READ.createNode(), l, 1)); + assertEquals(4d, ForeignAccess.sendRead(Message.READ.createNode(), l, 5d)); + assertEquals(true, ForeignAccess.sendRead(Message.READ.createNode(), l, 2)); + assertTrue(ForeignAccess.sendRead(Message.READ.createNode(), l, 4) instanceof RNull); - assertInteropException(() -> ForeignAccess.sendRead(Message.READ.createNode(), l, -1), UnknownIdentifierException.class); - assertInteropException(() -> ForeignAccess.sendRead(Message.READ.createNode(), l, 0f), UnknownIdentifierException.class); + assertInteropException(() -> ForeignAccess.sendRead(Message.READ.createNode(), l, -1), UnknownIdentifierException.class); + assertInteropException(() -> ForeignAccess.sendRead(Message.READ.createNode(), l, 0f), UnknownIdentifierException.class); - assertInteropException(() -> ForeignAccess.sendRead(Message.READ.createNode(), l, "nnnoooonnne"), UnknownIdentifierException.class); - assertInteropException(() -> ForeignAccess.sendRead(Message.READ.createNode(), l, 100), UnknownIdentifierException.class); + assertInteropException(() -> ForeignAccess.sendRead(Message.READ.createNode(), l, "nnnoooonnne"), UnknownIdentifierException.class); + assertInteropException(() -> ForeignAccess.sendRead(Message.READ.createNode(), l, 100), UnknownIdentifierException.class); - TruffleObject obj = (TruffleObject) ForeignAccess.sendWrite(Message.WRITE.createNode(), l, "d", 123.1); - assertEquals(123.1, ForeignAccess.sendRead(Message.READ.createNode(), obj, "d")); + TruffleObject obj = (TruffleObject) ForeignAccess.sendWrite(Message.WRITE.createNode(), l, "d", 123.1); + assertEquals(123.1, ForeignAccess.sendRead(Message.READ.createNode(), obj, "d")); - obj = (TruffleObject) ForeignAccess.sendWrite(Message.WRITE.createNode(), l, 2, false); - assertEquals(false, ForeignAccess.sendRead(Message.READ.createNode(), obj, "b")); + obj = (TruffleObject) ForeignAccess.sendWrite(Message.WRITE.createNode(), l, 2, false); + assertEquals(false, ForeignAccess.sendRead(Message.READ.createNode(), obj, "b")); - obj = (TruffleObject) ForeignAccess.sendWrite(Message.WRITE.createNode(), l, "newnew", "nneeww"); - assertEquals("nneeww", ForeignAccess.sendRead(Message.READ.createNode(), obj, "newnew")); + obj = (TruffleObject) ForeignAccess.sendWrite(Message.WRITE.createNode(), l, "newnew", "nneeww"); + assertEquals("nneeww", ForeignAccess.sendRead(Message.READ.createNode(), obj, "newnew")); - assertInteropException(() -> ForeignAccess.sendWrite(Message.WRITE.createNode(), l, 0f, false), UnknownIdentifierException.class); - assertInteropException(() -> ForeignAccess.sendWrite(Message.WRITE.createNode(), l, 0d, false), UnknownIdentifierException.class); - return null; - }); + assertInteropException(() -> ForeignAccess.sendWrite(Message.WRITE.createNode(), l, 0f, false), UnknownIdentifierException.class); + assertInteropException(() -> ForeignAccess.sendWrite(Message.WRITE.createNode(), l, 0d, false), UnknownIdentifierException.class); } @Test @@ -103,54 +100,51 @@ public class ListMRTest extends AbstractMRTest { } public void testKeysInfo(String createFun) { - execInContext(() -> { - RAbstractContainer l = create(createFun, testValues); - - int info = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), l, "nnoonnee"); - assertFalse(KeyInfo.isExisting(info)); - assertFalse(KeyInfo.isReadable(info)); - assertFalse(KeyInfo.isWritable(info)); - assertFalse(KeyInfo.isInvocable(info)); - assertFalse(KeyInfo.isInternal(info)); - - info = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), l, "d"); - assertTrue(KeyInfo.isExisting(info)); - assertTrue(KeyInfo.isReadable(info)); - assertTrue(KeyInfo.isWritable(info)); - assertFalse(KeyInfo.isInvocable(info)); - assertFalse(KeyInfo.isInternal(info)); - - info = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), l, "fn"); - assertTrue(KeyInfo.isExisting(info)); - assertTrue(KeyInfo.isReadable(info)); - assertTrue(KeyInfo.isWritable(info)); - assertTrue(KeyInfo.isInvocable(info)); - assertFalse(KeyInfo.isInternal(info)); - - info = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), l, -1); - assertFalse(KeyInfo.isExisting(info)); - - info = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), l, l.getLength()); - assertFalse(KeyInfo.isExisting(info)); - - info = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), l, 1f); - assertFalse(KeyInfo.isExisting(info)); - - info = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), l, 0); - assertTrue(KeyInfo.isExisting(info)); - assertTrue(KeyInfo.isReadable(info)); - assertTrue(KeyInfo.isWritable(info)); - assertFalse(KeyInfo.isInvocable(info)); - assertFalse(KeyInfo.isInternal(info)); - - info = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), l, 1d); - assertTrue(KeyInfo.isExisting(info)); - assertTrue(KeyInfo.isReadable(info)); - assertTrue(KeyInfo.isWritable(info)); - assertFalse(KeyInfo.isInvocable(info)); - assertFalse(KeyInfo.isInternal(info)); - return null; - }); + RAbstractContainer l = create(createFun, testValues); + + int info = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), l, "nnoonnee"); + assertFalse(KeyInfo.isExisting(info)); + assertFalse(KeyInfo.isReadable(info)); + assertFalse(KeyInfo.isWritable(info)); + assertFalse(KeyInfo.isInvocable(info)); + assertFalse(KeyInfo.isInternal(info)); + + info = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), l, "d"); + assertTrue(KeyInfo.isExisting(info)); + assertTrue(KeyInfo.isReadable(info)); + assertTrue(KeyInfo.isWritable(info)); + assertFalse(KeyInfo.isInvocable(info)); + assertFalse(KeyInfo.isInternal(info)); + + info = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), l, "fn"); + assertTrue(KeyInfo.isExisting(info)); + assertTrue(KeyInfo.isReadable(info)); + assertTrue(KeyInfo.isWritable(info)); + assertTrue(KeyInfo.isInvocable(info)); + assertFalse(KeyInfo.isInternal(info)); + + info = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), l, -1); + assertFalse(KeyInfo.isExisting(info)); + + info = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), l, l.getLength()); + assertFalse(KeyInfo.isExisting(info)); + + info = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), l, 1f); + assertFalse(KeyInfo.isExisting(info)); + + info = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), l, 0); + assertTrue(KeyInfo.isExisting(info)); + assertTrue(KeyInfo.isReadable(info)); + assertTrue(KeyInfo.isWritable(info)); + assertFalse(KeyInfo.isInvocable(info)); + assertFalse(KeyInfo.isInternal(info)); + + info = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), l, 1d); + assertTrue(KeyInfo.isExisting(info)); + assertTrue(KeyInfo.isReadable(info)); + assertTrue(KeyInfo.isWritable(info)); + assertFalse(KeyInfo.isInvocable(info)); + assertFalse(KeyInfo.isInternal(info)); } private static RAbstractContainer create(String createFun, String values) { diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/RFunctionMRTest.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/RFunctionMRTest.java index a6ce7ce890d7fa8de67873e722c4fea74942cefc..d58670ae75aaca281dd6e7693dabc57817acf843 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/RFunctionMRTest.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/RFunctionMRTest.java @@ -38,34 +38,30 @@ import com.oracle.truffle.r.test.generate.FastRSession; public class RFunctionMRTest extends AbstractMRTest { @Test - public void testExecute() { - execInContext(() -> { - RFunction f = create("function() {}"); - assertTrue(ForeignAccess.sendIsExecutable(Message.IS_EXECUTABLE.createNode(), f)); + public void testExecute() throws Exception { + RFunction f = create("function() {}"); + assertTrue(ForeignAccess.sendIsExecutable(Message.IS_EXECUTABLE.createNode(), f)); - TruffleObject result = (TruffleObject) ForeignAccess.sendExecute(Message.createExecute(0).createNode(), f); - assertTrue(ForeignAccess.sendIsNull(Message.IS_NULL.createNode(), result)); + TruffleObject result = (TruffleObject) ForeignAccess.sendExecute(Message.createExecute(0).createNode(), f); + assertTrue(ForeignAccess.sendIsNull(Message.IS_NULL.createNode(), result)); - f = create("function() {1L}"); - assertEquals(1, ForeignAccess.sendExecute(Message.createExecute(0).createNode(), f)); + f = create("function() {1L}"); + assertEquals(1, ForeignAccess.sendExecute(Message.createExecute(0).createNode(), f)); - f = create("function() {1}"); - assertEquals(1.0, ForeignAccess.sendExecute(Message.createExecute(0).createNode(), f)); + f = create("function() {1}"); + assertEquals(1.0, ForeignAccess.sendExecute(Message.createExecute(0).createNode(), f)); - f = create("function() {TRUE}"); - assertEquals(true, ForeignAccess.sendExecute(Message.createExecute(0).createNode(), f)); + f = create("function() {TRUE}"); + assertEquals(true, ForeignAccess.sendExecute(Message.createExecute(0).createNode(), f)); - f = create("function(a) {a}"); - assertEquals("abc", ForeignAccess.sendExecute(Message.createExecute(1).createNode(), f, "abc")); + f = create("function(a) {a}"); + assertEquals("abc", ForeignAccess.sendExecute(Message.createExecute(1).createNode(), f, "abc")); - f = create("function(a) { is.logical(a) }"); - assertEquals(true, ForeignAccess.sendExecute(Message.createExecute(1).createNode(), f, true)); - - f = create("function(a) { as.external.short(a) }"); - assertTrue(ForeignAccess.sendExecute(Message.createExecute(1).createNode(), f, 123) instanceof Short); - return null; - }); + f = create("function(a) { is.logical(a) }"); + assertEquals(true, ForeignAccess.sendExecute(Message.createExecute(1).createNode(), f, true)); + f = create("function(a) { as.external.short(a) }"); + assertTrue(ForeignAccess.sendExecute(Message.createExecute(1).createNode(), f, 123) instanceof Short); } @Override diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/RInteropScalarMRTest.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/RInteropScalarMRTest.java index 38283b935412ad28af30034f10540ec8d79641de..5b5fd10c4fb8f1923f731221d773a121ab55ed37 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/RInteropScalarMRTest.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/RInteropScalarMRTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2018, 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 @@ -38,13 +38,10 @@ public class RInteropScalarMRTest extends AbstractMRTest { @Test public void testRInteroptScalar() throws Exception { - execInContext(() -> { - for (TruffleObject obj : createTruffleObjects()) { - RInteropScalar is = (RInteropScalar) obj; - testRIS(obj, is.getJavaType()); - } - return null; - }); + for (TruffleObject obj : createTruffleObjects()) { + RInteropScalar is = (RInteropScalar) obj; + testRIS(obj, is.getJavaType()); + } } private static void testRIS(TruffleObject obj, Class<?> unboxedType) throws Exception { diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/RLanguageMRTest.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/RLanguageMRTest.java index 66e0ff602c8c224e24604e50c80fcd8212d28247..728acdac3a2ff54b1823845c291a3251f1778dcd 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/RLanguageMRTest.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/RLanguageMRTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2018, 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 @@ -25,6 +25,8 @@ package com.oracle.truffle.r.test.engine.interop; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import org.graalvm.polyglot.Source; +import org.graalvm.polyglot.Value; import org.junit.Assert; import org.junit.Test; @@ -33,17 +35,15 @@ import com.oracle.truffle.api.interop.KeyInfo; import com.oracle.truffle.api.interop.Message; import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.interop.UnknownIdentifierException; -import com.oracle.truffle.api.interop.UnsupportedMessageException; -import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.runtime.data.RPairList; +import com.oracle.truffle.r.runtime.data.RSymbol; import com.oracle.truffle.r.test.generate.FastRSession; -import org.graalvm.polyglot.Source; -import org.graalvm.polyglot.Value; public class RLanguageMRTest extends AbstractMRTest { @Test public void testKeysInfo() throws Exception { - RLanguage rl = (RLanguage) createTruffleObjects()[0]; + RPairList rl = (RPairList) createTruffleObjects()[0]; int info = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), rl, "nnoonnee"); assertFalse(KeyInfo.isExisting(info)); @@ -56,51 +56,55 @@ public class RLanguageMRTest extends AbstractMRTest { info = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), rl, 0); assertTrue(KeyInfo.isExisting(info)); assertTrue(KeyInfo.isReadable(info)); - assertFalse(KeyInfo.isWritable(info)); + assertTrue(KeyInfo.isWritable(info)); assertFalse(KeyInfo.isInvocable(info)); assertFalse(KeyInfo.isInternal(info)); info = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), rl, 1); assertTrue(KeyInfo.isExisting(info)); assertTrue(KeyInfo.isReadable(info)); - assertFalse(KeyInfo.isWritable(info)); + assertTrue(KeyInfo.isWritable(info)); assertFalse(KeyInfo.isInvocable(info)); assertFalse(KeyInfo.isInternal(info)); info = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), rl, 2); assertTrue(KeyInfo.isExisting(info)); assertTrue(KeyInfo.isReadable(info)); - assertFalse(KeyInfo.isWritable(info)); + assertTrue(KeyInfo.isWritable(info)); assertFalse(KeyInfo.isInvocable(info)); assertFalse(KeyInfo.isInternal(info)); } @Test public void testReadWrite() throws Exception { - RLanguage rl = (RLanguage) createTruffleObjects()[0]; + RPairList rl = (RPairList) createTruffleObjects()[0]; assertInteropException(() -> ForeignAccess.sendRead(Message.READ.createNode(), rl, "nnnoooonnne"), UnknownIdentifierException.class); assertInteropException(() -> ForeignAccess.sendRead(Message.READ.createNode(), rl, rl.getLength()), UnknownIdentifierException.class); - assertInteropException(() -> ForeignAccess.sendRead(Message.READ.createNode(), rl, 0d), UnknownIdentifierException.class); + assertTrue(ForeignAccess.sendRead(Message.READ.createNode(), rl, 0d) == RSymbol.install("+")); assertInteropException(() -> ForeignAccess.sendRead(Message.READ.createNode(), rl, 0f), UnknownIdentifierException.class); - // TODO add some meaningfull read tests + // TODO add some meaningful read tests Assert.assertNotNull(ForeignAccess.sendRead(Message.READ.createNode(), rl, 0)); - assertInteropException(() -> ForeignAccess.sendWrite(Message.WRITE.createNode(), rl, "aaa", "abc"), UnsupportedMessageException.class); - assertInteropException(() -> ForeignAccess.sendWrite(Message.WRITE.createNode(), rl, 0, "abc"), UnsupportedMessageException.class); - + // shouldn't fail: + ForeignAccess.sendWrite(Message.WRITE.createNode(), rl, "aaa", "abc"); + ForeignAccess.sendWrite(Message.WRITE.createNode(), rl, 0, "abc"); } @Override protected TruffleObject[] createTruffleObjects() { - // TODO any simpler way to create a RLanguage ? - String srcTxt = "ne <- new.env(); delayedAssign('x', 1 + 2, assign.env = ne); substitute(x, ne)"; + String srcTxt = "quote(1+2)"; Source src = Source.newBuilder("R", srcTxt, "<testrlanguage>").internal(true).buildLiteral(); Value result = context.eval(src); return new TruffleObject[]{(TruffleObject) FastRSession.getReceiver(result)}; } + @Override + protected String[] getKeys(TruffleObject obj) { + return new String[0]; + } + @Override protected TruffleObject createEmptyTruffleObject() throws Exception { return null; @@ -108,6 +112,6 @@ public class RLanguageMRTest extends AbstractMRTest { @Override protected int getSize(TruffleObject obj) { - return ((RLanguage) obj).getLength(); + return ((RPairList) obj).getLength(); } } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/VectorMRTest.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/VectorMRTest.java index 697cdeb547ea7913d619d8b228a027faaa2be8f1..2166e63dcedf89d3fcc9d5efe1166bfcda697a79 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/VectorMRTest.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/VectorMRTest.java @@ -42,52 +42,46 @@ public class VectorMRTest extends AbstractMRTest { @Test public void testReadWrite() throws Exception { - execInContext(() -> { - final TruffleObject vi = RDataFactory.createIntSequence(1, 1, 10); - assertEquals(3, ForeignAccess.sendRead(Message.READ.createNode(), vi, 2)); - assertEquals(3, ForeignAccess.sendRead(Message.READ.createNode(), vi, 2L)); + final TruffleObject vi = RDataFactory.createIntSequence(1, 1, 10); + assertEquals(3, ForeignAccess.sendRead(Message.READ.createNode(), vi, 2)); + assertEquals(3, ForeignAccess.sendRead(Message.READ.createNode(), vi, 2L)); - assertInteropException(() -> ForeignAccess.sendRead(Message.READ.createNode(), vi, "a"), UnknownIdentifierException.class); - assertInteropException(() -> ForeignAccess.sendRead(Message.READ.createNode(), vi, 100), UnknownIdentifierException.class); - assertInteropException(() -> ForeignAccess.sendWrite(Message.WRITE.createNode(), vi, "s", "abc"), UnknownIdentifierException.class); + assertInteropException(() -> ForeignAccess.sendRead(Message.READ.createNode(), vi, "a"), UnknownIdentifierException.class); + assertInteropException(() -> ForeignAccess.sendRead(Message.READ.createNode(), vi, 100), UnknownIdentifierException.class); + assertInteropException(() -> ForeignAccess.sendWrite(Message.WRITE.createNode(), vi, "s", "abc"), UnknownIdentifierException.class); - TruffleObject vd = RDataFactory.createDoubleSequence(1.1, 1, 10); - assertEquals(1.1, ForeignAccess.sendRead(Message.READ.createNode(), vd, 0)); + TruffleObject vd = RDataFactory.createDoubleSequence(1.1, 1, 10); + assertEquals(1.1, ForeignAccess.sendRead(Message.READ.createNode(), vd, 0)); - TruffleObject vb = RDataFactory.createLogicalVector(new byte[]{1, 0, 1}, true); - assertEquals(true, ForeignAccess.sendRead(Message.READ.createNode(), vb, 0)); + TruffleObject vb = RDataFactory.createLogicalVector(new byte[]{1, 0, 1}, true); + assertEquals(true, ForeignAccess.sendRead(Message.READ.createNode(), vb, 0)); - TruffleObject nvi = (TruffleObject) ForeignAccess.sendWrite(Message.WRITE.createNode(), vi, 0, 123); - assertEquals(123, ForeignAccess.sendRead(Message.READ.createNode(), nvi, 0)); + TruffleObject nvi = (TruffleObject) ForeignAccess.sendWrite(Message.WRITE.createNode(), vi, 0, 123); + assertEquals(123, ForeignAccess.sendRead(Message.READ.createNode(), nvi, 0)); - assertEquals(10, ForeignAccess.sendGetSize(Message.GET_SIZE.createNode(), nvi)); - nvi = (TruffleObject) ForeignAccess.sendWrite(Message.WRITE.createNode(), nvi, 100, 321); - assertEquals(101, ForeignAccess.sendGetSize(Message.GET_SIZE.createNode(), nvi)); - assertEquals(321, ForeignAccess.sendRead(Message.READ.createNode(), nvi, 100)); + assertEquals(10, ForeignAccess.sendGetSize(Message.GET_SIZE.createNode(), nvi)); + nvi = (TruffleObject) ForeignAccess.sendWrite(Message.WRITE.createNode(), nvi, 100, 321); + assertEquals(101, ForeignAccess.sendGetSize(Message.GET_SIZE.createNode(), nvi)); + assertEquals(321, ForeignAccess.sendRead(Message.READ.createNode(), nvi, 100)); - nvi = (TruffleObject) ForeignAccess.sendWrite(Message.WRITE.createNode(), nvi, 0, "abc"); - assertEquals("abc", ForeignAccess.sendRead(Message.READ.createNode(), nvi, 0)); - return null; - }); + nvi = (TruffleObject) ForeignAccess.sendWrite(Message.WRITE.createNode(), nvi, 0, "abc"); + assertEquals("abc", ForeignAccess.sendRead(Message.READ.createNode(), nvi, 0)); } @Test public void testKeyInfo() throws Exception { - execInContext(() -> { - TruffleObject v = RDataFactory.createLogicalVector(new byte[]{1, 0, 1}, true); - assertInteropException(() -> ForeignAccess.sendKeys(Message.KEYS.createNode(), v), UnsupportedMessageException.class); - - int keyInfo = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), v, 0); - assertTrue(KeyInfo.isExisting(keyInfo)); - assertTrue(KeyInfo.isReadable(keyInfo)); - assertTrue(KeyInfo.isWritable(keyInfo)); - assertFalse(KeyInfo.isInvocable(keyInfo)); - assertFalse(KeyInfo.isInternal(keyInfo)); - - keyInfo = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), v, 100); - assertFalse(KeyInfo.isExisting(keyInfo)); - return null; - }); + TruffleObject v = RDataFactory.createLogicalVector(new byte[]{1, 0, 1}, true); + assertInteropException(() -> ForeignAccess.sendKeys(Message.KEYS.createNode(), v), UnsupportedMessageException.class); + + int keyInfo = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), v, 0); + assertTrue(KeyInfo.isExisting(keyInfo)); + assertTrue(KeyInfo.isReadable(keyInfo)); + assertTrue(KeyInfo.isWritable(keyInfo)); + assertFalse(KeyInfo.isInvocable(keyInfo)); + assertFalse(KeyInfo.isInternal(keyInfo)); + + keyInfo = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), v, 100); + assertFalse(KeyInfo.isExisting(keyInfo)); } @Override diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestSimpleVectors.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestSimpleVectors.java index c5c3df31e1d5c3a1e07cf9633c98f7d8dbc99195..57a1f724bdd9bd8c51e08587aeadffaacece0456 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestSimpleVectors.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestSimpleVectors.java @@ -712,6 +712,18 @@ public class TestSimpleVectors extends TestBase { assertEval("{ x<-quote(function(x, y=7) 42); x[[2]] }"); assertEval("{ f<-quote(function(x=42) x); f[[2]]$x<-7; eval(f)() }"); + + assertEval("f <- function(x) x[[1]]; l <- as.pairlist(c('a','b')); f(l); l <- quote(a+b); f(l)"); + assertEval("l <- quote(a+b+c); l[[c(2,2)]]; l[[c(2,3)]]; l[[c(2,2)]]; l[[c(3)]]; l <- as.pairlist(c('+','x','c')); l[[2]] <- as.pairlist(c('+','a','b')); l[[c(2,2)]]; l[[c(2,3)]]; l[[c(2,2)]]; l[[c(3)]]"); + } + + @Test + public void testPairList() { + assertEval("l <- as.pairlist(c(1,2,3,4)); typeof(l); l[[3]] <- 123; typeof(l); l"); + assertEval("l <- as.pairlist(c(1,2,3,4)); l2 <- l; typeof(l); l[[3]] <- 123; typeof(l); l"); + assertEval("x <- as.pairlist(list(7,42)); x[[1]] <- list(); typeof(x); x$foo <- 123; typeof(x); x[1] <- list(1); typeof(x)"); + assertEval("l <- quote(a(\"b\",1,4,3)); typeof(l); typeof(l[[1]]); typeof(l[1]); typeof(l[1:5]); typeof(l[4:5]); l[4:5]"); + assertEval("l <- pairlist(\"a\",\"b\",1,4,3); typeof(l); typeof(l[[1]]); typeof(l[1]); typeof(l[1:5]); typeof(l[4:5]); l[4:5]"); } @Test diff --git a/mx.fastr/mx_fastr.py b/mx.fastr/mx_fastr.py index 87cb779ed29927269b55847d7133630b176003bf..4281149ab5bd0416c2efa28f35b44ecfb3cb5d86 100644 --- a/mx.fastr/mx_fastr.py +++ b/mx.fastr/mx_fastr.py @@ -324,6 +324,9 @@ def ut_default(args): def ut_gate(args): return mx_unittest.unittest(args + _gate_unit_tests()) +def ut_gen(args): + return mx_unittest.unittest(args + _all_generated_unit_tests()) + def _test_package(): return 'com.oracle.truffle.r.test' @@ -597,6 +600,7 @@ _commands = { 'rutsimple' : [ut_simple, ['options']], 'rutdefault' : [ut_default, ['options']], 'rutgate' : [ut_gate, ['options']], + 'rutgen' : [ut_gen, ['options']], 'rutnoapps' : [ut_noapps, ['options']], 'rbcheck' : [rbcheck, '--filter [gnur-only,fastr-only,both,both-diff]'], 'rbdiag' : [rbdiag, '(builtin)* [-v] [-n] [-m] [--sweep | --sweep=lite | --sweep=total] [--mnonly] [--noSelfTest] [--matchLevel=same | --matchLevel=error] [--maxSweeps=N] [--outMaxLev=N]'], diff --git a/mx.fastr/mx_fastr_edinclude.py b/mx.fastr/mx_fastr_edinclude.py index 5f2efebcfd18ef31d49e145b920c4cf7dd9b02a3..fc7326f5dc72a57752f3829ad1c0bccc8ef95391 100644 --- a/mx.fastr/mx_fastr_edinclude.py +++ b/mx.fastr/mx_fastr_edinclude.py @@ -74,17 +74,6 @@ use_internals_end = '''#endif ''' -# This rewrite is disabled, because it causes compilation error with Rcpp -# The long term solution shall be to unify RPairList and RLanguage and -# possibly RArgsValuesAndNames(?) to be able to change the type in place. -set_typeof_rewrite = '''#ifdef FASTR -SEXP SET_TYPEOF_FASTR(SEXP x, int v); -#ifndef NO_FASTR_REDEFINE -#define SET_TYPEOF(X,Y) X=SET_TYPEOF_FASTR(X,Y) -#endif -#endif -''' - def ed_r_internals(gnu_dir): r_internals_h = join(gnu_dir, 'Rinternals.h') with open(r_internals_h) as f: @@ -116,10 +105,6 @@ def ed_r_internals(gnu_dir): rewrite_var(f, var, line) else: f.write(line) - # disabled because of compilations problems with Rcpp - # elif 'SET_TYPEOF' in line and '(SEXP' in line: - # f.write(line) - # f.write(set_typeof_rewrite) else: f.write(line) diff --git a/mx.fastr/suite.py b/mx.fastr/suite.py index 191682f6b95ccb2a9c5a6af7a1ef1551fc65c8f6..7e17fff9837880a077c7eb7b3c5904bb0a86be44 100644 --- a/mx.fastr/suite.py +++ b/mx.fastr/suite.py @@ -7,7 +7,7 @@ suite = { { "name" : "truffle", "subdir" : True, - "version" : "e5a96fc63e69bed9a93e812936c9961a69d8d25e", + "version" : "3760adf8d12c471782649e2fc2430f7647a0eda1", "urls" : [ {"url" : "https://github.com/graalvm/graal", "kind" : "git"}, {"url" : "https://curio.ssw.jku.at/nexus/content/repositories/snapshots", "kind" : "binary"},