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 d5654f2083c42eda2cd73d28972b5a446800ec97..1a344a8c2151546862992a3fb6306549ab525a5a 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 @@ -215,8 +215,8 @@ public final class REngine implements RContext.Engine { RootCallTarget callTarget = makeCallTarget(exprRep); MaterializedFrame envFrame = envir.getFrame(); VirtualFrame vFrame = RRuntime.createFunctionFrame(function); - // We make the new frame look like it was a real call to "function". - RArguments.setEnclosingFrame(vFrame, function.getEnclosingFrame()); + RArguments.setEnclosingFrame(vFrame, RArguments.getEnclosingFrame(envFrame)); + // We make the new frame look like it was a real call to "function" (why?) RArguments.setFunction(vFrame, function); FrameDescriptor envfd = envFrame.getFrameDescriptor(); FrameDescriptor vfd = vFrame.getFrameDescriptor(); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RTruffleVisitor.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RTruffleVisitor.java index d0e85230e7d13f37aeed26162bbd5e21940c7f88..fcb6240c92febc9c4b4636b838e1f20c465f1a15 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RTruffleVisitor.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/RTruffleVisitor.java @@ -322,6 +322,21 @@ public final class RTruffleVisitor extends BasicVisitor<RNode> { return access; } + /** + * The sequence created for a {@linkplain #visit(Replacement) replacement} consists of the + * following elements: + * <ol> + * <li>(prefix) store the right-hand side in an anonymous slot, + * <li>(prefix) assign the left-hand side to {@code *tmp*}, + * <li>(suffix) assign from the replacement call, + * <li>(suffix) remove *tmp*, + * <li>(suffix) remove the anonymous right-hand side slot and answer its value. + * <ol> + */ + private static RNode[] createReplacementSequence() { + return new RNode[5]; + } + private static final String varSymbol = "*tmp*"; private static Object constructReplacementPrefix(RNode[] seq, RNode rhs, RNode replacementArg, WriteVariableNode.Mode rhsWriteMode) { @@ -333,7 +348,6 @@ public final class RTruffleVisitor extends BasicVisitor<RNode> { final Object rhsSymbol = new Object(); WriteVariableNode rhsAssign = WriteVariableNode.create(rhsSymbol, rhs, false, false, rhsWriteMode); - WriteVariableNode varAssign = WriteVariableNode.create(varSymbol, replacementArg, false, false, WriteVariableNode.Mode.TEMP); seq[0] = rhsAssign; @@ -343,14 +357,14 @@ public final class RTruffleVisitor extends BasicVisitor<RNode> { } private static SequenceNode constructReplacementSuffix(RNode[] seq, RNode assignFromTemp, Object rhsSymbol, SourceSection source) { - // assign var, read rhs - WriteVariableNode varReset = WriteVariableNode.create(varSymbol, ConstantNode.create(RNull.instance), false, false); - ReadVariableNode rhsRead = ReadVariableNode.create(RRuntime.toString(rhsSymbol), false); + // remove var and rhs, returning rhs' value + RemoveAndAnswerNode rmVar = RemoveAndAnswerNode.create(varSymbol); + RemoveAndAnswerNode rmRhs = RemoveAndAnswerNode.create(rhsSymbol); // assemble seq[2] = assignFromTemp; - seq[3] = varReset; - seq[4] = Invisible.create(rhsRead); + seq[3] = rmVar; + seq[4] = rmRhs; SequenceNode replacement = new SequenceNode(seq); replacement.assignSourceSection(source); return replacement; @@ -394,7 +408,7 @@ public final class RTruffleVisitor extends BasicVisitor<RNode> { SimpleAccessVariable varAST = (SimpleAccessVariable) a.getVector(); String vSymbol = RRuntime.toString(varAST.getSymbol()); - RNode[] seq = new RNode[5]; + RNode[] seq = createReplacementSequence(); ReadVariableNode v = isSuper ? ReadVariableSuperMaterializedNode.create(varAST.getSource(), vSymbol, RRuntime.TYPE_ANY) : ReadVariableNode.create(varAST.getSource(), vSymbol, RRuntime.TYPE_ANY, varAST.shouldCopyValue()); final Object rhsSymbol = constructReplacementPrefix(seq, rhs, v, WriteVariableNode.Mode.INVISIBLE); @@ -433,7 +447,7 @@ public final class RTruffleVisitor extends BasicVisitor<RNode> { SimpleAccessVariable varAST = getFieldAccessVariable(accessAST); String vSymbol = RRuntime.toString(varAST.getSymbol()); - RNode[] seq = new RNode[5]; + RNode[] seq = createReplacementSequence(); ReadVariableNode v = isSuper ? ReadVariableSuperMaterializedNode.create(varAST.getSource(), vSymbol, RRuntime.TYPE_ANY) : ReadVariableNode.create(varAST.getSource(), vSymbol, RRuntime.TYPE_ANY, varAST.shouldCopyValue()); final Object rhsSymbol = constructReplacementPrefix(seq, rhs, v, WriteVariableNode.Mode.INVISIBLE); @@ -502,7 +516,7 @@ public final class RTruffleVisitor extends BasicVisitor<RNode> { * </pre> * * We take an anonymous object to store a, as the anonymous object is unique to this - * replacement. We omit the removal of *tmp*. + * replacement. This value must be stored as it is the result of the entire replacement expression. */ //@formatter:on @Override @@ -516,7 +530,7 @@ public final class RTruffleVisitor extends BasicVisitor<RNode> { if (val instanceof SimpleAccessVariable) { SimpleAccessVariable callArg = (SimpleAccessVariable) val; String vSymbol = RRuntime.toString(callArg.getSymbol()); - RNode[] seq = new RNode[5]; + RNode[] seq = createReplacementSequence(); ReadVariableNode replacementCallArg = createReplacementForVariableUsing(callArg, vSymbol, replacement); final Object rhsSymbol = constructReplacementPrefix(seq, rhs, replacementCallArg, WriteVariableNode.Mode.COPY); RNode replacementCall = prepareReplacementCall(f, args, rhsSymbol, true); @@ -525,7 +539,7 @@ public final class RTruffleVisitor extends BasicVisitor<RNode> { } else if (val instanceof AccessVector) { AccessVector callArgAst = (AccessVector) val; RNode replacementArg = callArgAst.accept(this); - RNode[] seq = new RNode[5]; + RNode[] seq = createReplacementSequence(); final Object rhsSymbol = constructReplacementPrefix(seq, rhs, replacementArg, WriteVariableNode.Mode.COPY); RNode replacementCall = prepareReplacementCall(f, args, rhsSymbol, false); // see AssignVariable.writeVector (number of args must match) @@ -535,7 +549,7 @@ public final class RTruffleVisitor extends BasicVisitor<RNode> { } else { FieldAccess callArgAst = (FieldAccess) val; RNode replacementArg = callArgAst.accept(this); - RNode[] seq = new RNode[5]; + RNode[] seq = createReplacementSequence(); final Object rhsSymbol = constructReplacementPrefix(seq, rhs, replacementArg, WriteVariableNode.Mode.COPY); RNode replacementCall = prepareReplacementCall(f, args, rhsSymbol, false); RNode assignFromTemp = createFieldUpdate(callArgAst, replacementCall, replacement.isSuper(), replacement.getSource()); @@ -620,7 +634,7 @@ public final class RTruffleVisitor extends BasicVisitor<RNode> { } String vSymbol = RRuntime.toString(varAST.getSymbol()); - RNode[] seq = new RNode[5]; + RNode[] seq = createReplacementSequence(); ReadVariableNode v = isSuper ? ReadVariableSuperMaterializedNode.create(varAST.getSource(), vSymbol, RRuntime.TYPE_ANY) : ReadVariableNode.create(varAST.getSource(), vSymbol, RRuntime.TYPE_ANY, varAST.shouldCopyValue()); final Object rhsSymbol = constructReplacementPrefix(seq, rhs, v, WriteVariableNode.Mode.INVISIBLE); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/AccessArgumentNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/AccessArgumentNode.java index 3bfb621c7e447da9fc7ead44fe2dfed7c11750ac..9eb645aa7c21eaf981a1a432614f1f86c4f3f6d5 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/AccessArgumentNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/AccessArgumentNode.java @@ -23,6 +23,7 @@ package com.oracle.truffle.r.nodes.access; import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.api.utilities.*; import com.oracle.truffle.r.nodes.*; import com.oracle.truffle.r.nodes.function.*; import com.oracle.truffle.r.runtime.*; @@ -45,6 +46,9 @@ public class AccessArgumentNode extends RNode { */ private final EnvProvider envProvider; + private final BranchProfile needsCalleeFrame = new BranchProfile(); + private final BranchProfile strictEvaluation = new BranchProfile(); + public AccessArgumentNode(int index, EnvProvider envProvider) { this.index = index; this.envProvider = envProvider; @@ -71,6 +75,7 @@ public class AccessArgumentNode extends RNode { // Check whether it is necessary to create a callee REnvironment for the promise if (promise.needsCalleeFrame()) { + needsCalleeFrame.enter(); // In this case the promise might lack the proper REnvironment, as it was created before // the environment was promise.updateEnv(envProvider.getREnvironmentFor(frame)); @@ -78,6 +83,7 @@ public class AccessArgumentNode extends RNode { // Now force evaluation for STRICT if (promise.getEvalPolicy() == EvalPolicy.STRICT) { + strictEvaluation.enter(); return promise.evaluate(frame); } return promiseObj; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/ReadVariableNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/ReadVariableNode.java index 6a180347a054ba63cbf63c39a359f6cef748ea3e..866ac7d601be8bdaf57ebe912356464f6c613ad6 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/ReadVariableNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/ReadVariableNode.java @@ -54,6 +54,15 @@ public abstract class ReadVariableNode extends RNode implements VisibilityContro return create(symbol, RRuntime.TYPE_ANY, shouldCopyValue); } + /** + * Convenience method. + * + * @return {@link #create(String, boolean)} + */ + public static ReadVariableNode create(Object symbol, boolean shouldCopyValue) { + return create(symbol.toString(), shouldCopyValue); + } + /** * Convenience method * @@ -140,7 +149,7 @@ public abstract class ReadVariableNode extends RNode implements VisibilityContro public ReadCheckPromiseNode(ReadVariableNode readNode) { super(); this.readNode = readNode; - this.readNodeInitial = readNode; + this.readNodeInitial = NodeUtil.cloneNode(readNode); } @Override @@ -168,7 +177,7 @@ public abstract class ReadVariableNode extends RNode implements VisibilityContro Object promiseValue = promise.evaluate(frame); if (checkType(promiseValue, ((HasMode) readNode).getMode())) { // Replace with ReadPromiseNode and execute it! - return replace(new ReadPromiseNode(getSymbol(), promise)).execute(frame); + return replace(new ReadPromiseNode(getSymbol(), promise, readNode)).execute(frame); } else { // didn't match, restart the search from the beginning // N.B. since this promise has been evaluated it will @@ -179,7 +188,7 @@ public abstract class ReadVariableNode extends RNode implements VisibilityContro // Value is no promise: Replace with ReadVariableNode... replace(readNode); - return value; // ...and return it, as its already there. + return value; // ...and return it, as it's already there. } @Override @@ -195,20 +204,38 @@ public abstract class ReadVariableNode extends RNode implements VisibilityContro private final Symbol symbol; private final RPromise promise; + @Child private ReadVariableNode readNode; - public ReadPromiseNode(Symbol symbol, RPromise promise) { + public ReadPromiseNode(Symbol symbol, RPromise promise, ReadVariableNode readNode) { super(); this.symbol = symbol; this.promise = promise; + this.readNode = readNode; } @Override public Object execute(VirtualFrame frame, MaterializedFrame enclosingFrame) { + // TODO ASSUMPTION: Use has-changed-assumption OR is-promise assumption here when + // available and replace readNode.execute! + Object value = readNode.execute(frame); + if (value != promise) { // Does this compile? + // Value changed: It might know be a simple value - or another promise, created by + // delayedAssign, e.g. + CompilerDirectives.transferToInterpreterAndInvalidate(); + return replace(new ReadCheckPromiseNode(readNode)).execute(frame, enclosingFrame); + } return promise.getValue(); } @Override public Object execute(VirtualFrame frame) { + Object value = readNode.execute(frame); + if (value != promise) { + // Value changed: It might know be a simple value - or another promise, created by + // delayedAssign, e.g. + CompilerDirectives.transferToInterpreterAndInvalidate(); + return replace(new ReadCheckPromiseNode(readNode)).execute(frame); + } return promise.getValue(); } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/RemoveAndAnswerNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/RemoveAndAnswerNode.java new file mode 100644 index 0000000000000000000000000000000000000000..1c41dfaff31feb88481bb908717a84572eab1e4d --- /dev/null +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/RemoveAndAnswerNode.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.r.nodes.access; + +import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.r.nodes.*; +import com.oracle.truffle.r.parser.ast.*; +import com.oracle.truffle.r.runtime.*; + +/** + * This node removes a slot from the current frame (i.e., sets it to {@code null} to allow fast-path + * usage) and returns the slot's value. The node must be used with extreme caution as it does not + * perform checking; it is to be used for internal purposes. A sample use case is a + * {@linkplain RTruffleVisitor#visit(Replacement) replacement}. + */ +public final class RemoveAndAnswerNode extends RNode implements VisibilityController { + + /** + * The name of the variable that is to be removed and whose value is to be returned. + */ + private final String name; + + private RemoveAndAnswerNode(String name) { + this.name = name; + } + + public static RemoveAndAnswerNode create(String name) { + return new RemoveAndAnswerNode(name); + } + + public static RemoveAndAnswerNode create(Object name) { + return new RemoveAndAnswerNode(name.toString()); + } + + @Override + public Object execute(VirtualFrame frame) { + controlVisibility(); + FrameSlot fs = frame.getFrameDescriptor().findFrameSlot(name); + if (fs == null) { + RError.warning(this.getEncapsulatingSourceSection(), RError.Message.UNKNOWN_OBJECT, name); + } + Object result = frame.getValue(fs); + frame.setObject(fs, null); // use null (not an R value) to represent "undefined" + return result; + } + + @Override + public boolean getVisibility() { + return false; + } + +} diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/APerm.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/APerm.java index f93e658824048a8e1f1f7e222795b1d9addbe610..113b8094f37a71de31822ad2ebc8deaba74ccf72 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/APerm.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/APerm.java @@ -17,6 +17,7 @@ import java.util.*; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.r.nodes.*; +import com.oracle.truffle.r.nodes.access.*; import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.nodes.unary.*; import com.oracle.truffle.r.runtime.*; @@ -24,8 +25,14 @@ import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.*; //TODO: Implement permuting with DimNames -@RBuiltin(name = "aperm", kind = INTERNAL) +@RBuiltin(name = "aperm", kind = INTERNAL, parameterNames = {"a", "perm", "..."}) public abstract class APerm extends RBuiltinNode { + + @Override + public RNode[] getParameterValues() { + return new RNode[]{ConstantNode.create(RMissing.instance), ConstantNode.create(RMissing.instance), ConstantNode.create(RMissing.instance)}; + } + @CreateCast("arguments") public RNode[] createCastPermute(RNode[] arguments) { RNode permVector = CastToVectorNodeFactory.create(arguments[1], false, false, false, false); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/AnyDuplicated.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/AnyDuplicated.java index 2a44ac0e47f8a96bed02add969f189dd9369a5d6..817f8ed4ef6e8e6c1699200ae126d77bcc3cb21d 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/AnyDuplicated.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/AnyDuplicated.java @@ -18,18 +18,26 @@ import com.oracle.truffle.api.CompilerDirectives.SlowPath; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.r.nodes.*; +import com.oracle.truffle.r.nodes.access.*; import com.oracle.truffle.r.nodes.binary.*; import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.nodes.unary.*; import com.oracle.truffle.r.runtime.*; +import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.*; -@RBuiltin(name = "anyDuplicated", kind = RBuiltinKind.INTERNAL) +@RBuiltin(name = "anyDuplicated", kind = RBuiltinKind.INTERNAL, parameterNames = {"x", "imcomparables", "..."}) public abstract class AnyDuplicated extends RBuiltinNode { @Child private CastTypeNode castTypeNode; @Child private Typeof typeof; + @Override + public RNode[] getParameterValues() { + // x, incomparables = FALSE, ... + return new RNode[]{ConstantNode.create(RMissing.instance), ConstantNode.create(RRuntime.LOGICAL_FALSE), ConstantNode.create(RMissing.instance)}; + } + @CreateCast("arguments") public RNode[] castArguments(RNode[] arguments) { arguments[2] = CastLogicalNodeFactory.create(arguments[2], true, false, false); @@ -37,19 +45,19 @@ public abstract class AnyDuplicated extends RBuiltinNode { } @SuppressWarnings("unused") - @Specialization(guards = {"!isIncomparable", "!isFromLast"}, order = 0) + @Specialization(guards = {"!isIncomparable", "!isFromLast", "!empty"}, order = 0) public int anyDuplicatedFalseIncomparablesFromStart(RAbstractVector x, byte incomparables, byte fromLast) { return getIndexFromStart(x); } @SuppressWarnings("unused") - @Specialization(guards = {"!isIncomparable", "isFromLast"}, order = 1) + @Specialization(guards = {"!isIncomparable", "isFromLast", "!empty"}, order = 1) public int anyDuplicatedFalseIncomparablesFromLast(RAbstractVector x, byte incomparables, byte fromLast) { return getIndexFromLast(x); } @SuppressWarnings("unused") - @Specialization(guards = {"isIncomparable", "!isFromLast"}, order = 2) + @Specialization(guards = {"isIncomparable", "!isFromLast", "!empty"}, order = 2) public int anyDuplicatedTrueIncomparablesFromStart(VirtualFrame frame, RAbstractVector x, byte incomparables, byte fromLast) { initTypeof(); initCastTypeNode(); @@ -58,7 +66,7 @@ public abstract class AnyDuplicated extends RBuiltinNode { } @SuppressWarnings("unused") - @Specialization(guards = {"isIncomparable", "isFromLast"}, order = 3) + @Specialization(guards = {"isIncomparable", "isFromLast", "!empty"}, order = 3) public int anyDuplicatedTrueIncomparablesFromLast(VirtualFrame frame, RAbstractVector x, byte incomparables, byte fromLast) { initTypeof(); initCastTypeNode(); @@ -66,7 +74,7 @@ public abstract class AnyDuplicated extends RBuiltinNode { return getIndexFromLast(x, (RAbstractVector) (castTypeNode.execute(frame, incomparables, xType))); } - @Specialization(guards = "!isFromLast", order = 4) + @Specialization(guards = {"!isFromLast", "!empty"}, order = 4) public int anyDuplicatedFromStart(VirtualFrame frame, RAbstractVector x, RAbstractVector incomparables, @SuppressWarnings("unused") byte fromLast) { initTypeof(); initCastTypeNode(); @@ -74,7 +82,7 @@ public abstract class AnyDuplicated extends RBuiltinNode { return getIndexFromStart(x, (RAbstractVector) (castTypeNode.execute(frame, incomparables, xType))); } - @Specialization(guards = "isFromLast", order = 5) + @Specialization(guards = {"isFromLast", "!empty"}, order = 5) public int anyDuplicatedFromLast(VirtualFrame frame, RAbstractVector x, RAbstractVector incomparables, @SuppressWarnings("unused") byte fromLast) { initTypeof(); initCastTypeNode(); @@ -82,6 +90,12 @@ public abstract class AnyDuplicated extends RBuiltinNode { return getIndexFromLast(x, (RAbstractVector) (castTypeNode.execute(frame, incomparables, xType))); } + @SuppressWarnings("unused") + @Specialization(guards = "empty", order = 10) + public int anyDuplicatedEmpty(VirtualFrame frame, RAbstractVector x, RAbstractVector incomparables, byte fromLast) { + return 0; + } + @SlowPath private static int getIndexFromStart(RAbstractVector x, RAbstractVector incomparables) { HashSet<Object> incompContents = new HashSet<>(); @@ -166,6 +180,10 @@ public abstract class AnyDuplicated extends RBuiltinNode { return fromLast == RRuntime.LOGICAL_TRUE; } + protected boolean empty(RAbstractVector x) { + return x.getLength() == 0; + } + private void initCastTypeNode() { if (castTypeNode == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Array.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Array.java index 47ed5eb861058bf5bed32afa72d79eb195c8c6e9..6573440cf9e677e47ccab1f8a127d2d4a7443e68 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Array.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Array.java @@ -27,6 +27,7 @@ import static com.oracle.truffle.r.runtime.RBuiltinKind.*; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.r.nodes.*; +import com.oracle.truffle.r.nodes.access.*; import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.nodes.unary.*; import com.oracle.truffle.r.runtime.*; @@ -43,9 +44,16 @@ import com.oracle.truffle.r.runtime.data.model.*; * * TODO complete. This is sufficient for the b25 benchmark use. */ -@RBuiltin(name = "array", kind = INTERNAL) +@RBuiltin(name = "array", kind = INTERNAL, parameterNames = {"data", "dim", "dimnames"}) public abstract class Array extends RBuiltinNode { + @Override + public RNode[] getParameterValues() { + // TODO What is the correct NA value for "data"??? + // is inserted as cast, see below in "createCastDimensions" + return new RNode[]{ConstantNode.create(RRuntime.NA_HEADER), null, ConstantNode.create(RNull.instance)}; + } + @CreateCast({"arguments"}) public RNode[] createCastDimensions(RNode[] children) { RNode dimsVector = CastToVectorNodeFactory.create(children[1], false, false, false, false); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java index 0832946b27f4f0e8be8f5c111fcc908947832d42..5bf3a4d9d3b2829403c9b7b9d9e986d2dfa18156 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java @@ -35,12 +35,10 @@ import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.*; -@RBuiltin(name = "as.vector", kind = SUBSTITUTE) +@RBuiltin(name = "as.vector", kind = SUBSTITUTE, parameterNames = {"x", "mode"}) // TODO should be INTERNAL public abstract class AsVector extends RBuiltinNode { - private static final String[] PARAMETER_NAMES = new String[]{"x", "mode"}; - @Child private CastIntegerNode castInteger; @Child private CastDoubleNode castDouble; @Child private CastComplexNode castComplex; @@ -114,11 +112,6 @@ public abstract class AsVector extends RBuiltinNode { return castList.executeList(frame, operand); } - @Override - public Object[] getParameterNames() { - return PARAMETER_NAMES; - } - @Override public RNode[] getParameterValues() { return new RNode[]{ConstantNode.create(RMissing.instance), ConstantNode.create(RRuntime.TYPE_ANY)}; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Assign.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Assign.java index f061d1c718261ca3eab82cbd8e2fc621c3950e28..d36d1d1e2ff60fb5b4335dfa590dc4a1b0bde009 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Assign.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Assign.java @@ -90,9 +90,8 @@ public abstract class Assign extends RInvisibleBuiltinNode { controlVisibility(); MaterializedFrame materializedFrame = virtualFrame.materialize(); FrameSlot slot = materializedFrame.getFrameDescriptor().findFrameSlot(variableName); - int i = 0; int iterationsAmount = CompilerAsserts.compilationConstant(slotFoundOnIteration.length); - for (; i < iterationsAmount; i++) { + for (int i=0; i < iterationsAmount; i++) { if (isAppropriateFrameSlot(slot, materializedFrame)) { addValueToFrame(variableName, variableValue, materializedFrame, slot); return variableValue; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/AttachFunctions.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/AttachFunctions.java index 2029d200b9dccbc1e23240715434232aa160d0f8..e4e3203b078dd6a37f78122bc0a7576fdd2773f6 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/AttachFunctions.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/AttachFunctions.java @@ -26,6 +26,8 @@ import static com.oracle.truffle.r.runtime.RBuiltinKind.*; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.r.nodes.*; +import com.oracle.truffle.r.nodes.access.*; import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.REnvironment.DetachException; @@ -36,11 +38,17 @@ import com.oracle.truffle.r.runtime.data.model.*; * TODO The specialization signatures are weird owing to issues with named parameter handling. */ public class AttachFunctions { - @RBuiltin(name = "attach", kind = INTERNAL) + @RBuiltin(name = "attach", kind = INTERNAL, parameterNames = {"what", "pos", "name", "warn.conflicts"}) public abstract static class Attach extends RInvisibleBuiltinNode { private static final String POS_WARNING = "*** 'pos=1' is not possible; setting 'pos=2' for now.\n" + "*** Note that 'pos=1' will give an error in the future"; + // TODO 3rd parameter "name" has default "deparse(substitute(what)" + @Override + public RNode[] getParameterValues() { + return new RNode[]{ConstantNode.create(RMissing.instance), ConstantNode.create(2), null, ConstantNode.create(RRuntime.LOGICAL_FALSE), ConstantNode.create(RRuntime.LOGICAL_FALSE)}; + } + @Specialization(order = 0) public REnvironment doAttach(@SuppressWarnings("unused") RNull what, int pos, String name) { controlVisibility(); @@ -129,8 +137,15 @@ public class AttachFunctions { } } - @RBuiltin(name = "detach", kind = INTERNAL) + @RBuiltin(name = "detach", kind = INTERNAL, parameterNames = {"name", "pos", "unload", "character.only", "force"}) public abstract static class Detach extends RInvisibleBuiltinNode { + + @Override + public RNode[] getParameterValues() { + return new RNode[]{ConstantNode.create(RMissing.instance), ConstantNode.create(2), ConstantNode.create(RRuntime.LOGICAL_FALSE), ConstantNode.create(RRuntime.LOGICAL_FALSE), + ConstantNode.create(RRuntime.LOGICAL_FALSE)}; + } + @SuppressWarnings("unused") @Specialization public Object doDetach1(VirtualFrame frame, int name, int pos, byte unload, byte characterOnly, byte force) { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Cat.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Cat.java index 2ec4430fafab9b6c70b91e37451583f01f95864e..85dccfb7b34409ade1353907e8d135717504292a 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Cat.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Cat.java @@ -32,6 +32,7 @@ import com.oracle.truffle.api.frame.*; import com.oracle.truffle.r.nodes.*; import com.oracle.truffle.r.nodes.access.*; import com.oracle.truffle.r.nodes.builtin.*; +import com.oracle.truffle.r.nodes.unary.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.*; @@ -53,14 +54,14 @@ public abstract class Cat extends RInvisibleBuiltinNode { ConstantNode.create(RRuntime.LOGICAL_FALSE)}; } - @Child private ToString toString; + @Child private ToStringNode toString; @CompilationFinal private String currentSep; private void ensureToString(String sep) { if (toString == null || !sep.equals(currentSep)) { CompilerDirectives.transferToInterpreterAndInvalidate(); - toString = insert(ToStringFactory.create(new RNode[1], getBuiltin(), getSuppliedArgsNames())); + toString = insert(ToStringNodeFactory.create(null)); toString.setSeparator(sep); toString.setQuotes(false); toString.setIntL(false); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/CharacterBuiltin.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/CharacterBuiltin.java index dd3254f0e00ad2bb2b679963ea41d1650794ed9f..4d5b772b469d4d687e784488c5597a31365bd744 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/CharacterBuiltin.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/CharacterBuiltin.java @@ -25,15 +25,22 @@ package com.oracle.truffle.r.nodes.builtin.base; import static com.oracle.truffle.r.runtime.RBuiltinKind.*; import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.r.nodes.*; +import com.oracle.truffle.r.nodes.access.*; import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.*; -@RBuiltin(name = "character", kind = SUBSTITUTE) +@RBuiltin(name = "character", kind = SUBSTITUTE, parameterNames = {"length"}) // TODO Implement in R public abstract class CharacterBuiltin extends RBuiltinNode { + @Override + public RNode[] getParameterValues() { + return new RNode[]{ConstantNode.create(0)}; + } + @Specialization public Object createCharacterVector(int length) { controlVisibility(); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/ColMeans.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/ColMeans.java index 638590e66ed431803e107195401f746c68a9ac14..01348b299cd7cb64230b4b45cbf86f74cefd86e7 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/ColMeans.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/ColMeans.java @@ -13,6 +13,7 @@ package com.oracle.truffle.r.nodes.builtin.base; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.r.nodes.*; +import com.oracle.truffle.r.nodes.access.*; import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.nodes.unary.*; import com.oracle.truffle.r.runtime.*; @@ -21,9 +22,16 @@ import com.oracle.truffle.r.runtime.data.model.*; import com.oracle.truffle.r.runtime.ops.*; import com.oracle.truffle.r.runtime.ops.na.*; -@RBuiltin(name = "colMeans", kind = RBuiltinKind.INTERNAL) +//Implements .colMeans +@RBuiltin(name = "colMeans", kind = RBuiltinKind.INTERNAL, parameterNames = {"X", "m", "n", "na.rm"}) public abstract class ColMeans extends RBuiltinNode { + @Override + public RNode[] getParameterValues() { + // X, m, n, na.rm = FALSE + return new RNode[]{ConstantNode.create(RMissing.instance), ConstantNode.create(RMissing.instance), ConstantNode.create(RMissing.instance), ConstantNode.create(RRuntime.FALSE)}; + } + @Child protected BinaryArithmetic add = BinaryArithmetic.ADD.create(); private final NACheck na = NACheck.create(); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/ColSums.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/ColSums.java index b559ec81c7c28bd4fe94d18c2a1b3f4224da82f7..e9975e3b1be10e8c723e5b55dd8e83685eb7c126 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/ColSums.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/ColSums.java @@ -25,6 +25,7 @@ package com.oracle.truffle.r.nodes.builtin.base; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.r.nodes.*; +import com.oracle.truffle.r.nodes.access.*; import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.nodes.unary.*; import com.oracle.truffle.r.runtime.*; @@ -33,9 +34,16 @@ import com.oracle.truffle.r.runtime.data.model.*; import com.oracle.truffle.r.runtime.ops.*; import com.oracle.truffle.r.runtime.ops.na.*; -@RBuiltin(name = "colSums", kind = RBuiltinKind.INTERNAL) +//Implements .colSums +@RBuiltin(name = "colSums", kind = RBuiltinKind.INTERNAL, parameterNames = {"X", "m", "n", "na.rm"}) public abstract class ColSums extends RBuiltinNode { + @Override + public RNode[] getParameterValues() { + // X, m, n, na.rm = FALSE + return new RNode[]{ConstantNode.create(RMissing.instance), ConstantNode.create(RMissing.instance), ConstantNode.create(RMissing.instance), ConstantNode.create(RRuntime.FALSE)}; + } + @Child protected BinaryArithmetic add = BinaryArithmetic.ADD.create(); private final NACheck na = NACheck.create(); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Cor.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Cor.java index 98d5f4358b675d0fe8108f36c07514f663f31bef..a3ab5746fa8a38c82a05e44311fb1650884431c2 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Cor.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Cor.java @@ -25,21 +25,37 @@ package com.oracle.truffle.r.nodes.builtin.base; import static com.oracle.truffle.r.runtime.RBuiltinKind.*; import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.r.nodes.*; +import com.oracle.truffle.r.nodes.access.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; -@RBuiltin(name = "cor", kind = SUBSTITUTE) +@RBuiltin(name = "cor", kind = SUBSTITUTE, parameterNames = {"x", "y", "use", "method"}) public abstract class Cor extends Covcor { + @Override + public RNode[] getParameterValues() { + // x, y = NULL, use = "everything", method = c("pearson", "kendall", "spearman") + return new RNode[]{ConstantNode.create(RMissing.instance), ConstantNode.create(RNull.instance), ConstantNode.create("everything"), + ConstantNode.create(RDataFactory.createStringVector(new String[]{"pearson", "kendall", "spearman"}, true))}; + } + @Specialization - public RDoubleVector dimWithDimensions(RDoubleVector vector1, RDoubleVector vector2) { + public RDoubleVector dimWithDimensions(RDoubleVector vector1, RDoubleVector vector2, @SuppressWarnings("unused") String use, @SuppressWarnings("unused") RStringVector method) { controlVisibility(); return corcov(vector1, vector2, false, true); } @Specialization @SuppressWarnings("unused") - public RDoubleVector dimWithDimensions(RDoubleVector vector1, RMissing vector2) { + public RDoubleVector dimWithDimensions(RDoubleVector vector1, RMissing vector2, String use, RStringVector method) { + controlVisibility(); + return corcov(vector1, null, false, true); + } + + @Specialization + @SuppressWarnings("unused") + public RDoubleVector dimWithDimensions(RDoubleVector vector1, RNull vector2, String use, RStringVector method) { controlVisibility(); return corcov(vector1, null, false, true); } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Cov.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Cov.java index b94eb87e40504824787a98cda34ff06fd20519ad..c6b4e717753d0dc197f07ba9ff9f031a9436747d 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Cov.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Cov.java @@ -25,12 +25,22 @@ package com.oracle.truffle.r.nodes.builtin.base; import static com.oracle.truffle.r.runtime.RBuiltinKind.*; import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.r.nodes.*; +import com.oracle.truffle.r.nodes.access.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; -@RBuiltin(name = "cov", kind = SUBSTITUTE) +@RBuiltin(name = "cov", kind = SUBSTITUTE, parameterNames = {"x", "y", "use", "method"}) public abstract class Cov extends Covcor { + @Override + public RNode[] getParameterValues() { + // x, y = NULL, use = "everything", method = c("pearson", "kendall", "spearman") + // TODO Is there a constant for "everyting"? + return new RNode[]{ConstantNode.create(RMissing.instance), ConstantNode.create(RNull.instance), ConstantNode.create("everything"), + ConstantNode.create(RDataFactory.createStringVector(new String[]{"pearson", "kendall", "spearman"}, true))}; + } + @Specialization public RDoubleVector dimWithDimensions(RDoubleVector vector1, RDoubleVector vector2) { controlVisibility(); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Crossprod.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Crossprod.java index 213a1f1746c14f45ad518dd0011ecb83628577f8..0b00018ac8b97a9620e0569767b7ac20e4915789 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Crossprod.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Crossprod.java @@ -34,7 +34,7 @@ import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.*; import com.oracle.truffle.r.runtime.ops.na.*; -@RBuiltin(name = "crossprod", kind = INTERNAL) +@RBuiltin(name = "crossprod", kind = INTERNAL, parameterNames = {"x", "y"}) public abstract class Crossprod extends RBuiltinNode { // TODO: this is supposed to be slightly faster than t(x) %*% y but for now it should suffice diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Deparse.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Deparse.java index 1a843efc8c795ad9610badaf93a89a416db9369d..f54048e9a64cb7deb92edf3079f0f6e88c443ad7 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Deparse.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Deparse.java @@ -14,6 +14,7 @@ package com.oracle.truffle.r.nodes.builtin.base; import com.oracle.truffle.api.CompilerDirectives.SlowPath; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.r.nodes.*; +import com.oracle.truffle.r.nodes.access.*; import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.nodes.unary.*; import com.oracle.truffle.r.runtime.*; @@ -21,11 +22,21 @@ import com.oracle.truffle.r.runtime.data.*; // Part of this transcribed from GnuR src/main/deparse.c -@RBuiltin(name = "deparse", kind = RBuiltinKind.INTERNAL) +@RBuiltin(name = "deparse", kind = RBuiltinKind.INTERNAL, parameterNames = {"expr", "width.cutoff", "backtick", "control", "nlines"}) public abstract class Deparse extends RBuiltinNode { + + @Override + public RNode[] getParameterValues() { + // expr, width.cutoff = 60L, backtick = mode(expr) %in% c("call", "expression", "(", + // "function"), control = c("keepInteger", "showAttributes", "keepNA"), nlines = -1L + return new RNode[]{ConstantNode.create(RMissing.instance), ConstantNode.create(60), ConstantNode.create(RDataFactory.createLogicalVector(new byte[]{RRuntime.LOGICAL_TRUE}, true)), + ConstantNode.create(RDataFactory.createStringVector(new String[]{"keepInteger", "showAttributes", "keepNA"}, true)), ConstantNode.create(-1)}; + } + @CreateCast("arguments") public RNode[] castArguments(RNode[] arguments) { arguments[2] = CastLogicalNodeFactory.create(arguments[2], false, false, false); + // TODO Introduce default value for backtick if argument[3] == RMissing! arguments[3] = CastIntegerNodeFactory.create(arguments[3], false, false, false); return arguments; } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Diag.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Diag.java index 62533b44528cd41b5c6c3ce8d3cffc6f57de5fae..b333ec5eecafc3813902afa6af9c7534b891d191 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Diag.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Diag.java @@ -26,19 +26,25 @@ import static com.oracle.truffle.r.runtime.RBuiltinKind.*; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.r.nodes.*; +import com.oracle.truffle.r.nodes.access.*; import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.nodes.unary.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.ops.na.*; -@RBuiltin(name = "diag", kind = SUBSTITUTE) +@RBuiltin(name = "diag", kind = SUBSTITUTE, parameterNames = {"x", "nrow", "ncol"}) // TODO INTERNAL @SuppressWarnings("unused") public abstract class Diag extends RBuiltinNode { private NACheck check = NACheck.create(); + @Override + public RNode[] getParameterValues() { + return new RNode[]{ConstantNode.create(1), ConstantNode.create(RMissing.instance), ConstantNode.create(RMissing.instance)}; + } + @CreateCast({"arguments"}) public RNode[] createCastValue(RNode[] children) { return new RNode[]{children[0], CastIntegerNodeFactory.create(children[1], false, false, false), CastIntegerNodeFactory.create(children[2], false, false, false)}; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/DoubleBuiltin.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/DoubleBuiltin.java index d1e9558cb936258c66b2106c0ded064af8c42463..86e24b50a586e536b881731eb671756e416b79a6 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/DoubleBuiltin.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/DoubleBuiltin.java @@ -25,14 +25,21 @@ package com.oracle.truffle.r.nodes.builtin.base; import static com.oracle.truffle.r.runtime.RBuiltinKind.*; import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.r.nodes.*; +import com.oracle.truffle.r.nodes.access.*; import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; -@RBuiltin(name = "double", kind = SUBSTITUTE) +@RBuiltin(name = "double", kind = SUBSTITUTE, parameterNames = {"length"}) // TODO revert to R implementation public abstract class DoubleBuiltin extends RBuiltinNode { + @Override + public RNode[] getParameterValues() { + return new RNode[]{ConstantNode.create(0)}; + } + @Specialization public Object createDoubleVector(int length) { controlVisibility(); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Drop.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Drop.java index f4da11303fab5f50aecbdb4609529ab107bd1527..48d2d430d3edb54b9c53975f6fa26c286150ba7a 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Drop.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Drop.java @@ -30,7 +30,7 @@ import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.*; -@RBuiltin(name = "drop", kind = RBuiltinKind.INTERNAL) +@RBuiltin(name = "drop", kind = RBuiltinKind.INTERNAL, parameterNames = {"x"}) public abstract class Drop extends RBuiltinNode { @Specialization public RAbstractVector doDrop(RAbstractVector x) { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/EncodeString.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/EncodeString.java index e63fb15f8b69b5b4cc829632d01c94471823235c..45fa6c76e54e4039b8a78ef093f8158b857065ca 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/EncodeString.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/EncodeString.java @@ -15,6 +15,7 @@ import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.utilities.*; import com.oracle.truffle.r.nodes.*; +import com.oracle.truffle.r.nodes.access.*; import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.nodes.unary.*; import com.oracle.truffle.r.runtime.*; @@ -22,7 +23,7 @@ import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.*; import com.oracle.truffle.r.runtime.ops.na.*; -@RBuiltin(name = "encodeString", kind = RBuiltinKind.INTERNAL) +@RBuiltin(name = "encodeString", kind = RBuiltinKind.INTERNAL, parameterNames = {"x", "width", "quote", "justify", "na.encode"}) public abstract class EncodeString extends RBuiltinNode { private static enum JUSTIFY { @@ -35,6 +36,11 @@ public abstract class EncodeString extends RBuiltinNode { private final NACheck na = NACheck.create(); private BranchProfile everSeenNA = new BranchProfile(); + @Override + public RNode[] getParameterValues() { + return new RNode[]{ConstantNode.create(RMissing.instance), ConstantNode.create(0), ConstantNode.create(""), ConstantNode.create("left"), ConstantNode.create(RRuntime.TRUE)}; + } + @CreateCast("arguments") public RNode[] castArguments(RNode[] arguments) { arguments[1] = CastIntegerNodeFactory.create(arguments[1], true, false, false); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/EnvFunctions.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/EnvFunctions.java index 83acc9c299c7e8061a77b9592d5936f0ce605439..e8d6ed808e6e38ec2ed16536c2f5906f64fff98e 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/EnvFunctions.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/EnvFunctions.java @@ -27,9 +27,12 @@ import static com.oracle.truffle.r.runtime.RBuiltinKind.*; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.frame.FrameInstance.FrameAccess; +import com.oracle.truffle.r.nodes.*; +import com.oracle.truffle.r.nodes.access.*; import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; +import com.oracle.truffle.r.runtime.data.model.*; /** * Encapsulates all the builtins related to R environments as nested static classes. @@ -76,8 +79,9 @@ public class EnvFunctions { } @Specialization - public REnvironment asEnvironment(VirtualFrame frame, String name) { + public REnvironment asEnvironment(VirtualFrame frame, RAbstractStringVector nameVec) { controlVisibility(); + String name = nameVec.getDataAt(0); String[] searchPath = REnvironment.searchPath(); for (String e : searchPath) { if (e.equals(name)) { @@ -122,7 +126,7 @@ public class EnvFunctions { } } - @RBuiltin(name = "parent.env", kind = INTERNAL) + @RBuiltin(name = "parent.env", kind = INTERNAL, parameterNames = {"env"}) public abstract static class ParentEnv extends RBuiltinNode { @Specialization @@ -136,7 +140,8 @@ public class EnvFunctions { } - @RBuiltin(name = "parent.env<-", kind = INTERNAL) + @RBuiltin(name = "parent.env<-", kind = INTERNAL, parameterNames = {"env", ""}) + // 2nd parameter is "value", but should not be matched to so it's empty public abstract static class SetParentEnv extends RBuiltinNode { @Specialization @@ -161,9 +166,14 @@ public class EnvFunctions { } } - @RBuiltin(name = "environment", kind = INTERNAL) + @RBuiltin(name = "environment", kind = INTERNAL, parameterNames = {"fun"}) public abstract static class Environment extends RBuiltinNode { + @Override + public RNode[] getParameterValues() { + return new RNode[]{ConstantNode.create(RNull.instance)}; + } + @Specialization(order = 0) public Object environment(@SuppressWarnings("unused") RNull x) { controlVisibility(); @@ -192,9 +202,15 @@ public class EnvFunctions { } - @RBuiltin(name = "environmentName", kind = INTERNAL) + @RBuiltin(name = "environmentName", kind = INTERNAL, parameterNames = {"fun"}) public abstract static class EnvironmentName extends RBuiltinNode { + @Override + public RNode[] getParameterValues() { + // fun = NULL + return new RNode[]{ConstantNode.create(RNull.instance)}; + } + @Specialization public String environmentName(REnvironment env) { controlVisibility(); @@ -209,14 +225,17 @@ public class EnvFunctions { } } - @RBuiltin(name = "new.env", kind = INTERNAL) + @RBuiltin(name = "new.env", kind = INTERNAL, parameterNames = {"hash", "parent", "size"}) public abstract static class NewEnv extends RBuiltinNode { - - private static final Object[] PARAMETER_NAMES = new Object[]{"hash", "parent", "size"}; - @Override - public Object[] getParameterNames() { - return PARAMETER_NAMES; + public RNode[] getParameterValues() { + return new RNode[]{ConstantNode.create(RRuntime.LOGICAL_TRUE), ConstantNode.create(RMissing.instance), ConstantNode.create(29)}; + } + + @Specialization + @SuppressWarnings("unused") + public REnvironment newEnv(VirtualFrame frame, byte hash, RMissing parent, int size) { + return newEnv(frame, hash, RNull.instance, size); } @Specialization @@ -245,8 +264,15 @@ public class EnvFunctions { } } - @RBuiltin(name = "lockEnvironment", kind = INTERNAL) + @RBuiltin(name = "lockEnvironment", kind = INTERNAL, parameterNames = {"env", "bindings"}) public abstract static class LockEnvironment extends RInvisibleBuiltinNode { + + @Override + public RNode[] getParameterValues() { + // env, bindings = FALSE + return new RNode[]{ConstantNode.create(RMissing.instance), ConstantNode.create(RRuntime.LOGICAL_FALSE)}; + } + @Specialization(order = 0) public Object lockEnvironment(REnvironment env, byte bindings) { controlVisibility(); @@ -256,7 +282,7 @@ public class EnvFunctions { } - @RBuiltin(name = "environmentIsLocked", kind = INTERNAL) + @RBuiltin(name = "environmentIsLocked", kind = INTERNAL, parameterNames = {"env"}) public abstract static class EnvironmentIsLocked extends RBuiltinNode { @Specialization(order = 0) public Object lockEnvironment(REnvironment env) { @@ -266,7 +292,7 @@ public class EnvFunctions { } - @RBuiltin(name = "lockBinding", kind = INTERNAL) + @RBuiltin(name = "lockBinding", kind = INTERNAL, parameterNames = {"sym", "env"}) public abstract static class LockBinding extends RInvisibleBuiltinNode { @Specialization(order = 0) public Object lockBinding(String sym, REnvironment env) { @@ -277,7 +303,7 @@ public class EnvFunctions { } - @RBuiltin(name = "unlockBinding", kind = INTERNAL) + @RBuiltin(name = "unlockBinding", kind = INTERNAL, parameterNames = {"sym", "env"}) public abstract static class UnlockBinding extends RInvisibleBuiltinNode { @Specialization(order = 0) public Object unlockBinding(String sym, REnvironment env) { @@ -288,7 +314,7 @@ public class EnvFunctions { } - @RBuiltin(name = "bindingIsLocked", kind = INTERNAL) + @RBuiltin(name = "bindingIsLocked", kind = INTERNAL, parameterNames = {"sym", "env"}) public abstract static class BindingIsLocked extends RBuiltinNode { @Specialization(order = 0) public Object bindingIsLocked(String sym, REnvironment env) { @@ -298,7 +324,7 @@ public class EnvFunctions { } - @RBuiltin(name = "makeActiveBinding", kind = INTERNAL) + @RBuiltin(name = "makeActiveBinding", kind = INTERNAL, parameterNames = {"sym", "fun", "env"}) public abstract static class MakeActiveBinding extends RInvisibleBuiltinNode { @SuppressWarnings("unused") @Specialization(order = 0) @@ -309,7 +335,7 @@ public class EnvFunctions { } } - @RBuiltin(name = "bindingIsActive", kind = INTERNAL) + @RBuiltin(name = "bindingIsActive", kind = INTERNAL, parameterNames = {"sym", "env"}) public abstract static class BindingIsActive extends RInvisibleBuiltinNode { @SuppressWarnings("unused") @Specialization(order = 0) diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java index b0d39669a1da54db1744a46e15e225faae4d3f63..ed83767b2b2fe4220bbe5d5d2e75900c352cc151 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/FileFunctions.java @@ -41,9 +41,14 @@ import com.oracle.truffle.r.runtime.data.model.*; public class FileFunctions { - @RBuiltin(name = "file.create", kind = INTERNAL) + @RBuiltin(name = "file.create", kind = INTERNAL, parameterNames = {"...", "showWarnings"}) public abstract static class FileCreate extends RBuiltinNode { + @Override + public RNode[] getParameterValues() { + return new RNode[]{ConstantNode.create(RMissing.instance), ConstantNode.create(RRuntime.LOGICAL_TRUE)}; + } + @Specialization public Object doFileCreate(RAbstractStringVector vec, byte showWarnings) { controlVisibility(); @@ -75,7 +80,7 @@ public class FileFunctions { } } - @RBuiltin(name = "file.info", kind = INTERNAL) + @RBuiltin(name = "file.info", kind = INTERNAL, parameterNames = {"fn"}) public abstract static class FileInfo extends RBuiltinNode { private static final String[] NAMES = new String[]{"size", "isdir", "mode", "mtime", "ctime", "atime", "uid", "gid", "uname", "grname"}; private static final RStringVector NAMES_VECTOR = RDataFactory.createStringVector(NAMES, RDataFactory.COMPLETE_VECTOR); @@ -151,7 +156,7 @@ public class FileFunctions { } } - @RBuiltin(name = "file.link", kind = INTERNAL) + @RBuiltin(name = "file.link", kind = INTERNAL, parameterNames = {"from", "to"}) public abstract static class FileLink extends FileLinkAdaptor { @Specialization public Object doFileLink(VirtualFrame frame, RAbstractStringVector vecFrom, RAbstractStringVector vecTo) { @@ -166,7 +171,7 @@ public class FileFunctions { } } - @RBuiltin(name = "file.symlink", kind = INTERNAL) + @RBuiltin(name = "file.symlink", kind = INTERNAL, parameterNames = {"from", "to"}) public abstract static class FileSymLink extends FileLinkAdaptor { @Specialization public Object doFileSymLink(VirtualFrame frame, RAbstractStringVector vecFrom, RAbstractStringVector vecTo) { @@ -181,7 +186,7 @@ public class FileFunctions { } } - @RBuiltin(name = "file.remove", kind = INTERNAL) + @RBuiltin(name = "file.remove", kind = INTERNAL, parameterNames = {"..."}) public abstract static class FileRemove extends RBuiltinNode { @Specialization @@ -211,7 +216,7 @@ public class FileFunctions { } } - @RBuiltin(name = "file.rename", kind = INTERNAL) + @RBuiltin(name = "file.rename", kind = INTERNAL, parameterNames = {"from", "to"}) public abstract static class FileRename extends RBuiltinNode { @Specialization public Object doFileRename(VirtualFrame frame, RAbstractStringVector vecFrom, RAbstractStringVector vecTo) { @@ -246,7 +251,7 @@ public class FileFunctions { } } - @RBuiltin(name = "file.exists", kind = INTERNAL) + @RBuiltin(name = "file.exists", kind = INTERNAL, parameterNames = {"..."}) public abstract static class FileExists extends RBuiltinNode { @Specialization @@ -274,8 +279,14 @@ public class FileFunctions { } } - @RBuiltin(name = "list.files", kind = INTERNAL) + @RBuiltin(name = "list.files", kind = INTERNAL, parameterNames = {"path", "pattern", "all.files", "full.names", "recursive", "ignore.case", "include.dirs", "no.."}) public abstract static class ListFiles extends RBuiltinNode { + @Override + public RNode[] getParameterValues() { + return new RNode[]{ConstantNode.create("."), ConstantNode.create(RNull.instance), ConstantNode.create(RRuntime.LOGICAL_FALSE), ConstantNode.create(RRuntime.LOGICAL_FALSE), + ConstantNode.create(RRuntime.LOGICAL_FALSE), ConstantNode.create(RRuntime.LOGICAL_FALSE), ConstantNode.create(RRuntime.LOGICAL_FALSE), + ConstantNode.create(RRuntime.LOGICAL_FALSE)}; + } // @formatter:off @SuppressWarnings("unused") @@ -322,14 +333,8 @@ public class FileFunctions { // TODO make .Internal, when resolving .Platform in files.R is fixed // TODO handle the general case, which is similar to paste - @RBuiltin(name = "file.path", kind = SUBSTITUTE) + @RBuiltin(name = "file.path", kind = SUBSTITUTE, parameterNames = {"...", "fsep"}) public abstract static class FilePath extends RBuiltinNode { - private static final Object[] PARAMETER_NAMES = new Object[]{"...", "fsep"}; - - @Override - public Object[] getParameterNames() { - return PARAMETER_NAMES; - } @Override public RNode[] getParameterValues() { @@ -430,7 +435,7 @@ public class FileFunctions { } } - @RBuiltin(name = "dirname", kind = INTERNAL) + @RBuiltin(name = "dirname", kind = INTERNAL, parameterNames = {"path"}) public abstract static class DirName extends XyzNameAdapter { private static class ParentPathFunction extends XyzNameAdapter.PathFunction { @@ -451,7 +456,7 @@ public class FileFunctions { } } - @RBuiltin(name = "basename", kind = INTERNAL) + @RBuiltin(name = "basename", kind = INTERNAL, parameterNames = {"path"}) public abstract static class BaseName extends XyzNameAdapter { private static class BasePathFunction extends XyzNameAdapter.PathFunction { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Force.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Force.java index 7cbf71d6c69545e56e3da0b5c8224f4d8ae9db1b..96e210be72dc730d5b304de4f25f8cf8b3444f83 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Force.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Force.java @@ -30,7 +30,7 @@ import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; -@RBuiltin(name = "force", kind = SUBSTITUTE) +@RBuiltin(name = "force", kind = SUBSTITUTE, parameterNames = {"x"}) // TODO revert to R (promises) public abstract class Force extends RBuiltinNode { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/FrameFunctions.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/FrameFunctions.java index 3cb08797ab832af09688617b0efc2aaa1b54870b..7dd90066808e81a409bfedc31326c57b9aa35342 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/FrameFunctions.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/FrameFunctions.java @@ -27,6 +27,8 @@ import static com.oracle.truffle.r.runtime.RBuiltinKind.*; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.frame.FrameInstance.FrameAccess; +import com.oracle.truffle.r.nodes.*; +import com.oracle.truffle.r.nodes.access.*; import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; @@ -73,8 +75,14 @@ public class FrameFunctions { } } - @RBuiltin(name = "sys.frame", kind = INTERNAL) + @RBuiltin(name = "sys.frame", kind = INTERNAL, parameterNames = {"which"}) public abstract static class SysFrame extends FrameHelper { + + @Override + public RNode[] getParameterValues() { + return new RNode[]{ConstantNode.create(0)}; + } + @Specialization() public REnvironment sysFrame(VirtualFrame frame, int nd) { controlVisibility(); @@ -95,8 +103,14 @@ public class FrameFunctions { } } - @RBuiltin(name = "sys.parent", kind = INTERNAL) + @RBuiltin(name = "sys.parent", kind = INTERNAL, parameterNames = {"n"}) public abstract static class SysParent extends RBuiltinNode { + + @Override + public RNode[] getParameterValues() { + return new RNode[]{ConstantNode.create(1)}; + } + @Specialization() public int sysParent(int nd) { controlVisibility(); @@ -115,8 +129,14 @@ public class FrameFunctions { } } - @RBuiltin(name = "sys.function", kind = INTERNAL) + @RBuiltin(name = "sys.function", kind = INTERNAL, parameterNames = {"which"}) public abstract static class SysFunction extends FrameHelper { + + @Override + public RNode[] getParameterValues() { + return new RNode[]{ConstantNode.create(0)}; + } + @Specialization() public Object sysFunction(VirtualFrame frame, int nd) { controlVisibility(); @@ -162,8 +182,14 @@ public class FrameFunctions { /** * The environment of the caller of the function that called parent.frame. */ - @RBuiltin(name = "parent.frame", kind = INTERNAL) + @RBuiltin(name = "parent.frame", kind = INTERNAL, parameterNames = {"n"}) public abstract static class ParentFrame extends FrameHelper { + + @Override + public RNode[] getParameterValues() { + return new RNode[]{ConstantNode.create(1)}; + } + @Specialization() public REnvironment parentFrame(VirtualFrame frame, double nd) { controlVisibility(); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/GetText.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/GetText.java index a18b721f3debbfc2383d4c5b6579a23f9e9c26c7..d8fbd34d88f8c67d4f57d346cd7f8bb8ce442a2d 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/GetText.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/GetText.java @@ -25,16 +25,25 @@ package com.oracle.truffle.r.nodes.builtin.base; import static com.oracle.truffle.r.runtime.RBuiltinKind.*; import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.r.nodes.*; +import com.oracle.truffle.r.nodes.access.*; import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.runtime.*; +import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.*; @SuppressWarnings("unused") -@RBuiltin(name = "gettext", kind = INTERNAL) +@RBuiltin(name = "gettext", kind = INTERNAL, parameterNames = {"...", "domain"}) public abstract class GetText extends RBuiltinNode { + @Override + public RNode[] getParameterValues() { + // ..., domain = NULL + return new RNode[]{ConstantNode.create(RMissing.instance), ConstantNode.create(RNull.instance)}; + } + @Specialization - RAbstractVector getText(Object domain, RAbstractVector vector) { + RAbstractVector getText(RAbstractVector vector, Object domain) { // no translation done at this point return vector; } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/GrepFunctions.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/GrepFunctions.java index 905e2152576443a3e52036748d99d7cadf8bdbac..00d6d922e75c83bbb248032e82dc4b227e9bf00b 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/GrepFunctions.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/GrepFunctions.java @@ -29,6 +29,8 @@ import java.util.regex.*; import com.oracle.truffle.api.CompilerDirectives.SlowPath; import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.r.nodes.*; +import com.oracle.truffle.r.nodes.access.*; import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; @@ -85,9 +87,18 @@ public class GrepFunctions { } } - @RBuiltin(name = "grep", kind = INTERNAL) + @RBuiltin(name = "grep", kind = INTERNAL, parameterNames = {"pattern", "x", "ignore.case", "perl", "value", "fixed", "useBytes", "invert"}) public abstract static class Grep extends ExtraArgsChecker { + @Override + public RNode[] getParameterValues() { + // pattern, x, ignore.case = FALSE, perl = FALSE, value = FALSE, fixed = FALSE, useBytes + // = FALSE, invert = FALSE + return new RNode[]{ConstantNode.create(RMissing.instance), ConstantNode.create(RMissing.instance), ConstantNode.create(RRuntime.LOGICAL_FALSE), + ConstantNode.create(RRuntime.LOGICAL_FALSE), ConstantNode.create(RRuntime.LOGICAL_FALSE), ConstantNode.create(RRuntime.LOGICAL_FALSE), + ConstantNode.create(RRuntime.LOGICAL_FALSE), ConstantNode.create(RRuntime.LOGICAL_FALSE)}; + } + @Specialization public RIntVector grep(String patternArg, RAbstractStringVector vector, byte ignoreCase, byte value, byte perl, byte fixed, byte useBytes, byte invert) { controlVisibility(); @@ -126,9 +137,16 @@ public class GrepFunctions { } } - @RBuiltin(name = "grepl", kind = INTERNAL) + @RBuiltin(name = "grepl", kind = INTERNAL, parameterNames = {"pattern", "x", "ignore.case", "perl", "fixed", "useBytes"}) public abstract static class GrepL extends ExtraArgsChecker { + @Override + public RNode[] getParameterValues() { + // pattern, x, ignore.case = FALSE, perl = FALSE, fixed = FALSE, useBytes = FALSE + return new RNode[]{ConstantNode.create(RMissing.instance), ConstantNode.create(RMissing.instance), ConstantNode.create(RRuntime.LOGICAL_FALSE), + ConstantNode.create(RRuntime.LOGICAL_FALSE), ConstantNode.create(RRuntime.LOGICAL_FALSE), ConstantNode.create(RRuntime.LOGICAL_FALSE)}; + } + @Specialization public Object grep(String patternArg, RAbstractStringVector vector, byte ignoreCase, byte perl, byte fixed, byte useBytes) { controlVisibility(); @@ -142,9 +160,17 @@ public class GrepFunctions { } } - @RBuiltin(name = "sub", kind = INTERNAL) + @RBuiltin(name = "sub", kind = INTERNAL, parameterNames = {"pattern", "replacement", "x", "ignore.case", "perl", "fixed", "useBytes"}) public abstract static class Sub extends ExtraArgsChecker { + @Override + public RNode[] getParameterValues() { + // pattern, replacement, x, ignore.case = FALSE, perl = FALSE, fixed = FALSE, useBytes = +// FALSE + return new RNode[]{ConstantNode.create(RMissing.instance), ConstantNode.create(RMissing.instance), ConstantNode.create(RMissing.instance), ConstantNode.create(RRuntime.LOGICAL_FALSE), + ConstantNode.create(RRuntime.LOGICAL_FALSE), ConstantNode.create(RRuntime.LOGICAL_FALSE), ConstantNode.create(RRuntime.LOGICAL_FALSE)}; + } + @Specialization(order = 1) public String sub(String patternArg, String replacement, String x, byte ignoreCase, byte perl, byte fixed, byte useBytes) { controlVisibility(); @@ -194,9 +220,17 @@ public class GrepFunctions { } } - @RBuiltin(name = "gsub", kind = INTERNAL) + @RBuiltin(name = "gsub", kind = INTERNAL, parameterNames = {"pattern", "replacement", "x", "ignore.case", "perl", "fixed", "useBytes"}) public abstract static class GSub extends Sub { + @Override + public RNode[] getParameterValues() { + // pattern, replacement, x, ignore.case = FALSE, perl = FALSE, fixed = FALSE, useBytes = +// FALSE + return new RNode[]{ConstantNode.create(RMissing.instance), ConstantNode.create(RMissing.instance), ConstantNode.create(RMissing.instance), ConstantNode.create(RRuntime.LOGICAL_FALSE), + ConstantNode.create(RRuntime.LOGICAL_FALSE), ConstantNode.create(RRuntime.LOGICAL_FALSE), ConstantNode.create(RRuntime.LOGICAL_FALSE)}; + } + @Specialization(order = 1) @Override public String sub(String patternArg, String replacement, String x, byte ignoreCase, byte perl, byte fixed, byte useBytes) { @@ -222,9 +256,16 @@ public class GrepFunctions { } } - @RBuiltin(name = "regexpr", kind = INTERNAL) + @RBuiltin(name = "regexpr", kind = INTERNAL, parameterNames = {"pattern", "text", "ignore.case", "perl", "fixed", "useBytes"}) public abstract static class Regexp extends ExtraArgsChecker { + @Override + public RNode[] getParameterValues() { + // pattern, text, ignore.case = FALSE, perl = FALSE, fixed = FALSE, useBytes = FALSE + return new RNode[]{ConstantNode.create(RMissing.instance), ConstantNode.create(RMissing.instance), ConstantNode.create(RRuntime.LOGICAL_FALSE), + ConstantNode.create(RRuntime.LOGICAL_FALSE), ConstantNode.create(RRuntime.LOGICAL_FALSE), ConstantNode.create(RRuntime.LOGICAL_FALSE)}; + } + @Specialization public Object regexp(String patternArg, RAbstractStringVector vector, byte ignoreCase, byte perl, byte fixed, byte useBytes) { controlVisibility(); @@ -257,9 +298,16 @@ public class GrepFunctions { } } - @RBuiltin(name = "gregexpr", kind = INTERNAL) + @RBuiltin(name = "gregexpr", kind = INTERNAL, parameterNames = {"pattern", "text", "ignore.case", "perl", "fixed", "useBytes"}) public abstract static class Gregexpr extends Regexp { + @Override + public RNode[] getParameterValues() { + // pattern, text, ignore.case = FALSE, perl = FALSE, fixed = FALSE, useBytes = FALSE + return new RNode[]{ConstantNode.create(RMissing.instance), ConstantNode.create(RMissing.instance), ConstantNode.create(RRuntime.LOGICAL_FALSE), + ConstantNode.create(RRuntime.LOGICAL_FALSE), ConstantNode.create(RRuntime.LOGICAL_FALSE), ConstantNode.create(RRuntime.LOGICAL_FALSE)}; + } + @Specialization @Override public Object regexp(String patternArg, RAbstractStringVector vector, byte ignoreCase, byte perl, byte fixed, byte useBytes) { @@ -283,8 +331,18 @@ public class GrepFunctions { } } - @RBuiltin(name = "agrep", kind = INTERNAL) + @RBuiltin(name = "agrep", kind = INTERNAL, parameterNames = {"pattern", "x", "max.distance", "costs", "ignore.case", "value", "fixed", "useBytes"}) public abstract static class AGrep extends ExtraArgsChecker { + + @Override + public RNode[] getParameterValues() { + // pattern, x, max.distance = 0.1, costs = NULL, ignore.case = FALSE, value = FALSE, + // fixed = TRUE, useBytes = FALSE + return new RNode[]{ConstantNode.create(RMissing.instance), ConstantNode.create(RMissing.instance), ConstantNode.create(0.1d), ConstantNode.create(RNull.instance), + ConstantNode.create(RRuntime.LOGICAL_FALSE), ConstantNode.create(RRuntime.LOGICAL_FALSE), ConstantNode.create(RRuntime.LOGICAL_TRUE), + ConstantNode.create(RRuntime.LOGICAL_FALSE)}; + } + @SuppressWarnings("unused") @Specialization public Object aGrep(String patternArg, RAbstractStringVector vector, byte ignoreCase, byte value, RIntVector costs, RDoubleVector bounds, byte useBytes, byte fixed) { @@ -312,8 +370,17 @@ public class GrepFunctions { } } - @RBuiltin(name = "agrepl", kind = INTERNAL) + @RBuiltin(name = "agrepl", kind = INTERNAL, parameterNames = {"pattern", "x", "max.distance", "costs", "ignore.case", "fixed", "useBytes"}) public abstract static class AGrepL extends ExtraArgsChecker { + + @Override + public RNode[] getParameterValues() { + // pattern, x, max.distance = 0.1, costs = NULL, ignore.case = FALSE, fixed = TRUE, +// useBytes = FALSE + return new RNode[]{ConstantNode.create(RMissing.instance), ConstantNode.create(RMissing.instance), ConstantNode.create(0.1d), ConstantNode.create(RNull.instance), + ConstantNode.create(RRuntime.LOGICAL_FALSE), ConstantNode.create(RRuntime.LOGICAL_TRUE), ConstantNode.create(RRuntime.LOGICAL_FALSE)}; + } + @SuppressWarnings("unused") @Specialization public Object aGrep(String patternArg, RAbstractStringVector vector, byte ignoreCase, RIntVector costs, RDoubleVector bounds, byte useBytes, byte fixed) { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Identical.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Identical.java index 1ac7bfcc4f14ac2917292eb9509b245e6cfe2a0d..d01d8b29fca481a4fe6e7f09158708f9c088aaee 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Identical.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Identical.java @@ -25,6 +25,8 @@ package com.oracle.truffle.r.nodes.builtin.base; import static com.oracle.truffle.r.runtime.RBuiltinKind.*; import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.r.nodes.*; +import com.oracle.truffle.r.nodes.access.*; import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; @@ -34,8 +36,13 @@ import com.oracle.truffle.r.runtime.data.model.*; * Internal part of {@code identical}. The default values for args after {@code x} and {@code y} are * all set to {@code TRUE/FALSE} by the R wrapper. */ -@RBuiltin(name = "identical", kind = INTERNAL) +@RBuiltin(name = "identical", kind = INTERNAL, parameterNames = {"x", "y", "num.eq", "single.NA", "attrib.as.set", "ignore.bytecode", "ignore.environment"}) public abstract class Identical extends RBuiltinNode { + @Override + public RNode[] getParameterValues() { + return new RNode[]{ConstantNode.create(RMissing.instance), ConstantNode.create(RMissing.instance), ConstantNode.create(RRuntime.LOGICAL_TRUE), ConstantNode.create(RRuntime.LOGICAL_TRUE), + ConstantNode.create(RRuntime.LOGICAL_TRUE), ConstantNode.create(RRuntime.LOGICAL_TRUE), ConstantNode.create(RRuntime.LOGICAL_FALSE)}; + } @Specialization(order = 0) public byte doInternalIdentical(byte x, byte y, diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Ifelse.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Ifelse.java index 7b0fe8b6c4cea4568fa1c2720b1a71029ba43719..f9bdf1a14776229f5ef0e94863e2bad9b5ed4761 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Ifelse.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Ifelse.java @@ -31,7 +31,7 @@ import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.ops.na.*; @SuppressWarnings("unused") -@RBuiltin(name = "ifelse", kind = SUBSTITUTE) +@RBuiltin(name = "ifelse", kind = SUBSTITUTE, parameterNames = {"test", "yes", "no"}) // TODO revert to R public abstract class Ifelse extends RBuiltinNode { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/IntegerBuiltin.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/IntegerBuiltin.java index 757432f6cec50c3682da90f8d2bf5bd06dadf63c..9d2662be2945694d4c6204095c9944b0338f6914 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/IntegerBuiltin.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/IntegerBuiltin.java @@ -25,14 +25,22 @@ package com.oracle.truffle.r.nodes.builtin.base; import static com.oracle.truffle.r.runtime.RBuiltinKind.*; import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.r.nodes.*; +import com.oracle.truffle.r.nodes.access.*; import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; -@RBuiltin(name = "integer", kind = SUBSTITUTE) +@RBuiltin(name = "integer", kind = SUBSTITUTE, parameterNames = {"length"}) // TODO revert to R public abstract class IntegerBuiltin extends RBuiltinNode { + @Override + public RNode[] getParameterValues() { + // length = 0 + return new RNode[]{ConstantNode.create(0)}; + } + @Specialization public Object createIntegerVector(int length) { controlVisibility(); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/IsDataFrame.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/IsDataFrame.java index 15ab795772522161ef91c319673d088107029074..55b4fd846f01d4502f9663ced8d4dff6bc72d081 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/IsDataFrame.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/IsDataFrame.java @@ -30,7 +30,7 @@ import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.*; -@RBuiltin(name = "is.data.frame", kind = SUBSTITUTE) +@RBuiltin(name = "is.data.frame", kind = SUBSTITUTE, parameterNames = {"x"}) // TODO revert to R @SuppressWarnings("unused") public abstract class IsDataFrame extends RBuiltinNode { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/IsTRUE.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/IsTRUE.java index 371bac1b1095b2b128a77124d497f3c09744231f..f0daa8e0ec579de9f1ac578d6dbb7c794f5e95dd 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/IsTRUE.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/IsTRUE.java @@ -33,7 +33,7 @@ import com.oracle.truffle.r.runtime.data.*; * Arguably unnecessary when {@code identical} is implemented, as {@code isTRUE(x)} is defined to be * {@code identical(TRUE, x}. */ -@RBuiltin(name = "isTRUE", kind = SUBSTITUTE) +@RBuiltin(name = "isTRUE", kind = SUBSTITUTE, parameterNames = {"x"}) // TODO revert to R public abstract class IsTRUE extends RBuiltinNode { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/IsVector.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/IsVector.java index b0b214140ccd1f77641c6e14dba854a5ffe024aa..5b4e799022fa24826e42ad4e40efb25a90874f1e 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/IsVector.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/IsVector.java @@ -25,14 +25,22 @@ package com.oracle.truffle.r.nodes.builtin.base; import static com.oracle.truffle.r.runtime.RBuiltinKind.*; import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.r.nodes.*; +import com.oracle.truffle.r.nodes.access.*; import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.*; -@RBuiltin(name = "is.vector", kind = PRIMITIVE, parameterNames = {"x"}) +@RBuiltin(name = "is.vector", kind = PRIMITIVE, parameterNames = {"x", "mode"}) public abstract class IsVector extends RBuiltinNode { + @Override + public RNode[] getParameterValues() { + // x, mode = "any" + return new RNode[]{ConstantNode.create(RMissing.instance), ConstantNode.create(RRuntime.TYPE_ANY)}; + } + @SuppressWarnings("unused") @Specialization(order = 1) public byte isNull(RNull operand, Object mode) { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/LogicalBuiltin.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/LogicalBuiltin.java index bebd084a9a7fcf06b2871c8ff10f84fde7d16f6a..ea5d6a5b0bf09c0acac25d4de7f0c56a94778716 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/LogicalBuiltin.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/LogicalBuiltin.java @@ -25,14 +25,21 @@ package com.oracle.truffle.r.nodes.builtin.base; import static com.oracle.truffle.r.runtime.RBuiltinKind.*; import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.r.nodes.*; +import com.oracle.truffle.r.nodes.access.*; import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; -@RBuiltin(name = "logical", kind = SUBSTITUTE) -// TODO revert to R +@RBuiltin(name = "logical", kind = SUBSTITUTE, parameterNames = {"length"}) +// TODO Implement in R public abstract class LogicalBuiltin extends RBuiltinNode { + @Override + public RNode[] getParameterValues() { + return new RNode[]{ConstantNode.create(0)}; + } + @Specialization public Object createLogicalVector(int length) { controlVisibility(); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Ls.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Ls.java index 8ace39017634d203aea89a0a423df5d0e9d90f16..b3e11266c4e4a1cf65124036310039471a94bdde 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Ls.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Ls.java @@ -80,7 +80,6 @@ public abstract class Ls extends RBuiltinNode { @SuppressWarnings("unused") public RStringVector ls(VirtualFrame frame, RMissing name, int pos, RMissing envir, byte allNames, String pattern) { controlVisibility(); - // this is the ls() specialisation return REnvironment.createLsCurrent(frame.materialize()).ls(RRuntime.fromLogical(allNames), compile(pattern)); } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/MatMult.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/MatMult.java index 0dfb420ff2dcce4f2180f20c85ff577038563834..88645de0872deea1c72f53e85714fb8e4bb90970 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/MatMult.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/MatMult.java @@ -35,7 +35,7 @@ import com.oracle.truffle.r.runtime.data.model.*; import com.oracle.truffle.r.runtime.ops.*; import com.oracle.truffle.r.runtime.ops.na.*; -@RBuiltin(name = "%*%", kind = PRIMITIVE) +@RBuiltin(name = "%*%", kind = PRIMITIVE, parameterNames = {"", ""}) public abstract class MatMult extends RBuiltinNode { @Child protected BinaryArithmeticNode mult = BinaryArithmeticNode.create(BinaryArithmetic.MULTIPLY); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Match.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Match.java index 65f8027c7cdca74ba96c8f610c9e0b61f22bbff3..b42997be2966ae1767a48b5f77770857fbf4dbaa 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Match.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Match.java @@ -27,6 +27,8 @@ import static com.oracle.truffle.r.runtime.RBuiltinKind.*; import com.oracle.truffle.api.*; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.r.nodes.*; +import com.oracle.truffle.r.nodes.access.*; import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.nodes.unary.*; import com.oracle.truffle.r.runtime.*; @@ -34,12 +36,18 @@ import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.*; import com.oracle.truffle.r.runtime.ops.*; -@RBuiltin(name = "match", kind = INTERNAL) +@RBuiltin(name = "match", kind = INTERNAL, parameterNames = {"x", "table", "nomatch", "incomparables"}) public abstract class Match extends RBuiltinNode { @Child private CastStringNode castString; @Child private CastIntegerNode castInt; + @Override + public RNode[] getParameterValues() { + // x, table, nomatch = NA_integer_, incomparables = NULL + return new RNode[]{ConstantNode.create(RMissing.instance), ConstantNode.create(RMissing.instance), ConstantNode.create(RRuntime.INT_NA), ConstantNode.create(RNull.instance)}; + } + private String castString(VirtualFrame frame, Object operand) { if (castString == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/NChar.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/NChar.java index 291bfaa886888e42182a6e0f66de15a4e05842e0..8a59a6b4a1e753752a782a354d08c64e6b41d622 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/NChar.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/NChar.java @@ -27,6 +27,8 @@ import static com.oracle.truffle.r.runtime.RBuiltinKind.*; import com.oracle.truffle.api.*; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.r.nodes.*; +import com.oracle.truffle.r.nodes.access.*; import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.nodes.unary.*; import com.oracle.truffle.r.nodes.unary.ConvertNode.ConversionFailedException; @@ -35,11 +37,17 @@ import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.*; // TODO interpret "type" and "allowNA" arguments -@RBuiltin(name = "nchar", kind = INTERNAL) +@RBuiltin(name = "nchar", kind = INTERNAL, parameterNames = {"x", "type", "allowNA"}) public abstract class NChar extends RBuiltinNode { @Child CastStringNode convertString; + @Override + public RNode[] getParameterValues() { + // x, type = "chars", allowNA = FALSE + return new RNode[]{ConstantNode.create(RMissing.instance), ConstantNode.create("chars"), ConstantNode.create(RRuntime.LOGICAL_FALSE)}; + } + private String coerceContent(VirtualFrame frame, Object content) { if (convertString == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/NGetText.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/NGetText.java index 729410572234b2c8e373bfb6e72032bcd042ac05..b42ef7a8f7c7c382985439225bf2277c1d6c13ed 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/NGetText.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/NGetText.java @@ -27,6 +27,7 @@ import static com.oracle.truffle.r.runtime.RBuiltinKind.*; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.r.nodes.*; +import com.oracle.truffle.r.nodes.access.*; import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.nodes.unary.*; import com.oracle.truffle.r.runtime.*; @@ -34,9 +35,15 @@ import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.*; @SuppressWarnings("unused") -@RBuiltin(name = "ngettext", kind = INTERNAL) +@RBuiltin(name = "ngettext", kind = INTERNAL, parameterNames = {"n", "msg1", "msg2", "domain"}) public abstract class NGetText extends RBuiltinNode { + @Override + public RNode[] getParameterValues() { + // n, msg1, msg2, domain = NULL + return new RNode[]{ConstantNode.create(RMissing.instance), ConstantNode.create(RMissing.instance), ConstantNode.create(RMissing.instance), ConstantNode.create(RNull.instance)}; + } + @CreateCast("arguments") public RNode[] createCastValue(RNode[] children) { return new RNode[]{CastIntegerNodeFactory.create(children[0], false, false, false), children[1], children[2], children[3]}; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/PMatch.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/PMatch.java index de1225ae96e727c9a77076fdca13fc3c133369cc..741387cf1aad96d193caf9175cea00cca0133e72 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/PMatch.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/PMatch.java @@ -26,15 +26,21 @@ import static com.oracle.truffle.r.runtime.RBuiltinKind.*; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.r.nodes.*; +import com.oracle.truffle.r.nodes.access.*; import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.nodes.unary.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.*; -@RBuiltin(name = "pmatch", kind = INTERNAL) +@RBuiltin(name = "pmatch", kind = INTERNAL, parameterNames = {"x", "table", "nomatch", "duplicates.ok"}) public abstract class PMatch extends RBuiltinNode { + @Override + public RNode[] getParameterValues() { + return new RNode[]{ConstantNode.create(RMissing.instance), ConstantNode.create(RMissing.instance), ConstantNode.create(RRuntime.INT_NA), ConstantNode.create(RRuntime.LOGICAL_FALSE)}; + } + @CreateCast("arguments") public RNode[] castArguments(RNode[] arguments) { arguments[2] = CastIntegerNodeFactory.create(arguments[2], false, false, false); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Paste.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Paste.java index a2d71668e36355dcbf37d53efa74eb9e4ac3ca15..572853ace4afea4ff2bf78765f579b0e31bf8f38 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Paste.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Paste.java @@ -28,18 +28,26 @@ import com.oracle.truffle.api.*; import com.oracle.truffle.api.CompilerDirectives.SlowPath; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.r.nodes.*; +import com.oracle.truffle.r.nodes.access.*; import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.nodes.unary.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; -@RBuiltin(name = "paste", kind = INTERNAL) +@RBuiltin(name = "paste", kind = INTERNAL, parameterNames = {"...", "sep", "collapse"}) public abstract class Paste extends RBuiltinNode { public abstract Object executeList(VirtualFrame frame, RList value, String sep, Object collapse); @Child CastStringNode castCharacterNode; + @Override + public RNode[] getParameterValues() { + // ..., sep = " ", collapse = NULL + return new RNode[]{ConstantNode.create(RMissing.instance), ConstantNode.create(" "), ConstantNode.create(RNull.instance)}; + } + private String castCharacter(VirtualFrame frame, Object o) { if (castCharacterNode == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); @@ -61,6 +69,11 @@ public abstract class Paste extends RBuiltinNode { } } + @Specialization + public RStringVector pasteList(VirtualFrame frame, RList values, String sep, RNull collapse) { + return pasteList(frame, values, sep, (Object) collapse); + } + @Specialization public RStringVector pasteList(VirtualFrame frame, RList values, String sep, Object collapse) { controlVisibility(); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Paste0.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Paste0.java index 6e14c5d0d814da4c817ffce51e742fb8b7147e04..46c137e40e599e63f1e3b3637e8be3e7577dd606 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Paste0.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Paste0.java @@ -28,6 +28,7 @@ import com.oracle.truffle.api.*; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.r.nodes.*; +import com.oracle.truffle.r.nodes.access.*; import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; @@ -36,11 +37,17 @@ import com.oracle.truffle.r.runtime.data.*; * A straightforward implementation in terms of {@code paste} that doesn't attempt to be more * efficient. */ -@RBuiltin(name = "paste0", kind = INTERNAL) +@RBuiltin(name = "paste0", kind = INTERNAL, parameterNames = {"...", "collapse"}) public abstract class Paste0 extends RBuiltinNode { @Child Paste pasteNode; + @Override + public RNode[] getParameterValues() { + // ..., collapse = NULL + return new RNode[]{ConstantNode.create(RMissing.instance), ConstantNode.create(RNull.instance)}; + } + private Object paste(VirtualFrame frame, RList values, Object collapse) { if (pasteNode == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Print.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Print.java index 84a7fbf4aa90e4917da741f30b5899b91068cd8e..72c822528763c00b09525f4046049bfc39754684 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Print.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Print.java @@ -36,9 +36,9 @@ import com.oracle.truffle.r.runtime.data.*; // TODO revert to R public abstract class Print extends RInvisibleBuiltinNode { - private static final String[] PARAMETER_NAMES = new String[]{"x"}; + private static final String[] PARAMETER_NAMES = new String[]{"x", "quote"}; - private static final RNode[] PARAMETER_VALUES = new RNode[]{ConstantNode.create(RNull.instance)}; + private static final RNode[] PARAMETER_VALUES = new RNode[]{ConstantNode.create(RNull.instance), ConstantNode.create(RRuntime.TRUE)}; @Child protected PrettyPrinterNode prettyPrinter = PrettyPrinterNodeFactory.create(null, null, null, false); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Quit.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Quit.java index 4f50594ab18481c6e01c0c12a0268706432dd428..4d103aaaa9ae4f5befe11407016b166d0f5464d7 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Quit.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Quit.java @@ -31,7 +31,7 @@ import com.oracle.truffle.r.nodes.unary.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; -@RBuiltin(name = "quit", kind = INTERNAL) +@RBuiltin(name = "quit", kind = INTERNAL, parameterNames = {"save", "status", "runLast"}) public abstract class Quit extends RInvisibleBuiltinNode { @CreateCast("arguments") diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/R/grep.R b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/R/grep.R index 3ece8772eb7d3fc5037231a300ea971e013ab5b0..bf2f267b43783b717fb1e8e941f4bcb5c0f1d42e 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/R/grep.R +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/R/grep.R @@ -35,8 +35,7 @@ grepl <- fixed = FALSE, useBytes = FALSE) { if(!is.character(x)) x <- as.character(x) - .Internal(grepl(as.character(pattern), x, ignore.case, FALSE, - perl, fixed, useBytes, FALSE)) + .Internal(grepl(as.character(pattern), x, ignore.case, perl, fixed, useBytes)) } sub <- diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/R/paste.R b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/R/paste.R index 45ea8c5ded41271208b740a31f2354f3d2f7c6cd..70581a53b184282c4f315a70145761708360adc8 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/R/paste.R +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/R/paste.R @@ -17,9 +17,9 @@ # http://www.r-project.org/Licenses/ paste <- function (..., sep = " ", collapse = NULL) - .Internal(paste(list(...), sep, collapse)) + .Internal(paste(list(...), sep = sep, collapse = collapse)) paste0 <- function(..., collapse = NULL) - .Internal(paste0(list(...), collapse)) + .Internal(paste0(list(...), collapse = collapse)) ##=== Could we extend paste(.) to (optionally) accept a ## 2-vector for collapse ? With the following functionality diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/R/stop.R b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/R/stop.R index 8c236b2c7e952db07e92adddec2115e7a7ed2782..289826b94022cd5d4961e68c83986b5218167359 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/R/stop.R +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/R/stop.R @@ -19,7 +19,7 @@ gettext <- function(..., domain = NULL) { args <- lapply(list(...), as.character) - .Internal(gettext(domain, unlist(args))) + .Internal(gettext(unlist(args), domain = domain)) } #bindtextdomain <- function(domain, dirname = NULL) diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/R/toString.R b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/R/toString.R new file mode 100644 index 0000000000000000000000000000000000000000..bcb6beeb05cdb1903376ca16230ebbd9c9276867 --- /dev/null +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/R/toString.R @@ -0,0 +1,32 @@ +# File src/library/base/R/toString.R +# Part of the R package, http://www.R-project.org +# +# Copyright (C) 1995-2012 The R Core Team +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program 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 for more details. +# +# A copy of the GNU General Public License is available at +# http://www.r-project.org/Licenses/ + +#functions to convert their first argument to strings +toString <- function(x, ...) UseMethod("toString") + +toString.default <- function(x, width = NULL, ...) +{ + string <- paste(x, collapse=", ") + if( missing(width) || is.null(width) || width == 0) return(string) + if( width < 0 ) stop("'width' must be positive") + if(nchar(string, type = "w") > width) { + width <- max(6, width) ## Leave something! + string <- paste0(strtrim(string, width - 4), "....") + } + string +} diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/RNGFunctions.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/RNGFunctions.java index ac425a3d94c64713dfe5ba0ee8f62b3d9a924095..3a9225288df8441ad71193208db87833d6e7eca8 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/RNGFunctions.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/RNGFunctions.java @@ -27,6 +27,8 @@ import static com.oracle.truffle.r.runtime.RBuiltinKind.*; import com.oracle.truffle.api.*; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.r.nodes.*; +import com.oracle.truffle.r.nodes.access.*; import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; @@ -35,8 +37,12 @@ import com.oracle.truffle.r.runtime.rng.*; import com.oracle.truffle.r.runtime.rng.RRNG.RNGException; public class RNGFunctions { - @RBuiltin(name = "set.seed", kind = INTERNAL) + @RBuiltin(name = "set.seed", kind = INTERNAL, parameterNames = {"seed", "kind", "normal.kind"}) public abstract static class SetSeed extends RInvisibleBuiltinNode { + @Override + public RNode[] getParameterValues() { + return new RNode[]{ConstantNode.create(RMissing.instance), ConstantNode.create(RNull.instance), ConstantNode.create(RNull.instance)}; + } @SuppressWarnings("unused") @Specialization(order = 0) diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/RSerialize.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/RSerialize.java index 69f15cef0ae3e443d6d49f9f06924059de0bd3d6..fcbdb3d3009a858fe3a73ed6615fea01a08d52e1 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/RSerialize.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/RSerialize.java @@ -192,9 +192,7 @@ public class RSerialize { case NAMESPACESXP: { RStringVector s = inStringVec(false); - addReadRef(findNamespace(s)); - - break; + return addReadRef(findNamespace(s)); } case VECSXP: { @@ -280,19 +278,20 @@ public class RSerialize { case PROMSXP: case DOTSXP: { Object attrItem = null; - RSymbol tagItem = null; + Object tagItem = null; if (flags.hasAttr) { attrItem = readItem(); } if (flags.hasTag) { - tagItem = (RSymbol) readItem(); + tagItem = readItem(); } Object carItem = readItem(); Object cdrItem = readItem(); - RPairList pairList = new RPairList(carItem, cdrItem, tagItem == null ? null : tagItem.getName(), type); + RPairList pairList = new RPairList(carItem, cdrItem, tagItem, type); result = pairList; if (attrItem != null) { + assert false; // Can't attribute a RPairList // pairList.setAttr(name, value); } @@ -300,11 +299,17 @@ public class RSerialize { // must convert the RPairList to a FastR RFunction // We could convert to an AST directly, but it is easier and more robust // to deparse and reparse. - String deparse = RDeparse.deparse((RPairList) result); + RPairList rpl = (RPairList) result; + String deparse = RDeparse.deparse(rpl); try { - // TODO is there a problem with the lexical environment? + /* + * The tag of result is the enclosing environment (from NAMESPACESEXP) for + * the function. However the namespace is locked, so can't just eval there + * (and overwrite the promise), so we fix the enclosing frame up on return. + */ RExpression expr = RContext.getEngine().parse(deparse); - RFunction func = (RFunction) RContext.getEngine().eval(expr, new REnvironment.NewEnv(REnvironment.globalEnv(), 0)); + RFunction func = (RFunction) RContext.getEngine().eval(expr, new REnvironment.NewEnv(REnvironment.emptyEnv(), 0)); + func.setEnclosingFrame(((REnvironment) rpl.getTag()).getFrame()); result = func; } catch (RContext.Engine.ParseException | PutException ex) { // denotes a deparse/eval error, which is an unrecoverable bug @@ -346,9 +351,10 @@ public class RSerialize { */ RPairList pl = (RPairList) attr; while (true) { - String tag = pl.getTag(); + RSymbol tagSym = (RSymbol) pl.getTag(); + String tag = tagSym.getName(); Object car = pl.car(); - // Eventually we can just use the generic setAttr + // TODO just use the generic setAttr if (tag.equals(RRuntime.NAMES_ATTR_KEY)) { vec.setNames(car); } else if (tag.equals(RRuntime.DIMNAMES_ATTR_KEY)) { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Repeat.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Repeat.java index 7f66b457ea4a15b4884b58475e92253514bfeb62..43574858d5aadb8e0be62a128e12506f47023334 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Repeat.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Repeat.java @@ -40,19 +40,12 @@ import com.oracle.truffle.r.runtime.data.model.*; // FIXME honour times in case length.out is given but NA // FIXME honour "each" parameter -@RBuiltin(name = "rep", kind = PRIMITIVE) +@RBuiltin(name = "rep", kind = PRIMITIVE, parameterNames = {"x", "times", "length.out", "each"}) public abstract class Repeat extends RBuiltinNode { - private static final String[] PARAMETER_NAMES = new String[]{"x", "times", "length.out", "each"}; - BranchProfile withNames = new BranchProfile(); BranchProfile noNames = new BranchProfile(); - @Override - public String[] getParameterNames() { - return PARAMETER_NAMES; - } - @Override public RNode[] getParameterValues() { return new RNode[]{ConstantNode.create(RMissing.instance), ConstantNode.create(1), ConstantNode.create(RMissing.instance), ConstantNode.create(1)}; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/RepeatInternal.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/RepeatInternal.java index 60a94a42f19391c177f121c9f1d08dd055786e7d..4bf888c5eec3c209c735baf145cab170597de13c 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/RepeatInternal.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/RepeatInternal.java @@ -34,7 +34,7 @@ import com.oracle.truffle.r.nodes.unary.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; -@RBuiltin(name = "rep.int", kind = SUBSTITUTE) +@RBuiltin(name = "rep.int", kind = SUBSTITUTE, parameterNames = {"x", "times"}) // TODO INTERNAL public abstract class RepeatInternal extends RBuiltinNode { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/RepeatLength.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/RepeatLength.java index d703ebacd1bd40f27cce24ec5952a2fe59bc9f04..9f6241b4fcd9cf216f48935f19a2fc6008acc03b 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/RepeatLength.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/RepeatLength.java @@ -23,14 +23,8 @@ import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.*; -@RBuiltin(name = "rep_len", kind = SUBSTITUTE) +@RBuiltin(name = "rep_len", kind = SUBSTITUTE, parameterNames = {"x", "length.out"}) public abstract class RepeatLength extends RBuiltinNode { - private final String[] PARAMETER_NAMES={"x", "length.out"}; - - @Override - protected Object[] getParameterNames() { - return PARAMETER_NAMES; - } @CreateCast("arguments") protected RNode[] castStatusArgument(RNode[] arguments) { @@ -124,6 +118,17 @@ public abstract class RepeatLength extends RBuiltinNode { return RDataFactory.createDoubleVector(array, value.isComplete()); } + @Specialization + public RStringVector repLen(RStringVector vectorToRepeat, int length) { + controlVisibility(); + String[] result = new String[length]; + int vectorToRepeatLength = vectorToRepeat.getLength(); + for (int i = 0; i < length; i++) { + result[i] = vectorToRepeat.getDataAt(i % vectorToRepeatLength); + } + return RDataFactory.createStringVector(result, true); + } + @Specialization public RRawVector repLen(RRawVector value, int length) { controlVisibility(); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Rev.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Rev.java index 80318605b086937eab096aad0a9a94ade55af53f..cf4c04b49b3cf76cb04a2c69730e1d15a09aa17d 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Rev.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Rev.java @@ -29,7 +29,7 @@ import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; -@RBuiltin(name = "rev", aliases = {"rev.default"}, kind = SUBSTITUTE) +@RBuiltin(name = "rev", aliases = {"rev.default"}, kind = SUBSTITUTE, parameterNames = {"x"}) // TODO implement in R public abstract class Rev extends RBuiltinNode { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/RowMeans.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/RowMeans.java index 8091a1f86e64eaca927920a5c2b82efae3699f76..2e1fba74791f7d173bab59efd2e115e80998b5ca 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/RowMeans.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/RowMeans.java @@ -13,6 +13,7 @@ package com.oracle.truffle.r.nodes.builtin.base; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.r.nodes.*; +import com.oracle.truffle.r.nodes.access.*; import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.nodes.unary.*; import com.oracle.truffle.r.runtime.*; @@ -21,9 +22,16 @@ import com.oracle.truffle.r.runtime.data.model.*; import com.oracle.truffle.r.runtime.ops.*; import com.oracle.truffle.r.runtime.ops.na.*; -@RBuiltin(name = "rowMeans", kind = RBuiltinKind.INTERNAL) +// Implements .rowMeans +@RBuiltin(name = "rowMeans", kind = RBuiltinKind.INTERNAL, parameterNames = {"X", "m", "n", "na.rm"}) public abstract class RowMeans extends RBuiltinNode { + @Override + public RNode[] getParameterValues() { + // X, m, n, na.rm = FALSE + return new RNode[]{ConstantNode.create(RMissing.instance), ConstantNode.create(RMissing.instance), ConstantNode.create(RMissing.instance), ConstantNode.create(RRuntime.FALSE)}; + } + @Child protected BinaryArithmetic add = BinaryArithmetic.ADD.create(); private final NACheck na = NACheck.create(); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/RowSums.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/RowSums.java index c482a1765406c0e7f3fab0880e671f01b9183515..00f34422decb3773a37d8a1136974cdfd732fcb0 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/RowSums.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/RowSums.java @@ -13,6 +13,7 @@ package com.oracle.truffle.r.nodes.builtin.base; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.r.nodes.*; +import com.oracle.truffle.r.nodes.access.*; import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.nodes.unary.*; import com.oracle.truffle.r.runtime.*; @@ -21,9 +22,16 @@ import com.oracle.truffle.r.runtime.data.model.*; import com.oracle.truffle.r.runtime.ops.*; import com.oracle.truffle.r.runtime.ops.na.*; -@RBuiltin(name = "rowSums", kind = RBuiltinKind.INTERNAL) +// Implements .rowSums +@RBuiltin(name = "rowSums", kind = RBuiltinKind.INTERNAL, parameterNames = {"X", "m", "n", "na.rm"}) public abstract class RowSums extends RBuiltinNode { + @Override + public RNode[] getParameterValues() { + // X, m, n, na.rm = FALSE + return new RNode[]{ConstantNode.create(RMissing.instance), ConstantNode.create(RMissing.instance), ConstantNode.create(RMissing.instance), ConstantNode.create(RRuntime.FALSE)}; + } + @Child protected BinaryArithmetic add = BinaryArithmetic.ADD.create(); private final NACheck na = NACheck.create(); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Sample.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Sample.java index 272394397b02d0590e177590734806301a72af67..1723ab2e00e06f351de21a545408aa1a27d88510 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Sample.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Sample.java @@ -17,15 +17,22 @@ package com.oracle.truffle.r.nodes.builtin.base; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.r.nodes.*; +import com.oracle.truffle.r.nodes.access.*; import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.nodes.unary.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.rng.*; -@RBuiltin(name = "sample", kind = RBuiltinKind.INTERNAL) +@RBuiltin(name = "sample", kind = RBuiltinKind.INTERNAL, parameterNames = {"x", "size", "replace", "prob"}) public abstract class Sample extends RBuiltinNode { + @Override + public RNode[] getParameterValues() { + // x, size, replace = FALSE, prob = NULL + return new RNode[]{ConstantNode.create(RMissing.instance), ConstantNode.create(RMissing.instance), ConstantNode.create(RRuntime.LOGICAL_FALSE), ConstantNode.create(RNull.instance)}; + } + @CreateCast("arguments") public RNode[] castArguments(RNode[] arguments) { arguments[0] = CastIntegerNodeFactory.create(arguments[0], true, false, false); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/ShortRowNames.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/ShortRowNames.java index bc58665be505ee4d51f5218cc1a2b3486643cd72..874ac1d714c7a863450353ce57699df61fdf0899 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/ShortRowNames.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/ShortRowNames.java @@ -33,7 +33,7 @@ import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.*; -@RBuiltin(name = "shortRowNames", kind = INTERNAL) +@RBuiltin(name = "shortRowNames", kind = INTERNAL, parameterNames = {"x", "type"}) public abstract class ShortRowNames extends RBuiltinNode { @CreateCast({"arguments"}) diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/SortFunctions.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/SortFunctions.java index 47809cc86ab013b408c12fca44b92394d31f111e..05070e5e813093c2290e2263bdc61f33b1661030 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/SortFunctions.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/SortFunctions.java @@ -44,17 +44,10 @@ import com.oracle.truffle.r.runtime.data.model.*; */ public class SortFunctions { - @RBuiltin(name = "sort.list", kind = SUBSTITUTE) + @RBuiltin(name = "sort.list", kind = SUBSTITUTE, parameterNames = {"x", "partial", "na.last", "decreasing", "method"}) // TODO Implement in R public abstract static class SortList extends RBuiltinNode { - private static final String[] PARAMETER_NAMES = new String[]{"x", "partial", "na.last", "decreasing", "method"}; - - @Override - public Object[] getParameterNames() { - return PARAMETER_NAMES; - } - @Override public RNode[] getParameterValues() { return new RNode[]{ConstantNode.create(RMissing.instance), ConstantNode.create(RNull.instance), ConstantNode.create(RRuntime.LOGICAL_TRUE), ConstantNode.create(RRuntime.LOGICAL_FALSE), @@ -84,7 +77,7 @@ public class SortFunctions { } } - @RBuiltin(name = "qsort", kind = INTERNAL) + @RBuiltin(name = "qsort", kind = INTERNAL, parameterNames = {"x", "index.return"}) // TODO full implementation in Java handling NAs public abstract static class QSort extends RBuiltinNode { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Strsplit.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Strsplit.java index cb823a5bcc03bc7459b7c36741aec2a7cbbc287b..a81b1c3881e91039bed98a411de51a240d71a082 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Strsplit.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Strsplit.java @@ -26,17 +26,26 @@ import static com.oracle.truffle.r.runtime.RBuiltinKind.*; import com.oracle.truffle.api.CompilerDirectives.SlowPath; import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.r.nodes.*; +import com.oracle.truffle.r.nodes.access.*; import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.*; import com.oracle.truffle.r.runtime.ops.na.*; -@RBuiltin(name = "strsplit", kind = INTERNAL) +@RBuiltin(name = "strsplit", kind = INTERNAL, parameterNames = {"x", "split", "fixed", "perl", "useBytes"}) public abstract class Strsplit extends RBuiltinNode { protected final NACheck na = NACheck.create(); + @Override + public RNode[] getParameterValues() { + // x, split, fixed = FALSE, perl = FALSE, useBytes = FALSE + return new RNode[]{ConstantNode.create(RMissing.instance), ConstantNode.create(RMissing.instance), ConstantNode.create(RRuntime.LOGICAL_FALSE), ConstantNode.create(RRuntime.LOGICAL_FALSE), + ConstantNode.create(RRuntime.LOGICAL_FALSE)}; + } + @SuppressWarnings("unused") @Specialization public RList split(RAbstractStringVector x, String split, byte fixed, byte perl, byte useBytes) { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Substr.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Substr.java index ca73b9788f4d0783487bcb847fddd8d2769ac31a..9faf176767b6e8abfb6200270be2f40780b6bab1 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Substr.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Substr.java @@ -33,7 +33,7 @@ import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.*; import com.oracle.truffle.r.runtime.ops.na.*; -@RBuiltin(name = "substr", kind = INTERNAL) +@RBuiltin(name = "substr", kind = INTERNAL, parameterNames = {"x", "start", "stop"}) public abstract class Substr extends RBuiltinNode { protected final NACheck na = NACheck.create(); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/SysFunctions.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/SysFunctions.java index 570e99f4660c2a2c9de93f90bedcabd311ec7752..81ca45fef893d8c5801f2cf97f8a47a8f2f235b6 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/SysFunctions.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/SysFunctions.java @@ -29,6 +29,8 @@ import java.util.*; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.r.nodes.*; +import com.oracle.truffle.r.nodes.access.*; import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; @@ -48,9 +50,14 @@ public class SysFunctions { } } - @RBuiltin(name = "Sys.getenv", kind = INTERNAL) + @RBuiltin(name = "Sys.getenv", kind = INTERNAL, parameterNames = {"x", "unset", "names"}) public abstract static class SysGetenv extends RBuiltinNode { + @Override + public RNode[] getParameterValues() { + return new RNode[]{ConstantNode.create(RNull.instance), ConstantNode.create(""), ConstantNode.create(RRuntime.LOGICAL_NA)}; + } + @Specialization public Object sysGetEnv(RAbstractStringVector x, String unset) { controlVisibility(); @@ -91,14 +98,13 @@ public class SysFunctions { } - @RBuiltin(name = "Sys.setenv", kind = SUBSTITUTE) + @RBuiltin(name = "Sys.setenv", kind = SUBSTITUTE, parameterNames = {"..."}) // TODO INTERNAL when argument names available in list(...) public abstract static class SysSetEnv extends RInvisibleBuiltinNode { - private static final Object[] PARAMETER_NAMES = new Object[]{"..."}; @Override - public Object[] getParameterNames() { - return PARAMETER_NAMES; + public RNode[] getParameterValues() { + return new RNode[]{ConstantNode.create(RMissing.instance)}; } @Specialization @@ -134,8 +140,9 @@ public class SysFunctions { } } - @RBuiltin(name = "Sys.unsetenv", kind = INTERNAL) + @RBuiltin(name = "Sys.unsetenv", kind = INTERNAL, parameterNames = {"x"}) public abstract static class SysUnSetEnv extends RInvisibleBuiltinNode { + @Specialization public RLogicalVector doSysSetEnv(RAbstractStringVector argVec) { byte[] data = new byte[argVec.getLength()]; @@ -146,7 +153,7 @@ public class SysFunctions { } } - @RBuiltin(name = "Sys.sleep", kind = INTERNAL) + @RBuiltin(name = "Sys.sleep", kind = INTERNAL, parameterNames = {"time"}) public abstract static class SysSleep extends RInvisibleBuiltinNode { @Specialization(order = 0) @@ -206,7 +213,7 @@ public class SysFunctions { /** * TODO: Handle ~ expansion which is not handled by POSIX. */ - @RBuiltin(name = "Sys.readlink", kind = INTERNAL) + @RBuiltin(name = "Sys.readlink", kind = INTERNAL, parameterNames = {"paths"}) public abstract static class SysReadlink extends RBuiltinNode { @Specialization(order = 0) diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/ToLower.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/ToLower.java index 6444ae06d7c4114cbd73b3124db0f93eaf6ec0b7..77ecfe914c1d266f7dfb36b62997eb71d86cf805 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/ToLower.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/ToLower.java @@ -30,7 +30,7 @@ import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; -@RBuiltin(name = "tolower", kind = INTERNAL) +@RBuiltin(name = "tolower", kind = INTERNAL, parameterNames = {"x"}) public abstract class ToLower extends RBuiltinNode { @Specialization diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/ToUpper.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/ToUpper.java index e937ad66bd0f8ba739464554049db6bf63ce5f65..e1c41c31b5adb3f5a59fcfcf3f930aed20a97cba 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/ToUpper.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/ToUpper.java @@ -30,7 +30,7 @@ import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; -@RBuiltin(name = "toupper", kind = INTERNAL) +@RBuiltin(name = "toupper", kind = INTERNAL, parameterNames = {"x"}) public abstract class ToUpper extends RBuiltinNode { @Specialization diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Typeof.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Typeof.java index 25e8fb8225adde7eaea79249a446a2e1aad90587..d68dc4012fcb48e418e886411f77d64e6fe814d1 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Typeof.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Typeof.java @@ -30,7 +30,7 @@ import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; -@RBuiltin(name = "typeof", kind = SUBSTITUTE) +@RBuiltin(name = "typeof", kind = SUBSTITUTE, parameterNames = {"x"}) // TODO INTERNAL @SuppressWarnings("unused") public abstract class Typeof extends RBuiltinNode { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Unique.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Unique.java index b50775736800534d6d1946f7080fc992c74884f8..3820f712be824c147670f67f9e1fc496ff394ba5 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Unique.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Unique.java @@ -27,20 +27,30 @@ import static com.oracle.truffle.r.runtime.RBuiltinKind.*; import java.util.*; import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.r.nodes.*; +import com.oracle.truffle.r.nodes.access.*; import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.*; -@RBuiltin(name = "unique", kind = INTERNAL) +// Implements default S3 method +@RBuiltin(name = "unique", kind = INTERNAL, parameterNames = {"x", "incomparables", "fromLast", "nmax", "..."}) // TODO A more efficient implementation is in order; GNU R uses hash tables so perhaps we should // consider using one of the existing libraries that offer hash table implementations for primitive // types public abstract class Unique extends RBuiltinNode { + @Override + public RNode[] getParameterValues() { + // x, incomparables = FALSE, fromLast = FALSE, nmax = NA, ... + return new RNode[]{ConstantNode.create(RMissing.instance), ConstantNode.create(RRuntime.LOGICAL_FALSE), ConstantNode.create(RRuntime.LOGICAL_FALSE), ConstantNode.create(RRuntime.INT_NA), + ConstantNode.create(RMissing.instance)}; + } + @SuppressWarnings("unused") @Specialization - public RStringVector doUnique(RAbstractStringVector vec, byte incomparables, byte fromLast, byte nmax) { + public RStringVector doUnique(RAbstractStringVector vec, byte incomparables, byte fromLast, byte nmax, RMissing vararg) { ArrayList<String> dataList = new ArrayList<>(vec.getLength()); for (int i = 0; i < vec.getLength(); i++) { String s = vec.getDataAt(i); @@ -183,7 +193,7 @@ public abstract class Unique extends RBuiltinNode { @SuppressWarnings("unused") @Specialization - public RIntVector doUnique(RAbstractIntVector vec, byte incomparables, byte fromLast, byte nmax) { + public RIntVector doUnique(RAbstractIntVector vec, byte incomparables, byte fromLast, byte nmax, RMissing vararg) { IntArray dataList = new IntArray(vec.getLength()); for (int i = 0; i < vec.getLength(); i++) { int val = vec.getDataAt(i); @@ -196,7 +206,7 @@ public abstract class Unique extends RBuiltinNode { @SuppressWarnings("unused") @Specialization - public RDoubleVector doUnique(RAbstractDoubleVector vec, byte incomparables, byte fromLast, byte nmax) { + public RDoubleVector doUnique(RAbstractDoubleVector vec, byte incomparables, byte fromLast, byte nmax, RMissing vararg) { DoubleArray dataList = new DoubleArray(vec.getLength()); for (int i = 0; i < vec.getLength(); i++) { double val = vec.getDataAt(i); @@ -209,7 +219,7 @@ public abstract class Unique extends RBuiltinNode { @SuppressWarnings("unused") @Specialization - public RLogicalVector doUnique(RAbstractLogicalVector vec, byte incomparables, byte fromLast, byte nmax) { + public RLogicalVector doUnique(RAbstractLogicalVector vec, byte incomparables, byte fromLast, byte nmax, RMissing vararg) { ByteArray dataList = new ByteArray(vec.getLength()); for (int i = 0; i < vec.getLength(); i++) { byte val = vec.getDataAt(i); @@ -222,7 +232,7 @@ public abstract class Unique extends RBuiltinNode { @SuppressWarnings("unused") @Specialization - public RComplexVector doUnique(RAbstractComplexVector vec, byte incomparables, byte fromLast, byte nmax) { + public RComplexVector doUnique(RAbstractComplexVector vec, byte incomparables, byte fromLast, byte nmax, RMissing vararg) { DoubleArrayForComplex dataList = new DoubleArrayForComplex(vec.getLength()); for (int i = 0; i < vec.getLength(); i++) { RComplex s = vec.getDataAt(i); @@ -235,7 +245,7 @@ public abstract class Unique extends RBuiltinNode { @SuppressWarnings("unused") @Specialization - public RRawVector doUnique(RAbstractRawVector vec, byte incomparables, byte fromLast, byte nmax) { + public RRawVector doUnique(RAbstractRawVector vec, byte incomparables, byte fromLast, byte nmax, RMissing vararg) { ByteArray dataList = new ByteArray(vec.getLength()); for (int i = 0; i < vec.getLength(); i++) { byte val = vec.getDataAt(i).getValue(); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Unlist.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Unlist.java index 3d2792ddc016e56ebea219fd74ebe17259cb98c8..97457b1cfccf8f5cde69f0ccba0520e9607ad399 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Unlist.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Unlist.java @@ -26,19 +26,12 @@ import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.*; import com.oracle.truffle.r.nodes.builtin.base.UnlistFactory.RecursiveLengthFactory; -@RBuiltin(name = "unlist", kind = SUBSTITUTE) +@RBuiltin(name = "unlist", kind = SUBSTITUTE, parameterNames = {"x", "recursive", "use.names"}) // TODO INTERNAL public abstract class Unlist extends RBuiltinNode { // portions of the algorithm were transcribed from GNU R - private static final Object[] PARAMETER_NAMES = new Object[]{"x", "recursive", "use.names"}; - - @Override - public Object[] getParameterNames() { - return PARAMETER_NAMES; - } - @Override public RNode[] getParameterValues() { return new RNode[]{ConstantNode.create(RMissing.instance), ConstantNode.create(RRuntime.LOGICAL_TRUE), ConstantNode.create(RRuntime.LOGICAL_TRUE)}; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttr.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttr.java index 45309b95a63f07d44097859bbc5a43bf18d1b80a..914c5aaa7bb0b2dfe2610d15383fc8bf1ba3ccc9 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttr.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttr.java @@ -35,7 +35,8 @@ import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.*; -@RBuiltin(name = "attr<-", kind = PRIMITIVE, parameterNames = {"x", "which"}) +@RBuiltin(name = "attr<-", kind = PRIMITIVE, parameterNames = {"x", "which", ""}) +// 2nd parameter is "value", but should not be matched against, so "" @SuppressWarnings("unused") public abstract class UpdateAttr extends RInvisibleBuiltinNode { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttributes.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttributes.java index 972965e0752485c975696aaf2ae08903025ba6fc..bf4ac27a835b8f54ea68f8acf904fef780baa4c4 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttributes.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateAttributes.java @@ -34,7 +34,8 @@ import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.*; -@RBuiltin(name = "attributes<-", kind = PRIMITIVE, parameterNames = {"obj"}) +@RBuiltin(name = "attributes<-", kind = PRIMITIVE, parameterNames = {"obj", ""}) +// 2nd parameter is "value", but should not be matched against, so "" @SuppressWarnings("unused") public abstract class UpdateAttributes extends RInvisibleBuiltinNode { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateClass.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateClass.java index a4830c965678f8aec9f3f73cc42f2c4230ab1cba..c0ba30c075d506a89759792a0b70beb3b14e7d07 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateClass.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateClass.java @@ -24,7 +24,8 @@ import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.*; -@RBuiltin(name = "class<-", kind = PRIMITIVE, parameterNames = {"x"}) +@RBuiltin(name = "class<-", kind = PRIMITIVE, parameterNames = {"x", ""}) +// 2nd parameter is "value", but should not be matched against, so "" public abstract class UpdateClass extends RInvisibleBuiltinNode { @Child private CastTypeNode castTypeNode; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDiag.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDiag.java index 3158d0bb05df9319faa60ac62d0d53809c4e23a5..6fc62cc92734a5386c131a0470f0748eb50bd693 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDiag.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDiag.java @@ -34,7 +34,8 @@ import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.*; import com.oracle.truffle.r.runtime.ops.na.*; -@RBuiltin(name = "diag<-", kind = SUBSTITUTE) +@RBuiltin(name = "diag<-", kind = SUBSTITUTE, parameterNames = {"x", ""}) +// 2nd parameter is "value", but should not be matched against, so "") // TODO Implement in R public abstract class UpdateDiag extends RInvisibleBuiltinNode { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDim.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDim.java index 4e8a780ebf70d90770a211e4443ba4cf2f2abf21..3b6d7dac39b1bf493dd791f18e081c59545abfe6 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDim.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDim.java @@ -33,7 +33,8 @@ import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.*; -@RBuiltin(name = "dim<-", kind = PRIMITIVE, parameterNames = {"x"}) +@RBuiltin(name = "dim<-", kind = PRIMITIVE, parameterNames = {"x", ""}) +// 2nd parameter is "value", but should not be matched against, so "" @SuppressWarnings("unused") public abstract class UpdateDim extends RInvisibleBuiltinNode { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDimNames.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDimNames.java index e7af8c87937a16085689b6401d49465324c1d2c2..77b3a57c60f11bb1d9ccd54f95d8335e374ccb44 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDimNames.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateDimNames.java @@ -33,7 +33,8 @@ import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.*; -@RBuiltin(name = "dimnames<-", kind = PRIMITIVE, parameterNames = {"x"}) +@RBuiltin(name = "dimnames<-", kind = PRIMITIVE, parameterNames = {"x", ""}) +// 2nd parameter is "value", but should not be matched against, so "" @SuppressWarnings("unused") public abstract class UpdateDimNames extends RInvisibleBuiltinNode { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateLength.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateLength.java index ce54f7eb9a3d6582aede75eb5d379beda88b702b..8851a2ba404d4890ad3c336ab653c2c8bcac2e95 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateLength.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateLength.java @@ -33,7 +33,8 @@ import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.*; -@RBuiltin(name = "length<-", kind = PRIMITIVE, parameterNames = {"x"}) +@RBuiltin(name = "length<-", kind = PRIMITIVE, parameterNames = {"x", ""}) +// 2nd parameter is "value", but should not be matched against, so "" public abstract class UpdateLength extends RInvisibleBuiltinNode { @CreateCast("arguments") diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateLevels.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateLevels.java index 0c02f4568068bf09496572f42f56a4c66c13a2ed..85b8434b6908208ffb85739b8081c08ab0d72ec6 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateLevels.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateLevels.java @@ -17,7 +17,8 @@ import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.*; -@RBuiltin(name = "levels<-", kind = RBuiltinKind.PRIMITIVE, parameterNames = {"x"}) +@RBuiltin(name = "levels<-", kind = RBuiltinKind.PRIMITIVE, parameterNames = {"x", ""}) +// 2nd parameter is "value", but should not be matched against, so "" public abstract class UpdateLevels extends RInvisibleBuiltinNode { @Specialization diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateNames.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateNames.java index 3de3538bb0e05704ffe402006538072c597fb251..5474cf570f92fb04201764a71ec170ee82e689ef 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateNames.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateNames.java @@ -35,7 +35,8 @@ import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.*; -@RBuiltin(name = "names<-", kind = PRIMITIVE, parameterNames = {"x"}) +@RBuiltin(name = "names<-", kind = PRIMITIVE, parameterNames = {"x", ""}) +// 2nd parameter is "value", but should not be matched against, so "" public abstract class UpdateNames extends RInvisibleBuiltinNode { @Child CastStringNode castStringNode; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateOldClass.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateOldClass.java index aa7b159aebcca464b0cfa64f2d3c9205344cac33..e832a37aa3186b66c197021cedcbbee75f8c20b2 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateOldClass.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateOldClass.java @@ -36,7 +36,8 @@ import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.*; // oldClass<- (as opposed to class<-), simply sets the attribute (without handling "implicit" attributes) -@RBuiltin(name = "oldClass<-", kind = PRIMITIVE, parameterNames = {"x"}) +@RBuiltin(name = "oldClass<-", kind = PRIMITIVE, parameterNames = {"x", ""}) +// 2nd parameter is "value", but should not be matched against, so "" public abstract class UpdateOldClass extends RInvisibleBuiltinNode { @Child private CastTypeNode castTypeNode; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateStorageMode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateStorageMode.java index d46b6ba306886a820205711919f1fb6cd8a3df55..91a8c233efa695d6ae9374a88be3d255e0daa469 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateStorageMode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateStorageMode.java @@ -24,7 +24,8 @@ import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.RAttributes.RAttribute; -@RBuiltin(name = "storage.mode<-", kind = PRIMITIVE, parameterNames = {"x"}) +@RBuiltin(name = "storage.mode<-", kind = PRIMITIVE, parameterNames = {"x", ""}) +// 2nd parameter is "value", but should not be matched against, so "" public abstract class UpdateStorageMode extends RBuiltinNode { @Child private Typeof typeof; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateSubstr.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateSubstr.java index ed9a67f962469fe344a2dfa075a86c3b3c0dc06a..0b7257604c679870bc9deb8ac95ff1ba8db347e9 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateSubstr.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UpdateSubstr.java @@ -34,7 +34,8 @@ import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.*; import com.oracle.truffle.r.runtime.ops.na.*; -@RBuiltin(name = "substr<-", kind = INTERNAL) +@RBuiltin(name = "substr<-", kind = INTERNAL, parameterNames = {"x", "start", "stop", ""}) +// 2nd parameter is "value", but should not be matched against, so "") public abstract class UpdateSubstr extends RBuiltinNode { protected final NACheck na = NACheck.create(); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UseMethodDispatchNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UseMethodDispatchNode.java index db508692e2ad708717c7b113f3de7fac24a62bed..380a8db0a80e9c1f0f34f4e201ff0bab3fa11120 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UseMethodDispatchNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/UseMethodDispatchNode.java @@ -119,8 +119,15 @@ public class UseMethodDispatchNode extends S3DispatchNode { return funCallNode.call(newFrame, targetFunction.getTarget(), argObject); } - @SlowPath private void findTargetFunction(VirtualFrame frame, Frame callerFrame) { + findTargetFunctionLookup(callerFrame); + if (targetFunction == null) { + throw RError.error(frame, getEncapsulatingSourceSection(), RError.Message.UNKNOWN_FUNCTION_USE_METHOD, this.genericName, RRuntime.toString(this.type)); + } + } + + @SlowPath + private void findTargetFunctionLookup(Frame callerFrame) { for (int i = 0; i < this.type.getLength(); ++i) { findFunction(this.genericName, this.type.getDataAt(i), callerFrame); if (targetFunction != null) { @@ -137,11 +144,9 @@ public class UseMethodDispatchNode extends S3DispatchNode { break; } } - if (targetFunction == null) { - findFunction(this.genericName, RRuntime.DEFAULT, callerFrame); - if (targetFunction == null) { - throw RError.error(frame, getEncapsulatingSourceSection(), RError.Message.UNKNOWN_FUNCTION_USE_METHOD, this.genericName, RRuntime.toString(this.type)); - } + if (targetFunction != null) { + return; } + findFunction(this.genericName, RRuntime.DEFAULT, callerFrame); } } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Vector.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Vector.java index e093dbbf02df341df33a44a3e6b8279e01a1a734..31928feb4c18575cdf2854a236cffeb17e736aa9 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Vector.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/Vector.java @@ -29,15 +29,22 @@ import java.util.*; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.r.nodes.*; +import com.oracle.truffle.r.nodes.access.*; import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.nodes.unary.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.*; -@RBuiltin(name = "vector", kind = INTERNAL) +@RBuiltin(name = "vector", kind = INTERNAL, parameterNames = {"mode", "length"}) public abstract class Vector extends RBuiltinNode { + @Override + public RNode[] getParameterValues() { + // mode = "logical", length = 0 + return new RNode[]{ConstantNode.create(RRuntime.TYPE_LOGICAL), ConstantNode.create(0)}; + } + @CreateCast("arguments") protected RNode[] castLength(RNode[] arguments) { // length is at index 1 diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/WhichFunctions.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/WhichFunctions.java index 2276361f50ffb257d9a04cb8ce0dc2673f93973c..16d19de00f4b5520c15b1c84be711dd65e99cc8a 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/WhichFunctions.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/WhichFunctions.java @@ -28,6 +28,7 @@ import java.util.*; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.r.nodes.*; +import com.oracle.truffle.r.nodes.access.*; import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.nodes.unary.*; import com.oracle.truffle.r.runtime.*; @@ -39,9 +40,14 @@ import com.oracle.truffle.r.runtime.data.model.*; */ public class WhichFunctions { - @RBuiltin(name = "which", kind = INTERNAL) + @RBuiltin(name = "which", kind = INTERNAL, parameterNames = {"x", "arr.ind", "useNames"}) public abstract static class Which extends RBuiltinNode { + @Override + public RNode[] getParameterValues() { + return new RNode[]{ConstantNode.create(RMissing.instance), ConstantNode.create(RRuntime.LOGICAL_FALSE), ConstantNode.create(RRuntime.LOGICAL_TRUE)}; + } + @Specialization public RIntVector which(RAbstractLogicalVector x) { controlVisibility(); @@ -59,7 +65,7 @@ public class WhichFunctions { } } - @RBuiltin(name = "which.max", kind = RBuiltinKind.INTERNAL) + @RBuiltin(name = "which.max", kind = RBuiltinKind.INTERNAL, parameterNames = {"x"}) public abstract static class WhichMax extends RBuiltinNode { @CreateCast("arguments") @@ -84,7 +90,7 @@ public class WhichFunctions { } - @RBuiltin(name = "which.min", kind = RBuiltinKind.INTERNAL) + @RBuiltin(name = "which.min", kind = RBuiltinKind.INTERNAL, parameterNames = {"x"}) public abstract static class WhichMin extends RBuiltinNode { @CreateCast("arguments") diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRRunDump.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRRunDump.java new file mode 100644 index 0000000000000000000000000000000000000000..56916e88206ccf6cf1d8066ffc7eb6c632d04c53 --- /dev/null +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/fastr/FastRRunDump.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.truffle.r.nodes.builtin.fastr; + +import static com.oracle.truffle.r.runtime.RBuiltinKind.*; + +import com.oracle.graal.debug.*; +import com.oracle.graal.debug.Debug.Scope; +import com.oracle.truffle.api.*; +import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.api.frame.*; +import com.oracle.truffle.api.nodes.*; +import com.oracle.truffle.r.nodes.*; +import com.oracle.truffle.r.nodes.access.*; +import com.oracle.truffle.r.nodes.builtin.*; +import com.oracle.truffle.r.runtime.*; +import com.oracle.truffle.r.runtime.data.*; + +/** + * Run a FastR function, and dump its AST to IGV before and after running. If no function is passed, + * this builtin does not do anything. + */ +@RBuiltin(name = "fastr.rundump", parameterNames = {"function"}, kind = PRIMITIVE) +public abstract class FastRRunDump extends RInvisibleBuiltinNode { + + // TODO Make this more versatile by allowing actual function calls with arguments to be + // observed. This requires ... to work properly. + + @Child private IndirectCallNode call = Truffle.getRuntime().createIndirectCallNode(); + + private final GraphPrintVisitor graphPrinter = new GraphPrintVisitor(); + + @Override + public RNode[] getParameterValues() { + return new RNode[]{ConstantNode.create(RNull.instance)}; + } + + @Specialization + public Object runDump(RNull function) { + return function; + } + + @Specialization + public Object runDump(VirtualFrame frame, RFunction function) { + controlVisibility(); + Object r = RNull.instance; + graphPrinter.beginGroup(RRuntime.toString(function)); + try (Scope s = Debug.scope("FastR")) { + graphPrinter.beginGraph("before").visit(function.getTarget().getRootNode()); + r = call.call(frame, function.getTarget(), RArguments.create(function)); + graphPrinter.beginGraph("after").visit(function.getTarget().getRootNode()); + } catch (Throwable t) { + Debug.handle(t); + } finally { + graphPrinter.printToNetwork(true); + } + return r; + } + +} diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/stats/Runif.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/stats/Runif.java index 510b2dad2cbcc3e114de0b2469ed01074dfbda69..3478c7acfa61b05c6a2efa2623bb16618a87d6a0 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/stats/Runif.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/stats/Runif.java @@ -25,6 +25,8 @@ package com.oracle.truffle.r.nodes.builtin.stats; import static com.oracle.truffle.r.runtime.RBuiltinKind.*; import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.r.nodes.*; +import com.oracle.truffle.r.nodes.access.*; import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; @@ -33,9 +35,15 @@ import com.oracle.truffle.r.runtime.rng.*; /** * TODO GnuR checks/updates {@code .Random.seed} across this call. */ -@RBuiltin(name = "runif", kind = SUBSTITUTE) +@RBuiltin(name = "runif", kind = SUBSTITUTE, parameterNames = {"n", "min", "max"}) public abstract class Runif extends RBuiltinNode { + @Override + public RNode[] getParameterValues() { + // n, min = 0, max = 1 + return new RNode[]{ConstantNode.create(RMissing.instance), ConstantNode.create(0), ConstantNode.create(1)}; + } + @Specialization public RDoubleVector runif(int n) { controlVisibility(); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/IfNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/IfNode.java index e5259e438aceb825983914ca39b78a55ec309a5a..23948555946fd5fa6c5ad43ceffb5fb477f3d466 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/IfNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/control/IfNode.java @@ -24,70 +24,77 @@ package com.oracle.truffle.r.nodes.control; import com.oracle.truffle.api.source.*; import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.api.frame.*; import com.oracle.truffle.r.nodes.*; import com.oracle.truffle.r.nodes.access.*; import com.oracle.truffle.r.nodes.unary.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; -@SuppressWarnings("unused") -@NodeChildren({@NodeChild("condition"), @NodeChild("thenPart"), @NodeChild("elsePart")}) -@NodeField(name = "elseGiven", type = boolean.class) -public abstract class IfNode extends RNode implements VisibilityController { +public class IfNode extends RNode implements VisibilityController { - protected abstract boolean isElseGiven(); + @Child private ConvertBooleanNode condition; + @Child private RNode thenPart; + @Child private RNode elsePart; + + private final boolean elseGiven; + + protected IfNode(RNode condition, RNode thenPart, RNode elsePart) { + this.condition = ConvertBooleanNode.create(condition); + this.thenPart = thenPart; + this.elseGiven = elsePart != null; + this.elsePart = elseGiven ? elsePart : ConstantNode.create(RNull.instance); + } + + public static IfNode create(RNode condition, RNode thenPart, RNode elsePart) { + return new IfNode(condition, thenPart, elsePart); + } + + public static IfNode create(SourceSection src, RNode condition, RNode thenPart, RNode elsePart) { + IfNode i = create(condition, thenPart, elsePart); + i.assignSourceSection(src); + return i; + } /** - * Result visibility of an if node depends on whether there is an else branch or not, and on the - * condition. For instance, the expression {@code if (FALSE) 23} will evaluate to {@code NULL}, - * but the result will not be printed in the shell. Conversely, {@code NULL} will be printed for + * Result visibility of an {@code if} expression is not only a property of the {@code if} + * builtin; it also depends on whether there is an else branch or not, and on the condition. For + * instance, the expression {@code if (FALSE) 23} will evaluate to {@code NULL}, but the result + * will not be printed in the shell. Conversely, {@code NULL} will be printed for * {@code if (FALSE) 23 else NULL} because the else branch is given. * * This means that we need to take care of visibility in this class, and do a double check of - * the condition and the presence of an else branch below in {@link #doObject}. + * the condition and the presence of an else branch below in {@link #execute}. */ - private boolean isVisible; + private boolean isVisible = true; @Override public boolean getVisibility() { return isVisible; } - public static RNode create(RNode condition, RNode thenPart, RNode elsePart) { - if (elsePart != null) { - return IfNodeFactory.create(condition, thenPart, elsePart, true); - } else { - return IfNodeFactory.create(condition, thenPart, ConstantNode.create(RNull.instance), false); - } - } - - public static RNode create(SourceSection src, RNode condition, RNode thenPart, RNode elsePart) { - RNode i = create(condition, thenPart, elsePart); - i.assignSourceSection(src); - return i; - } - @CreateCast({"condition"}) public ConvertBooleanNode conditionToBoolean(RNode node) { return ConvertBooleanNode.create(node); } - @ShortCircuit("thenPart") - public static boolean needsThenPart(byte condition) { - return condition == RRuntime.LOGICAL_TRUE; - } - - @ShortCircuit("elsePart") - public static boolean needsElsePart(byte condition, boolean hasThenPart, Object value) { - return !hasThenPart; - } - - @Specialization - public Object doObject(byte condition, boolean hasThen, Object left, boolean hasElse, Object right) { + @Override + public Object execute(VirtualFrame frame) { + byte cond = condition.executeByte(frame); if (!RContext.isHeadless()) { - isVisible = condition == RRuntime.LOGICAL_TRUE || isElseGiven(); + isVisible = cond == RRuntime.LOGICAL_TRUE || elseGiven; } controlVisibility(); - return hasThen ? left : right; + if (cond == RRuntime.LOGICAL_TRUE) { + return thenPart.execute(frame); + } else if (cond == RRuntime.LOGICAL_FALSE) { + if (elseGiven) { + return elsePart.execute(frame); + } else { + return RNull.instance; + } + } + // NA is the only remaining option + throw RError.error(frame, getSourceSection(), RError.Message.NA_UNEXP); } } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ArgumentMatcher.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ArgumentMatcher.java index b280c72357a87a40b2d7b935f4eecce55df92cce..8eee85a63fe1245e60f2c1156538abed657387b0 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ArgumentMatcher.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/ArgumentMatcher.java @@ -24,6 +24,7 @@ package com.oracle.truffle.r.nodes.function; import java.util.*; +import com.oracle.truffle.api.*; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.api.nodes.*; import com.oracle.truffle.api.source.*; @@ -282,20 +283,11 @@ public class ArgumentMatcher { int varArgIndex = formals.getVarArgIndex(); boolean hasVarArgs = varArgIndex != FormalArguments.NO_VARARG; - // Error check: Unused argument - RRootNode rootNode = (RRootNode) function.getTarget().getRootNode(); - final boolean isBuiltin = rootNode instanceof RBuiltinRootNode; - if (!isBuiltin && !hasVarArgs && suppliedArgs.length > rootNode.getParameterCount()) { - RNode unusedArgNode = (RNode) suppliedArgs[rootNode.getParameterCount()]; - throw RError.error(frame, encapsulatingSrc, RError.Message.UNUSED_ARGUMENT, unusedArgNode.getSourceSection().getCode()); - } - - // Start by finding a matching arguments by name - T[] resultArgs = arrFactory.newArray(hasVarArgs ? formalNames.length : Math.max(formalNames.length, suppliedArgs.length)); - BitSet matchedSuppliedNames = new BitSet(suppliedNames.length); + // MATCH by exact name + T[] resultArgs = arrFactory.newArray(formalNames.length); + BitSet matchedSuppliedArgs = new BitSet(suppliedNames.length); BitSet matchedFormalArgs = new BitSet(formalNames.length); - int unmatchedNameCount = 0; // The nr of formal arguments that have no supplied argument - int varArgMatches = 0; // The nr of arguments that matches the vararg "..." + int unmatchedNameCount = 0; // The nr of named supplied args that do not match // si = suppliedIndex, fi = formalIndex for (int si = 0; si < suppliedNames.length; si++) { if (suppliedNames[si] == null) { @@ -305,64 +297,166 @@ public class ArgumentMatcher { // Search for argument name inside formal arguments int fi = findParameterPosition(frame, formalNames, suppliedNames[si], matchedFormalArgs, si, hasVarArgs, suppliedArgs[si], encapsulatingSrc); if (fi >= 0) { - // Supplied argument is matched! - if (fi >= varArgIndex) { - // This argument matches to "..." - ++varArgMatches; - } resultArgs[fi] = suppliedArgs[si]; - matchedSuppliedNames.set(si); + matchedSuppliedArgs.set(si); } else { - // Formal argument's name was not found in supplied list + // Named supplied arg that has no match: Vararg candidate! unmatchedNameCount++; } } - /* - * Next, check for supplied arguments for vararg: To find the remaining arguments that can - * match to ... we should subtract sum of varArgIndex and number of variable arguments - * already matched from total number of arguments. - */ - int varArgCount = suppliedArgs.length - (varArgIndex + varArgMatches); - if (varArgIndex >= 0 && varArgCount >= 0) { - // Create new nodes and names for vararg + // TODO MATCH by partial name + + // MATCH by position + UnmatchedSuppliedIterator<T> siCursor = new UnmatchedSuppliedIterator<>(suppliedArgs, matchedSuppliedArgs); + for (int fi = 0; fi < resultArgs.length; fi++) { + // Unmatched? + if (!matchedFormalArgs.get(fi)) { + while (siCursor.hasNext() && siCursor.nextIndex() < suppliedNames.length && suppliedNames[siCursor.nextIndex()] != null) { + // Slide over named parameters and find subsequent location of unnamed parameter + siCursor.next(); + } + boolean followsDots = hasVarArgs && fi >= varArgIndex; + if (siCursor.hasNext() && !followsDots) { + resultArgs[fi] = siCursor.next(); + + // set formal status AND "remove" supplied arg from list + matchedFormalArgs.set(fi); + siCursor.remove(); + } + } + } + + // MATCH rest to vararg "..." + if (hasVarArgs) { + int varArgCount = suppliedArgs.length - matchedSuppliedArgs.cardinality(); + + // Create vararg array (+ names if necessary) T[] varArgsArray = arrFactory.newArray(varArgCount); String[] namesArray = null; if (unmatchedNameCount != 0) { namesArray = new String[varArgCount]; } - // Every supplied argument that has not been matched or is longer then names list: - // Add to vararg! + // Add every supplied argument that has not been matched int pos = 0; - for (int i = varArgIndex; i < suppliedArgs.length; i++) { - if (i > suppliedNames.length || !matchedSuppliedNames.get(i)) { - varArgsArray[pos] = suppliedArgs[i]; - if (namesArray != null) { - namesArray[pos] = suppliedNames[i] != null ? suppliedNames[i] : ""; - } - pos++; + UnmatchedSuppliedIterator<T> si = new UnmatchedSuppliedIterator<>(suppliedArgs, matchedSuppliedArgs); + while (si.hasNext()) { + varArgsArray[pos] = si.next(); + si.remove(); + if (namesArray != null) { + String suppliedName = suppliedNames[si.lastIndex()]; + namesArray[pos] = suppliedName != null ? suppliedName : ""; } + pos++; } resultArgs[varArgIndex] = listFactory.makeList(varArgsArray, namesArray); } - // Now fill arguments that have not been set 'by name' by order of their appearance - int cursor = 0; - for (int fi = 0; fi < resultArgs.length && (!hasVarArgs || fi < varArgIndex); fi++) { - if (resultArgs[fi] == null) { - while (cursor < suppliedNames.length && matchedSuppliedNames.get(cursor)) { - cursor++; - } - if (cursor < suppliedArgs.length) { - resultArgs[fi] = suppliedArgs[cursor++]; + // Error check: Unused argument? + int leftoverCount = suppliedArgs.length - matchedSuppliedArgs.cardinality(); + if (leftoverCount > 0) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + + UnmatchedSuppliedIterator<T> si = new UnmatchedSuppliedIterator<>(suppliedArgs, matchedSuppliedArgs); + + // UNUSED_ARGUMENT(S)? + if (leftoverCount == 1) { + // TODO Check for precise error messages + String argStr = arrFactory.debugString(si.next()); + // TODO This is a HACK, remove it when proper vararg unwrapping is implemented! + if (argStr.equals(ArgumentsTrait.VARARG_NAME)) { + return resultArgs; } + throw RError.error(frame, encapsulatingSrc, RError.Message.UNUSED_ARGUMENT, argStr); } + + // Create error message: + T[] debugArgs = arrFactory.newArray(leftoverCount); + int pos = 0; + while (si.hasNext()) { + debugArgs[pos++] = si.next(); + } + + // TODO Check for precise error messages + String debugStr = arrFactory.debugString(debugArgs); + throw RError.error(frame, encapsulatingSrc, RError.Message.UNUSED_ARGUMENTS, debugStr); } return resultArgs; } + /** + * Used in + * {@link ArgumentMatcher#permuteArguments(VirtualFrame, RFunction, Object[], String[], FormalArguments, VarArgsFactory, ArrayFactory, SourceSection)} + * for iteration over suppliedArgs + * + * @param <T> + */ + private static class UnmatchedSuppliedIterator<T> implements Iterator<T> { + private static final int NO_MORE_ARGS = -1; + private int si = 0; + private int lastSi = 0; + private final T[] suppliedArgs; + private final BitSet matchedSuppliedArgs; + + public UnmatchedSuppliedIterator(T[] suppliedArgs, BitSet matchedSuppliedArgs) { + this.suppliedArgs = suppliedArgs; + this.matchedSuppliedArgs = matchedSuppliedArgs; + } + + /** + * @return Index of the argument returned by the last {@link #next()} call. + */ + public int lastIndex() { + return lastSi; + } + + /** + * @return The argument which is going to be returned from the next {@link #next()} call. + * @throws NoSuchElementException If {@link #hasNext()} == true! + */ + public int nextIndex() { + int next = getNextIndex(si); + if (next == NO_MORE_ARGS) { + throw new NoSuchElementException(); + } + return next; + } + + @Override + public boolean hasNext() { + return getNextIndex(si) != NO_MORE_ARGS; + } + + private int getNextIndex(int from) { + if (from == NO_MORE_ARGS) { + return NO_MORE_ARGS; + } + int next = matchedSuppliedArgs.nextClearBit(from); + if (next == NO_MORE_ARGS || next >= suppliedArgs.length) { + return NO_MORE_ARGS; + } + return next; + } + + @Override + public T next() { + int next = getNextIndex(si); + if (next == NO_MORE_ARGS) { + throw new NoSuchElementException(); + } + lastSi = next; + si = getNextIndex(next + 1); + return suppliedArgs[lastSi]; + } + + @Override + public void remove() { + matchedSuppliedArgs.set(lastSi); + } + } + /** * Similar to * {@link #permuteArguments(VirtualFrame, RFunction, Object[], String[], FormalArguments, VarArgsFactory, ArrayFactory, SourceSection)} @@ -384,6 +478,8 @@ public class ArgumentMatcher { protected static <T> int[] permuteArgumentsIndices(VirtualFrame frame, RFunction function, T[] suppliedArgs, String[] suppliedNames, FormalArguments formals, SourceSection encapsulatingSrc) { String[] formalNames = formals.getNames(); + assert false; + // Preparations int varArgIndex = formals.getVarArgIndex(); boolean hasVarArgs = varArgIndex != FormalArguments.NO_VARARG; @@ -403,10 +499,14 @@ public class ArgumentMatcher { // Start by finding a matching arguments by name BitSet matchedSuppliedNames = new BitSet(suppliedNames.length); BitSet matchedFormalArgs = new BitSet(formalNames.length); - int varArgMatches = 0; // The nr of arguments that matches the vararg "..." // si = suppliedIndex, fi = formalIndex + int varArgCount = 0; for (int si = 0; si < suppliedNames.length; si++) { if (suppliedNames[si] == null) { + if (si >= varArgIndex) { + // unnamed arguments past vararg index match to "..." + varArgCount++; + } continue; } @@ -414,12 +514,12 @@ public class ArgumentMatcher { int fi = findParameterPosition(frame, formalNames, suppliedNames[si], matchedFormalArgs, si, hasVarArgs, suppliedArgs[si], encapsulatingSrc); if (fi >= 0) { // Supplied argument is matched! - if (fi >= varArgIndex) { - // This argument matches to "..." - ++varArgMatches; - } resultPos[si] = fi; matchedSuppliedNames.set(si); + } else { + // Formal argument's name was not found in supplied list + // named unmatched arguments arguments match to "..." + varArgCount++; } } @@ -428,13 +528,12 @@ public class ArgumentMatcher { * match to ... we should subtract sum of varArgIndex and number of variable arguments * already matched from total number of arguments. */ - int varArgCount = suppliedArgs.length - (varArgIndex + varArgMatches); if (varArgIndex >= 0 && varArgCount >= 0) { // Every supplied argument that has not been matched or is longer then names list: // Add to vararg! int pos = 0; for (int i = varArgIndex; i < suppliedArgs.length; i++) { - if (i > suppliedNames.length || !matchedSuppliedNames.get(i)) { + if (i > suppliedNames.length || (!matchedSuppliedNames.get(i) && (i >= varArgIndex || suppliedNames[i] != null))) { resultPos[pos + varArgIndex] = i; pos++; } @@ -445,7 +544,8 @@ public class ArgumentMatcher { int cursor = 0; for (int fi = 0; fi < resultPos.length && (!hasVarArgs || fi < varArgIndex); fi++) { if (resultPos[fi] == ARG_NOT_SET) { - while (cursor < suppliedNames.length && matchedSuppliedNames.get(cursor)) { + while (cursor < suppliedNames.length && suppliedNames[cursor] != null) { + // find subsequent location of unnamed parameter cursor++; } if (cursor < suppliedArgs.length) { @@ -503,7 +603,6 @@ public class ArgumentMatcher { if (found >= 0 || hasVarArgs) { return found; } - // Error! String debugSrc = suppliedName; if (debugArgNode instanceof RNode) { @@ -614,6 +713,18 @@ public class ArgumentMatcher { * @return A fresh (type safe) array of type T */ T[] newArray(int length); + + /** + * @param args + * @return A {@link String} containing debug names of all given args + */ + String debugString(T[] args); + + default String debugString(T arg) { + T[] args = newArray(1); + args[0] = arg; + return debugString(args); + } } /** @@ -623,6 +734,11 @@ public class ArgumentMatcher { public RNode[] newArray(int length) { return new RNode[length]; } + + public String debugString(RNode[] args) { + SourceSection src = Utils.sourceBoundingBox(args); + return String.valueOf(src); + } } /** @@ -632,6 +748,17 @@ public class ArgumentMatcher { public Object[] newArray(int length) { return new Object[length]; } + + public String debugString(Object[] args) { + StringBuilder b = new StringBuilder(); + for (int i = 0; i < args.length; i++) { + b.append(String.valueOf(args[i])); + if (i != args.length - 1) { + b.append(", "); + } + } + return b.toString(); + } } /** 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 3d9a322bf4d980da0ca151ebf58089785d1721af..1744ffe032993f7e4b5399e4bb72ef4658fa2dd0 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 @@ -86,7 +86,7 @@ public abstract class RCallNode extends RNode { BuiltinFunctionVariableNode functionNode = BuiltinFunctionVariableNodeFactory.create(function, symbol); assert internalCallArg instanceof UninitializedCallNode; UninitializedCallNode current = new UninitializedCallNode(functionNode, ((UninitializedCallNode) internalCallArg).args); - RCallNode result = current.createCacheNode(frame, function); + RCallNode result = current.createCacheNode(frame, function, src); result.assignSourceSection(src); return result; } @@ -247,7 +247,7 @@ public abstract class RCallNode extends RNode { CompilerAsserts.neverPartOfCompilation(); if (depth < INLINE_CACHE_SIZE) { - final RCallNode current = createCacheNode(frame, function); + final RCallNode current = createCacheNode(frame, function, getEncapsulatingSourceSection()); final RootCallNode cachedNode = new CachedCallNode(this.functionNode, current, new UninitializedCallNode(this), function); current.onCreate(); this.replace(cachedNode); @@ -268,7 +268,7 @@ public abstract class RCallNode extends RNode { return parentNode; } - protected RCallNode createCacheNode(VirtualFrame frame, RFunction function) { + protected RCallNode createCacheNode(VirtualFrame frame, RFunction function, SourceSection debugSrc) { // Check implementation: If written in Java, handle differently! if (function.isBuiltin()) { RootCallTarget callTarget = function.getTarget(); @@ -276,7 +276,7 @@ public abstract class RCallNode extends RNode { if (root != null) { // We inline the given arguments here, as builtins are executed inside the same // frame as they are called. - InlinedArguments inlinedArgs = ArgumentMatcher.matchArgumentsInlined(frame, function, args, getEncapsulatingSourceSection()); + InlinedArguments inlinedArgs = ArgumentMatcher.matchArgumentsInlined(frame, function, args, debugSrc); // TODO Set proper parent <-> child relations for arguments!! return root.inline(inlinedArgs); } @@ -289,7 +289,7 @@ public abstract class RCallNode extends RNode { return new DispatchedVarArgsCallNode(function, args); } else { // Nope! (peeewh) - MatchedArgumentsNode matchedArgs = ArgumentMatcher.matchArguments(frame, function, args, getEncapsulatingSourceSection()); + MatchedArgumentsNode matchedArgs = ArgumentMatcher.matchArguments(frame, function, args, debugSrc); return new DispatchedCallNode(function, matchedArgs); } } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RMissingHelper.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RMissingHelper.java index 724f84f827bc9087aca2214e8e78f7f50cdf90c0..063e5703ed70ade55450d6db62f34ec0e0c6473f 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RMissingHelper.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RMissingHelper.java @@ -22,6 +22,7 @@ */ package com.oracle.truffle.r.nodes.function; +import com.oracle.truffle.api.CompilerDirectives.SlowPath; import com.oracle.truffle.api.frame.*; import com.oracle.truffle.r.nodes.access.*; import com.oracle.truffle.r.runtime.data.*; @@ -78,6 +79,7 @@ public class RMissingHelper { * @param symbol The {@link Symbol} which to check * @return See {@link #isMissingSymbol(RPromise)} */ + @SlowPath public static boolean isMissingArgument(Frame frame, Symbol symbol) { // TODO IsDotDotSymbol: Anything special to do here? @@ -113,6 +115,7 @@ public class RMissingHelper { * {@link #isMissingArgument(Frame, Symbol)}. * @return Whether the given {@link RPromise} represents a symbol that is 'missing' in its frame */ + @SlowPath public static boolean isMissingSymbol(RPromise promise) { boolean result = false; // Missing RPromises throw an error on evaluation, so this might only be checked if it has 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 e999fa8a0f34c29ca543a07423e510164c266608..72ce6ec77e9a177465404850b0f907713e982094 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 @@ -24,15 +24,13 @@ package com.oracle.truffle.r.nodes.unary; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.r.nodes.*; -import com.oracle.truffle.r.nodes.builtin.base.*; import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.*; @NodeField(name = "emptyVectorConvertedToNull", type = boolean.class) public abstract class CastStringNode extends CastNode { - @Child private ToString toString = ToStringFactory.create(new RNode[1], null, null); + @Child private ToStringNode toString = ToStringNodeFactory.create(null); public abstract Object executeString(VirtualFrame frame, int o); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastSymbolNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastSymbolNode.java index 67d668d5d0aa156c804b71ec902e4a9f85087464..82a605f67a383e151e3f183f7496142f8c62368a 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastSymbolNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastSymbolNode.java @@ -25,14 +25,12 @@ package com.oracle.truffle.r.nodes.unary; import com.oracle.truffle.api.CompilerDirectives.SlowPath; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.r.nodes.*; -import com.oracle.truffle.r.nodes.builtin.base.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; @NodeField(name = "emptyVectorConvertedToNull", type = boolean.class) public abstract class CastSymbolNode extends CastNode { - @Child private ToString toString = ToStringFactory.create(new RNode[1], null, null); + @Child private ToStringNode toString = ToStringNodeFactory.create(null); public abstract Object executeSymbol(VirtualFrame frame, Object o); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/ToString.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ToStringNode.java similarity index 87% rename from com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/ToString.java rename to com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ToStringNode.java index d288e844b3fc1df84285754f197d1cd4c80fde56..19128d729f3d80527f71afe0db8def0642460b2e 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/base/ToString.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/ToStringNode.java @@ -20,26 +20,19 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package com.oracle.truffle.r.nodes.builtin.base; - -import static com.oracle.truffle.r.runtime.RBuiltinKind.*; +package com.oracle.truffle.r.nodes.unary; import com.oracle.truffle.api.*; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.CompilerDirectives.SlowPath; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.frame.*; -import com.oracle.truffle.r.nodes.*; -import com.oracle.truffle.r.nodes.builtin.*; import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.data.*; -@RBuiltin(name = "toString", kind = SUBSTITUTE) -// TODO Implement in R -@SuppressWarnings("unused") -public abstract class ToString extends RBuiltinNode { +public abstract class ToStringNode extends UnaryNode { - @Child ToString recursiveToString; + @Child ToStringNode recursiveToString; @CompilationFinal private boolean quotes = true; @@ -50,7 +43,7 @@ public abstract class ToString extends RBuiltinNode { private String toStringRecursive(VirtualFrame frame, Object o) { if (recursiveToString == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); - recursiveToString = insert(ToStringFactory.create(new RNode[1], getBuiltin(), getSuppliedArgsNames())); + recursiveToString = insert(ToStringNodeFactory.create(null)); recursiveToString.setSeparator(separator); recursiveToString.setQuotes(quotes); recursiveToString.setIntL(intL); @@ -61,11 +54,11 @@ public abstract class ToString extends RBuiltinNode { // FIXME custom separators require breaking some rules // FIXME separator should be a @NodeField - not possible as default values cannot be set - public ToString() { + public ToStringNode() { this.separator = DEFAULT_SEPARATOR; } - public ToString(ToString prev) { + public ToStringNode(ToStringNode prev) { this.separator = prev.separator; this.quotes = prev.quotes; this.intL = prev.intL; @@ -101,51 +94,43 @@ public abstract class ToString extends RBuiltinNode { } @Specialization - public String toString(RNull vector) { - controlVisibility(); + public String toString(@SuppressWarnings("unused") RNull vector) { return "NULL"; } @Specialization public String toString(RFunction function) { - controlVisibility(); return RRuntime.toString(function); } @Specialization public String toString(RComplex complex) { - controlVisibility(); return complex.toString(); } @Specialization public String toString(RRaw raw) { - controlVisibility(); return raw.toString(); } @Specialization() public String toString(int operand) { - controlVisibility(); return RRuntime.intToString(operand, intL); } @Specialization public String toString(double operand) { - controlVisibility(); return RRuntime.doubleToString(operand); } @Specialization public String toString(byte operand) { - controlVisibility(); return RRuntime.logicalToString(operand); } @SlowPath @Specialization(order = 100) public String toString(RIntVector vector) { - controlVisibility(); int length = vector.getLength(); if (length == 0) { return "integer(0)"; @@ -163,7 +148,6 @@ public abstract class ToString extends RBuiltinNode { @SlowPath @Specialization(order = 200) public String toString(RDoubleVector vector) { - controlVisibility(); int length = vector.getLength(); if (length == 0) { return "numeric(0)"; @@ -181,7 +165,6 @@ public abstract class ToString extends RBuiltinNode { @SlowPath @Specialization public String toString(RStringVector vector) { - controlVisibility(); int length = vector.getLength(); if (length == 0) { return "character(0)"; @@ -199,7 +182,6 @@ public abstract class ToString extends RBuiltinNode { @SlowPath @Specialization(order = 300) public String toString(RLogicalVector vector) { - controlVisibility(); int length = vector.getLength(); if (length == 0) { return "logical(0)"; @@ -217,7 +199,6 @@ public abstract class ToString extends RBuiltinNode { @SlowPath @Specialization public String toString(RRawVector vector) { - controlVisibility(); int length = vector.getLength(); if (length == 0) { return "raw(0)"; @@ -235,7 +216,6 @@ public abstract class ToString extends RBuiltinNode { @SlowPath @Specialization(order = 500) public String toString(RComplexVector vector) { - controlVisibility(); int length = vector.getLength(); if (length == 0) { return "complex(0)"; @@ -253,7 +233,6 @@ public abstract class ToString extends RBuiltinNode { @SlowPath @Specialization(order = 600) public String toString(VirtualFrame frame, RList vector) { - controlVisibility(); int length = vector.getLength(); if (length == 0) { return "list()"; @@ -280,19 +259,16 @@ public abstract class ToString extends RBuiltinNode { @Specialization public String toString(VirtualFrame frame, RIntSequence vector) { - controlVisibility(); return toStringRecursive(frame, vector.createVector()); } @Specialization public String toString(VirtualFrame frame, RDoubleSequence vector) { - controlVisibility(); return toStringRecursive(frame, vector.createVector()); } @Specialization public String toString(REnvironment env) { - controlVisibility(); return env.toString(); } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryNotNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryNotNode.java index 5238c35319e041a183f0bd2069cca79fcc21a8ff..4fcc2ee67996488fbd73eaa774238ed8f135c072 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryNotNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/UnaryNotNode.java @@ -30,7 +30,7 @@ import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.*; import com.oracle.truffle.r.runtime.ops.na.*; -@RBuiltin(name = "!", kind = RBuiltinKind.PRIMITIVE) +@RBuiltin(name = "!", kind = RBuiltinKind.PRIMITIVE, parameterNames = {""}) public abstract class UnaryNotNode extends RBuiltinNode { private final NACheck na = NACheck.create(); 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 4697ad51043aaf1e9d24a8324d6323de9d72bbe6..b1362c32b997a432d6535af4ac847d02a2a2a7ee 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 @@ -596,7 +596,7 @@ public class RDeparse { RPairList arglist = args; while (arglist != null) { if (arglist.getTag() != null) { - state.append(arglist.getTag()); + state.append(((RSymbol) arglist.getTag()).getName()); if (formals) { if (arglist.car() != RMissing.instance) { state.append(" = "); diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/REnvironment.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/REnvironment.java index 0ad174a769dfb15525b7746ac52839ef20bb766e..b33799831ef61b29bd5cb8e1aa33b532216fd741 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/REnvironment.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/REnvironment.java @@ -73,6 +73,10 @@ import com.oracle.truffle.r.runtime.envframe.*; * "imports" environment. The parent of "package:base" is the empty environment, but the parent of * "namespace:base" is the global environment. * + * TODO retire the {@code Package}, {@code Namespace} and {@code Imports} classes as they are only + * used by the builtin packages, and will be completely redundant when they are loaded from + * serialized package meta-data as will happen in due course. + * */ public abstract class REnvironment implements RAttributable { public enum PackageKind { @@ -486,14 +490,27 @@ public abstract class REnvironment implements RAttributable { if (this instanceof Namespace) { return true; } else { - Object value = frameAccess.get(NAMESPACE_KEY); - if (value != null && value instanceof REnvironment) { - REnvironment info = (REnvironment) value; - Object spec = info.frameAccess.get("spec"); - return (spec != null) && spec instanceof RStringVector && ((RStringVector) spec).getLength() > 0; + RStringVector spec = getNamespaceSpec(); + return spec != null; + } + } + + /** + * Return the "spec" attribute of the "info" env in a namespace or {@code null} if not found. + */ + private RStringVector getNamespaceSpec() { + Object value = frameAccess.get(NAMESPACE_KEY); + if (value != null && value instanceof REnvironment) { + REnvironment info = (REnvironment) value; + Object spec = info.frameAccess.get("spec"); + if ((spec != null) && spec instanceof RStringVector) { + RStringVector infoVec = (RStringVector) spec; + if (infoVec.getLength() > 0) { + return infoVec; + } } - return false; } + return null; } @SlowPath @@ -573,10 +590,20 @@ public abstract class REnvironment implements RAttributable { } protected String getPrintNameHelper() { - if (name.equals(UNNAMED)) { - return String.format("%#x", hashCode()); + String attrName = getName(); + if (name.equals(UNNAMED) && attrName.equals(UNNAMED)) { + /* + * namespaces are a special case; they have no name attribute, but they print with the + * name which is buried. + */ + RStringVector spec = getNamespaceSpec(); + if (spec != null) { + return "namespace:" + spec.getDataAt(0); + } else { + return String.format("%#x", hashCode()); + } } else { - return getName(); + return attrName; } } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java index bca4eb3dca163d6bb1e59c1c2f5350d212c41868..89e9241b88a55dad1e033e25a1c0c93d60749969 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java @@ -370,8 +370,8 @@ public final class RError extends RuntimeException { ATTRIBUTE_VECTOR_SAME_LENGTH("'%s' attribute [%d] must be the same length as the vector [%d]"), SCAN_UNEXPECTED("scan() expected '%s', got '%s'"), MUST_BE_ENVIRON("'%s' must be an environment"), - // below: FIXME: GNU-R gives a list of all unused arguments UNUSED_ARGUMENT("unused argument (%s)"), + UNUSED_ARGUMENTS("unused arguments (%s)"), INFINITE_MISSING_VALUES("infinite or missing values in '%s'"), NON_SQUARE_MATRIX("non-square matrix in '%s'"), LAPACK_ERROR("error code %d from Lapack routine '%s'"), 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 5f18ccaa55ca338d463bb7fcdaecea9126fc0ac1..0544ce74b73d6ad0bc5f8f7297aab39b425132c6 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 @@ -33,7 +33,7 @@ import com.oracle.truffle.r.runtime.gnur.*; public class RPairList implements RAttributable, RAbstractContainer { private Object car; private Object cdr; - private String tag; + private Object tag; private RAttributes attributes; /** * Denotes the (GnuR) typeof entity that the pairlist represents. @@ -47,7 +47,7 @@ public class RPairList implements RAttributable, RAbstractContainer { /** * Variant used in unserialization to record the GnuR type the pairlist denotes. */ - public RPairList(Object car, Object cdr, String tag, SEXPTYPE type) { + public RPairList(Object car, Object cdr, Object tag, SEXPTYPE type) { this.car = car; this.cdr = cdr; this.tag = tag; @@ -87,11 +87,11 @@ public class RPairList implements RAttributable, RAbstractContainer { return pl.car; } - public String getTag() { + public Object getTag() { return tag; } - public void setTag(String tag) { + public void setTag(Object tag) { this.tag = tag; } @@ -157,7 +157,7 @@ public class RPairList implements RAttributable, RAbstractContainer { boolean complete = RDataFactory.COMPLETE_VECTOR; int i = 0; while (pl != null) { - data[i] = pl.tag; + data[i] = (String) pl.tag; if (pl.tag == RRuntime.STRING_NA) { complete = false; } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPromise.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPromise.java index 68fa6885d78e285f8271f93d71f041444a6e8b27..0142a9b114d76153f08ac5cab00211fffafcbf07 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPromise.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPromise.java @@ -177,6 +177,7 @@ public class RPromise { return value; } + @SlowPath protected Object doEvalArgument() { Object result = null; assert env != null; diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BinaryArithmetic.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BinaryArithmetic.java index 4e7b31f24502d55941e0d8b9431a4ad9ae32b047..598c85db612f58480424c5863e300008e4dcc520 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BinaryArithmetic.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BinaryArithmetic.java @@ -27,31 +27,31 @@ public abstract class BinaryArithmetic extends Operation { /* Fake RBuiltins to unify the binary operations */ - @RBuiltin(name = "+", kind = RBuiltinKind.PRIMITIVE) + @RBuiltin(name = "+", kind = RBuiltinKind.PRIMITIVE, parameterNames = {"", ""}) public static class AddBuiltin { } - @RBuiltin(name = "-", kind = RBuiltinKind.PRIMITIVE) + @RBuiltin(name = "-", kind = RBuiltinKind.PRIMITIVE, parameterNames = {"", ""}) public static class SubtractBuiltin { } - @RBuiltin(name = "/", kind = RBuiltinKind.PRIMITIVE) + @RBuiltin(name = "/", kind = RBuiltinKind.PRIMITIVE, parameterNames = {"", ""}) public static class DivBuiltin { } - @RBuiltin(name = "%/%", kind = RBuiltinKind.PRIMITIVE) + @RBuiltin(name = "%/%", kind = RBuiltinKind.PRIMITIVE, parameterNames = {"", ""}) public static class IntegerDivBuiltin { } - @RBuiltin(name = "%%", kind = RBuiltinKind.PRIMITIVE) + @RBuiltin(name = "%%", kind = RBuiltinKind.PRIMITIVE, parameterNames = {"", ""}) public static class ModBuiltin { } - @RBuiltin(name = "*", kind = RBuiltinKind.PRIMITIVE) + @RBuiltin(name = "*", kind = RBuiltinKind.PRIMITIVE, parameterNames = {"", ""}) public static class MultiplyBuiltin { } - @RBuiltin(name = "^", kind = RBuiltinKind.PRIMITIVE) + @RBuiltin(name = "^", kind = RBuiltinKind.PRIMITIVE, parameterNames = {"", ""}) public static class PowBuiltin { } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BinaryCompare.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BinaryCompare.java index 5d72aea5fe043244515536de10145c473d7b8369..8952590b280444e61c953a1a1d85a731c1128363 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BinaryCompare.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BinaryCompare.java @@ -29,27 +29,27 @@ import com.oracle.truffle.r.runtime.ops.na.*; public abstract class BinaryCompare extends BooleanOperation { /* Fake RBuiltins to unify the compare operations */ - @RBuiltin(name = "==", kind = RBuiltinKind.PRIMITIVE) + @RBuiltin(name = "==", kind = RBuiltinKind.PRIMITIVE, parameterNames = {"", ""}) public static class EqualBuiltin { } - @RBuiltin(name = "!=", kind = RBuiltinKind.PRIMITIVE) + @RBuiltin(name = "!=", kind = RBuiltinKind.PRIMITIVE, parameterNames = {"", ""}) public static class NotEqualBuiltin { } - @RBuiltin(name = ">=", kind = RBuiltinKind.PRIMITIVE) + @RBuiltin(name = ">=", kind = RBuiltinKind.PRIMITIVE, parameterNames = {"", ""}) public static class GreaterEqualBuiltin { } - @RBuiltin(name = ">", kind = RBuiltinKind.PRIMITIVE) + @RBuiltin(name = ">", kind = RBuiltinKind.PRIMITIVE, parameterNames = {"", ""}) public static class GreaterBuiltin { } - @RBuiltin(name = "<=", kind = RBuiltinKind.PRIMITIVE) + @RBuiltin(name = "<=", kind = RBuiltinKind.PRIMITIVE, parameterNames = {"", ""}) public static class LessEqualBuiltin { } - @RBuiltin(name = "<", kind = RBuiltinKind.PRIMITIVE) + @RBuiltin(name = "<", kind = RBuiltinKind.PRIMITIVE, parameterNames = {"", ""}) public static class LessBuiltin { } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BinaryLogic.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BinaryLogic.java index 7293e220001b1fff1e8616329d9384eb71e025d9..53eb1c5be405f0d05d40de3548bdb8dcde0fb2de 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BinaryLogic.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/ops/BinaryLogic.java @@ -30,19 +30,19 @@ public abstract class BinaryLogic extends BooleanOperation { /* Fake RBuiltins to unify the binary operations */ - @RBuiltin(name = "&&", kind = RBuiltinKind.PRIMITIVE) + @RBuiltin(name = "&&", kind = RBuiltinKind.PRIMITIVE, parameterNames = {"", ""}) public static class NonVectorAndBuiltin { } - @RBuiltin(name = "||", kind = RBuiltinKind.PRIMITIVE) + @RBuiltin(name = "||", kind = RBuiltinKind.PRIMITIVE, parameterNames = {"", ""}) public static class NonVectorOrBuiltin { } - @RBuiltin(name = "&", kind = RBuiltinKind.PRIMITIVE) + @RBuiltin(name = "&", kind = RBuiltinKind.PRIMITIVE, parameterNames = {"", ""}) public static class AndBuiltin { } - @RBuiltin(name = "|", kind = RBuiltinKind.PRIMITIVE) + @RBuiltin(name = "|", kind = RBuiltinKind.PRIMITIVE, parameterNames = {"", ""}) public static class OrBuiltin { } 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 5ea39b405234586a6422bc9b78b3aced2e443fce..6f055d47c5d3d54a0906f156e6da0b0813bdc684 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 @@ -6043,6 +6043,18 @@ Error in array(dim = c(-2, 2)) : negative length vectors are not allowed #{ length(array(dim=c(1,0,2,3))) } [1] 0 +##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testDelayedAssign +#{ delayedAssign("x", a+b); a <- 1 ; b <- 3 ; x } +[1] 4 + +##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testDelayedAssign +#{ delayedAssign("x", y); y <- 10; x } +[1] 10 + +##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testDelayedAssign +#{ f <- function() { delayedAssign("x", y); y <- 10; x } ; f() } +[1] 10 + ##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testDeparse #{ deparse(TRUE) } [1] "TRUE" @@ -6866,6 +6878,10 @@ Error in rm("foo", envir = baseenv()) : #{ a <- 1; eval(expression(a + 1)) } [1] 2 +##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testEval +#{ e1 <- new.env(); assign("x", 100, e1); e2 <- new.env(parent = e1); evalq(x, e2) } +[1] 100 + ##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testEval #{ eval(2 ^ 2 ^ 3)} [1] 256 @@ -8815,6 +8831,10 @@ attr(,"class") attr(,"class") [1] "fooX" +##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testOpsGroupDispatchLs +#{x<-1;y<-7;class(x)<-"foo";class(y)<-"foo";"*.foo"<-function(e1,e2){min(e1,e2)}; ls()} +[1] "*.foo" "x" "y" + ##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testOrder #{ order(c("a","c","b","d","e","f")) } [1] 1 3 2 4 5 6 @@ -9833,6 +9853,31 @@ numeric(0) #{rep_len(4, x="text")} [1] "text" "text" "text" "text" +##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testRepLen +#{rep_len(c("abcd", "efg"), 0)} +character(0) + +##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testRepLen +#{rep_len(c("abcd", "efg"), 1)} +[1] "abcd" + +##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testRepLen +#{rep_len(c("abcd", "efg"), 14)} + [1] "abcd" "efg" "abcd" "efg" "abcd" "efg" "abcd" "efg" "abcd" "efg" +[11] "abcd" "efg" "abcd" "efg" + +##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testRepLen +#{rep_len(c("abcd", "efg"), 2)} +[1] "abcd" "efg" + +##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testRepLen +#{rep_len(c("abcd", "efg"), 7)} +[1] "abcd" "efg" "abcd" "efg" "abcd" "efg" "abcd" + +##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testRepLen +#{rep_len(c("abcd", "efg"), 8)} +[1] "abcd" "efg" "abcd" "efg" "abcd" "efg" "abcd" "efg" + ##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testRepLen #{rep_len(length.out=4, "text")} [1] "text" "text" "text" "text" @@ -10849,6 +10894,22 @@ character(0) #{ x<-character(); substr(x,integer(),3)<-NULL; x } character(0) +##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testSubstringIgnore +#{ substring("123456", first=2, last=4) } +[1] "234" + +##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testSubstringIgnore +#{ substring("123456", first=2.8, last=4) } +[1] "234" + +##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testSubstringIgnore +#{ substring("fastr", first=NA, last=2) } +[1] NA + +##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testSubstringIgnore +#{ substring(c("hello", "bye"), first=c(1,2,3), last=4) } +[1] "hell" "ye" "ll" + ##com.oracle.truffle.r.test.simple.TestSimpleBuiltins.testSum #{ `sum`(1:10) } [1] 55 @@ -13327,6 +13388,10 @@ $row.names #{ typeof(a~b) } [1] "language" +##com.oracle.truffle.r.test.simple.TestSimpleFunctions.testArgs +#{ f<-function(x, row.names = NULL, optional = FALSE, ...) {print(optional)}; f(c(7,42), row.names=NULL, nm="x") } +[1] FALSE + ##com.oracle.truffle.r.test.simple.TestSimpleFunctions.testBinding #{ f <- function(func, a) { func(a) && TRUE } ; g <- function(x) {TRUE} ; f(g, 5) ; f(is.na, 4) } [1] FALSE @@ -13609,6 +13674,10 @@ Error in f(hello = 1, bye = 3) : unused argument (bye = 3) #{ x<-function(foo,bar){foo*bar} ; x(fo=10, bar=2) } [1] 20 +##com.oracle.truffle.r.test.simple.TestSimpleFunctions.testPromises +#{ f <- function(x) { for (i in 1:10) { x <- g(x,i) }; x }; g <- function(x,i) { x + i }; f(2) } +[1] 57 + ##com.oracle.truffle.r.test.simple.TestSimpleFunctions.testPromises #{ z <- 1 ; f <- function(c = z) { c(1,2) ; z <- z + 1 ; c } ; f() } [1] 1 @@ -13821,9 +13890,18 @@ In if (x) 1 else 2 : #{ if (FALSE) 23 else NULL } NULL +##com.oracle.truffle.r.test.simple.TestSimpleIfEvaluator.testIfVisibility +#{ if (FALSE) 23 else invisible(23) } + ##com.oracle.truffle.r.test.simple.TestSimpleIfEvaluator.testIfVisibility #{ if (FALSE) 23 } +##com.oracle.truffle.r.test.simple.TestSimpleIfEvaluator.testIfVisibility +#{ if (TRUE) invisible(23) else 23 } + +##com.oracle.truffle.r.test.simple.TestSimpleIfEvaluator.testIfVisibility +#{ if (TRUE) invisible(23) } + ##com.oracle.truffle.r.test.simple.TestSimpleIfEvaluator.testIfWithoutElse #if(TRUE) 1 [1] 1 diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/TestBase.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/TestBase.java index 5686c190aca3cb1efd36482d142a18d82bf300dc..9f6e6f50305114e4fb6428474cba0a5517faa12b 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/TestBase.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/TestBase.java @@ -55,6 +55,7 @@ public class TestBase { private static File diffsOutputFile; private static final String GEN_EXPECTED = "gen-expected"; + private static final String GEN_EXPECTED_QUIET = "gen-expected-quiet"; private static final String CHECK_EXPECTED = "check-expected"; private static final String EXPECTED = "expected="; private static final String GEN_FASTR = "gen-fastr="; @@ -76,6 +77,7 @@ public class TestBase { File fastROutputFile = null; boolean checkExpected = false; boolean genExpected = false; + boolean genExpectedQuiet = false; if (arg != null) { String[] args = arg.split(","); for (String directive : args) { @@ -87,6 +89,8 @@ public class TestBase { diffsOutputFile = new File(new File(directive.replace(GEN_DIFFS, "")), TestOutputManager.TEST_DIFF_OUTPUT_FILE); } else if (directive.equals(GEN_EXPECTED)) { genExpected = true; + } else if (directive.equals(GEN_EXPECTED_QUIET)) { + genExpectedQuiet = true; } else if (directive.equals(CHECK_EXPECTED)) { checkExpected = true; } else if (directive.equals(KEEP_TRAILING_WHITESPACEG)) { @@ -98,7 +102,7 @@ public class TestBase { } } } - expectedOutputManager = new ExpectedTestOutputManager(expectedOutputFile, genExpected, checkExpected); + expectedOutputManager = new ExpectedTestOutputManager(expectedOutputFile, genExpected, checkExpected, genExpectedQuiet); fastROutputManager = new FastRTestOutputManager(fastROutputFile); } catch (IOException ex) { throw new RuntimeException(ex); @@ -153,7 +157,7 @@ public class TestBase { Assert.fail("cannot find " + TestOutputManager.TEST_EXPECTED_OUTPUT_FILE + " resource"); } else { try { - expectedOutputManager = new ExpectedTestOutputManager(new File(expectedTestOutputURL.getPath()), false, false); + expectedOutputManager = new ExpectedTestOutputManager(new File(expectedTestOutputURL.getPath()), false, false, false); } catch (IOException ex) { Assert.fail("error reading: " + expectedTestOutputURL.getPath() + ": " + ex); } @@ -163,6 +167,7 @@ public class TestBase { private static class ExpectedTestOutputManager extends TestOutputManager { final boolean generate; + /** * When {@code true}, indicates that test generation is in check only mode. */ @@ -174,10 +179,13 @@ public class TestBase { private boolean haveRSession; - protected ExpectedTestOutputManager(File outputFile, boolean generate, boolean checkOnly) throws IOException { + protected ExpectedTestOutputManager(File outputFile, boolean generate, boolean checkOnly, boolean genExpectedQuiet) throws IOException { super(outputFile); this.checkOnly = checkOnly; this.generate = generate; + if (genExpectedQuiet) { + localDiagnosticHandler.setQuiet(); + } oldExpectedOutputFileContent = readTestOutputFile(); if (generate) { createRSession(); @@ -674,6 +682,8 @@ public class TestBase { private static final LocalDiagnosticHandler localDiagnosticHandler = new LocalDiagnosticHandler(); private static class LocalDiagnosticHandler implements TestOutputManager.DiagnosticHandler { + private boolean quiet; + // CheckStyle: stop system..print check public void warning(String msg) { @@ -681,13 +691,19 @@ public class TestBase { } public void note(String msg) { - System.out.println("note: " + msg); + if (!quiet) { + System.out.println("note: " + msg); + } } public void error(String msg) { System.err.println("error: " + msg); } + void setQuiet() { + quiet = true; + } + } } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/all/AllTests.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/all/AllTests.java index 05c9f0e816d77537450bf2bcca52a8e6a2e3fa2b..4a18b9b9a718b8c57a27460833a4781246121dba 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/all/AllTests.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/all/AllTests.java @@ -6589,32 +6589,37 @@ public class AllTests extends TestBase { } @Test - public void TestSimpleBuiltins_testDelayedAssign_79fb1d399e2b39a496dac5a9749fb873() { + public void TestSimpleBuiltins_testDelayedAssignIgnore_87d161302160393963ba6b1003b818c8() { + assertEval("{ f <- function() print (\"outer\"); g <- function() { delayedAssign(\"f\", 1); f() }; g()}"); + } + + @Test + public void TestSimpleBuiltins_testDelayedAssignIgnore_79fb1d399e2b39a496dac5a9749fb873() { assertEval("{ h <- new.env(parent=emptyenv()) ; delayedAssign(\"x\", y, h, h) ; assign(\"y\", 2, h) ; get(\"x\", h) }"); } @Test - public void TestSimpleBuiltins_testDelayedAssign_af327b1b6a16f6b664839a659452d6ff() { + public void TestSimpleBuiltins_testDelayedAssignIgnore_af327b1b6a16f6b664839a659452d6ff() { assertEval("{ h <- new.env(parent=emptyenv()) ; assign(\"x\", 1, h) ; delayedAssign(\"x\", y, h, h) ; assign(\"y\", 2, h) ; get(\"x\", h) }"); } @Test - public void TestSimpleBuiltins_testDelayedAssign_b0a8cc01cf8e5fc94f5e4084097107ad() { + public void TestSimpleBuiltins_testDelayedAssignIgnore_b0a8cc01cf8e5fc94f5e4084097107ad() { assertEval("{ f <- function(...) { delayedAssign(\"x\", ..1) ; y <<- x } ; f(10) ; y }"); } @Test - public void TestSimpleBuiltins_testDelayedAssign_2650fc25df477fca9f65b4ae42030ddc() { + public void TestSimpleBuiltins_testDelayedAssignIgnore_2650fc25df477fca9f65b4ae42030ddc() { assertEval("{ f <- function() { delayedAssign(\"x\", 3); delayedAssign(\"x\", 2); x } ; f() }"); } @Test - public void TestSimpleBuiltins_testDelayedAssign_8c59e6c2915b2b15a962ae541292c0db() { + public void TestSimpleBuiltins_testDelayedAssignIgnore_8c59e6c2915b2b15a962ae541292c0db() { assertEval("{ f <- function() { x <- 4 ; delayedAssign(\"x\", y); y <- 10; x } ; f() }"); } @Test - public void TestSimpleBuiltins_testDelayedAssign_83064c7d347757ad66074441e8cfc90e() { + public void TestSimpleBuiltins_testDelayedAssignIgnore_83064c7d347757ad66074441e8cfc90e() { assertEvalError("{ f <- function() { delayedAssign(\"x\", y); delayedAssign(\"y\", x) ; x } ; f() }"); } @@ -7548,6 +7553,11 @@ public class AllTests extends TestBase { assertEval("{ ne <- new.env(); evalq(envir=ne, expr=x <- 1); ls(ne) }"); } + @Test + public void TestSimpleBuiltins_testEval_18a57a80600eee4b234b2842bb7b149d() { + assertEval("{ e1 <- new.env(); assign(\"x\", 100, e1); e2 <- new.env(parent = e1); evalq(x, e2) }"); + } + @Test public void TestSimpleBuiltins_testEvalIgnore_a2bb4f39d740a0564a45a2fa5a7f8259() { assertEval("{ eval({ xx <- pi; xx^2}) ; xx }"); @@ -11058,6 +11068,36 @@ public class AllTests extends TestBase { assertEval("{x<-\"text\"; length.out<-4; rep_len(length.out=length.out, x=x)}"); } + @Test + public void TestSimpleBuiltins_testRepLen_8429224a33cc26907ae3f0e002b3d7a9() { + assertEval("{rep_len(c(\"abcd\", \"efg\"), 7)}"); + } + + @Test + public void TestSimpleBuiltins_testRepLen_81b03b50821133ffb87b06692b01665e() { + assertEval("{rep_len(c(\"abcd\", \"efg\"), 14)}"); + } + + @Test + public void TestSimpleBuiltins_testRepLen_3adbca74b8af3c026793e1946f29b25f() { + assertEval("{rep_len(c(\"abcd\", \"efg\"), 8)}"); + } + + @Test + public void TestSimpleBuiltins_testRepLen_36703236ce021537228fca985495233a() { + assertEval("{rep_len(c(\"abcd\", \"efg\"), 0)}"); + } + + @Test + public void TestSimpleBuiltins_testRepLen_384cd1468eadfe80fc5c51793f3b2b35() { + assertEval("{rep_len(c(\"abcd\", \"efg\"), 1)}"); + } + + @Test + public void TestSimpleBuiltins_testRepLen_5b20f822b44b9833616610e8b91bf41b() { + assertEval("{rep_len(c(\"abcd\", \"efg\"), 2)}"); + } + @Test public void TestSimpleBuiltins_testRev_4d0b89f7d5b9601a90230cf009915fc3() { assertEval("{ rev(1:3) }"); @@ -15243,6 +15283,16 @@ public class AllTests extends TestBase { assertEval("{ class(a~b) }"); } + @Test + public void TestSimpleFunctions_testArgs_88c2c495f154230921998b06b16d441c() { + assertEval("{ f<-function(x, row.names = NULL, optional = FALSE, ...) {print(optional)}; f(c(7,42), row.names=NULL, nm=\"x\") }"); + } + + @Test + public void TestSimpleFunctions_testArgsIgnore_4f0bba29449d73452b8aeb86b93aafb5() { + assertEval("{ f<-function(x, row.names = NULL, optional = FALSE, ...) {print(optional); for (i in list(...)) {print(i)} }; f(c(7,42), row.names=NULL, nm=\"x\") }"); + } + @Test public void TestSimpleFunctions_testBinding_08912db0fc81d6f3582a954d1f9c1fa5() { assertEval("{ myapp <- function(f, x, y) { f(x,y) } ; myapp(function(x,y) { x + y }, 1, 2) ; myapp(sum, 1, 2) }"); @@ -15878,6 +15928,11 @@ public class AllTests extends TestBase { assertEval("{ z <- 1 ; f <- function(c = z) { c(1,2) ; z <- z + 1 ; c } ; f() }"); } + @Test + public void TestSimpleFunctions_testPromises_b6fbb8465490b39a24121d9c2576252a() { + assertEval("{ f <- function(x) { for (i in 1:10) { x <- g(x,i) }; x }; g <- function(x,i) { x + i }; f(2) }"); + } + @Test public void TestSimpleFunctions_testPromisesIgnore_c7558b8584a0a8c1dff6c7ee5575ab52() { assertEval("{ f <- function(x = z) { z = 1 ; x } ; f() }"); @@ -16138,6 +16193,21 @@ public class AllTests extends TestBase { assertEval("{ if (FALSE) 23 else NULL }"); } + @Test + public void TestSimpleIfEvaluator_testIfVisibility_623c4f9534806a63158804e058d093cb() { + assertEval("{ if (TRUE) invisible(23) else 23 }"); + } + + @Test + public void TestSimpleIfEvaluator_testIfVisibility_39dd9ca187b36acefd2b7bb24fbf9873() { + assertEval("{ if (TRUE) invisible(23) }"); + } + + @Test + public void TestSimpleIfEvaluator_testIfVisibility_01427999a084605da3b7f52f6cccf2d1() { + assertEval("{ if (FALSE) 23 else invisible(23) }"); + } + @Test public void TestSimpleIfEvaluator_testIfWithoutElse_fda700832dfd7d9e6c06cb66fd9e25c8() { assertEval("if(TRUE) 1"); @@ -23388,6 +23458,11 @@ public class AllTests extends TestBase { assertEval("{ x <- 1:3 ; f <- function() { x[2] <- 10 ; x[2] <<- 100 ; x[2] <- 1000 } ; f() ; x }"); } + @Test + public void TestSimpleVectors_testTmpUpdate_f6ccb4168af3fd4313e35696afc3f2f5() { + assertEval("{ x<-c(1,2); x[1]<-42; `*tmp*`[1]<-7; x }"); + } + @Test public void TestSimpleVectors_testUpdateOther_eea525ae4479446e708a52622475cd5b() { assertEval("{ f<-function() { print(`*tmp*`[2]); `*tmp*`[2]<-7; 1 } ; x<-c(1,2); x[f()]<-42; x }"); @@ -23403,11 +23478,6 @@ public class AllTests extends TestBase { assertEval("{ x<-c(1,2); f<-function() { x<-c(100, 200); x[1]<-4; print(x) } ; f(); x }"); } - @Test - public void TestSimpleVectors_testUpdateOther_f6ccb4168af3fd4313e35696afc3f2f5() { - assertEval("{ x<-c(1,2); x[1]<-42; `*tmp*`[1]<-7; x }"); - } - @Test public void TestSimpleVectors_testUpdateOther_2a527d7409757c6f8ae809606cf60294() { assertEval("{ x<-c(1,2); f<-function() { x<-c(100, 200); x[1]<<-4; print(x) } ; f(); x }"); diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/failing/FailingTests.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/failing/FailingTests.java index 67778915d92e30798d8543c7ad823e4317a6aed5..e1eb7051c04847deff7ad87921782f450d32748e 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/failing/FailingTests.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/failing/FailingTests.java @@ -639,47 +639,37 @@ public class FailingTests extends TestBase { } @Ignore - public void TestSimpleBuiltins_testDelayedAssign_8ec95e38ecb3a999ffba3e7abc6ffb72() { - assertEval("{ delayedAssign(\"x\", y); y <- 10; x }"); + public void TestSimpleBuiltins_testDelayedAssignIgnore_87d161302160393963ba6b1003b818c8() { + assertEval("{ f <- function() print (\"outer\"); g <- function() { delayedAssign(\"f\", 1); f() }; g()}"); } @Ignore - public void TestSimpleBuiltins_testDelayedAssign_e828fbbef10258dab93aa4d7350c38f9() { - assertEval("{ delayedAssign(\"x\", a+b); a <- 1 ; b <- 3 ; x }"); - } - - @Ignore - public void TestSimpleBuiltins_testDelayedAssign_cedc0d1753c9e0fc71d5868f5654e3ef() { - assertEval("{ f <- function() { delayedAssign(\"x\", y); y <- 10; x } ; f() }"); - } - - @Ignore - public void TestSimpleBuiltins_testDelayedAssign_79fb1d399e2b39a496dac5a9749fb873() { + public void TestSimpleBuiltins_testDelayedAssignIgnore_79fb1d399e2b39a496dac5a9749fb873() { assertEval("{ h <- new.env(parent=emptyenv()) ; delayedAssign(\"x\", y, h, h) ; assign(\"y\", 2, h) ; get(\"x\", h) }"); } @Ignore - public void TestSimpleBuiltins_testDelayedAssign_af327b1b6a16f6b664839a659452d6ff() { + public void TestSimpleBuiltins_testDelayedAssignIgnore_af327b1b6a16f6b664839a659452d6ff() { assertEval("{ h <- new.env(parent=emptyenv()) ; assign(\"x\", 1, h) ; delayedAssign(\"x\", y, h, h) ; assign(\"y\", 2, h) ; get(\"x\", h) }"); } @Ignore - public void TestSimpleBuiltins_testDelayedAssign_b0a8cc01cf8e5fc94f5e4084097107ad() { + public void TestSimpleBuiltins_testDelayedAssignIgnore_b0a8cc01cf8e5fc94f5e4084097107ad() { assertEval("{ f <- function(...) { delayedAssign(\"x\", ..1) ; y <<- x } ; f(10) ; y }"); } @Ignore - public void TestSimpleBuiltins_testDelayedAssign_2650fc25df477fca9f65b4ae42030ddc() { + public void TestSimpleBuiltins_testDelayedAssignIgnore_2650fc25df477fca9f65b4ae42030ddc() { assertEval("{ f <- function() { delayedAssign(\"x\", 3); delayedAssign(\"x\", 2); x } ; f() }"); } @Ignore - public void TestSimpleBuiltins_testDelayedAssign_8c59e6c2915b2b15a962ae541292c0db() { + public void TestSimpleBuiltins_testDelayedAssignIgnore_8c59e6c2915b2b15a962ae541292c0db() { assertEval("{ f <- function() { x <- 4 ; delayedAssign(\"x\", y); y <- 10; x } ; f() }"); } @Ignore - public void TestSimpleBuiltins_testDelayedAssign_83064c7d347757ad66074441e8cfc90e() { + public void TestSimpleBuiltins_testDelayedAssignIgnore_83064c7d347757ad66074441e8cfc90e() { assertEvalError("{ f <- function() { delayedAssign(\"x\", y); delayedAssign(\"y\", x) ; x } ; f() }"); } @@ -1113,11 +1103,6 @@ public class FailingTests extends TestBase { assertEval("{ `%*%`(3,5) }"); } - @Ignore - public void TestSimpleBuiltins_testOpsGroupDispatchLs_2b92f252b506f74c3dd61aa019e285ed() { - assertEval("{x<-1;y<-7;class(x)<-\"foo\";class(y)<-\"foo\";\"*.foo\"<-function(e1,e2){min(e1,e2)}; ls()}"); - } - @Ignore public void TestSimpleBuiltins_testOrderIgnore_9d9e462e8a8cc7dbbf92366b9602bf39() { assertEval("{ order(1:3) }"); @@ -1863,26 +1848,6 @@ public class FailingTests extends TestBase { assertEval("{ f <- function(...) { substitute(list(...)) } ; f(x + z, a * b) }"); } - @Ignore - public void TestSimpleBuiltins_testSubstringIgnore_41302c9bd877c3627e699cd303bfef78() { - assertEval("{ substring(\"123456\", first=2, last=4) }"); - } - - @Ignore - public void TestSimpleBuiltins_testSubstringIgnore_747b32e2b791c976fc9b634a5aef6b23() { - assertEval("{ substring(\"123456\", first=2.8, last=4) }"); - } - - @Ignore - public void TestSimpleBuiltins_testSubstringIgnore_8ce15f4973c2ddb4ca609ef2c4836ab5() { - assertEval("{ substring(c(\"hello\", \"bye\"), first=c(1,2,3), last=4) }"); - } - - @Ignore - public void TestSimpleBuiltins_testSubstringIgnore_6dd56114a5d7ba502c449ca3c03308ae() { - assertEval("{ substring(\"fastr\", first=NA, last=2) }"); - } - @Ignore public void TestSimpleBuiltins_testSumIgnore_512304594d55f1330efacd6cc594cf7a() { assertEval("{ sum(0, 1[3]) }"); @@ -2053,6 +2018,11 @@ public class FailingTests extends TestBase { assertEval("{ f <- function(a,b) { a > b } ; f(1,2) ; f(1L,2) ; f(\"hello\"[2], \"hi\") }"); } + @Ignore + public void TestSimpleFunctions_testArgsIgnore_4f0bba29449d73452b8aeb86b93aafb5() { + assertEval("{ f<-function(x, row.names = NULL, optional = FALSE, ...) {print(optional); for (i in list(...)) {print(i)} }; f(c(7,42), row.names=NULL, nm=\"x\") }"); + } + @Ignore public void TestSimpleFunctions_testDefinitionsIgnore_b8d75a017c31d73d6dbf7c6a93953d67() { assertEval("{ x <- function(a,b) { a^b } ; f <- function() { x <- \"sum\" ; sapply(1, x, 2) } ; f() }"); @@ -2528,6 +2498,11 @@ public class FailingTests extends TestBase { assertEvalError("{ x <- 4:10 ; x[[\"z\"]] <- NULL ; x }"); } + @Ignore + public void TestSimpleVectors_testTmpUpdate_f6ccb4168af3fd4313e35696afc3f2f5() { + assertEval("{ x<-c(1,2); x[1]<-42; `*tmp*`[1]<-7; x }"); + } + @Ignore public void TestSimpleVectors_testUpdateOther_eea525ae4479446e708a52622475cd5b() { assertEval("{ f<-function() { print(`*tmp*`[2]); `*tmp*`[2]<-7; 1 } ; x<-c(1,2); x[f()]<-42; x }"); @@ -2543,11 +2518,6 @@ public class FailingTests extends TestBase { assertEval("{ x<-c(1,2); f<-function() { x<-c(100, 200); x[1]<-4; print(x) } ; f(); x }"); } - @Ignore - public void TestSimpleVectors_testUpdateOther_f6ccb4168af3fd4313e35696afc3f2f5() { - assertEval("{ x<-c(1,2); x[1]<-42; `*tmp*`[1]<-7; x }"); - } - @Ignore public void TestSimpleVectors_testUpdateOther_2a527d7409757c6f8ae809606cf60294() { assertEval("{ x<-c(1,2); f<-function() { x<-c(100, 200); x[1]<<-4; print(x) } ; f(); x }"); diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/generate/TestOutputManager.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/generate/TestOutputManager.java index dbd1f3d0630989f47e40ae03f7f997fa0472a6db..34527d3b192ebee4d857e72fc8a82455d66d373b 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/generate/TestOutputManager.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/generate/TestOutputManager.java @@ -27,10 +27,10 @@ import java.util.*; /** * Supports the management of expected test output. - * + * * In the normal mode of operation (i.e. during unit testing) an existing file of expected outputs * is read and an optimized lookup map is created for use by {@link #getOutput(String)}. - * + * */ public class TestOutputManager { /** @@ -173,7 +173,7 @@ public class TestOutputManager { try (SaveBufferedReader in = new SaveBufferedReader(new FileReader(outputFile), content)) { // line format for element name: ##elementName // line format for input lines: #input - // output lines do not start with # + // output lines do not start with ## String line = in.readLine(); while (true) { if (line == null) { @@ -191,7 +191,7 @@ public class TestOutputManager { StringBuilder output = new StringBuilder(); while (true) { line = in.readLine(); - if (line == null || line.startsWith("#")) { + if (line == null || line.startsWith("##")) { break; } output.append(line).append('\n'); @@ -207,11 +207,11 @@ public class TestOutputManager { /** * Writes the contents of {@link #testMaps} to {link #testOutputFile}. - * + * * @param oldContent can be passed in to avoid the file update if the content would not change * @param checkOnly does not update the file but returns {@code true} if it would be updated. In * this case, {@code oldContent} must be provided. - * + * * @return {@code true} if the file was updated */ public boolean writeTestOutputFile(String oldContent, boolean checkOnly) throws IOException { @@ -311,7 +311,7 @@ public class TestOutputManager { /** * Generate a test result using GnuR. - * + * * @param testElementName identification of the annotated test element, i.e., * {@code class.testmethod}. * @param testMethodName name of method invoking specific test diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleBuiltins.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleBuiltins.java index e2b0354c8233f17a3bce6bcd4dd5230a19a1dcce..d299887dafad27e31ddde2c22affd6385542a979 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleBuiltins.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleBuiltins.java @@ -231,6 +231,13 @@ public class TestSimpleBuiltins extends TestBase { assertEval("{rep_len(4, x=\"text\")}"); assertEval("{x<-\"text\"; length.out<-4; rep_len(x=x, length.out=length.out)}"); assertEval("{x<-\"text\"; length.out<-4; rep_len(length.out=length.out, x=x)}"); + // test string vector argument + assertEval("{rep_len(c(\"abcd\", \"efg\"), 7)}"); + assertEval("{rep_len(c(\"abcd\", \"efg\"), 14)}"); + assertEval("{rep_len(c(\"abcd\", \"efg\"), 8)}"); + assertEval("{rep_len(c(\"abcd\", \"efg\"), 0)}"); + assertEval("{rep_len(c(\"abcd\", \"efg\"), 1)}"); + assertEval("{rep_len(c(\"abcd\", \"efg\"), 2)}"); } @Test @@ -1125,7 +1132,6 @@ public class TestSimpleBuiltins extends TestBase { } @Test - @Ignore public void testSubstringIgnore() { assertEval("{ substring(\"123456\", first=2, last=4) }"); assertEval("{ substring(\"123456\", first=2.8, last=4) }"); @@ -2241,11 +2247,16 @@ public class TestSimpleBuiltins extends TestBase { } @Test - @Ignore public void testDelayedAssign() { assertEval("{ delayedAssign(\"x\", y); y <- 10; x }"); assertEval("{ delayedAssign(\"x\", a+b); a <- 1 ; b <- 3 ; x }"); assertEval("{ f <- function() { delayedAssign(\"x\", y); y <- 10; x } ; f() }"); + } + + @Test + @Ignore + public void testDelayedAssignIgnore() { + assertEval("{ f <- function() print (\"outer\"); g <- function() { delayedAssign(\"f\", 1); f() }; g()}"); assertEval("{ h <- new.env(parent=emptyenv()) ; delayedAssign(\"x\", y, h, h) ; assign(\"y\", 2, h) ; get(\"x\", h) }"); assertEval("{ h <- new.env(parent=emptyenv()) ; assign(\"x\", 1, h) ; delayedAssign(\"x\", y, h, h) ; assign(\"y\", 2, h) ; get(\"x\", h) }"); assertEvalError("{ f <- function() { delayedAssign(\"x\", y); delayedAssign(\"y\", x) ; x } ; f() }"); @@ -2380,6 +2391,7 @@ public class TestSimpleBuiltins extends TestBase { assertEval("{ ne <- new.env(); eval(x <- 1, ne); ls() }"); assertEval("{ ne <- new.env(); evalq(x <- 1, ne); ls(ne) }"); assertEval("{ ne <- new.env(); evalq(envir=ne, expr=x <- 1); ls(ne) }"); + assertEval("{ e1 <- new.env(); assign(\"x\", 100, e1); e2 <- new.env(parent = e1); evalq(x, e2) }"); } @Test @@ -2877,7 +2889,6 @@ public class TestSimpleBuiltins extends TestBase { } @Test - @Ignore public void testOpsGroupDispatchLs() { assertEval("{x<-1;y<-7;class(x)<-\"foo\";class(y)<-\"foo\";\"*.foo\"<-function(e1,e2){min(e1,e2)}; ls()}"); } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleFunctions.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleFunctions.java index e1eeeffcdbb825a2873843305e1dab581aa13f85..50d258d132ac3a0ef511240e5c89b642e8735d1b 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleFunctions.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleFunctions.java @@ -151,6 +151,7 @@ public class TestSimpleFunctions extends TestBase { @Test public void testPromises() { assertEval("{ z <- 1 ; f <- function(c = z) { c(1,2) ; z <- z + 1 ; c } ; f() }"); + assertEval("{ f <- function(x) { for (i in 1:10) { x <- g(x,i) }; x }; g <- function(x,i) { x + i }; f(2) }"); } @Test @@ -244,4 +245,14 @@ public class TestSimpleFunctions extends TestBase { assertEval("{ f <- function(x) x+1 ; g <- function(x) x+2 ; funs <- list(f,g) ; funs[[2]](1) }"); } + @Test + public void testArgs() { + assertEval("{ f<-function(x, row.names = NULL, optional = FALSE, ...) {print(optional)}; f(c(7,42), row.names=NULL, nm=\"x\") }"); + } + + @Test + @Ignore + public void testArgsIgnore() { + assertEval("{ f<-function(x, row.names = NULL, optional = FALSE, ...) {print(optional); for (i in list(...)) {print(i)} }; f(c(7,42), row.names=NULL, nm=\"x\") }"); + } } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleIfEvaluator.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleIfEvaluator.java index ef249716ed6616afb9d791869b50d4ea18f805c6..4c301fc6c23d35b129c1559fecab74dbfe32fdd6 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleIfEvaluator.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleIfEvaluator.java @@ -96,6 +96,9 @@ public class TestSimpleIfEvaluator extends TestBase { public void testIfVisibility() { assertEval("{ if (FALSE) 23 }"); assertEval("{ if (FALSE) 23 else NULL }"); + assertEval("{ if (TRUE) invisible(23) else 23 }"); + assertEval("{ if (TRUE) invisible(23) }"); + assertEval("{ if (FALSE) 23 else invisible(23) }"); } } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleVectors.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleVectors.java index 65ed283362faaed20b88f3d47b1a0b9b86962c2d..c65e5d02e69b42f5e1e482e6fdf9ffe62e3d94e0 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleVectors.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/simple/TestSimpleVectors.java @@ -2077,7 +2077,12 @@ public class TestSimpleVectors extends TestBase { assertEval("{ f<-function() { print(`*tmp*`[2]); `*tmp*`[2]<-7; 1 } ; x<-c(1,2); x[f()]<-42; x }"); assertEval("{ f<-function() { print(`*tmp*`[2]); `*tmp*`[2]<<-7; 1 } ; x<-c(1,2); x[f()]<-42; x }"); assertEval("{ x<-c(1,2); f<-function() { x<-c(100, 200); x[1]<-4; print(x) } ; f(); x }"); - assertEval("{ x<-c(1,2); x[1]<-42; `*tmp*`[1]<-7; x }"); assertEval("{ x<-c(1,2); f<-function() { x<-c(100, 200); x[1]<<-4; print(x) } ; f(); x }"); } + + @Test + @Ignore + public void testTmpUpdate() { + assertEval("{ x<-c(1,2); x[1]<-42; `*tmp*`[1]<-7; x }"); + } } diff --git a/mx.fastr/mx_fastr.py b/mx.fastr/mx_fastr.py index 7774ba33e652119d240ca82b1cb2a609af86aedf..36dad1dc2edbd3a780b90205f2e8690d5902b53d 100644 --- a/mx.fastr/mx_fastr.py +++ b/mx.fastr/mx_fastr.py @@ -193,6 +193,9 @@ def _junit_r_harness(args, vmArgs, junitArgs): if args.keep_trailing_whitespace: runlistener_arg = add_arg_separator() runlistener_arg += 'keep-trailing-whitespace' + if args.gen_expected_quiet: + runlistener_arg = add_arg_separator() + runlistener_arg += 'gen-expected-quiet' if args.gen_diff_output: runlistener_arg = add_arg_separator() @@ -220,6 +223,7 @@ def junit(args): '''run R Junit tests''' parser = ArgumentParser(prog='r junit') parser.add_argument('--gen-expected-output', action='store_true', help='generate/update expected test output file') + parser.add_argument('--gen-expected-quiet', action='store_true', help='suppress output on new tests being added') parser.add_argument('--keep-trailing-whitespace', action='store_true', help='keep trailing whitespace in expected test output file') parser.add_argument('--check-expected-output', action='store_true', help='check but do not update expected test output file') parser.add_argument('--gen-fastr-output', action='store', metavar='<path>', help='generate FastR test output file') @@ -239,12 +243,18 @@ def _default_unit_tests(): def testgen(args): '''generate the expected output for unit tests, and All/Failing test classes''' + parser = ArgumentParser(prog='r testgen') + parser.add_argument('--tests', action='store', default=_default_unit_tests(), help='pattern to match test classes') + args = parser.parse_args(args) # clean the test project to invoke the test analyzer AP testOnly = ['--projects', 'com.oracle.truffle.r.test'] mx.clean(['--no-dist', ] + testOnly) mx.build(testOnly) # now just invoke junit with the appropriate options - junit(args + ['--tests', _default_unit_tests(), '--gen-expected-output']) + mx.log("generating expected output for packages: ") + for pkg in args.tests.split(','): + mx.log(" " + str(pkg)) + junit(['--tests', args.tests, '--gen-expected-output', '--gen-expected-quiet']) def unittest(args): print "use 'junit --tests testclasses' or 'junitsimple' to run FastR unit tests"