diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AnyNA.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AnyNA.java index 38789f6c31b05e8622637f3bbde62bb4dfd9fa29..f7be50677a4077bef69c530505b797df8c0d4892 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AnyNA.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AnyNA.java @@ -33,17 +33,10 @@ import com.oracle.truffle.r.runtime.RBuiltinKind; import com.oracle.truffle.r.runtime.RDispatch; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.data.RComplex; -import com.oracle.truffle.r.runtime.data.RFactor; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RRaw; -import com.oracle.truffle.r.runtime.data.model.RAbstractComplexVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractRawVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractVector; +import com.oracle.truffle.r.runtime.data.model.*; import com.oracle.truffle.r.runtime.ops.na.NACheck; @RBuiltin(name = "anyNA", kind = RBuiltinKind.PRIMITIVE, parameterNames = {"x"}, dispatch = RDispatch.INTERNAL_GENERIC) @@ -140,11 +133,6 @@ public abstract class AnyNA extends RBuiltinNode { return doScalar(false); } - @Specialization - protected byte isNA(RFactor value) { - return doVector(value.getVector(), (v, i) -> naCheck.check(v.getDataAt(i))); - } - protected AnyNA createRecursive() { return AnyNANodeGen.create(null); } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsDouble.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsDouble.java index fa8dec148fd08e6e98b32a2e18097b45c6269008..5b8d1e5d4807c0f7d0af5120f518d7946bbbd4de 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsDouble.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsDouble.java @@ -30,13 +30,7 @@ import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.unary.CastDoubleNode; import com.oracle.truffle.r.nodes.unary.CastDoubleNodeGen; import com.oracle.truffle.r.runtime.RBuiltin; -import com.oracle.truffle.r.runtime.data.RComplex; -import com.oracle.truffle.r.runtime.data.RDataFactory; -import com.oracle.truffle.r.runtime.data.RDoubleSequence; -import com.oracle.truffle.r.runtime.data.RDoubleVector; -import com.oracle.truffle.r.runtime.data.RFactor; -import com.oracle.truffle.r.runtime.data.RIntSequence; -import com.oracle.truffle.r.runtime.data.RNull; +import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; @RBuiltin(name = "as.double", aliases = {"as.numeric"}, kind = PRIMITIVE, parameterNames = {"x", "..."}) @@ -116,9 +110,4 @@ public abstract class AsDouble extends RBuiltinNode { initCast(); return (RDoubleVector) castDoubleNode.executeDouble(vector); } - - @Specialization - protected RDoubleVector asDouble(RFactor vector) { - return asDouble(vector.getVector()); - } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsInteger.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsInteger.java index 5f760658c2501b741868d7cbef536235cd53c8ea..02ea4ef335d976d9c416d0d91fc283a6866b1990 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsInteger.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsInteger.java @@ -31,13 +31,7 @@ import com.oracle.truffle.r.nodes.unary.CastIntegerNode; import com.oracle.truffle.r.nodes.unary.CastIntegerNodeGen; import com.oracle.truffle.r.runtime.RBuiltin; import com.oracle.truffle.r.runtime.conn.RConnection; -import com.oracle.truffle.r.runtime.data.RComplex; -import com.oracle.truffle.r.runtime.data.RDataFactory; -import com.oracle.truffle.r.runtime.data.RFactor; -import com.oracle.truffle.r.runtime.data.RIntSequence; -import com.oracle.truffle.r.runtime.data.RIntVector; -import com.oracle.truffle.r.runtime.data.RNull; -import com.oracle.truffle.r.runtime.data.RRaw; +import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; @@ -119,11 +113,6 @@ public abstract class AsInteger extends RBuiltinNode { return (RAbstractIntVector) castIntNode.executeInt(vector); } - @Specialization - protected RIntVector asInteger(RFactor factor) { - return asInteger(factor.getVector()); - } - @Specialization protected int asInteger(RConnection conn) { return conn.getDescriptor(); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java index 7d067318ffd014d0e830cb5de23443bbab1aa67a..b7c3348fa9ac9ac44554ad2aa232bf2802507337 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsVector.java @@ -24,243 +24,233 @@ package com.oracle.truffle.r.nodes.builtin.base; import static com.oracle.truffle.r.runtime.RBuiltinKind.INTERNAL; +import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.dsl.TypeSystemReference; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; -import com.oracle.truffle.r.nodes.unary.CastComplexNode; -import com.oracle.truffle.r.nodes.unary.CastDoubleNode; -import com.oracle.truffle.r.nodes.unary.CastExpressionNode; -import com.oracle.truffle.r.nodes.unary.CastIntegerNode; -import com.oracle.truffle.r.nodes.unary.CastListNode; -import com.oracle.truffle.r.nodes.unary.CastListNodeGen; -import com.oracle.truffle.r.nodes.unary.CastLogicalNode; -import com.oracle.truffle.r.nodes.unary.CastRawNode; -import com.oracle.truffle.r.nodes.unary.CastSymbolNode; -import com.oracle.truffle.r.runtime.RBuiltin; -import com.oracle.truffle.r.runtime.RError; -import com.oracle.truffle.r.runtime.RRuntime; -import com.oracle.truffle.r.runtime.RType; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; -import com.oracle.truffle.r.runtime.data.RComplex; -import com.oracle.truffle.r.runtime.data.RDataFactory; -import com.oracle.truffle.r.runtime.data.RDouble; -import com.oracle.truffle.r.runtime.data.RFactor; -import com.oracle.truffle.r.runtime.data.RIntVector; -import com.oracle.truffle.r.runtime.data.RInteger; -import com.oracle.truffle.r.runtime.data.RList; -import com.oracle.truffle.r.runtime.data.RLogical; -import com.oracle.truffle.r.runtime.data.RMissing; -import com.oracle.truffle.r.runtime.data.RNull; -import com.oracle.truffle.r.runtime.data.RRaw; -import com.oracle.truffle.r.runtime.data.RSymbol; -import com.oracle.truffle.r.runtime.data.RVector; +import com.oracle.truffle.r.nodes.builtin.base.AsVectorNodeGen.AsVectorInternalNodeGen; +import com.oracle.truffle.r.nodes.function.ClassHierarchyNode; +import com.oracle.truffle.r.nodes.function.ClassHierarchyNodeGen; +import com.oracle.truffle.r.nodes.function.S3FunctionLookupNode; +import com.oracle.truffle.r.nodes.function.UseMethodInternalNode; +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.RAbstractContainer; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; @RBuiltin(name = "as.vector", kind = INTERNAL, parameterNames = {"x", "mode"}) public abstract class AsVector extends RBuiltinNode { - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); + @Child private AsVectorInternal internal = AsVectorInternalNodeGen.create(); + @Child private ClassHierarchyNode classHierarchy = ClassHierarchyNodeGen.create(false, false); + @Child private UseMethodInternalNode useMethod; + + private final ConditionProfile hasClassProfile = ConditionProfile.createBinaryProfile(); @Override protected void createCasts(CastBuilder casts) { casts.firstStringWithError(1, RError.Message.INVALID_ARGUMENT, "mode"); } - @Specialization - protected Object asVector(RNull x, @SuppressWarnings("unused") RMissing mode) { - controlVisibility(); - return x; + protected static AsVectorInternal createInternal() { + return AsVectorInternalNodeGen.create(); } - @Specialization(guards = "castToString(mode)") - protected Object asVectorString(Object x, @SuppressWarnings("unused") String mode, // - @Cached("create()") AsCharacter asCharacter) { - controlVisibility(); - return asCharacter.execute(x); - } + private static final ArgumentsSignature SIGNATURE = ArgumentsSignature.get("x", "mode"); - @Specialization(guards = "castToInt(x, mode)") - protected Object asVectorInt(RAbstractContainer x, @SuppressWarnings("unused") String mode, // - @Cached("createNonPreserving()") CastIntegerNode cast) { + @Specialization + protected Object asVector(VirtualFrame frame, Object x, String mode) { controlVisibility(); - return cast.execute(x); + RStringVector clazz = classHierarchy.execute(x); + if (hasClassProfile.profile(clazz != null)) { + if (useMethod == null) { + // Note: this dispatch takes care of factor, because there is as.vector.factor + // specialization in R + CompilerDirectives.transferToInterpreterAndInvalidate(); + useMethod = insert(new UseMethodInternalNode("as.vector", SIGNATURE, false)); + } + try { + return useMethod.execute(frame, clazz, new Object[]{x, mode}); + } catch (S3FunctionLookupNode.NoGenericMethodException e) { + // fallthrough + } + } + return internal.execute(x, mode); } - @Specialization(guards = "castToDouble(x, mode)") - protected Object asVectorDouble(RAbstractContainer x, @SuppressWarnings("unused") String mode, // - @Cached("createNonPreserving()") CastDoubleNode cast) { - controlVisibility(); - return cast.execute(x); - } + @TypeSystemReference(RTypes.class) + public abstract static class AsVectorInternal extends Node { - @Specialization(guards = "castToComplex(x, mode)") - protected Object asVectorComplex(RAbstractContainer x, @SuppressWarnings("unused") String mode, // - @Cached("createNonPreserving()") CastComplexNode cast) { - controlVisibility(); - return cast.execute(x); - } + public abstract Object execute(Object x, String mode); - @Specialization(guards = "castToLogical(x, mode)") - protected Object asVectorLogical(RAbstractContainer x, @SuppressWarnings("unused") String mode, // - @Cached("createNonPreserving()") CastLogicalNode cast) { - controlVisibility(); - return cast.execute(x); - } + private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); - @Specialization(guards = "castToRaw(x, mode)") - protected Object asVectorRaw(RAbstractContainer x, @SuppressWarnings("unused") String mode, // - @Cached("createNonPreserving()") CastRawNode cast) { - controlVisibility(); - return cast.execute(x); - } + @Specialization(guards = "castToString(mode)") + protected Object asVectorString(Object x, @SuppressWarnings("unused") String mode, // + @Cached("create()") AsCharacter asCharacter) { + return asCharacter.execute(x); + } - protected static CastListNode createListCast() { - return CastListNodeGen.create(true, false, false); - } + @Specialization(guards = "castToInt(x, mode)") + protected Object asVectorInt(RAbstractContainer x, @SuppressWarnings("unused") String mode, // + @Cached("createNonPreserving()") CastIntegerNode cast) { + return cast.execute(x); + } - @Specialization(guards = "castToList(mode)") - protected Object asVectorList(RAbstractContainer x, @SuppressWarnings("unused") String mode, // - @Cached("createListCast()") CastListNode cast) { - controlVisibility(); - return cast.execute(x); - } + @Specialization(guards = "castToDouble(x, mode)") + protected Object asVectorDouble(RAbstractContainer x, @SuppressWarnings("unused") String mode, // + @Cached("createNonPreserving()") CastDoubleNode cast) { + return cast.execute(x); + } - @Specialization(guards = "castToSymbol(x, mode)") - protected Object asVectorSymbol(RAbstractContainer x, @SuppressWarnings("unused") String mode, // - @Cached("createNonPreserving()") CastSymbolNode cast) { - controlVisibility(); - return cast.execute(x); - } + @Specialization(guards = "castToComplex(x, mode)") + protected Object asVectorComplex(RAbstractContainer x, @SuppressWarnings("unused") String mode, // + @Cached("createNonPreserving()") CastComplexNode cast) { + return cast.execute(x); + } - @Specialization(guards = "castToExpression(mode)") - protected Object asVectorExpression(Object x, @SuppressWarnings("unused") String mode, // - @Cached("createNonPreserving()") CastExpressionNode cast) { - controlVisibility(); - return cast.execute(x); - } + @Specialization(guards = "castToLogical(x, mode)") + protected Object asVectorLogical(RAbstractContainer x, @SuppressWarnings("unused") String mode, // + @Cached("createNonPreserving()") CastLogicalNode cast) { + return cast.execute(x); + } - @Specialization(guards = "castToList(mode)") - protected RAbstractVector asVectorList(@SuppressWarnings("unused") RNull x, @SuppressWarnings("unused") String mode) { - controlVisibility(); - return RDataFactory.createList(); - } + @Specialization(guards = "castToRaw(x, mode)") + protected Object asVectorRaw(RAbstractContainer x, @SuppressWarnings("unused") String mode, // + @Cached("createNonPreserving()") CastRawNode cast) { + return cast.execute(x); + } - @Specialization(guards = "isSymbol(x, mode)") - protected RSymbol asVectorSymbol(RSymbol x, @SuppressWarnings("unused") String mode) { - controlVisibility(); - String sName = x.getName(); - return RDataFactory.createSymbol(sName); - } + protected static CastListNode createListCast() { + return CastListNodeGen.create(true, false, false); + } - protected boolean isSymbol(@SuppressWarnings("unused") RSymbol x, String mode) { - return RType.Symbol.getName().equals(mode); - } + @Specialization(guards = "castToList(mode)") + protected Object asVectorList(RAbstractContainer x, @SuppressWarnings("unused") String mode, // + @Cached("createListCast()") CastListNode cast) { + return cast.execute(x); + } - @Specialization(guards = "modeIsAny(mode)") - protected RAbstractVector asVector(RList x, @SuppressWarnings("unused") String mode) { - controlVisibility(); - RList result = x.copyWithNewDimensions(null); - result.copyNamesFrom(attrProfiles, x); - return result; - } + @Specialization(guards = "castToSymbol(x, mode)") + protected Object asVectorSymbol(RAbstractContainer x, @SuppressWarnings("unused") String mode, // + @Cached("createNonPreserving()") CastSymbolNode cast) { + return cast.execute(x); + } - @Specialization(guards = "modeIsAny(mode)") - protected RAbstractVector asVector(RFactor x, @SuppressWarnings("unused") String mode) { - RVector levels = x.getLevels(attrProfiles); - RVector result = levels.createEmptySameType(x.getLength(), RDataFactory.COMPLETE_VECTOR); - RIntVector factorData = x.getVector(); - for (int i = 0; i < result.getLength(); i++) { - result.transferElementSameType(i, levels, factorData.getDataAt(i) - 1); + @Specialization(guards = "castToExpression(mode)") + protected Object asVectorExpression(Object x, @SuppressWarnings("unused") String mode, // + @Cached("createNonPreserving()") CastExpressionNode cast) { + return cast.execute(x); } - return result; - } - @Specialization(guards = "modeIsAny(mode)") - protected RNull asVector(RNull x, @SuppressWarnings("unused") String mode) { - controlVisibility(); - return x; - } + @Specialization(guards = "castToList(mode)") + protected RAbstractVector asVectorList(@SuppressWarnings("unused") RNull x, @SuppressWarnings("unused") String mode) { + return RDataFactory.createList(); + } - @Specialization(guards = "modeIsPairList(mode)") - protected Object asVectorPairList(RList x, @SuppressWarnings("unused") String mode) { - controlVisibility(); - // TODO implement non-empty element list conversion; this is a placeholder for type test - if (x.getLength() == 0) { - return RNull.instance; - } else { - throw RError.nyi(this, "non-empty lists"); + @Specialization(guards = "isSymbol(x, mode)") + protected RSymbol asVectorSymbol(RSymbol x, @SuppressWarnings("unused") String mode) { + String sName = x.getName(); + return RDataFactory.createSymbol(sName); } - } - @Specialization(guards = "modeIsAny(mode)") - protected RAbstractVector asVectorAny(RAbstractVector x, @SuppressWarnings("unused") String mode) { - controlVisibility(); - return x.copyWithNewDimensions(null); - } + protected boolean isSymbol(@SuppressWarnings("unused") RSymbol x, String mode) { + return RType.Symbol.getName().equals(mode); + } - @Specialization(guards = "modeMatches(x, mode)") - protected RAbstractVector asVector(RAbstractVector x, @SuppressWarnings("unused") String mode) { - controlVisibility(); - return x.copyWithNewDimensions(null); - } + @Specialization(guards = "modeIsAny(mode)") + protected RAbstractVector asVector(RList x, @SuppressWarnings("unused") String mode) { + RList result = x.copyWithNewDimensions(null); + result.copyNamesFrom(attrProfiles, x); + return result; + } - protected boolean castToInt(RAbstractContainer x, String mode) { - return x.getElementClass() != RInteger.class && RType.Integer.getName().equals(mode); - } + @Specialization(guards = "modeIsAny(mode)") + protected RNull asVector(RNull x, @SuppressWarnings("unused") String mode) { + return x; + } - protected boolean castToDouble(RAbstractContainer x, String mode) { - return x.getElementClass() != RDouble.class && (RType.Double.getClazz().equals(mode) || RType.Double.getName().equals(mode)); - } + @Specialization(guards = "modeIsPairList(mode)") + protected Object asVectorPairList(RList x, @SuppressWarnings("unused") String mode) { + // TODO implement non-empty element list conversion; this is a placeholder for type test + if (x.getLength() == 0) { + return RNull.instance; + } else { + throw RError.nyi(RError.SHOW_CALLER, "non-empty lists"); + } + } - protected boolean castToComplex(RAbstractContainer x, String mode) { - return x.getElementClass() != RComplex.class && RType.Complex.getName().equals(mode); - } + @Specialization(guards = "modeIsAny(mode)") + protected RAbstractVector asVectorAny(RAbstractVector x, @SuppressWarnings("unused") String mode) { + return x.copyWithNewDimensions(null); + } - protected boolean castToLogical(RAbstractContainer x, String mode) { - return x.getElementClass() != RLogical.class && RType.Logical.getName().equals(mode); - } + @Specialization(guards = "modeMatches(x, mode)") + protected RAbstractVector asVector(RAbstractVector x, @SuppressWarnings("unused") String mode) { + return x.copyWithNewDimensions(null); + } - protected boolean castToString(String mode) { - return RType.Character.getName().equals(mode); - } + protected boolean castToInt(RAbstractContainer x, String mode) { + return x.getElementClass() != RInteger.class && RType.Integer.getName().equals(mode); + } - protected boolean castToRaw(RAbstractContainer x, String mode) { - return x.getElementClass() != RRaw.class && RType.Raw.getName().equals(mode); - } + protected boolean castToDouble(RAbstractContainer x, String mode) { + return x.getElementClass() != RDouble.class && (RType.Double.getClazz().equals(mode) || RType.Double.getName().equals(mode)); + } - protected boolean castToList(String mode) { - return RType.List.getName().equals(mode); - } + protected boolean castToComplex(RAbstractContainer x, String mode) { + return x.getElementClass() != RComplex.class && RType.Complex.getName().equals(mode); + } - protected boolean castToSymbol(RAbstractContainer x, String mode) { - return x.getElementClass() != Object.class && RType.Symbol.getName().equals(mode); - } + protected boolean castToLogical(RAbstractContainer x, String mode) { + return x.getElementClass() != RLogical.class && RType.Logical.getName().equals(mode); + } - protected boolean castToExpression(String mode) { - return RType.Expression.getName().equals(mode); - } + protected boolean castToString(String mode) { + return RType.Character.getName().equals(mode); + } - protected boolean modeMatches(RAbstractVector x, String mode) { - return RRuntime.classToString(x.getElementClass()).equals(mode) || x.getElementClass() == RDouble.class && RType.Double.getName().equals(mode); - } + protected boolean castToRaw(RAbstractContainer x, String mode) { + return x.getElementClass() != RRaw.class && RType.Raw.getName().equals(mode); + } - protected boolean modeIsAny(String mode) { - return RType.Any.getName().equals(mode); - } + protected boolean castToList(String mode) { + return RType.List.getName().equals(mode); + } - protected boolean modeIsPairList(String mode) { - return RType.PairList.getName().equals(mode); - } + protected boolean castToSymbol(RAbstractContainer x, String mode) { + return x.getElementClass() != Object.class && RType.Symbol.getName().equals(mode); + } - @SuppressWarnings("unused") - @Fallback - @TruffleBoundary - protected RAbstractVector asVectorWrongMode(Object x, Object mode) { - controlVisibility(); - throw RError.error(RError.SHOW_CALLER, RError.Message.INVALID_ARGUMENT, "mode"); + protected boolean castToExpression(String mode) { + return RType.Expression.getName().equals(mode); + } + + protected boolean modeMatches(RAbstractVector x, String mode) { + return RRuntime.classToString(x.getElementClass()).equals(mode) || x.getElementClass() == RDouble.class && RType.Double.getName().equals(mode); + } + + protected boolean modeIsAny(String mode) { + return RType.Any.getName().equals(mode); + } + + protected boolean modeIsPairList(String mode) { + return RType.PairList.getName().equals(mode); + } + + @SuppressWarnings("unused") + @Fallback + @TruffleBoundary + protected RAbstractVector asVectorWrongMode(Object x, String mode) { + throw RError.error(RError.SHOW_CALLER, RError.Message.INVALID_ARGUMENT, "mode"); + } } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Bind.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Bind.java index 3e7d905c8275e80c958c998808ac306e8363502e..c541a7b83417fb90c612cd060f6240e680e7b0bd 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Bind.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Bind.java @@ -27,50 +27,21 @@ import static com.oracle.truffle.r.runtime.RBuiltinKind.INTERNAL; import java.util.Arrays; import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.api.profiles.ValueProfile; import com.oracle.truffle.r.nodes.RASTUtils; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; -import com.oracle.truffle.r.nodes.function.ClassHierarchyNode; -import com.oracle.truffle.r.nodes.function.ClassHierarchyNodeGen; import com.oracle.truffle.r.nodes.function.S3FunctionLookupNode; import com.oracle.truffle.r.nodes.function.UseMethodInternalNode; -import com.oracle.truffle.r.nodes.unary.CastComplexNode; -import com.oracle.truffle.r.nodes.unary.CastDoubleNode; -import com.oracle.truffle.r.nodes.unary.CastIntegerNode; -import com.oracle.truffle.r.nodes.unary.CastListNode; -import com.oracle.truffle.r.nodes.unary.CastLogicalNode; -import com.oracle.truffle.r.nodes.unary.CastLogicalNodeGen; -import com.oracle.truffle.r.nodes.unary.CastNode; -import com.oracle.truffle.r.nodes.unary.CastStringNode; -import com.oracle.truffle.r.nodes.unary.CastToVectorNode; -import com.oracle.truffle.r.nodes.unary.CastToVectorNodeGen; -import com.oracle.truffle.r.nodes.unary.PrecedenceNode; -import com.oracle.truffle.r.nodes.unary.PrecedenceNodeGen; -import com.oracle.truffle.r.runtime.ArgumentsSignature; -import com.oracle.truffle.r.runtime.RArguments; -import com.oracle.truffle.r.runtime.RBuiltin; -import com.oracle.truffle.r.runtime.RError; -import com.oracle.truffle.r.runtime.RInternalError; -import com.oracle.truffle.r.runtime.RRuntime; -import com.oracle.truffle.r.runtime.RType; -import com.oracle.truffle.r.runtime.Utils; -import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; -import com.oracle.truffle.r.runtime.data.RDataFactory; -import com.oracle.truffle.r.runtime.data.RList; -import com.oracle.truffle.r.runtime.data.RNull; -import com.oracle.truffle.r.runtime.data.RPromise; -import com.oracle.truffle.r.runtime.data.RStringVector; -import com.oracle.truffle.r.runtime.data.RSymbol; -import com.oracle.truffle.r.runtime.data.RVector; +import com.oracle.truffle.r.nodes.helpers.InheritsCheckNode; +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.RAbstractLogicalVector; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; import com.oracle.truffle.r.runtime.nodes.RBaseNode; @@ -387,35 +358,6 @@ public abstract class Bind extends RBaseNode { @Child private InheritsCheckNode inheritsCheck = new InheritsCheckNode(RRuntime.CLASS_DATA_FRAME); - public static final class InheritsCheckNode extends Node { - - @Child private ClassHierarchyNode classHierarchy = ClassHierarchyNodeGen.create(false, false); - private final ConditionProfile nullClassProfile = ConditionProfile.createBinaryProfile(); - @CompilationFinal private ConditionProfile exactMatchProfile; - private final String checkedClazz; - - public InheritsCheckNode(String checkedClazz) { - this.checkedClazz = checkedClazz; - assert RType.fromMode(checkedClazz) == null; - } - - public boolean execute(Object value) { - RStringVector clazz = classHierarchy.execute(value); - if (nullClassProfile.profile(clazz != null)) { - for (int j = 0; j < clazz.getLength(); ++j) { - if (exactMatchProfile == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - exactMatchProfile = ConditionProfile.createBinaryProfile(); - } - if (exactMatchProfile.profile(clazz.getDataAt(j) == checkedClazz) || clazz.getDataAt(j).equals(checkedClazz)) { - return true; - } - } - } - return false; - } - } - protected boolean isDataFrame(Object[] args) { for (int i = 0; i < args.length; i++) { if (inheritsCheck.execute(args[i])) { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CopyDFAttr.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CopyDFAttr.java index 101c464098932c834c544d786422577517ef74d6..2d4ed6aa7be1ea01176849c374d913dfbc82c11f 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CopyDFAttr.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/CopyDFAttr.java @@ -29,7 +29,6 @@ import com.oracle.truffle.r.nodes.builtin.RInvisibleBuiltinNode; import com.oracle.truffle.r.runtime.RBuiltin; import com.oracle.truffle.r.runtime.data.RAttributable; import com.oracle.truffle.r.runtime.data.RAttributeProfiles; -import com.oracle.truffle.r.runtime.data.RFactor; import com.oracle.truffle.r.runtime.data.RVector; import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; @@ -45,11 +44,4 @@ public abstract class CopyDFAttr extends RInvisibleBuiltinNode { res.resetAllAttributes(false); return res.copyAttributesFrom(attrProfiles, in); } - - @Specialization() - protected RAttributable copy(RAbstractContainer in, RFactor out) { - RVector res = out.getVector(); - res.resetAllAttributes(false); - return res.copyAttributesFrom(attrProfiles, in); - } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DimNames.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DimNames.java index 23a3b7157753b159e41743dee462c7fc65b2dbf2..269a3a17a3ca5e0e54c063e6cc907ad9ce5fdefb 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DimNames.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DimNames.java @@ -26,12 +26,10 @@ import static com.oracle.truffle.r.runtime.RBuiltinKind.PRIMITIVE; import static com.oracle.truffle.r.runtime.RDispatch.INTERNAL_GENERIC; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RBuiltin; import com.oracle.truffle.r.runtime.data.RAttributeProfiles; -import com.oracle.truffle.r.runtime.data.RFactor; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; @@ -41,9 +39,6 @@ public abstract class DimNames extends RBuiltinNode { private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); private final ConditionProfile nullProfile = ConditionProfile.createBinaryProfile(); - private final BranchProfile dataframeProfile = BranchProfile.create(); - private final BranchProfile factorProfile = BranchProfile.create(); - private final BranchProfile otherProfile = BranchProfile.create(); @Specialization protected RNull getDimNames(@SuppressWarnings("unused") RNull operand) { @@ -54,14 +49,7 @@ public abstract class DimNames extends RBuiltinNode { @Specialization protected Object getDimNames(RAbstractContainer container) { controlVisibility(); - RList names; - if (container instanceof RFactor) { - factorProfile.enter(); - names = ((RFactor) container).getVector().getDimNames(); - } else { - otherProfile.enter(); - names = container.getDimNames(attrProfiles); - } + RList names = container.getDimNames(attrProfiles); return nullProfile.profile(names == null) ? RNull.instance : names; } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EnvFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EnvFunctions.java index 12ba9db3e2243e0fba60f880c019c10299616e8b..289e049b082d60bafa210a567f341f4c93019d83 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EnvFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/EnvFunctions.java @@ -170,7 +170,7 @@ public class EnvFunctions { @Specialization protected Object asEnvironment(RS4Object obj) { // generic dispatch tried already - Object xData = obj.getAttribute(RRuntime.DOT_XDATA); + Object xData = obj.getAttr(RRuntime.DOT_XDATA); if (xData == null || !(xData instanceof REnvironment)) { throw RError.error(this, RError.Message.S4OBJECT_NX_ENVIRONMENT); } else { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Format.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Format.java index f6abfbfb732aab168b3a772697c8d145f103862c..9d47816e0c14736baf9d583785dcc0a327adf998 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Format.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Format.java @@ -13,16 +13,20 @@ package com.oracle.truffle.r.nodes.builtin.base; import static com.oracle.truffle.r.runtime.RBuiltinKind.INTERNAL; -import com.oracle.truffle.api.*; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.profiles.*; -import com.oracle.truffle.r.nodes.builtin.*; +import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.profiles.BranchProfile; +import com.oracle.truffle.r.nodes.builtin.CastBuilder; +import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.builtin.base.printer.AnyVectorToStringVectorWriter; import com.oracle.truffle.r.nodes.builtin.base.printer.ValuePrinterNode; import com.oracle.truffle.r.nodes.builtin.base.printer.ValuePrinterNodeGen; -import com.oracle.truffle.r.nodes.unary.*; -import com.oracle.truffle.r.runtime.*; -import com.oracle.truffle.r.runtime.context.*; +import com.oracle.truffle.r.nodes.unary.CastIntegerNode; +import com.oracle.truffle.r.nodes.unary.CastIntegerNodeGen; +import com.oracle.truffle.r.runtime.RBuiltin; +import com.oracle.truffle.r.runtime.RError; +import com.oracle.truffle.r.runtime.RRuntime; +import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.*; @@ -157,12 +161,6 @@ public abstract class Format extends RBuiltinNode { return value.materialize(); } - @Specialization - protected RStringVector format(RFactor value, RLogicalVector trimVec, RIntVector digitsVec, RIntVector nsmallVec, RIntVector widthVec, RIntVector justifyVec, RLogicalVector naEncodeVec, - RAbstractVector sciVec, RAbstractStringVector decimalMark) { - return format(value.getVector(), trimVec, digitsVec, nsmallVec, widthVec, justifyVec, naEncodeVec, sciVec, decimalMark); - } - // TruffleDSL bug - should not need multiple guards here protected void checkArgs(RLogicalVector trimVec, RIntVector digitsVec, RIntVector nsmallVec, RIntVector widthVec, RIntVector justifyVec, RLogicalVector naEncodeVec, RAbstractVector sciVec, RAbstractStringVector decimalMark) { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Identical.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Identical.java index 3cafe87eb6cba1625f4fc0f7feb186bbe4c4a558..f1dfce08df908a60d2d230e92b8b0d97f69fb3a6 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Identical.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Identical.java @@ -37,18 +37,8 @@ import com.oracle.truffle.r.runtime.RBuiltin; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.conn.RConnection; -import com.oracle.truffle.r.runtime.data.RAttributable; -import com.oracle.truffle.r.runtime.data.RAttributes; +import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.RAttributes.RAttribute; -import com.oracle.truffle.r.runtime.data.RExpression; -import com.oracle.truffle.r.runtime.data.RExternalPtr; -import com.oracle.truffle.r.runtime.data.RFactor; -import com.oracle.truffle.r.runtime.data.RFunction; -import com.oracle.truffle.r.runtime.data.RLanguage; -import com.oracle.truffle.r.runtime.data.RList; -import com.oracle.truffle.r.runtime.data.RPairList; -import com.oracle.truffle.r.runtime.data.RS4Object; -import com.oracle.truffle.r.runtime.data.RSymbol; import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; @@ -273,14 +263,6 @@ public abstract class Identical extends RBuiltinNode { return identicalAttr(x, y, numEq, singleNA, attribAsSet, ignoreBytecode, ignoreEnvironment); } - @Specialization - protected byte doInternalIdenticalGeneric(RFactor x, RFactor y, boolean numEq, boolean singleNA, boolean attribAsSet, boolean ignoreBytecode, boolean ignoreEnvironment) { - if (!recursive) { - controlVisibility(); - } - return doInternalIdenticalGeneric(x.getVector(), y.getVector(), numEq, singleNA, attribAsSet, ignoreBytecode, ignoreEnvironment); - } - @SuppressWarnings("unused") @Specialization protected byte doInternalIdenticalGeneric(RFunction x, RAbstractContainer y, boolean numEq, boolean singleNA, boolean attribAsSet, boolean ignoreBytecode, boolean ignoreEnvironment) { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsNA.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsNA.java index 5d2cc51956505cc994123bccef5f81f17b6bdd74..329afd4da9c4d1ed10e68d1d3d4fff2390a54c8a 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsNA.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsNA.java @@ -29,25 +29,14 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RBuiltin; +import com.oracle.truffle.r.runtime.RDispatch; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; -import com.oracle.truffle.r.runtime.data.RComplex; -import com.oracle.truffle.r.runtime.data.RComplexVector; -import com.oracle.truffle.r.runtime.data.RDataFactory; -import com.oracle.truffle.r.runtime.data.RFactor; -import com.oracle.truffle.r.runtime.data.RFunction; -import com.oracle.truffle.r.runtime.data.RLanguage; -import com.oracle.truffle.r.runtime.data.RList; -import com.oracle.truffle.r.runtime.data.RLogicalVector; -import com.oracle.truffle.r.runtime.data.RNull; -import com.oracle.truffle.r.runtime.data.RRaw; -import com.oracle.truffle.r.runtime.data.RRawVector; -import com.oracle.truffle.r.runtime.data.RStringVector; +import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; -@RBuiltin(name = "is.na", kind = PRIMITIVE, parameterNames = {"x"}) +@RBuiltin(name = "is.na", kind = PRIMITIVE, parameterNames = {"x"}, dispatch = RDispatch.INTERNAL_GENERIC) public abstract class IsNA extends RBuiltinNode { @Child private IsNA recursiveIsNA; @@ -172,11 +161,6 @@ public abstract class IsNA extends RBuiltinNode { return RRuntime.asLogical(RRuntime.isNA(value)); } - @Specialization - protected RLogicalVector isNA(RFactor value) { - return isNA(value.getVector()); - } - @Specialization protected byte isNA(@SuppressWarnings("unused") RRaw value) { controlVisibility(); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsTypeFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsTypeFunctions.java index 0d01a9641fc5ad1dd2bdfd3fac46295c79e0ae5a..34efd3d0d0c0ea36340c68c51bd4342d447c85cf 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsTypeFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsTypeFunctions.java @@ -30,32 +30,10 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; -import com.oracle.truffle.r.runtime.RBuiltin; -import com.oracle.truffle.r.runtime.RBuiltinKind; -import com.oracle.truffle.r.runtime.RError; -import com.oracle.truffle.r.runtime.RRuntime; -import com.oracle.truffle.r.runtime.RType; -import com.oracle.truffle.r.runtime.data.RAttributable; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; -import com.oracle.truffle.r.runtime.data.RComplex; -import com.oracle.truffle.r.runtime.data.RDouble; -import com.oracle.truffle.r.runtime.data.RExpression; -import com.oracle.truffle.r.runtime.data.RFactor; -import com.oracle.truffle.r.runtime.data.RFunction; -import com.oracle.truffle.r.runtime.data.RLanguage; -import com.oracle.truffle.r.runtime.data.RList; -import com.oracle.truffle.r.runtime.data.RMissing; -import com.oracle.truffle.r.runtime.data.RNull; -import com.oracle.truffle.r.runtime.data.RPairList; -import com.oracle.truffle.r.runtime.data.RRaw; -import com.oracle.truffle.r.runtime.data.RSymbol; -import com.oracle.truffle.r.runtime.data.model.RAbstractComplexVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractRawVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractVector; +import com.oracle.truffle.r.nodes.helpers.InheritsCheckNode; +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.nodes.RNode; /** @@ -121,12 +99,6 @@ public class IsTypeFunctions { return RRuntime.LOGICAL_TRUE; } - @Specialization - protected byte isRecursive(RFactor arg) { - controlVisibility(); - return RRuntime.LOGICAL_FALSE; - } - protected boolean isListVector(RAbstractVector arg) { return arg instanceof RList; } @@ -141,6 +113,8 @@ public class IsTypeFunctions { @RBuiltin(name = "is.atomic", kind = PRIMITIVE, parameterNames = {"x"}) public abstract static class IsAtomic extends MissingAdapter { + @Child private InheritsCheckNode inheritsFactorCheck = new InheritsCheckNode(RRuntime.CLASS_FACTOR); + @Specialization protected byte isAtomic(RNull arg) { controlVisibility(); @@ -153,18 +127,16 @@ public class IsTypeFunctions { return RRuntime.LOGICAL_TRUE; } - @Specialization - protected byte isAtomic(RFactor arg) { - controlVisibility(); - return RRuntime.LOGICAL_TRUE; - } - protected static boolean isNonListVector(Object value) { return value instanceof Integer || value instanceof Double || value instanceof RComplex || value instanceof String || value instanceof RRaw || (value instanceof RAbstractVector && !(value instanceof RList)); } - @Specialization(guards = {"!isRMissing(value)", "!isRNull(value)", "!isRFactor(value)", "!isNonListVector(value)"}) + protected boolean isFactor(Object value) { + return inheritsFactorCheck.execute(value); + } + + @Specialization(guards = {"!isRMissing(value)", "!isRNull(value)", "!isFactor(value)", "!isNonListVector(value)"}) protected byte isType(Object value) { controlVisibility(); return RRuntime.LOGICAL_FALSE; @@ -403,12 +375,18 @@ public class IsTypeFunctions { @RBuiltin(name = "is.numeric", kind = PRIMITIVE, parameterNames = {"x"}) public abstract static class IsNumeric extends MissingAdapter { - @Specialization + @Specialization(guards = "!isFactor(value)") protected byte isType(RAbstractIntVector value) { controlVisibility(); return RRuntime.LOGICAL_TRUE; } + @Specialization(guards = "isFactor(value)") + protected byte isTypeFactor(RAbstractIntVector value) { + controlVisibility(); + return RRuntime.LOGICAL_FALSE; + } + @Specialization protected byte isType(RAbstractDoubleVector value) { controlVisibility(); @@ -424,6 +402,12 @@ public class IsTypeFunctions { controlVisibility(); return RRuntime.LOGICAL_FALSE; } + + @Child private InheritsCheckNode inheritsCheck = new InheritsCheckNode(RRuntime.CLASS_FACTOR); + + protected boolean isFactor(Object o) { + return inheritsCheck.execute(o); + } } @RBuiltin(name = "is.null", kind = PRIMITIVE, parameterNames = {"x"}) diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Match.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Match.java index 24c6e65e3f655e2e3378c8b03387308bae5c2af4..0211b1e052040aa33a31e1f497a07d163310034a 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Match.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Match.java @@ -33,25 +33,15 @@ import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; +import com.oracle.truffle.r.nodes.helpers.InheritsCheckNode; import com.oracle.truffle.r.nodes.unary.CastStringNode; import com.oracle.truffle.r.nodes.unary.CastStringNodeGen; import com.oracle.truffle.r.runtime.RBuiltin; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; -import com.oracle.truffle.r.runtime.data.RComplex; -import com.oracle.truffle.r.runtime.data.RDataFactory; -import com.oracle.truffle.r.runtime.data.RFactor; -import com.oracle.truffle.r.runtime.data.RFunction; -import com.oracle.truffle.r.runtime.data.RIntVector; -import com.oracle.truffle.r.runtime.data.RNull; +import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.closures.RClosures; -import com.oracle.truffle.r.runtime.data.model.RAbstractComplexVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractVector; +import com.oracle.truffle.r.runtime.data.model.*; import com.oracle.truffle.r.runtime.ops.na.NACheck; import com.oracle.truffle.r.runtime.ops.na.NAProfile; @@ -116,22 +106,22 @@ public abstract class Match extends RBuiltinNode { return RDataFactory.createIntVector(data, naCheck.neverSeenNA()); } - @Specialization - protected Object match(RFactor x, RFactor table, RAbstractIntVector nomatchObj, Object incomparables) { - naCheck.enable(x.getVector()); - naCheck.enable(table.getVector()); + @Specialization(guards = {"isFactor(x)", "isFactor(table)"}) + protected Object matchFactor(RAbstractIntVector x, RAbstractIntVector table, RAbstractIntVector nomatchObj, Object incomparables) { + naCheck.enable(x); + naCheck.enable(table); return matchRecursive(RClosures.createFactorToVector(x, true, attrProfiles), RClosures.createFactorToVector(table, true, attrProfiles), nomatchObj, incomparables); } - @Specialization - protected Object match(RFactor x, RAbstractVector table, RAbstractIntVector nomatchObj, Object incomparables) { - naCheck.enable(x.getVector()); + @Specialization(guards = {"isFactor(x)", "!isFactor(table)"}) + protected Object matchFactor(RAbstractIntVector x, RAbstractVector table, RAbstractIntVector nomatchObj, Object incomparables) { + naCheck.enable(x); return matchRecursive(RClosures.createFactorToVector(x, true, attrProfiles), table, nomatchObj, incomparables); } - @Specialization - protected Object match(RAbstractVector x, RFactor table, RAbstractIntVector nomatchObj, Object incomparables) { - naCheck.enable(table.getVector()); + @Specialization(guards = {"!isFactor(x)", "isFactor(table)"}) + protected Object matchFactor(RAbstractVector x, RAbstractIntVector table, RAbstractIntVector nomatchObj, Object incomparables) { + naCheck.enable(table); return matchRecursive(x, RClosures.createFactorToVector(table, true, attrProfiles), nomatchObj, incomparables); } @@ -514,6 +504,12 @@ public abstract class Match extends RBuiltinNode { return table.getElementClass() == String.class; } + @Child private InheritsCheckNode factorInheritsCheck = new InheritsCheckNode(RRuntime.CLASS_FACTOR); + + protected boolean isFactor(Object o) { + return factorInheritsCheck.execute(o); + } + private static int[] initResult(int length, int nomatch) { int[] result = new int[length]; Arrays.fill(result, nomatch); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Mean.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Mean.java index 61b1c873ab9292923225d81a7b0c6ae5e159ff7d..6089d1efca02f36a976f96ecce2eb05cbeea04dd 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Mean.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Mean.java @@ -28,6 +28,7 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RBuiltin; +import com.oracle.truffle.r.runtime.RDispatch; import com.oracle.truffle.r.runtime.data.RComplex; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.model.RAbstractComplexVector; @@ -36,7 +37,7 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector; import com.oracle.truffle.r.runtime.ops.BinaryArithmetic; -@RBuiltin(name = "mean", kind = INTERNAL, parameterNames = {"x"}) +@RBuiltin(name = "mean", kind = INTERNAL, parameterNames = {"x"}, dispatch = RDispatch.INTERNAL_GENERIC) public abstract class Mean extends RBuiltinNode { private final BranchProfile emptyProfile = BranchProfile.create(); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NChar.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NChar.java index 2fd7dcd2d573eb429624b06442c8aed04d77a155..9fb021ee9d1d4a05c1ecb5baefbe32bcec831ad8 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NChar.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/NChar.java @@ -29,6 +29,7 @@ import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; +import com.oracle.truffle.r.nodes.helpers.InheritsCheckNode; import com.oracle.truffle.r.nodes.unary.CastStringNode; import com.oracle.truffle.r.nodes.unary.CastStringNodeGen; import com.oracle.truffle.r.nodes.unary.ConversionFailedException; @@ -38,7 +39,6 @@ import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.RType; import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RDataFactory; -import com.oracle.truffle.r.runtime.data.RFactor; import com.oracle.truffle.r.runtime.data.RIntVector; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; @@ -49,6 +49,7 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractVector; public abstract class NChar extends RBuiltinNode { @Child private CastStringNode convertString; + @Child private InheritsCheckNode factorInheritsCheck; private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); @@ -127,9 +128,15 @@ public abstract class NChar extends RBuiltinNode { @Fallback protected RIntVector nchar(Object obj, Object type, Object allowNA, Object keepNA) { controlVisibility(); - if (obj instanceof RFactor) { + if (factorInheritsCheck == null) { + CompilerDirectives.transferToInterpreter(); + factorInheritsCheck = insert(new InheritsCheckNode(RRuntime.CLASS_FACTOR)); + } + + if (factorInheritsCheck.execute(obj)) { throw RError.error(this, RError.Message.REQUIRES_CHAR_VECTOR, "nchar"); } + if (obj instanceof RAbstractVector) { RAbstractVector vector = (RAbstractVector) obj; int len = vector.getLength(); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/PrettyPrinterNode.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/PrettyPrinterNode.java index d4610cda7c2bb5c9a4ec460a82b86bb885ce2262..80c47dc37cab89037064f954c443331d0d1b3293 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/PrettyPrinterNode.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/PrettyPrinterNode.java @@ -37,56 +37,20 @@ import com.oracle.truffle.api.nodes.RootNode; import com.oracle.truffle.api.source.SourceSection; import com.oracle.truffle.r.nodes.RRootNode; import com.oracle.truffle.r.nodes.access.ConstantNode; -import com.oracle.truffle.r.nodes.builtin.base.PrettyPrinterNodeGen.PrettyPrinterSingleListElementNodeGen; -import com.oracle.truffle.r.nodes.builtin.base.PrettyPrinterNodeGen.PrettyPrinterSingleVectorElementNodeGen; -import com.oracle.truffle.r.nodes.builtin.base.PrettyPrinterNodeGen.PrintDimNodeGen; -import com.oracle.truffle.r.nodes.builtin.base.PrettyPrinterNodeGen.PrintVector2DimNodeGen; -import com.oracle.truffle.r.nodes.builtin.base.PrettyPrinterNodeGen.PrintVectorMultiDimNodeGen; +import com.oracle.truffle.r.nodes.builtin.base.PrettyPrinterNodeGen.*; import com.oracle.truffle.r.nodes.function.FormalArguments; +import com.oracle.truffle.r.nodes.helpers.InheritsCheckNode; +import com.oracle.truffle.r.nodes.helpers.RFactorNodes; import com.oracle.truffle.r.nodes.unary.CastStringNode; import com.oracle.truffle.r.nodes.unary.CastStringNodeGen; -import com.oracle.truffle.r.runtime.ArgumentsSignature; -import com.oracle.truffle.r.runtime.RArguments; -import com.oracle.truffle.r.runtime.RDeparse; -import com.oracle.truffle.r.runtime.RError; -import com.oracle.truffle.r.runtime.RRuntime; +import com.oracle.truffle.r.runtime.*; import com.oracle.truffle.r.runtime.conn.SocketConnections; import com.oracle.truffle.r.runtime.context.RContext; -import com.oracle.truffle.r.runtime.data.RAttributable; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; -import com.oracle.truffle.r.runtime.data.RAttributes; +import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.RAttributes.RAttribute; -import com.oracle.truffle.r.runtime.data.RBuiltinDescriptor; -import com.oracle.truffle.r.runtime.data.RComplex; -import com.oracle.truffle.r.runtime.data.RDataFactory; -import com.oracle.truffle.r.runtime.data.RDouble; -import com.oracle.truffle.r.runtime.data.RExpression; -import com.oracle.truffle.r.runtime.data.RExternalPtr; -import com.oracle.truffle.r.runtime.data.RFactor; -import com.oracle.truffle.r.runtime.data.RFunction; -import com.oracle.truffle.r.runtime.data.RIntVector; -import com.oracle.truffle.r.runtime.data.RLanguage; -import com.oracle.truffle.r.runtime.data.RList; -import com.oracle.truffle.r.runtime.data.RMissing; -import com.oracle.truffle.r.runtime.data.RNull; -import com.oracle.truffle.r.runtime.data.RPairList; -import com.oracle.truffle.r.runtime.data.RPromise; -import com.oracle.truffle.r.runtime.data.RRaw; -import com.oracle.truffle.r.runtime.data.RS4Object; -import com.oracle.truffle.r.runtime.data.RString; -import com.oracle.truffle.r.runtime.data.RStringVector; -import com.oracle.truffle.r.runtime.data.RSymbol; -import com.oracle.truffle.r.runtime.data.RVector; import com.oracle.truffle.r.runtime.data.closures.RClosures; import com.oracle.truffle.r.runtime.data.closures.RFactorToStringVectorClosure; -import com.oracle.truffle.r.runtime.data.model.RAbstractComplexVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; -import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractRawVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractVector; +import com.oracle.truffle.r.runtime.data.model.*; import com.oracle.truffle.r.runtime.env.REnvironment; import com.oracle.truffle.r.runtime.nodes.RNode; import com.oracle.truffle.r.runtime.ops.na.NACheck; @@ -1185,7 +1149,7 @@ public abstract class PrettyPrinterNode extends RNode { } @TruffleBoundary - @Specialization + @Specialization(guards = "!isFactor(operand)") protected String prettyPrintListElement(RAbstractVector operand, Object listElementName, byte quote, byte right) { return prettyPrintSingleElement(operand, listElementName, quote, right); } @@ -1220,10 +1184,22 @@ public abstract class PrettyPrinterNode extends RNode { return prettyPrintSingleElement(operand, listElementName, quote, right); } + @Child InheritsCheckNode factorInheritsCheck = new InheritsCheckNode(RRuntime.CLASS_FACTOR); + @Child RFactorNodes.GetLevels getFactorLevels; + + protected boolean isFactor(Object o) { + return this.factorInheritsCheck.execute(o); + } + // TODO: this should be handled by an S3 function - @Specialization - protected String prettyPrintListElement(RFactor operand, Object listElementName, byte quote, byte right) { - RVector vec = operand.getLevels(attrProfiles); + @Specialization(guards = "isFactor(factor)") + protected String prettyPrintListElement(RAbstractIntVector factor, Object listElementName, byte quote, byte right) { + if (getFactorLevels == null) { + CompilerDirectives.transferToInterpreter(); + getFactorLevels = insert(new RFactorNodes.GetLevels()); + } + + RVector vec = getFactorLevels.execute(factor); String[] strings; if (vec == null) { strings = new String[0]; @@ -1234,11 +1210,11 @@ public abstract class PrettyPrinterNode extends RNode { strings[i] = (String) castStringNode.executeString(vec.getDataAtAsObject(i)); } } - return formatLevelStrings(operand, listElementName, right, vec, strings); + return formatLevelStrings(factor, listElementName, right, vec, strings); } @TruffleBoundary - private String formatLevelStrings(RFactor operand, Object listElementName, byte right, RVector vec, String[] strings) { + private String formatLevelStrings(RAbstractIntVector operand, Object listElementName, byte right, RVector vec, String[] strings) { StringBuilder sb = new StringBuilder(prettyPrintSingleElement(RClosures.createFactorToVector(operand, true, attrProfiles), listElementName, RRuntime.LOGICAL_FALSE, right)); sb.append("\nLevels:"); if (vec != null) { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Repeat.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Repeat.java index eb19a426e9033c2025c18d6f82d1476f51c1babf..cc1f2ce326cfc7298fdbe351ce68f1af6115875c 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Repeat.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Repeat.java @@ -26,22 +26,16 @@ import static com.oracle.truffle.r.runtime.RBuiltinKind.PRIMITIVE; import java.util.Arrays; -import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RBuiltin; +import com.oracle.truffle.r.runtime.RDispatch; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; -import com.oracle.truffle.r.runtime.data.RDataFactory; -import com.oracle.truffle.r.runtime.data.RFactor; -import com.oracle.truffle.r.runtime.data.RMissing; -import com.oracle.truffle.r.runtime.data.RStringVector; -import com.oracle.truffle.r.runtime.data.RVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; +import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; @@ -66,27 +60,17 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractVector; * </ul> * </ol> */ -@RBuiltin(name = "rep", kind = PRIMITIVE, parameterNames = {"x", "times", "length.out", "each"}) +@RBuiltin(name = "rep", kind = PRIMITIVE, parameterNames = {"x", "times", "length.out", "each"}, dispatch = RDispatch.INTERNAL_GENERIC) public abstract class Repeat extends RBuiltinNode { protected abstract Object execute(RAbstractVector x, RAbstractIntVector times, int lengthOut, int each); - @Child private Repeat repeatRecursive; - private final ConditionProfile lengthOutOrTimes = ConditionProfile.createBinaryProfile(); private final BranchProfile errorBranch = BranchProfile.create(); private final ConditionProfile oneTimeGiven = ConditionProfile.createBinaryProfile(); private final ConditionProfile replicateOnce = ConditionProfile.createBinaryProfile(); private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); - private Object repeatRecursive(RAbstractVector x, RAbstractIntVector times, int lengthOut, int each) { - if (repeatRecursive == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - repeatRecursive = insert(RepeatNodeGen.create(null)); - } - return repeatRecursive.execute(x, times, lengthOut, each); - } - @Override public Object[] getDefaultParameterValues() { return new Object[]{RMissing.instance, 1, RRuntime.INT_NA, 1}; @@ -174,13 +158,6 @@ public abstract class Repeat extends RBuiltinNode { } } - @Specialization - protected RAbstractContainer rep(RFactor x, RAbstractIntVector times, int lengthOut, int each) { - RVector vec = (RVector) repeatRecursive(x.getVector(), times, lengthOut, each); - vec.setAttr(RRuntime.LEVELS_ATTR_KEY, x.getLevels(attrProfiles)); - return RVector.setVectorClassAttr(vec, x.getClassAttr(attrProfiles), null); - } - /** * Prepare the input vector by replicating its elements. */ diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Split.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Split.java index e1d45d77d9521b86cf4245a8d4143d3f6914d04d..0edc9d0761c24c95455103fda2bc949061b6fb2c 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Split.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Split.java @@ -26,27 +26,18 @@ import static com.oracle.truffle.r.runtime.RBuiltinKind.INTERNAL; import java.util.Arrays; -import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; -import com.oracle.truffle.r.nodes.unary.CastStringNode; -import com.oracle.truffle.r.nodes.unary.CastStringNodeGen; +import com.oracle.truffle.r.nodes.helpers.RFactorNodes; import com.oracle.truffle.r.runtime.RBuiltin; import com.oracle.truffle.r.runtime.Utils; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; -import com.oracle.truffle.r.runtime.data.RDataFactory; -import com.oracle.truffle.r.runtime.data.RFactor; -import com.oracle.truffle.r.runtime.data.RList; -import com.oracle.truffle.r.runtime.data.RStringVector; -import com.oracle.truffle.r.runtime.data.RVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; +import com.oracle.truffle.r.runtime.data.*; +import com.oracle.truffle.r.runtime.data.model.*; /** - * The {@code split} internal. + * The {@code split} internal. Internal version of 'split' is invoked from 'split.default' function + * implemented in R, which makes sure that the second argument is always a R factor. * * TODO Can we find a way to efficiently write the specializations as generics? The code is * identical except for the argument type. @@ -54,18 +45,23 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; @RBuiltin(name = "split", kind = INTERNAL, parameterNames = {"x", "f"}) public abstract class Split extends RBuiltinNode { - @Child private CastStringNode castString; + @Child private RFactorNodes.GetLevels getLevelNode = new RFactorNodes.GetLevels(); private final ConditionProfile noStringLevels = ConditionProfile.createBinaryProfile(); - private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); private static final int INITIAL_SIZE = 5; private static final int SCALE_FACTOR = 2; + public static class SplitTemplate { + private int[] collectResulSize; + private int nLevels; + } + @Specialization - protected RList split(RAbstractIntVector x, RFactor f) { - int[] factor = f.getVector().getDataWithoutCopying(); - final int nLevels = f.getNLevels(attrProfiles); + protected RList split(RAbstractIntVector x, RAbstractIntVector f) { + int[] factor = f.materialize().getDataWithoutCopying(); + RStringVector names = getLevelNode.execute(f); + final int nLevels = getNLevels(names); // initialise result arrays int[][] collectResults = new int[nLevels][]; @@ -91,13 +87,14 @@ public abstract class Split extends RBuiltinNode { results[i] = RDataFactory.createIntVector(Arrays.copyOfRange(collectResults[i], 0, collectResultSize[i]), x.isComplete()); } - return RDataFactory.createList(results, makeNames(f)); + return RDataFactory.createList(results, names); } @Specialization - protected RList split(RAbstractDoubleVector x, RFactor f) { - int[] factor = f.getVector().getDataWithoutCopying(); - final int nLevels = f.getNLevels(attrProfiles); + protected RList split(RAbstractDoubleVector x, RAbstractIntVector f) { + int[] factor = f.materialize().getDataWithoutCopying(); + RStringVector names = getLevelNode.execute(f); + final int nLevels = getNLevels(names); // initialise result arrays double[][] collectResults = new double[nLevels][]; @@ -123,13 +120,14 @@ public abstract class Split extends RBuiltinNode { results[i] = RDataFactory.createDoubleVector(Arrays.copyOfRange(collectResults[i], 0, collectResultSize[i]), RDataFactory.COMPLETE_VECTOR); } - return RDataFactory.createList(results, makeNames(f)); + return RDataFactory.createList(results, names); } @Specialization - protected RList split(RAbstractStringVector x, RFactor f) { - int[] factor = f.getVector().getDataWithoutCopying(); - final int nLevels = f.getNLevels(attrProfiles); + protected RList split(RAbstractStringVector x, RAbstractIntVector f) { + int[] factor = f.materialize().getDataWithoutCopying(); + RStringVector names = getLevelNode.execute(f); + final int nLevels = getNLevels(names); // initialise result arrays String[][] collectResults = new String[nLevels][]; @@ -155,13 +153,14 @@ public abstract class Split extends RBuiltinNode { results[i] = RDataFactory.createStringVector(Arrays.copyOfRange(collectResults[i], 0, collectResultSize[i]), RDataFactory.COMPLETE_VECTOR); } - return RDataFactory.createList(results, makeNames(f)); + return RDataFactory.createList(results, names); } @Specialization - protected RList split(RAbstractLogicalVector x, RFactor f) { - int[] factor = f.getVector().getDataWithoutCopying(); - final int nLevels = f.getNLevels(attrProfiles); + protected RList split(RAbstractLogicalVector x, RAbstractIntVector f) { + int[] factor = f.materialize().getDataWithoutCopying(); + RStringVector names = getLevelNode.execute(f); + final int nLevels = getNLevels(names); // initialise result arrays byte[][] collectResults = new byte[nLevels][]; @@ -187,20 +186,10 @@ public abstract class Split extends RBuiltinNode { results[i] = RDataFactory.createLogicalVector(Arrays.copyOfRange(collectResults[i], 0, collectResultSize[i]), x.isComplete()); } - return RDataFactory.createList(results, makeNames(f)); + return RDataFactory.createList(results, names); } - private RStringVector makeNames(RFactor f) { - RVector levels = f.getLevels(attrProfiles); - if (noStringLevels.profile(!(levels instanceof RStringVector))) { - if (castString == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - castString = insert(CastStringNodeGen.create(false, false, false, false)); - } - RStringVector slevels = (RStringVector) castString.executeString(f.getLevels(attrProfiles)); - return RDataFactory.createStringVector(slevels.getDataWithoutCopying(), RDataFactory.COMPLETE_VECTOR); - } else { - return RDataFactory.createStringVector(((RStringVector) levels).getDataCopy(), RDataFactory.COMPLETE_VECTOR); - } + private int getNLevels(RStringVector levels) { + return levels != null ? levels.getLength() : 0; } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Tabulate.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Tabulate.java index e10fb7d5ba8a50dc897dbc49c3494301dfbbbfa5..829cc8dcc93baee18b08e6ff57b7def021e0eda8 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Tabulate.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Tabulate.java @@ -22,7 +22,6 @@ import com.oracle.truffle.r.runtime.RBuiltinKind; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.data.RDataFactory; -import com.oracle.truffle.r.runtime.data.RFactor; import com.oracle.truffle.r.runtime.data.RIntVector; import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; @@ -55,11 +54,6 @@ public abstract class Tabulate extends RBuiltinNode { return RDataFactory.createIntVector(ans, RDataFactory.COMPLETE_VECTOR); } - @Specialization - protected RIntVector tabulate(RFactor bin, int nBins) { - return tabulate(bin.getVector(), nBins); - } - @SuppressWarnings("unused") @Fallback @TruffleBoundary diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UnClass.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UnClass.java index 22fc1a59678a9cd65c782a19ceba5eaec0d77c2b..92572424d17d380f3828b5d4a8bda9ffa9e41b49 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UnClass.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UnClass.java @@ -20,7 +20,6 @@ import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RBuiltin; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.data.RAttributeProfiles; -import com.oracle.truffle.r.runtime.data.RFactor; import com.oracle.truffle.r.runtime.data.RLanguage; import com.oracle.truffle.r.runtime.data.RS4Object; import com.oracle.truffle.r.runtime.data.RVector; @@ -48,19 +47,6 @@ public abstract class UnClass extends RBuiltinNode { return arg; } - @Specialization - @TruffleBoundary - protected Object unClass(RFactor arg) { - controlVisibility(); - RFactor resultFactor = arg; - if (!resultFactor.isTemporary()) { - resultFactor = resultFactor.copy(); - assert resultFactor.isTemporary(); - resultFactor.incRefCount(); - } - return RVector.setVectorClassAttr(resultFactor.getVector(), null, arg); - } - @Specialization protected Object unClass(RLanguage arg) { controlVisibility(); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Unique.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Unique.java index 5f954d44f38633e733a4005c6b6b89a205957053..7e7efef62fbe2f3ec3e406d0a44acbf323668797 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Unique.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Unique.java @@ -35,27 +35,8 @@ import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RBuiltin; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.Utils; -import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; -import com.oracle.truffle.r.runtime.data.RComplex; -import com.oracle.truffle.r.runtime.data.RComplexVector; -import com.oracle.truffle.r.runtime.data.RDataFactory; -import com.oracle.truffle.r.runtime.data.RDoubleVector; -import com.oracle.truffle.r.runtime.data.RFactor; -import com.oracle.truffle.r.runtime.data.RIntVector; -import com.oracle.truffle.r.runtime.data.RList; -import com.oracle.truffle.r.runtime.data.RLogicalVector; -import com.oracle.truffle.r.runtime.data.RNull; -import com.oracle.truffle.r.runtime.data.RRaw; -import com.oracle.truffle.r.runtime.data.RRawVector; -import com.oracle.truffle.r.runtime.data.RStringVector; -import com.oracle.truffle.r.runtime.data.RVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractComplexVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; -import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractRawVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; +import com.oracle.truffle.r.runtime.data.*; +import com.oracle.truffle.r.runtime.data.model.*; // Implements default S3 method @RBuiltin(name = "unique", kind = INTERNAL, parameterNames = {"x", "incomparables", "fromLast", "nmax", "..."}) @@ -86,11 +67,6 @@ public abstract class Unique extends RBuiltinNode { return vec; } - @Specialization - protected RAbstractContainer doUnique(VirtualFrame frame, RFactor factor, byte incomparables, byte fromLast, Object nmax, RArgsValuesAndNames vararg) { - return uniqueRecursive(frame, factor.getVector(), incomparables, fromLast, nmax, vararg); - } - @SuppressWarnings("unused") @Specialization protected RStringVector doUnique(RAbstractStringVector vec, byte incomparables, byte fromLast, Object nmax, RArgsValuesAndNames vararg) { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateLevels.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateLevels.java index 16426dd276fd6dcdbc7d0e2dc9e5a5ee15ca25a7..0d3d387ae3876196022c19cb9b30c9986a3764fa 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateLevels.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateLevels.java @@ -14,24 +14,21 @@ package com.oracle.truffle.r.nodes.builtin.base; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.r.nodes.builtin.RInvisibleBuiltinNode; -import com.oracle.truffle.r.nodes.unary.CastStringNode; -import com.oracle.truffle.r.nodes.unary.CastStringNodeGen; import com.oracle.truffle.r.nodes.unary.CastToVectorNode; import com.oracle.truffle.r.nodes.unary.CastToVectorNodeGen; import com.oracle.truffle.r.runtime.RBuiltin; import com.oracle.truffle.r.runtime.RBuiltinKind; +import com.oracle.truffle.r.runtime.RDispatch; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.data.RAttributeProfiles; -import com.oracle.truffle.r.runtime.data.RFactor; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RVector; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; -@RBuiltin(name = "levels<-", kind = RBuiltinKind.PRIMITIVE, parameterNames = {"x", "value"}) +@RBuiltin(name = "levels<-", kind = RBuiltinKind.PRIMITIVE, parameterNames = {"x", "value"}, dispatch = RDispatch.INTERNAL_GENERIC) public abstract class UpdateLevels extends RInvisibleBuiltinNode { @Child private CastToVectorNode castVector; - @Child private CastStringNode castString; private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); @@ -43,14 +40,6 @@ public abstract class UpdateLevels extends RInvisibleBuiltinNode { return (RAbstractVector) castVector.execute(value); } - private Object castString(Object operand) { - if (castString == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - castString = insert(CastStringNodeGen.create(false, true, false, false)); - } - return castString.execute(operand); - } - @Specialization protected RAbstractVector updateLevels(RAbstractVector vector, @SuppressWarnings("unused") RNull levels) { controlVisibility(); @@ -67,20 +56,6 @@ public abstract class UpdateLevels extends RInvisibleBuiltinNode { return v; } - @Specialization - protected RFactor updateLevels(RFactor factor, @SuppressWarnings("unused") RNull levels) { - controlVisibility(); - factor.getVector().removeAttr(attrProfiles, RRuntime.LEVELS_ATTR_KEY); - return factor; - } - - @Specialization(guards = "levelsNotNull(levels)") - protected RFactor updateLevels(RFactor factor, Object levels) { - controlVisibility(); - factor.getVector().setAttr(RRuntime.LEVELS_ATTR_KEY, castString(castVector(levels))); - return factor; - } - protected boolean levelsNotNull(Object levels) { return levels != RNull.instance; } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/FactorPrinter.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/FactorPrinter.java index b92ab79ade065e95f2a6724b8ec6f46f0190c861..595240c6942ddc969e97d1170dca5ceced16a96d 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/FactorPrinter.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/FactorPrinter.java @@ -29,9 +29,10 @@ import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RFactor; import com.oracle.truffle.r.runtime.data.RVector; import com.oracle.truffle.r.runtime.data.closures.RClosures; +import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; -final class FactorPrinter extends AbstractValuePrinter<RFactor> { +final class FactorPrinter extends AbstractValuePrinter<RAbstractIntVector> { static final FactorPrinter INSTANCE = new FactorPrinter(); @@ -42,28 +43,30 @@ final class FactorPrinter extends AbstractValuePrinter<RFactor> { private static RAttributeProfiles dummyAttrProfiles = RAttributeProfiles.create(); @Override - protected void printValue(RFactor operand, PrintContext printCtx) throws IOException { - // TODO: this should be handled by an S3 function - RVector vec = operand.getLevels(dummyAttrProfiles); + protected void printValue(RAbstractIntVector operand, PrintContext printCtx) throws IOException { + // TODO: this should be handled by an S3 function. Should it? For example, in C code for + // split, there is direct call to getAttrib. This should be refactored to use + // AttributeAccess node or even Factor.GetLevels node. The same holds for the access + RVector levels = RFactor.getLevels(operand); String[] strings; - if (vec == null) { + if (levels == null) { strings = new String[0]; } else { - strings = new String[vec.getLength()]; - for (int i = 0; i < vec.getLength(); i++) { - strings[i] = printCtx.printerNode().castString(vec.getDataAtAsObject(i)); + strings = new String[levels.getLength()]; + for (int i = 0; i < levels.getLength(); i++) { + strings[i] = printCtx.printerNode().castString(levels.getDataAtAsObject(i)); } } - RAbstractVector v = RClosures.createFactorToVector(operand, true, dummyAttrProfiles); + RAbstractVector v = RClosures.createFactorToVector(operand, true, levels); PrintContext vectorPrintCtx = printCtx.cloneContext(); vectorPrintCtx.parameters().setQuote(false); ValuePrinters.INSTANCE.println(v, vectorPrintCtx); final PrintWriter out = printCtx.output(); out.print("Levels:"); - if (vec != null) { - for (int i = 0; i < vec.getLength(); i++) { + if (levels != null) { + for (int i = 0; i < levels.getLength(); i++) { out.print(" "); out.print(strings[i]); } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ValuePrinters.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ValuePrinters.java index e0ccd70c7c8191564845a1475ac01db66182a6a7..fc0f02ef92c2aeac9cacac2dca11e249d2b8c94b 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ValuePrinters.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ValuePrinters.java @@ -23,15 +23,8 @@ package com.oracle.truffle.r.nodes.builtin.base.printer; import com.oracle.truffle.r.runtime.RInternalError; -import com.oracle.truffle.r.runtime.data.RExpression; -import com.oracle.truffle.r.runtime.data.RExternalPtr; -import com.oracle.truffle.r.runtime.data.RFactor; -import com.oracle.truffle.r.runtime.data.RFunction; -import com.oracle.truffle.r.runtime.data.RLanguage; -import com.oracle.truffle.r.runtime.data.RNull; -import com.oracle.truffle.r.runtime.data.RPairList; -import com.oracle.truffle.r.runtime.data.RS4Object; -import com.oracle.truffle.r.runtime.data.RSymbol; +import com.oracle.truffle.r.runtime.RRuntime; +import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.RAbstractComplexVector; import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; @@ -59,7 +52,6 @@ final class ValuePrinters implements ValuePrinter<Object> { printers.put(RExternalPtr.class, ExternalPtrPrinter.INSTANCE); printers.put(RS4Object.class, S4ObjectPrinter.INSTANCE); printers.put(RPairList.class, PairListPrinter.INSTANCE); - printers.put(RFactor.class, FactorPrinter.INSTANCE); } @SuppressWarnings({"rawtypes", "unchecked"}) @@ -74,7 +66,9 @@ final class ValuePrinters implements ValuePrinter<Object> { Object x = printCtx.printerNode().boxPrimitive(v); ValuePrinter printer = printers.get(x.getClass()); if (printer == null) { - if (x instanceof RAbstractStringVector) { + if (x instanceof RAbstractIntVector && ((RAttributable) x).hasClass(RRuntime.CLASS_FACTOR)) { + printer = FactorPrinter.INSTANCE; + } else if (x instanceof RAbstractStringVector) { printer = StringVectorPrinter.INSTANCE; } else if (x instanceof RAbstractDoubleVector) { printer = DoubleVectorPrinter.INSTANCE; diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/helpers/BrowserInteractNode.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/helpers/BrowserInteractNode.java index 34b9ab3141c55b3c626ea9f0f4e9730a52c8a580..cbfb84aa0fbfd4c31bff273cdec73584d94342c2 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/helpers/BrowserInteractNode.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/helpers/BrowserInteractNode.java @@ -147,10 +147,10 @@ public abstract class BrowserInteractNode extends RNode { } private static String getSrcinfo(RStringVector element) { - Object srcref = element.getAttribute(RRuntime.R_SRCREF); + Object srcref = element.getAttr(RRuntime.R_SRCREF); if (srcref != null) { RIntVector lloc = (RIntVector) srcref; - Object srcfile = lloc.getAttribute(RRuntime.R_SRCFILE); + Object srcfile = lloc.getAttr(RRuntime.R_SRCFILE); if (srcfile != null) { REnvironment env = (REnvironment) srcfile; return " at " + RRuntime.asString(env.get(RSrcref.SrcrefFields.filename.name())) + "#" + lloc.getDataAt(0); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedExtractVectorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedExtractVectorNode.java index 4c7357aab540ba5c9244ceeca17857f63ecdb39d..0b43bf6c4e06d0a319e64c173fec67cedcccd335 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedExtractVectorNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedExtractVectorNode.java @@ -39,19 +39,7 @@ import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.RType; import com.oracle.truffle.r.runtime.context.RContext; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; -import com.oracle.truffle.r.runtime.data.RAttributes; -import com.oracle.truffle.r.runtime.data.RDataFactory; -import com.oracle.truffle.r.runtime.data.RExpression; -import com.oracle.truffle.r.runtime.data.RFactor; -import com.oracle.truffle.r.runtime.data.RLanguage; -import com.oracle.truffle.r.runtime.data.RList; -import com.oracle.truffle.r.runtime.data.RLogical; -import com.oracle.truffle.r.runtime.data.RNull; -import com.oracle.truffle.r.runtime.data.RString; -import com.oracle.truffle.r.runtime.data.RStringVector; -import com.oracle.truffle.r.runtime.data.RTypedValue; -import com.oracle.truffle.r.runtime.data.RVector; +import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; @@ -139,10 +127,6 @@ final class CachedExtractVectorNode extends CachedVectorNode { */ return doEnvironment((REnvironment) castVector, positions); case Integer: - if (castVector instanceof RFactor) { - vector = ((RFactor) castVector).getVector(); - break; - } vector = (RAbstractContainer) castVector; break; default: diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedReplaceVectorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedReplaceVectorNode.java index a9a7f880199bbbe254747b6b9c6bf593fefa9cac..cc23fc946510bec07252a4d59f56135d1ab37f1a 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedReplaceVectorNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedReplaceVectorNode.java @@ -41,20 +41,7 @@ import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RError.Message; import com.oracle.truffle.r.runtime.RType; import com.oracle.truffle.r.runtime.context.RContext; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; -import com.oracle.truffle.r.runtime.data.RDataFactory; -import com.oracle.truffle.r.runtime.data.RExpression; -import com.oracle.truffle.r.runtime.data.RFactor; -import com.oracle.truffle.r.runtime.data.RLanguage; -import com.oracle.truffle.r.runtime.data.RList; -import com.oracle.truffle.r.runtime.data.RMissing; -import com.oracle.truffle.r.runtime.data.RNull; -import com.oracle.truffle.r.runtime.data.RPairList; -import com.oracle.truffle.r.runtime.data.RScalarVector; -import com.oracle.truffle.r.runtime.data.RShareable; -import com.oracle.truffle.r.runtime.data.RStringVector; -import com.oracle.truffle.r.runtime.data.RTypedValue; -import com.oracle.truffle.r.runtime.data.RVector; +import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; @@ -146,11 +133,7 @@ final class CachedReplaceVectorNode extends CachedVectorNode { value = castType.getEmpty(); } } else { - if (!isList() && castValue instanceof RFactor) { - value = ((RFactor) castValue).getVector(); - } else { - value = (RTypedValue) castValue; - } + value = (RTypedValue) castValue; } int appliedValueLength; @@ -183,9 +166,6 @@ final class CachedReplaceVectorNode extends CachedVectorNode { case Null: vector = castType.getEmpty(); break; - case Factor: - vector = ((RFactor) castVector).getVector(); - break; case PairList: vector = ((RPairList) castVector).toRList(); break; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedVectorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedVectorNode.java index b2084a03d51f5ae5f39df81c8f72d0af18a2620f..2622dfc83ebb23d9920416d187264533e4ce06fe 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedVectorNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/CachedVectorNode.java @@ -142,7 +142,6 @@ abstract class CachedVectorNode extends RBaseNode { switch (type) { case Null: case Language: - case Factor: case PairList: case Environment: case Expression: diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCastNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCastNode.java index 8cbb1b12d1d4d09459843b17e4417dd6f7fb5b36..6579b8088ef89d2b44493e1fc01361734f2dfc2e 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCastNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/PositionCastNode.java @@ -30,26 +30,8 @@ import com.oracle.truffle.r.nodes.unary.CastIntegerNode; import com.oracle.truffle.r.nodes.unary.CastIntegerNodeGen; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RType; -import com.oracle.truffle.r.runtime.data.RDataFactory; -import com.oracle.truffle.r.runtime.data.RDouble; -import com.oracle.truffle.r.runtime.data.REmpty; -import com.oracle.truffle.r.runtime.data.RFactor; -import com.oracle.truffle.r.runtime.data.RFunction; -import com.oracle.truffle.r.runtime.data.RInteger; -import com.oracle.truffle.r.runtime.data.RLogical; -import com.oracle.truffle.r.runtime.data.RMissing; -import com.oracle.truffle.r.runtime.data.RNull; -import com.oracle.truffle.r.runtime.data.RString; -import com.oracle.truffle.r.runtime.data.RSymbol; -import com.oracle.truffle.r.runtime.data.RTypedValue; -import com.oracle.truffle.r.runtime.data.model.RAbstractComplexVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractListVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractRawVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractVector; +import com.oracle.truffle.r.runtime.data.*; +import com.oracle.truffle.r.runtime.data.model.*; import com.oracle.truffle.r.runtime.env.REnvironment; import com.oracle.truffle.r.runtime.ops.na.NACheck; @@ -93,11 +75,6 @@ abstract class PositionCastNode extends Node { return position; } - @Specialization - protected RAbstractVector doFactor(RFactor position) { - return position.getVector(); - } - @Specialization protected RAbstractVector doDouble(double position, @Cached("create()") NACheck check) { if (mode.isSubscript()) { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/AttributeAccess.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/AttributeAccess.java index 0656f9ee9564215a5fba681332f49c5e9f2588ad..eff4b0c6e2f5e882b6d44441c7f6c68af3d5017c 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/AttributeAccess.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/AttributeAccess.java @@ -47,6 +47,10 @@ public abstract class AttributeAccess extends RBaseNode { this.name = name.intern(); } + public static AttributeAccess create(String name) { + return AttributeAccessNodeGen.create(name); + } + public abstract Object execute(RAttributes attr); protected boolean nameMatches(RAttributes attr, int index) { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryArithmeticNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryArithmeticNode.java index 7f5e12b3398960ed20185c99cf21c10092bb0312..a9c8c2fbf982d538e46ef3c846fd7cf8af5f8528 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryArithmeticNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryArithmeticNode.java @@ -31,7 +31,6 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.profiles.ValueProfile; import com.oracle.truffle.r.nodes.builtin.CastBuilder; -import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.control.RLengthNode; import com.oracle.truffle.r.nodes.primitive.BinaryMapNode; import com.oracle.truffle.r.nodes.profile.TruffleBoundaryNode; @@ -41,19 +40,19 @@ import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RError.Message; import com.oracle.truffle.r.runtime.RType; import com.oracle.truffle.r.runtime.data.RDataFactory; -import com.oracle.truffle.r.runtime.data.RFactor; import com.oracle.truffle.r.runtime.data.RMissing; import com.oracle.truffle.r.runtime.data.RNull; -import com.oracle.truffle.r.runtime.data.model.RAbstractComplexVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractVector; +import com.oracle.truffle.r.runtime.data.model.*; import com.oracle.truffle.r.runtime.ops.BinaryArithmetic; import com.oracle.truffle.r.runtime.ops.BinaryArithmeticFactory; import com.oracle.truffle.r.runtime.ops.UnaryArithmeticFactory; -public abstract class BinaryArithmeticNode extends RBuiltinNode { +/** + * Represents a binary or unary operation from the 'arithmetic' subset of Ops R group. The concrete + * operation is implemented by factory object given as a constructor parameter, e.g. + * {@link com.oracle.truffle.r.runtime.ops.BinaryArithmetic.Add} + */ +public abstract class BinaryArithmeticNode extends BinaryNodeBase { protected static final int CACHE_LIMIT = 5; @@ -74,13 +73,15 @@ public abstract class BinaryArithmeticNode extends RBuiltinNode { return BinaryArithmeticNodeGen.create(binary, unary, null); } - @Specialization(limit = "CACHE_LIMIT", guards = {"cached != null", "cached.isSupported(left, right)"}) + @Specialization(limit = "CACHE_LIMIT", guards = {"cached != null", "cached.isSupported(left, right)", + "!isFactor(left)", "!isFactor(right)"}) protected Object doNumericVectorCached(Object left, Object right, // @Cached("createFastCached(left, right)") BinaryMapNode cached) { return cached.apply(left, right); } - @Specialization(contains = "doNumericVectorCached", guards = {"isNumericVector(left)", "isNumericVector(right)"}) + @Specialization(contains = "doNumericVectorCached", guards = {"isNumericVector(left)", "isNumericVector(right)", + "!isFactor(left)", "!isFactor(right)"}) @TruffleBoundary protected Object doNumericVectorGeneric(Object left, Object right, // @Cached("binary.create()") BinaryArithmetic arithmetic, // @@ -117,33 +118,25 @@ public abstract class BinaryArithmeticNode extends RBuiltinNode { } } - protected static boolean isFactor(Object value) { - return value instanceof RFactor; - } - @Specialization(guards = "isFactor(left) || isFactor(right)") - protected Object doFactor(VirtualFrame frame, Object left, Object right, @Cached("create()") RLengthNode lengthNode) { + protected Object doFactor(VirtualFrame frame, RAbstractIntVector left, RAbstractIntVector right, @Cached("create()") RLengthNode lengthNode) { Message warning; - if (left instanceof RFactor) { - warning = getFactorWarning((RFactor) left); + if (isFactor(left)) { + warning = getFactorWarning(left); } else { - warning = getFactorWarning((RFactor) right); + warning = getFactorWarning(right); } RError.warning(this, warning, binary.create().opName()); return RDataFactory.createNAVector(Math.max(lengthNode.executeInteger(frame, left), lengthNode.executeInteger(frame, right))); } - private static Message getFactorWarning(RFactor factor) { - return factor.isOrdered() ? Message.NOT_MEANINGFUL_FOR_ORDERED_FACTORS : Message.NOT_MEANINGFUL_FOR_FACTORS; - } - @Specialization @SuppressWarnings("unused") protected static Object doBothNull(RNull left, RNull right) { return RType.Double.getEmpty(); } - @Specialization(guards = "isNumericVector(right)") + @Specialization(guards = {"isNumericVector(right)", "!isFactor(right)"}) protected static Object doLeftNull(@SuppressWarnings("unused") RNull left, Object right, // @Cached("createClassProfile()") ValueProfile classProfile) { if (((RAbstractVector) classProfile.profile(right)).getRType() == RType.Complex) { @@ -153,7 +146,7 @@ public abstract class BinaryArithmeticNode extends RBuiltinNode { } } - @Specialization(guards = "isNumericVector(left)") + @Specialization(guards = {"isNumericVector(left)", "!isFactor(left)"}) protected static Object doRightNull(Object left, RNull right, // @Cached("createClassProfile()") ValueProfile classProfile) { return doLeftNull(right, left, classProfile); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryBooleanNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryBooleanNode.java index e6480ed1fdc8aabe8740b72af06938ea81a2ad99..70123f839c15e0b154621bf3daeafa56d7accca9 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryBooleanNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryBooleanNode.java @@ -28,8 +28,8 @@ import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.nodes.builtin.CastBuilder; -import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.control.RLengthNode; import com.oracle.truffle.r.nodes.primitive.BinaryMapNode; import com.oracle.truffle.r.nodes.profile.TruffleBoundaryNode; @@ -39,16 +39,9 @@ import com.oracle.truffle.r.runtime.RType; import com.oracle.truffle.r.runtime.conn.RConnection; import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RDataFactory; -import com.oracle.truffle.r.runtime.data.RFactor; import com.oracle.truffle.r.runtime.data.RInteger; import com.oracle.truffle.r.runtime.data.closures.RClosures; -import com.oracle.truffle.r.runtime.data.model.RAbstractComplexVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractRawVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractVector; +import com.oracle.truffle.r.runtime.data.model.*; import com.oracle.truffle.r.runtime.ops.BinaryCompare; import com.oracle.truffle.r.runtime.ops.BinaryLogic; import com.oracle.truffle.r.runtime.ops.BinaryLogic.And; @@ -56,7 +49,13 @@ import com.oracle.truffle.r.runtime.ops.BinaryLogic.Or; import com.oracle.truffle.r.runtime.ops.BooleanOperation; import com.oracle.truffle.r.runtime.ops.BooleanOperationFactory; -public abstract class BinaryBooleanNode extends RBuiltinNode { +/** + * Represents a binary or unary operation from the 'logical' subset of Ops R group. The concrete + * operation is implemented by factory object given as a constructor parameter, e.g. + * {@link com.oracle.truffle.r.runtime.ops.BinaryCompare.Equal} or + * {@link com.oracle.truffle.r.runtime.ops.BinaryLogic.And}. + */ +public abstract class BinaryBooleanNode extends BinaryNodeBase { protected static final int CACHE_LIMIT = 5; @@ -123,10 +122,6 @@ public abstract class BinaryBooleanNode extends RBuiltinNode { (!isLogicOp(factory) && (value instanceof RAbstractStringVector || value instanceof RAbstractRawVector)); } - protected static boolean isFactor(Object value) { - return value instanceof RFactor; - } - @Specialization(guards = {"isRConnection(left) || isRConnection(right)"}) protected Object doConnection(VirtualFrame frame, Object left, Object right, // @Cached("createRecursive()") BinaryBooleanNode recursive) { @@ -146,13 +141,15 @@ public abstract class BinaryBooleanNode extends RBuiltinNode { @Cached("createRecursive()") BinaryBooleanNode recursive, // @Cached("create()") RAttributeProfiles attrProfiles) { Object recursiveLeft = left; - if (recursiveLeft instanceof RFactor) { - recursiveLeft = RClosures.createFactorToVector((RFactor) recursiveLeft, false, attrProfiles); + if (isFactor(left)) { + recursiveLeft = RClosures.createFactorToVector((RAbstractIntVector) left, false, attrProfiles); } + Object recursiveRight = right; - if (recursiveRight instanceof RFactor) { - recursiveRight = RClosures.createFactorToVector((RFactor) recursiveRight, false, attrProfiles); + if (isFactor(right)) { + recursiveRight = RClosures.createFactorToVector((RAbstractIntVector) right, false, attrProfiles); } + return recursive.execute(frame, recursiveLeft, recursiveRight); } @@ -163,34 +160,32 @@ public abstract class BinaryBooleanNode extends RBuiltinNode { @Specialization(guards = {"isFactor(left) || isFactor(right)", "!meaningfulFactorOp(left, right)"}) protected Object doFactorNotMeaniningful(VirtualFrame frame, Object left, Object right, @Cached("create()") RLengthNode lengthNode) { Message warning; - if (left instanceof RFactor) { - warning = getFactorWarning((RFactor) left); + if (isFactor(left)) { + warning = getFactorWarning((RAbstractIntVector) left); } else { - warning = getFactorWarning((RFactor) right); + warning = getFactorWarning((RAbstractIntVector) right); } RError.warning(this, warning, factory.create().opName()); return RDataFactory.createNAVector(Math.max(lengthNode.executeInteger(frame, left), lengthNode.executeInteger(frame, right))); } + private ConditionProfile meaningfulOpForFactors = ConditionProfile.createBinaryProfile(); + protected boolean meaningfulFactorOp(Object left, Object right) { - if (factory == BinaryCompare.EQUAL || factory == BinaryCompare.NOT_EQUAL) { + if (meaningfulOpForFactors.profile(factory == BinaryCompare.EQUAL || factory == BinaryCompare.NOT_EQUAL)) { return true; - } else if (left instanceof RFactor) { - boolean ordered = ((RFactor) left).isOrdered(); - if (right instanceof RFactor) { - return ordered && ((RFactor) right).isOrdered(); + } else if (isFactor(left)) { + boolean ordered = isOrderedFactor((RAbstractIntVector) left); + if (isFactor(right)) { + return ordered && isOrderedFactor((RAbstractIntVector) right); } return ordered; } else { - assert right instanceof RFactor; - return ((RFactor) right).isOrdered(); + assert isFactor(right) : "meaningfulFactorOp is expected to be invoked with at least one factor."; + return isOrderedFactor((RAbstractIntVector) right); } } - private static Message getFactorWarning(RFactor factor) { - return factor.isOrdered() ? Message.NOT_MEANINGFUL_FOR_ORDERED_FACTORS : Message.NOT_MEANINGFUL_FOR_FACTORS; - } - @SuppressWarnings("unused") @Specialization(guards = {"isRNullOrEmptyAndNotMissing(left, right)"}) protected static Object doEmptyOrNull(Object left, Object right) { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryNodeBase.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryNodeBase.java new file mode 100644 index 0000000000000000000000000000000000000000..4e2ff2270da74913382344965eba3973639b1c85 --- /dev/null +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/binary/BinaryNodeBase.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2016, 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.binary; + +import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; +import com.oracle.truffle.r.nodes.helpers.InheritsCheckNode; +import com.oracle.truffle.r.nodes.helpers.RFactorNodes; +import com.oracle.truffle.r.runtime.RError; +import com.oracle.truffle.r.runtime.RRuntime; +import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; + +/** + * Provides some shared code for nodes implemented in this package. + * + * TODO: for the time being, this code is only concerned with R factor class. Code specific to + * factors is necessary only because the proper R dispatch of operations implemented in this java + * package is not implemented yet. Once this is done, we can remove this base class. It also seems + * that {@link BinaryBooleanNode} and {@link BinaryArithmeticNode} are separate classes only to + * handle the difference in R specializations that implement them, e.g. Ops.factor handles + * 'arithmetic' subset of Ops differently than the 'logical'. + */ +abstract class BinaryNodeBase extends RBuiltinNode { + + @Child private InheritsCheckNode factorInheritCheck = new InheritsCheckNode(RRuntime.CLASS_FACTOR); + @Child private RFactorNodes.GetOrdered isOrderedFactor = null; + + protected boolean isFactor(Object value) { + return factorInheritCheck.execute(value); + } + + protected boolean isOrderedFactor(RAbstractIntVector factor) { + if (isOrderedFactor == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + isOrderedFactor = insert(new RFactorNodes.GetOrdered()); + } + + return isOrderedFactor.execute(factor); + } + + protected RError.Message getFactorWarning(RAbstractIntVector factor) { + return isOrderedFactor(factor) ? RError.Message.NOT_MEANINGFUL_FOR_ORDERED_FACTORS : RError.Message.NOT_MEANINGFUL_FOR_FACTORS; + } +} diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/WrapArgumentBaseNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/WrapArgumentBaseNode.java index 8990ac616929a540c5838c709b0ab1ece859d6f2..5210945655fb09e4166587e604b7aef188cbf9f4 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/WrapArgumentBaseNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/WrapArgumentBaseNode.java @@ -23,7 +23,6 @@ package com.oracle.truffle.r.nodes.function; import com.oracle.truffle.api.profiles.BranchProfile; -import com.oracle.truffle.r.runtime.data.RFactor; import com.oracle.truffle.r.runtime.data.RFunction; import com.oracle.truffle.r.runtime.data.RLanguage; import com.oracle.truffle.r.runtime.data.RS4Object; @@ -73,9 +72,6 @@ public abstract class WrapArgumentBaseNode extends RNode { if (result instanceof RVector) { everSeenVector.enter(); return (RVector) result; - } else if (result instanceof RFactor) { - everSeenFactor.enter(); - return ((RFactor) result).getVector(); } else if (result instanceof RLanguage) { everSeenLanguage.enter(); return (RLanguage) result; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/helpers/InheritsCheckNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/helpers/InheritsCheckNode.java new file mode 100644 index 0000000000000000000000000000000000000000..28a8070384beafcb8a5487ed8943365785b5fd0c --- /dev/null +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/helpers/InheritsCheckNode.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2016, 2016, 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.helpers; + +import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.r.nodes.function.ClassHierarchyNode; +import com.oracle.truffle.r.nodes.function.ClassHierarchyNodeGen; +import com.oracle.truffle.r.runtime.RType; +import com.oracle.truffle.r.runtime.data.RMissing; +import com.oracle.truffle.r.runtime.data.RStringVector; + +/** + * Checks if given object has given R class. More specifically: whether its attribute class is a + * vector that contains given class name as an element. + */ +public class InheritsCheckNode extends Node { + + @Child private ClassHierarchyNode classHierarchy = ClassHierarchyNodeGen.create(false, false); + private final ConditionProfile nullClassProfile = ConditionProfile.createBinaryProfile(); + @CompilationFinal private ConditionProfile exactMatchProfile; + private final String checkedClazz; + + public InheritsCheckNode(String checkedClazz) { + this.checkedClazz = checkedClazz; + assert RType.fromMode(checkedClazz) == null : "Class '" + checkedClazz + "' cannot be checked by InheritsCheckNode"; + } + + public boolean execute(Object value) { + if (value instanceof RMissing) { + return false; + } + + RStringVector clazz = classHierarchy.execute(value); + if (nullClassProfile.profile(clazz != null)) { + for (int j = 0; j < clazz.getLength(); ++j) { + if (exactMatchProfile == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + exactMatchProfile = ConditionProfile.createBinaryProfile(); + } + if (exactMatchProfile.profile(clazz.getDataAt(j) == checkedClazz) || clazz.getDataAt(j).equals(checkedClazz)) { + return true; + } + } + } + return false; + } +} diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/helpers/RFactorNodes.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/helpers/RFactorNodes.java new file mode 100644 index 0000000000000000000000000000000000000000..b05d17ea20f260ae2c35def3d0212bf3bb216958 --- /dev/null +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/helpers/RFactorNodes.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2016, 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.helpers; + +import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.profiles.BranchProfile; +import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.r.nodes.attributes.AttributeAccess; +import com.oracle.truffle.r.nodes.unary.CastStringNode; +import com.oracle.truffle.r.nodes.unary.CastStringNodeGen; +import com.oracle.truffle.r.runtime.RRuntime; +import com.oracle.truffle.r.runtime.data.RAttributeProfiles; +import com.oracle.truffle.r.runtime.data.RDataFactory; +import com.oracle.truffle.r.runtime.data.RStringVector; +import com.oracle.truffle.r.runtime.data.RVector; +import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; +import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector; + +/** + * Contains helper nodes related to factors, special R class of {@link RAbstractIntVector}. Note: + * there is also {@see IsFactorNode}, which implements a built-in, for checking factor class. + */ +public final class RFactorNodes { + + private RFactorNodes() { + } + + /** + * Encapsulates the operation of deciding whether a factor is ordered. + */ + public static class GetOrdered extends Node { + @Child private AttributeAccess isOrderedAccess = AttributeAccess.create(RRuntime.ORDERED_ATTR_KEY); + + public boolean execute(RAbstractIntVector factor) { + Object value = isOrderedAccess.execute(factor.getAttributes()); + if (value instanceof RAbstractLogicalVector) { + RAbstractLogicalVector vec = (RAbstractLogicalVector) value; + return vec.getLength() > 0 && RRuntime.fromLogical(vec.getDataAt(0)); + } + + return false; + } + } + + /** + * Encapsulates the operation of getting the 'levels' of a factor as a string vector. + */ + public static class GetLevels extends Node { + @Child private CastStringNode castString; + @Child private AttributeAccess attrAccess = AttributeAccess.create(RRuntime.LEVELS_ATTR_KEY); + + private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); + private final BranchProfile notVectorBranch = BranchProfile.create(); + private final ConditionProfile nonScalarLevels = ConditionProfile.createBinaryProfile(); + private final ConditionProfile stringVectorLevels = ConditionProfile.createBinaryProfile(); + + /** + * Returns the levels as a string vector. If the 'levels' attribute is not a string vector a + * cast is done. May return null, if the 'levels' attribute is not present. + */ + public RStringVector execute(RAbstractIntVector factor) { + Object attr = attrAccess.execute(factor.getAttributes()); + + // Convert scalars to vector if necessary + RVector vec; + if (nonScalarLevels.profile(attr instanceof RVector)) { + vec = (RVector) attr; + } else if (attr != null) { + vec = (RVector) RRuntime.asAbstractVector(attr); // scalar to vector + } else { + notVectorBranch.enter(); + // N.B: when a factor is lacking the 'levels' attribute, GNU R uses range 1:14331272 + // as levels, but probably only in 'split'. Following example prints a huge list: + // { f <- factor(1:5); attr(f, 'levels') <- NULL; split(1:2, f) } + return null; + } + + // Convert to string vector if necessary + if (stringVectorLevels.profile(vec instanceof RStringVector)) { + return (RStringVector) vec; + } else { + if (castString == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + castString = insert(CastStringNodeGen.create(false, false, false, false)); + } + RStringVector slevels = (RStringVector) castString.executeString(vec); + return RDataFactory.createStringVector(slevels.getDataWithoutCopying(), RDataFactory.COMPLETE_VECTOR); + } + } + } +} diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerNode.java index 9225582669eeeb4ae0686c58c7ac2a14509cd16e..7b15cf7fede1479f5f3718de78a5bbf3983a8978 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerNode.java @@ -29,22 +29,8 @@ import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; -import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; -import com.oracle.truffle.r.runtime.data.RComplex; -import com.oracle.truffle.r.runtime.data.RDataFactory; -import com.oracle.truffle.r.runtime.data.RDoubleSequence; -import com.oracle.truffle.r.runtime.data.RFactor; -import com.oracle.truffle.r.runtime.data.RIntSequence; -import com.oracle.truffle.r.runtime.data.RIntVector; -import com.oracle.truffle.r.runtime.data.RList; -import com.oracle.truffle.r.runtime.data.model.RAbstractComplexVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractListVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractRawVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractVector; +import com.oracle.truffle.r.runtime.data.*; +import com.oracle.truffle.r.runtime.data.model.*; import com.oracle.truffle.r.runtime.ops.na.NAProfile; public abstract class CastIntegerNode extends CastIntegerBaseNode { @@ -215,11 +201,6 @@ public abstract class CastIntegerNode extends CastIntegerBaseNode { return ret; } - @Specialization - protected RIntVector doFactor(RFactor factor) { - return factor.getVector(); - } - // TODO Should be type-variable and moved to CastNode @Specialization(guards = {"args.getLength() == 1", "isIntVector(args.getArgument(0))"}) protected RIntVector doRArgsValuesAndNames(RArgsValuesAndNames args) { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastLogicalNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastLogicalNode.java index b60cb438a3b5d72dca159bb03cb19dd004c929bd..b41b5aeb679f14847f948eaf926d99c3fdd01aab 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastLogicalNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastLogicalNode.java @@ -27,17 +27,9 @@ import java.util.Arrays; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.nodes.helpers.InheritsCheckNode; import com.oracle.truffle.r.runtime.RRuntime; -import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; -import com.oracle.truffle.r.runtime.data.RComplexVector; -import com.oracle.truffle.r.runtime.data.RDataFactory; -import com.oracle.truffle.r.runtime.data.RFactor; -import com.oracle.truffle.r.runtime.data.RList; -import com.oracle.truffle.r.runtime.data.RLogicalVector; -import com.oracle.truffle.r.runtime.data.RMissing; -import com.oracle.truffle.r.runtime.data.RNull; -import com.oracle.truffle.r.runtime.data.RRawVector; -import com.oracle.truffle.r.runtime.data.RStringVector; +import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; @@ -79,7 +71,7 @@ public abstract class CastLogicalNode extends CastLogicalBaseNode { return operand; } - @Specialization + @Specialization(guards = "!isFactor(operand)") protected RLogicalVector doIntVector(RAbstractIntVector operand) { return createResultVector(operand, index -> naCheck.convertIntToLogical(operand.getDataAt(index))); } @@ -154,8 +146,8 @@ public abstract class CastLogicalNode extends CastLogicalBaseNode { return missing; } - @Specialization - protected RLogicalVector asLogical(RFactor factor) { + @Specialization(guards = "isFactor(factor)") + protected RLogicalVector asLogical(RAbstractIntVector factor) { byte[] data = new byte[factor.getLength()]; Arrays.fill(data, RRuntime.LOGICAL_NA); return RDataFactory.createLogicalVector(data, RDataFactory.INCOMPLETE_VECTOR); @@ -170,4 +162,10 @@ public abstract class CastLogicalNode extends CastLogicalBaseNode { public static CastLogicalNode createNonPreserving() { return CastLogicalNodeGen.create(false, false, false); } + + @Child private InheritsCheckNode inheritsFactorCheck = new InheritsCheckNode(RRuntime.CLASS_FACTOR); + + protected boolean isFactor(Object o) { + return inheritsFactorCheck.execute(o); + } } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToContainerNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToContainerNode.java index 260cca0912bf6659377cb15f0778bdabe54a7c11..c1a512ea7c8deab823d2a831203ecbe995e53750 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToContainerNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToContainerNode.java @@ -23,12 +23,7 @@ package com.oracle.truffle.r.nodes.unary; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.r.runtime.data.RExpression; -import com.oracle.truffle.r.runtime.data.RFactor; -import com.oracle.truffle.r.runtime.data.RFunction; -import com.oracle.truffle.r.runtime.data.RLanguage; -import com.oracle.truffle.r.runtime.data.RNull; -import com.oracle.truffle.r.runtime.data.RPairList; +import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; import com.oracle.truffle.r.runtime.env.REnvironment; @@ -52,11 +47,6 @@ public abstract class CastToContainerNode extends CastBaseNode { return vector; } - @Specialization - protected RFactor cast(RFactor factor) { - return factor; - } - @Specialization protected RExpression cast(RExpression expression) { return expression; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToVectorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToVectorNode.java index 1734a58f8a5c0474be8b643ebb88c78427cd87c8..8f35c98a981be1d8b8318c449b2684fff67c227e 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToVectorNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToVectorNode.java @@ -24,12 +24,7 @@ package com.oracle.truffle.r.nodes.unary; import com.oracle.truffle.api.dsl.NodeField; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.r.runtime.data.RDataFactory; -import com.oracle.truffle.r.runtime.data.RExpression; -import com.oracle.truffle.r.runtime.data.RFactor; -import com.oracle.truffle.r.runtime.data.RFunction; -import com.oracle.truffle.r.runtime.data.RList; -import com.oracle.truffle.r.runtime.data.RNull; +import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; @NodeField(name = "nonVectorPreserved", type = boolean.class) @@ -60,11 +55,6 @@ public abstract class CastToVectorNode extends CastNode { return vector; } - @Specialization - protected RAbstractVector cast(RFactor factor) { - return factor.getVector(); - } - @Specialization protected RList cast(RExpression expression) { return expression.getList(); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/IsFactorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/IsFactorNode.java index 74f2c2e330bd72da3ce0ff68f3c91c92cd4dad20..bf740255bc676013010b0c5148b838d1212ac733 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/IsFactorNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/IsFactorNode.java @@ -11,16 +11,19 @@ package com.oracle.truffle.r.nodes.unary; +import static com.oracle.truffle.r.runtime.RRuntime.LOGICAL_FALSE; +import static com.oracle.truffle.r.runtime.RRuntime.LOGICAL_TRUE; + import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.nodes.helpers.InheritsCheckNode; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.RType; -import com.oracle.truffle.r.runtime.data.RDataFactory; public abstract class IsFactorNode extends UnaryNode { @Child private TypeofNode typeofNode; - @Child private InheritsNode inheritsNode; + @Child private InheritsCheckNode inheritsCheck; public abstract byte executeIsFactor(Object c); @@ -31,12 +34,15 @@ public abstract class IsFactorNode extends UnaryNode { typeofNode = insert(TypeofNodeGen.create()); } if (typeofNode.execute(x) != RType.Integer) { - return RRuntime.LOGICAL_FALSE; + // Note: R does not allow to set class 'factor' to an arbitrary object, unlike with + // data.frame + return LOGICAL_FALSE; } - if (inheritsNode == null) { + if (inheritsCheck == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); - inheritsNode = insert(InheritsNodeGen.create()); + inheritsCheck = insert(new InheritsCheckNode(RRuntime.CLASS_FACTOR)); } - return (byte) inheritsNode.executeObject(x, RDataFactory.createStringVector(RType.Factor.getName()), RRuntime.LOGICAL_FALSE); + + return inheritsCheck.execute(x) ? LOGICAL_TRUE : LOGICAL_FALSE; } } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/PrecedenceNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/PrecedenceNode.java index 8afec0273e921dbcfce320b4deec79f0241990bc..8c7b2e531442fb5589ed6c5774535a926a3a51a2 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/PrecedenceNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/PrecedenceNode.java @@ -26,26 +26,7 @@ import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.r.runtime.RRuntime; -import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; -import com.oracle.truffle.r.runtime.data.RComplex; -import com.oracle.truffle.r.runtime.data.RComplexVector; -import com.oracle.truffle.r.runtime.data.RDoubleSequence; -import com.oracle.truffle.r.runtime.data.RDoubleVector; -import com.oracle.truffle.r.runtime.data.RExpression; -import com.oracle.truffle.r.runtime.data.RFactor; -import com.oracle.truffle.r.runtime.data.RFunction; -import com.oracle.truffle.r.runtime.data.RIntSequence; -import com.oracle.truffle.r.runtime.data.RIntVector; -import com.oracle.truffle.r.runtime.data.RLanguage; -import com.oracle.truffle.r.runtime.data.RList; -import com.oracle.truffle.r.runtime.data.RLogicalVector; -import com.oracle.truffle.r.runtime.data.RNull; -import com.oracle.truffle.r.runtime.data.RPairList; -import com.oracle.truffle.r.runtime.data.RRaw; -import com.oracle.truffle.r.runtime.data.RRawVector; -import com.oracle.truffle.r.runtime.data.RS4Object; -import com.oracle.truffle.r.runtime.data.RStringVector; -import com.oracle.truffle.r.runtime.data.RSymbol; +import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.env.REnvironment; import com.oracle.truffle.r.runtime.nodes.RBaseNode; @@ -187,11 +168,6 @@ public abstract class PrecedenceNode extends RBaseNode { return EXPRESSION_PRECEDENCE; } - @Specialization - protected int doFactor(RFactor val, byte recursive) { - return INT_PRECEDENCE; - } - @Specialization protected int doS4Object(RS4Object o, byte recursive) { return LIST_PRECEDENCE; 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 4c52f4046f06685a7c1b5d115a6edf7722ccc236..c0c031affaa58c088ac0222e2abafa47b7c54c78 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 @@ -23,38 +23,14 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.source.Source; import com.oracle.truffle.api.source.SourceSection; import com.oracle.truffle.r.runtime.context.RContext; -import com.oracle.truffle.r.runtime.data.RAttributable; -import com.oracle.truffle.r.runtime.data.RAttributes; +import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.RAttributes.RAttribute; -import com.oracle.truffle.r.runtime.data.RComplex; -import com.oracle.truffle.r.runtime.data.RDataFactory; -import com.oracle.truffle.r.runtime.data.REmpty; -import com.oracle.truffle.r.runtime.data.RExpression; -import com.oracle.truffle.r.runtime.data.RExternalPtr; -import com.oracle.truffle.r.runtime.data.RFactor; -import com.oracle.truffle.r.runtime.data.RFunction; -import com.oracle.truffle.r.runtime.data.RIntSequence; -import com.oracle.truffle.r.runtime.data.RLanguage; -import com.oracle.truffle.r.runtime.data.RList; -import com.oracle.truffle.r.runtime.data.RMissing; -import com.oracle.truffle.r.runtime.data.RNull; -import com.oracle.truffle.r.runtime.data.RPairList; -import com.oracle.truffle.r.runtime.data.RS4Object; -import com.oracle.truffle.r.runtime.data.RStringVector; -import com.oracle.truffle.r.runtime.data.RSymbol; -import com.oracle.truffle.r.runtime.data.RTypedValue; import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; import com.oracle.truffle.r.runtime.data.model.RAbstractListVector; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; import com.oracle.truffle.r.runtime.env.REnvironment; import com.oracle.truffle.r.runtime.gnur.SEXPTYPE; -import com.oracle.truffle.r.runtime.nodes.RSyntaxCall; -import com.oracle.truffle.r.runtime.nodes.RSyntaxConstant; -import com.oracle.truffle.r.runtime.nodes.RSyntaxElement; -import com.oracle.truffle.r.runtime.nodes.RSyntaxFunction; -import com.oracle.truffle.r.runtime.nodes.RSyntaxLookup; -import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; -import com.oracle.truffle.r.runtime.nodes.RSyntaxVisitor; +import com.oracle.truffle.r.runtime.nodes.*; /** * Deparsing R objects. @@ -569,9 +545,6 @@ public class RDeparse { protected Void visit(RSyntaxConstant constant) { // coerce scalar values to vectors and unwrap data frames and factors: Object value = RRuntime.asAbstractVector(constant.getValue()); - if (value instanceof RFactor) { - value = ((RFactor) value).getVector(); - } if (value instanceof RExpression) { append("expression(").appendListContents(((RExpression) value).getList()).append(')'); @@ -600,7 +573,7 @@ public class RDeparse { append(')'); } else if (value instanceof RS4Object) { RS4Object s4Obj = (RS4Object) value; - Object clazz = s4Obj.getAttribute("class"); + Object clazz = s4Obj.getAttr("class"); String className = clazz == null ? "S4" : RRuntime.toString(RRuntime.asStringLengthOne(clazz)); append("new(\"").append(className).append('\"'); try (C c = indent()) { @@ -926,8 +899,7 @@ public class RDeparse { } /** - * Handles {@link RList}, (@link RExpression}, and {@link RFactor}. Method name same as - * GnuR. + * Handles {@link RList}, (@link RExpression}. Method name same as GnuR. */ private DeparseVisitor appendListContents(RAbstractListVector v) { int n = v.getLength(); diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntime.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntime.java index bf8611503b131b00dbb305493ec1c6f30d1526a8..9d60e49c9b15a7b223b94bdba45840e14d96a7a0 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntime.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RRuntime.java @@ -128,7 +128,8 @@ public class RRuntime { public static final String DOT_S3_CLASS = ".S3Class"; public static final String CLASS_DATA_FRAME = "data.frame"; - public static final String CLASS_ORDERED = "ordered"; + public static final String CLASS_FACTOR = "factor"; + public static final String ORDERED_ATTR_KEY = "ordered"; public static final String RS3MethodsTable = ".__S3MethodsTable__."; diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java index 5206b2ada7985e774651c6545c4c10530850fa55..a45378ddf386a42d0d0b7b6b21a4e2a5de927450 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RSerialize.java @@ -11,21 +11,9 @@ */ package com.oracle.truffle.r.runtime; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.PrintStream; +import java.io.*; import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.Deque; -import java.util.HashMap; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.Map; +import java.util.*; import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; @@ -34,37 +22,10 @@ import com.oracle.truffle.api.source.Source; import com.oracle.truffle.r.runtime.conn.RConnection; import com.oracle.truffle.r.runtime.context.Engine.ParseException; import com.oracle.truffle.r.runtime.context.RContext; -import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; -import com.oracle.truffle.r.runtime.data.RAttributable; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; -import com.oracle.truffle.r.runtime.data.RAttributes; +import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.RAttributes.RAttribute; -import com.oracle.truffle.r.runtime.data.RComplex; -import com.oracle.truffle.r.runtime.data.RComplexVector; -import com.oracle.truffle.r.runtime.data.RDataFactory; -import com.oracle.truffle.r.runtime.data.REmpty; -import com.oracle.truffle.r.runtime.data.RExpression; -import com.oracle.truffle.r.runtime.data.RExternalPtr; -import com.oracle.truffle.r.runtime.data.RFactor; -import com.oracle.truffle.r.runtime.data.RFunction; -import com.oracle.truffle.r.runtime.data.RIntVector; -import com.oracle.truffle.r.runtime.data.RLanguage; -import com.oracle.truffle.r.runtime.data.RList; -import com.oracle.truffle.r.runtime.data.RLogicalVector; -import com.oracle.truffle.r.runtime.data.RMissing; -import com.oracle.truffle.r.runtime.data.RNull; -import com.oracle.truffle.r.runtime.data.RPairList; -import com.oracle.truffle.r.runtime.data.RPromise; import com.oracle.truffle.r.runtime.data.RPromise.OptType; import com.oracle.truffle.r.runtime.data.RPromise.PromiseType; -import com.oracle.truffle.r.runtime.data.RRawVector; -import com.oracle.truffle.r.runtime.data.RScalar; -import com.oracle.truffle.r.runtime.data.RShareable; -import com.oracle.truffle.r.runtime.data.RStringVector; -import com.oracle.truffle.r.runtime.data.RSymbol; -import com.oracle.truffle.r.runtime.data.RTypedValue; -import com.oracle.truffle.r.runtime.data.RUnboundValue; -import com.oracle.truffle.r.runtime.data.RVector; import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; import com.oracle.truffle.r.runtime.data.model.RAbstractRawVector; @@ -1498,10 +1459,6 @@ public class RSerialize { writeItem(RNull.instance); } } - } else if (type == SEXPTYPE.FASTR_FACTOR) { - RFactor factor = (RFactor) obj; - writeItem(factor.getVector()); - return; } else { // flags RAttributes attributes = null; diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RType.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RType.java index 651c6f100aff2deafd0e947963144913b403fdbc..82816c766520b48e0bcdadc93231b55e693d8147 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RType.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RType.java @@ -36,7 +36,6 @@ public enum RType { Closure("closure", -1), Builtin("builtin", -1), Special("special", -1), - Factor("factor", -1), Symbol("symbol", -1), Environment("environment", -1), PairList("pairlist", -1), @@ -143,8 +142,6 @@ public enum RType { return Builtin; case "special": return Special; - case "factor": - return Factor; case "symbol": return Symbol; case "environment": diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/Utils.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/Utils.java index 9e9a027d826fd7149b75d41d8a76df84b2830d40..388ff08a9c6dd99bf2a3c95e00b11e14c681351a 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/Utils.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/Utils.java @@ -412,9 +412,10 @@ public final class Utils { assert call != null; RLanguage rl = RContext.getRRuntimeASTAccess().getSyntaxCaller(call); RSyntaxNode sn = (RSyntaxNode) rl.getRep(); - SourceSection ss = sn.getSourceSection(); + SourceSection ss = sn != null ? sn.getSourceSection() : null; // fabricate a srcref attribute from ss - String path = ss.getSource().getPath(); + Source source = ss != null ? ss.getSource() : null; + String path = source != null ? source.getPath() : null; if (path != null && RInternalSourceDescriptions.isInternal(path)) { path = null; } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributable.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributable.java index 609aef238392dc5b3b57b0678104620c299cdc3a..f5ed54d6b20c16c020e27db5d24cc9c4cdf3e1f3 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributable.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributable.java @@ -23,7 +23,6 @@ package com.oracle.truffle.r.runtime.data; import com.oracle.truffle.r.runtime.RRuntime; -import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; import com.oracle.truffle.r.runtime.env.REnvironment; /** @@ -33,6 +32,7 @@ import com.oracle.truffle.r.runtime.env.REnvironment; * {@link RAttributable} is implemented by the {@link RAttributes} class. */ public interface RAttributable extends RTypedValue { + /** * If the attribute set is not initialized, then initialize it. * @@ -49,16 +49,21 @@ public interface RAttributable extends RTypedValue { RAttributes getAttributes(); /** - * Returns the value of the {@code class} attribute. + * Returns the value of the {@code class} attribute or empty {@link RStringVector} if class + * attribute is not set. */ - RStringVector getClassHierarchy(); + default RStringVector getClassHierarchy() { + Object v = getAttr(RRuntime.CLASS_ATTR_KEY); + RStringVector result = v instanceof RStringVector ? (RStringVector) v : getImplicitClass(); + return result != null ? result : RDataFactory.createEmptyStringVector(); + } /** * Returns {@code true} if the {@code class} attribute is set to {@link RStringVector} whose * first element equals to the given className. */ default boolean hasClass(String className) { - RAbstractStringVector v = getClassHierarchy(); + RStringVector v = getClassHierarchy(); for (int i = 0; i < v.getLength(); ++i) { if (v.getDataAt(i).equals(className)) { return true; @@ -81,6 +86,14 @@ public interface RAttributable extends RTypedValue { } } + /** + * Get the value of an attribute. Returns {@code null} if not set. + */ + default Object getAttr(String name) { + RAttributes attr = getAttributes(); + return attr == null ? null : attr.get(name); + } + /** * Set the attribute {@code name} to {@code value}, overwriting any existing value. This is * generic; a class may need to override this to handle certain attributes specially. diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributeStorage.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributeStorage.java index c8950954a78e352fca4739d8a680cdf5297ae29a..44cf397f6e5f2c585b25d3eebb4613ded89fba98 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributeStorage.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RAttributeStorage.java @@ -22,8 +22,6 @@ */ package com.oracle.truffle.r.runtime.data; -import com.oracle.truffle.r.runtime.RRuntime; - /** * An adaptor class for the several R types that are attributable. Only useful for classes that * don't already inherit from another class, otherwise just cut and paste this code. @@ -50,21 +48,6 @@ public abstract class RAttributeStorage extends RBaseObject implements RAttribut this.attributes = newAttributes; } - public final Object getAttribute(String name) { - RAttributes attr = attributes; - return attr == null ? null : attr.get(name); - } - @Override public abstract RStringVector getImplicitClass(); - - @Override - public final RStringVector getClassHierarchy() { - RStringVector v = (RStringVector) getAttribute(RRuntime.CLASS_ATTR_KEY); - if (v == null) { - return getImplicitClass(); - } else { - return v; - } - } } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java index 51bb3a4873c4b5612c37e8fe9ceae54645b3d5c0..8cb3a253031143d295362945b3d4307940c9c566 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RDataFactory.java @@ -356,10 +356,6 @@ public final class RDataFactory { return traceDataCreated(new RExpression(list)); } - public static RFactor createFactor(RIntVector vector, boolean ordered) { - return traceDataCreated(new RFactor(vector, ordered)); - } - public static RSymbol createSymbol(String name) { assert name == name.intern(); return traceDataCreated(new RSymbol(name)); diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RExpression.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RExpression.java index ba4747180593c6b1052530889c88cd5abf7eeb34..a365680d20d128c48ab93657ad3970982033a771 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RExpression.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RExpression.java @@ -158,7 +158,7 @@ public class RExpression implements RShareable, RAbstractContainer { @Override public final RStringVector getClassHierarchy() { - RStringVector v = (RStringVector) data.getAttribute(RRuntime.CLASS_ATTR_KEY); + RStringVector v = (RStringVector) data.getAttr(RRuntime.CLASS_ATTR_KEY); if (v == null) { return getImplicitClass(); } else { diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RFactor.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RFactor.java index 3e2ecabe1960185a9ec20b006063bb83a22c4ce6..367011fce4b174e190e0e3a7831d051fba891122 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RFactor.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RFactor.java @@ -23,237 +23,32 @@ package com.oracle.truffle.r.runtime.data; import com.oracle.truffle.r.runtime.RRuntime; -import com.oracle.truffle.r.runtime.RType; -import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; -import com.oracle.truffle.r.runtime.data.model.RAbstractVector; +import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; -public final class RFactor implements RShareable, RAbstractContainer { +public final class RFactor { - private final RIntVector vector; - - private final boolean ordered; - - public RFactor(RIntVector vector, boolean ordered) { - this.vector = vector; - this.ordered = ordered; - } - - @Override - public int[] getInternalStore() { - return vector.getInternalStore(); - } - - @Override - public RType getRType() { - return RType.Integer; - } - - public RIntVector getVector() { - return vector; - } - - public boolean isOrdered() { - return ordered; - } - - @Override - public boolean isComplete() { - return vector.isComplete(); - } - - @Override - public int getLength() { - return vector.getLength(); - } - - @Override - public RAbstractContainer resize(int size) { - return vector.resize(size); - } - - @Override - public boolean isTemporary() { - return vector.isTemporary(); - } - - @Override - public boolean isShared() { - return vector.isShared(); - } - - @Override - public void incRefCount() { - vector.incRefCount(); - } - - @Override - public void decRefCount() { - vector.decRefCount(); - } - - @Override - public boolean isSharedPermanent() { - return vector.isSharedPermanent(); - } - - @Override - public void makeSharedPermanent() { - vector.makeSharedPermanent(); - } - - @Override - public RShareable getNonShared() { - RIntVector newVector = (RIntVector) vector.getNonShared(); - return newVector == vector ? this : RDataFactory.createFactor(newVector, ordered); - } - - @Override - public RFactor copy() { - return RDataFactory.createFactor((RIntVector) vector.copy(), ordered); - } - - @Override - public RAttributes getAttributes() { - return vector.getAttributes(); - } - - @Override - public boolean hasDimensions() { - return vector.hasDimensions(); - } - - @Override - public int[] getDimensions() { - return vector.getDimensions(); - } - - @Override - public void setDimensions(int[] newDimensions) { - vector.setDimensions(newDimensions); - } - - @Override - public Class<?> getElementClass() { - return RFactor.class; - } - - @Override - public RFactor materializeNonShared() { - RVector v = vector.materializeNonShared(); - return vector != v ? RDataFactory.createFactor((RIntVector) v, ordered) : this; - } - - @Override - public Object getDataAtAsObject(int index) { - return vector.getDataAtAsObject(index); - } - - @Override - public RStringVector getNames(RAttributeProfiles attrProfiles) { - return vector.getNames(attrProfiles); - } - - @Override - public void setNames(RStringVector newNames) { - vector.setNames(newNames); - } - - @Override - public RList getDimNames(RAttributeProfiles attrProfiles) { - return vector.getDimNames(); - } - - @Override - public void setDimNames(RList newDimNames) { - vector.setDimNames(newDimNames); - } - - @Override - public Object getRowNames(RAttributeProfiles attrProfiles) { - return vector.getRowNames(); - } - - @Override - public void setRowNames(RAbstractVector rowNames) { - vector.setRowNames(rowNames); - } - - @Override - public RStringVector getClassHierarchy() { - return vector.getClassHierarchy(); - } - - @Override - public RStringVector getImplicitClass() { - return vector.getImplicitClass(); - } - - @Override - public boolean isObject(RAttributeProfiles attrProfiles) { - return true; - } - - @Override - public RAttributes initAttributes() { - return vector.initAttributes(); - } - - @Override - public void initAttributes(RAttributes newAttributes) { - vector.initAttributes(newAttributes); - } - - @Override - public void setAttr(String name, Object value) { - vector.setAttr(name, value); - } - - @Override - public Object getAttr(RAttributeProfiles attrProfiles, String name) { - return vector.getAttr(attrProfiles, name); - } - - @Override - public RAttributes resetAllAttributes(boolean nullify) { - return vector.resetAllAttributes(nullify); - } - - @Override - public RShareable materializeToShareable() { - return this; - } - - public void setLevels(Object newLevels) { - vector.setAttr(RRuntime.LEVELS_ATTR_KEY, newLevels); - } - - @Override - public RAbstractContainer setClassAttr(RStringVector classAttr, boolean convertToInt) { - return vector.setClassAttr(classAttr, convertToInt); - } - - public RVector getLevels(RAttributeProfiles attrProfiles) { - Object attr = vector.getAttr(attrProfiles, RRuntime.LEVELS_ATTR_KEY); - if (attr instanceof RVector) { - return (RVector) attr; - } else { - // Scalar, must convert - return (RVector) RRuntime.asAbstractVector(attr); - } + private RFactor(RIntVector vector, boolean ordered) { + // only static helpers } - public int getNLevels(RAttributeProfiles attrProfiles) { - RVector levels = getLevels(attrProfiles); - return levels == null ? 0 : levels.getLength(); + /** + * Helper method to get 'levels' of a factor. However, all the invocations of this method should + * be replaced with FactorNodes.GetLevel in the future. + */ + public static RVector getLevels(RAbstractIntVector factor) { + return getLevelsImpl(factor.getAttr(RRuntime.LEVELS_ATTR_KEY)); } - @Override - public int getGPBits() { - return vector.getGPBits(); + /** + * Helper method to get 'levels' of a factor with profile. However, all the invocations of this + * method should be replaced with FactorNodes.GetLevel in the future. + */ + public static RVector getLevels(RAttributeProfiles profile, RAbstractIntVector factor) { + return getLevelsImpl(factor.getAttr(profile, RRuntime.LEVELS_ATTR_KEY)); } - @Override - public void setGPBits(int value) { - vector.setGPBits(value); + private static RVector getLevelsImpl(Object attr) { + // convert scalar to RVector if necessary + return attr instanceof RVector ? (RVector) attr : (RVector) RRuntime.asAbstractVector(attr); } } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RTypes.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RTypes.java index 790f1b2f2351db84be31a0675c2ede6a31201858..2aa99d23f1f6471b547c5c386006bb85cff8f46a 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RTypes.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RTypes.java @@ -51,7 +51,7 @@ import com.oracle.truffle.r.runtime.nodes.RNode; @TypeSystem({boolean.class, byte.class, int.class, double.class, RRaw.class, RComplex.class, String.class, RIntSequence.class, RDoubleSequence.class, RIntVector.class, RDoubleVector.class, RRawVector.class, RComplexVector.class, RStringVector.class, RLogicalVector.class, RFunction.class, RNull.class, RMissing.class, REmpty.class, REnvironment.class, RExpression.class, RConnection.class, MaterializedFrame.class, FrameSlot.class, RAbstractIntVector.class, RAbstractDoubleVector.class, RAbstractLogicalVector.class, RAbstractComplexVector.class, - RAbstractStringVector.class, RAbstractRawVector.class, RList.class, RAbstractVector.class, RFactor.class, RSymbol.class, RPromise.class, RLanguage.class, + RAbstractStringVector.class, RAbstractRawVector.class, RList.class, RAbstractVector.class, RSymbol.class, RPromise.class, RLanguage.class, RPairList.class, RExternalPtr.class, RS4Object.class, RAbstractContainer.class, RAttributable.class, RTypedValue.class, RArgsValuesAndNames.class, RType.class, Object[].class}) public class RTypes { diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RVector.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RVector.java index 4db5837712a5c7813680ca4d3beb54e810b37330..9292adf55f7794dcdcb8e2696eff364b578e5890 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RVector.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RVector.java @@ -503,40 +503,32 @@ public abstract class RVector extends RSharingAttributeStorage implements RShare // class attribute removed - no longer a data frame or factor (even if it was before) return vector; } else if (classAttr != null && classAttr.getLength() != 0) { - boolean ordered = false; for (int i = 0; i < classAttr.getLength(); i++) { String attr = classAttr.getDataAt(i); - if (RRuntime.CLASS_ORDERED.equals(attr)) { - // "ordered" must be specified before "factor" - hence it's enough to do the - // check only before encountering the "factor" - ordered = true; - } - if (RType.Factor.getName().equals(attr)) { + if (RRuntime.CLASS_FACTOR.equals(attr)) { + // For Factors we only have to check if the data-type is Integer, because + // otherwise we must show error. + // Note: this can only happen if the class is set by hand to some non-integral + // vector, i.e. attr(doubles, 'class') <- 'factor' vector.putAttribute(RRuntime.CLASS_ATTR_KEY, classAttr); - if (enclosingFactor != null) { - // was a factor and still is a factor - return enclosingFactor; - } else { - RIntVector resVector; - if (vector.getElementClass() != RInteger.class) { - if (vector.getElementClass() == RDouble.class && convertToInt) { - RDoubleVector sourceVector = (RDoubleVector) vector; - int[] data = new int[sourceVector.getLength()]; - for (int j = 0; j < data.length; j++) { - data[j] = RRuntime.double2int(sourceVector.getDataAt(j)); - } - resVector = RDataFactory.createIntVector(data, sourceVector.isComplete()); - resVector.copyAttributesFrom(sourceVector); - } else { - // TODO: add invoking node - throw RError.error(RError.SHOW_CALLER2, RError.Message.ADDING_INVALID_CLASS, "factor"); + if (vector.getElementClass() != RInteger.class) { + // TODO: check when this 'convertToInt' is necessary + if (vector.getElementClass() == RDouble.class && convertToInt) { + RDoubleVector sourceVector = (RDoubleVector) vector; + int[] data = new int[sourceVector.getLength()]; + for (int j = 0; j < data.length; j++) { + data[j] = RRuntime.double2int(sourceVector.getDataAt(j)); } + RIntVector resVector = RDataFactory.createIntVector(data, sourceVector.isComplete()); + resVector.copyAttributesFrom(sourceVector); + return resVector; } else { - resVector = (RIntVector) vector; + // TODO: add invoking node + throw RError.error(RError.SHOW_CALLER2, RError.Message.ADDING_INVALID_CLASS, "factor"); } - // it's a factor now - return RDataFactory.createFactor(resVector, ordered); } + + break; // TODO: check if setting connection and then factor shows both errors } else if (RType.Connection.getName().equals(attr)) { // convert to RConnection return ConnectionSupport.fromVector(vector, classAttr); diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RClosures.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RClosures.java index 128abb04ab71e9b131a383763ca70dc776cce073..1907afe018d8f94171746d739935f3fb60c38a7e 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RClosures.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RClosures.java @@ -22,22 +22,8 @@ */ package com.oracle.truffle.r.runtime.data.closures; -import com.oracle.truffle.r.runtime.data.RAttributeProfiles; -import com.oracle.truffle.r.runtime.data.RComplex; -import com.oracle.truffle.r.runtime.data.RDouble; -import com.oracle.truffle.r.runtime.data.RFactor; -import com.oracle.truffle.r.runtime.data.RInteger; -import com.oracle.truffle.r.runtime.data.RLogical; -import com.oracle.truffle.r.runtime.data.RRaw; -import com.oracle.truffle.r.runtime.data.RString; -import com.oracle.truffle.r.runtime.data.model.RAbstractComplexVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractListVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractRawVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractVector; +import com.oracle.truffle.r.runtime.data.*; +import com.oracle.truffle.r.runtime.data.model.*; public class RClosures { @@ -119,8 +105,11 @@ public class RClosures { // Factor to vector - public static RAbstractVector createFactorToVector(RFactor factor, boolean withNames, RAttributeProfiles attrProfiles) { - RAbstractVector levels = factor.getLevels(attrProfiles); + public static RAbstractVector createFactorToVector(RAbstractIntVector factor, boolean withNames, RAttributeProfiles attrProfiles) { + return createFactorToVector(factor, withNames, RFactor.getLevels(attrProfiles, factor)); + } + + public static RAbstractVector createFactorToVector(RAbstractIntVector factor, boolean withNames, RVector levels) { if (levels == null) { return new RFactorToStringVectorClosure(factor, null, withNames); } else { diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RFactorToComplexVectorClosure.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RFactorToComplexVectorClosure.java index 0ecce378181f1a44c1c00f818265e09824340300..680e2c5aebb22a6a30704d1d8b9349131b7d6187 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RFactorToComplexVectorClosure.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RFactorToComplexVectorClosure.java @@ -27,10 +27,10 @@ import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.RType; import com.oracle.truffle.r.runtime.data.RAttributeProfiles; import com.oracle.truffle.r.runtime.data.RComplex; -import com.oracle.truffle.r.runtime.data.RFactor; import com.oracle.truffle.r.runtime.data.RIntVector; import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.model.RAbstractComplexVector; +import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; /* @@ -41,8 +41,8 @@ final class RFactorToComplexVectorClosure extends RToComplexVectorClosure implem private final RAbstractComplexVector levels; private final boolean withNames; - RFactorToComplexVectorClosure(RFactor factor, RAbstractComplexVector levels, boolean withNames) { - super(factor.getVector()); + RFactorToComplexVectorClosure(RAbstractIntVector vector, RAbstractComplexVector levels, boolean withNames) { + super(vector); assert levels != null; this.levels = levels; this.withNames = withNames; diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RFactorToDoubleVectorClosure.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RFactorToDoubleVectorClosure.java index 6fac21bc3c61549c2174db272d847edc5b2e7c6e..45b41c2cfe2dc83860e11c908e1da96a3660f2ee 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RFactorToDoubleVectorClosure.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RFactorToDoubleVectorClosure.java @@ -26,10 +26,10 @@ import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.RType; import com.oracle.truffle.r.runtime.data.RAttributeProfiles; -import com.oracle.truffle.r.runtime.data.RFactor; import com.oracle.truffle.r.runtime.data.RIntVector; import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; +import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; /* @@ -40,8 +40,8 @@ final class RFactorToDoubleVectorClosure extends RToDoubleVectorClosure implemen private final RAbstractDoubleVector levels; private final boolean withNames; - RFactorToDoubleVectorClosure(RFactor factor, RAbstractDoubleVector levels, boolean withNames) { - super(factor.getVector()); + RFactorToDoubleVectorClosure(RAbstractIntVector vector, RAbstractDoubleVector levels, boolean withNames) { + super(vector); assert levels != null; this.levels = levels; this.withNames = withNames; diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RFactorToIntVectorClosure.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RFactorToIntVectorClosure.java index 39bb9913ef5b2cea6d9ac4d65ed5a6500131241e..8e09817efcc8de283347149733a2c36effd09be5 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RFactorToIntVectorClosure.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RFactorToIntVectorClosure.java @@ -26,7 +26,6 @@ import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.RType; import com.oracle.truffle.r.runtime.data.RAttributeProfiles; -import com.oracle.truffle.r.runtime.data.RFactor; import com.oracle.truffle.r.runtime.data.RIntVector; import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; @@ -40,8 +39,8 @@ final class RFactorToIntVectorClosure extends RToIntVectorClosure implements RAb private final RAbstractIntVector levels; private final boolean withNames; - RFactorToIntVectorClosure(RFactor factor, RAbstractIntVector levels, boolean withNames) { - super(factor.getVector()); + RFactorToIntVectorClosure(RAbstractIntVector vector, RAbstractIntVector levels, boolean withNames) { + super(vector); assert levels != null; this.levels = levels; this.withNames = withNames; diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RFactorToStringVectorClosure.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RFactorToStringVectorClosure.java index 5581ce61bb2fe5fb469f0e3ba7b140cb4cf35ba6..d6223712ab2613a0364bbab38612b35aced8b340 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RFactorToStringVectorClosure.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/closures/RFactorToStringVectorClosure.java @@ -27,9 +27,9 @@ import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.RType; import com.oracle.truffle.r.runtime.data.RAttributeProfiles; -import com.oracle.truffle.r.runtime.data.RFactor; import com.oracle.truffle.r.runtime.data.RIntVector; import com.oracle.truffle.r.runtime.data.RStringVector; +import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; @@ -41,8 +41,8 @@ public final class RFactorToStringVectorClosure extends RToStringVectorClosure i private final RAbstractStringVector levels; private final boolean withNames; - RFactorToStringVectorClosure(RFactor factor, RAbstractStringVector levels, boolean withNames) { - super(factor.getVector()); + RFactorToStringVectorClosure(RAbstractIntVector vector, RAbstractStringVector levels, boolean withNames) { + super(vector); this.levels = levels; this.withNames = withNames; if (this.levels == null) { diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/gnur/SEXPTYPE.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/gnur/SEXPTYPE.java index 9701130c96eb4f3af92341efb5c37c7f1fc47edf..7dc89eb98a5ebc01e718a2afd693acab71a7bb26 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/gnur/SEXPTYPE.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/gnur/SEXPTYPE.java @@ -17,32 +17,8 @@ import java.util.Map; import com.oracle.truffle.api.source.SourceSection; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.conn.RConnection; -import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; -import com.oracle.truffle.r.runtime.data.RComplex; -import com.oracle.truffle.r.runtime.data.RComplexVector; -import com.oracle.truffle.r.runtime.data.RDoubleSequence; -import com.oracle.truffle.r.runtime.data.RDoubleVector; -import com.oracle.truffle.r.runtime.data.REmpty; -import com.oracle.truffle.r.runtime.data.RExpression; -import com.oracle.truffle.r.runtime.data.RExternalPtr; -import com.oracle.truffle.r.runtime.data.RFactor; -import com.oracle.truffle.r.runtime.data.RFunction; -import com.oracle.truffle.r.runtime.data.RIntSequence; -import com.oracle.truffle.r.runtime.data.RIntVector; -import com.oracle.truffle.r.runtime.data.RLanguage; -import com.oracle.truffle.r.runtime.data.RList; -import com.oracle.truffle.r.runtime.data.RLogicalVector; -import com.oracle.truffle.r.runtime.data.RMissing; -import com.oracle.truffle.r.runtime.data.RNull; -import com.oracle.truffle.r.runtime.data.RPairList; -import com.oracle.truffle.r.runtime.data.RPromise; +import com.oracle.truffle.r.runtime.data.*; import com.oracle.truffle.r.runtime.data.RPromise.EagerPromise; -import com.oracle.truffle.r.runtime.data.RRaw; -import com.oracle.truffle.r.runtime.data.RRawVector; -import com.oracle.truffle.r.runtime.data.RS4Object; -import com.oracle.truffle.r.runtime.data.RStringVector; -import com.oracle.truffle.r.runtime.data.RSymbol; -import com.oracle.truffle.r.runtime.data.RUnboundValue; import com.oracle.truffle.r.runtime.env.REnvironment; // Transcribed from GnuR src/include/Rinternals.h and src/main/serialize.c @@ -57,8 +33,6 @@ public enum SEXPTYPE { FASTR_INT(301, Integer.class), FASTR_BYTE(302, Byte.class), FASTR_COMPLEX(303, RComplex.class), - // FastR special "vector" types - FASTR_FACTOR(305, RFactor.class), // very special case FASTR_SOURCESECTION(306, SourceSection.class), FASTR_CONNECTION(307, RConnection.class), @@ -196,8 +170,6 @@ public enum SEXPTYPE { return SEXPTYPE.LGLSXP; case FASTR_COMPLEX: return SEXPTYPE.CPLXSXP; - case FASTR_FACTOR: - return SEXPTYPE.VECSXP; case FASTR_CONNECTION: return SEXPTYPE.INTSXP; default: diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/RNode.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/RNode.java index 06dc66ae1cdda10bee55c1c23cecdbda6d4470db..e4bcc042eaa484f81539bab75c9e38729876ffc7 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/RNode.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/nodes/RNode.java @@ -33,39 +33,8 @@ import com.oracle.truffle.api.nodes.UnexpectedResultException; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.RType; import com.oracle.truffle.r.runtime.conn.RConnection; -import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; -import com.oracle.truffle.r.runtime.data.RAttributable; -import com.oracle.truffle.r.runtime.data.RAttributes; -import com.oracle.truffle.r.runtime.data.RComplex; -import com.oracle.truffle.r.runtime.data.RComplexVector; -import com.oracle.truffle.r.runtime.data.RDoubleSequence; -import com.oracle.truffle.r.runtime.data.RDoubleVector; -import com.oracle.truffle.r.runtime.data.RExpression; -import com.oracle.truffle.r.runtime.data.RFactor; -import com.oracle.truffle.r.runtime.data.RFunction; -import com.oracle.truffle.r.runtime.data.RIntSequence; -import com.oracle.truffle.r.runtime.data.RIntVector; -import com.oracle.truffle.r.runtime.data.RLanguage; -import com.oracle.truffle.r.runtime.data.RList; -import com.oracle.truffle.r.runtime.data.RLogicalVector; -import com.oracle.truffle.r.runtime.data.RMissing; -import com.oracle.truffle.r.runtime.data.RNull; -import com.oracle.truffle.r.runtime.data.RPairList; -import com.oracle.truffle.r.runtime.data.RPromise; -import com.oracle.truffle.r.runtime.data.RRaw; -import com.oracle.truffle.r.runtime.data.RRawVector; -import com.oracle.truffle.r.runtime.data.RStringVector; -import com.oracle.truffle.r.runtime.data.RSymbol; -import com.oracle.truffle.r.runtime.data.RTypes; -import com.oracle.truffle.r.runtime.data.RTypesGen; -import com.oracle.truffle.r.runtime.data.model.RAbstractComplexVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; -import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractRawVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractVector; +import com.oracle.truffle.r.runtime.data.*; +import com.oracle.truffle.r.runtime.data.model.*; import com.oracle.truffle.r.runtime.env.REnvironment; @TypeSystemReference(RTypes.class) @@ -193,10 +162,6 @@ public abstract class RNode extends RBaseNode implements RInstrumentableNode { return RTypesGen.expectRExpression(execute(frame)); } - public RFactor executeRFactor(VirtualFrame frame) throws UnexpectedResultException { - return RTypesGen.expectRFactor(execute(frame)); - } - public RSymbol executeRSymbol(VirtualFrame frame) throws UnexpectedResultException { return RTypesGen.expectRSymbol(execute(frame)); } @@ -285,10 +250,6 @@ public abstract class RNode extends RBaseNode implements RInstrumentableNode { return value instanceof RList; } - protected static boolean isRFactor(Object value) { - return value instanceof RFactor; - } - protected static boolean isRPromise(Object value) { return value instanceof RPromise; } 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 122d0bf014cc61f7da2d7319a96d271020482015..be36e61f8d8844183a60d73bd9911547f991b278 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 @@ -23552,6 +23552,15 @@ Error: unexpected symbol in " ', NA), mag = c('Min. :5.000 ', '1st Qu.:5.300 #argv <- list(structure(list(Topic = c('myTst-package', 'foo-class', 'myTst', 'show,foo-method', 'show,foo-method', 'show-methods'), File = c('myTst-package', 'foo-class', 'myTst-package', 'foo-class', 'show-methods', 'show-methods')), .Names = c('Topic', 'File'), row.names = c(3L, 1L, 4L, 2L, 6L, 5L), class = 'data.frame'));is.matrix(argv[[1]]); [1] FALSE +##com.oracle.truffle.r.test.builtins.TestBuiltin_isna.testIsNA +#is.na(data.frame(col1=1:5, col2=c(NA, 1, NA, 2, NA))) + col1 col2 +[1,] FALSE TRUE +[2,] FALSE FALSE +[3,] FALSE TRUE +[4,] FALSE FALSE +[5,] FALSE TRUE + ##com.oracle.truffle.r.test.builtins.TestBuiltin_isna.testIsNA #is.na(is.na)) Error: unexpected ')' in "is.na(is.na))" @@ -31534,6 +31543,25 @@ NULL [1] "some" [1] "test" +##com.oracle.truffle.r.test.builtins.TestBuiltin_operators.testDispatchToOpsSpecializations +#data.frame(factor(c(1,2,1))) == data.frame(factor(c(1,2,2))) + factor.c.1..2..1.. +[1,] TRUE +[2,] TRUE +[3,] FALSE + +##com.oracle.truffle.r.test.builtins.TestBuiltin_operators.testDispatchToOpsSpecializations +#data.frame(factor(c(1,2,3))) == data.frame(factor(c(1,2,3))) + factor.c.1..2..3.. +[1,] TRUE +[2,] TRUE +[3,] TRUE + +##com.oracle.truffle.r.test.builtins.TestBuiltin_operators.testDispatchToOpsSpecializations +#factor(c("a","b","c")) == factor(c(1,2,3)) +Error in Ops.factor(factor(c("a", "b", "c")), factor(c(1, 2, 3))) : + level sets of factors are different + ##com.oracle.truffle.r.test.builtins.TestBuiltin_operators.testIn #{ "hello" %in% c("I", "say", "hello", "world") } [1] TRUE diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_isna.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_isna.java index 1d32d7b884107d3adcefbdc4b1df28aa8f96f80e..610e8a0c3c45cf3185af28ae89f100440b8b68bd 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_isna.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_isna.java @@ -265,5 +265,8 @@ public class TestBuiltin_isna extends TestBase { assertEval("{ is.na(list(1[10],1L[10],list(),integer())) }"); assertEval(Output.ContainsWarning, "is.na(quote(x()))"); assertEval("is.na(is.na))"); + + // Note: is.na.data.frame calls do.call("cbind", lapply(x, "is.na")) - there is the error + assertEval(Ignored.Unimplemented, "is.na(data.frame(col1=1:5, col2=c(NA, 1, NA, 2, NA)))"); } } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_operators.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_operators.java index 147b62182ec86227055a1a6a917e21cc90e868b9..134587376b167655ccbc67329bd787200dec691b 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_operators.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_operators.java @@ -1921,6 +1921,13 @@ public class TestBuiltin_operators extends TestBase { assertEval("argv <- list(181L, 3.14159265358979);`*`(argv[[1]],argv[[2]]);"); } + @Test + public void testDispatchToOpsSpecializations() { + assertEval(Output.ContainsError, "factor(c(\"a\",\"b\",\"c\")) == factor(c(1,2,3))"); + assertEval("data.frame(factor(c(1,2,3))) == data.frame(factor(c(1,2,3)))"); + assertEval("data.frame(factor(c(1,2,1))) == data.frame(factor(c(1,2,2)))"); + } + @Test public void testOperators() { assertEval("{ `+`(1,2) }");