diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Array.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Array.java index d6e7259a25514429a9b088b7ee6f21662c796196..31c17451af606214a9552bd2cf6d5a7487a458f8 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Array.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Array.java @@ -42,7 +42,6 @@ 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.RTypedValue; @@ -54,7 +53,6 @@ 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; /** * The {@code} .Internal part of the {@code array} function. The R code may alter the arguments diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCharacter.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCharacter.java index c4fb5330bdcd0ac41c253c49b64fe851285cf1ac..7c29e7beb057ffa40802f9bf1c38f497b40fc028 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCharacter.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsCharacter.java @@ -28,27 +28,26 @@ import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE; import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE; import com.oracle.truffle.api.dsl.Specialization; +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.RDeparse; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.builtins.RBuiltin; import com.oracle.truffle.r.runtime.data.RDataFactory; -import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RStringVector; +import com.oracle.truffle.r.runtime.data.model.RAbstractListVector; import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; @RBuiltin(name = "as.character", kind = PRIMITIVE, parameterNames = {"x", "..."}, dispatch = INTERNAL_GENERIC, behavior = PURE) public abstract class AsCharacter extends RBuiltinNode { - public static AsCharacter create() { - return AsCharacterNodeGen.create(null); - } + private final ConditionProfile noAttributes = ConditionProfile.createBinaryProfile(); @Override protected void createCasts(CastBuilder casts) { - casts.arg("x").mapIf(instanceOf(RList.class).not(), asStringVector()); + casts.arg("x").mapIf(instanceOf(RAbstractListVector.class).not(), asStringVector()); } @Specialization @@ -58,12 +57,15 @@ public abstract class AsCharacter extends RBuiltinNode { @Specialization protected RAbstractStringVector asCharacter(RAbstractStringVector v) { - return v; + if (noAttributes.profile(v.getAttributes() == null)) { + return v; + } else { + return (RAbstractStringVector) v.copyDropAttributes(); + } } @Specialization - protected RStringVector asCharacter(Object l) { - RList list = (RList) l; + protected RStringVector asCharacter(RAbstractListVector list) { int len = list.getLength(); boolean complete = RDataFactory.COMPLETE_VECTOR; String[] data = new String[len]; diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsComplex.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsComplex.java index b962a7a88ae0cf3c00cd0ecced191c31f3bb5273..964c8bceec1b1198a9d4b2d4a4cc554e722f92a3 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsComplex.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsComplex.java @@ -25,72 +25,37 @@ package com.oracle.truffle.r.nodes.builtin.base; import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE; import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE; -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.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; -import com.oracle.truffle.r.nodes.unary.CastComplexNode; -import com.oracle.truffle.r.nodes.unary.CastComplexNodeGen; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -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.RNull; -import com.oracle.truffle.r.runtime.data.model.RAbstractVector; +import com.oracle.truffle.r.runtime.data.model.RAbstractComplexVector; @RBuiltin(name = "as.complex", kind = PRIMITIVE, parameterNames = {"x", "..."}, behavior = PURE) public abstract class AsComplex extends RBuiltinNode { - @Child private CastComplexNode castComplexNode; + private final ConditionProfile noAttributes = ConditionProfile.createBinaryProfile(); - private void initCast() { - if (castComplexNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - castComplexNode = insert(CastComplexNodeGen.create(false, false, false)); - } - } - - @Specialization - protected RComplex doComplex(RComplex value) { - return value; - } - - @Specialization - protected RComplex doInt(int value) { - initCast(); - return (RComplex) castComplexNode.executeComplex(value); - } - - @Specialization - protected RComplex doDouble(double value) { - initCast(); - return (RComplex) castComplexNode.executeComplex(value); + @Override + protected void createCasts(CastBuilder casts) { + casts.arg("x").asComplexVector(); } @Specialization - protected RComplex doLogical(byte value) { - initCast(); - return (RComplex) castComplexNode.executeComplex(value); + protected RAbstractComplexVector asComplex(@SuppressWarnings("unused") RNull n) { + return RDataFactory.createEmptyComplexVector(); } @Specialization - protected RComplex doString(String value) { - initCast(); - return (RComplex) castComplexNode.executeComplex(value); - } - - @Specialization - protected RComplexVector doNull(@SuppressWarnings("unused") RNull value) { - return RDataFactory.createComplexVector(0); - } - - @Specialization - protected RComplexVector doComplexVector(RComplexVector vector) { - return RDataFactory.createComplexVector(vector.getDataCopy(), vector.isComplete()); + protected RAbstractComplexVector asComplex(RAbstractComplexVector v) { + if (noAttributes.profile(v.getAttributes() == null)) { + return v; + } else { + return (RAbstractComplexVector) v.copyDropAttributes(); + } } - @Specialization - protected RComplexVector doIntVector(RAbstractVector vector) { - initCast(); - return (RComplexVector) castComplexNode.executeComplex(vector); - } } 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 d177ac1281fb04a3f54e792612a17b1cb20149d7..39780bb2a6ad5b9880a96d7d39422154be6673fe 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 @@ -25,84 +25,36 @@ package com.oracle.truffle.r.nodes.builtin.base; import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE; import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE; -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.CastBuilder; 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.builtins.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.RIntSequence; import com.oracle.truffle.r.runtime.data.RNull; -import com.oracle.truffle.r.runtime.data.model.RAbstractVector; +import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector; @RBuiltin(name = "as.double", aliases = {"as.numeric"}, kind = PRIMITIVE, parameterNames = {"x", "..."}, behavior = PURE) public abstract class AsDouble extends RBuiltinNode { - @Child private CastDoubleNode castDoubleNode; + private final ConditionProfile noAttributes = ConditionProfile.createBinaryProfile(); - private void initCast() { - if (castDoubleNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - castDoubleNode = insert(CastDoubleNodeGen.create(false, false, false)); - } - } - - @Specialization - protected double asDouble(double value) { - return value; - } - - @Specialization - protected double asDoubleInt(int value) { - initCast(); - return (double) castDoubleNode.executeDouble(value); - } - - @Specialization - protected double asDouble(byte value) { - initCast(); - return (double) castDoubleNode.executeDouble(value); - } - - @Specialization - protected double asDouble(RComplex value) { - initCast(); - return (double) castDoubleNode.executeDouble(value); + @Override + protected void createCasts(CastBuilder casts) { + casts.arg("x").asDoubleVector(); } @Specialization - protected double asDouble(String value) { - initCast(); - return (double) castDoubleNode.executeDouble(value); + protected RAbstractDoubleVector asDouble(@SuppressWarnings("unused") RNull n) { + return RDataFactory.createEmptyDoubleVector(); } @Specialization - protected RDoubleVector asDouble(@SuppressWarnings("unused") RNull vector) { - return RDataFactory.createDoubleVector(0); - } - - @Specialization - protected RDoubleVector asDouble(RDoubleVector vector) { - return RDataFactory.createDoubleVector(vector.getDataCopy(), vector.isComplete()); - } - - @Specialization - protected RDoubleSequence asDouble(RDoubleSequence sequence) { - return sequence; - } - - @Specialization - protected RDoubleSequence asDouble(RIntSequence sequence) { - return RDataFactory.createDoubleSequence(sequence.getStart(), sequence.getStride(), sequence.getLength()); - } - - @Specialization - protected RDoubleVector asDouble(RAbstractVector vector) { - initCast(); - return (RDoubleVector) castDoubleNode.executeDouble(vector); + protected RAbstractDoubleVector asDouble(RAbstractDoubleVector v) { + if (noAttributes.profile(v.getAttributes() == null)) { + return v; + } else { + return (RAbstractDoubleVector) v.copyDropAttributes(); + } } } 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 0f64433f130c212751add7f60c81ba9a70816ee7..c6a78959fa4142db09ac12146080ef1d05d2f176 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 @@ -25,92 +25,43 @@ package com.oracle.truffle.r.nodes.builtin.base; import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE; import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE; -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.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; -import com.oracle.truffle.r.nodes.unary.CastIntegerNode; -import com.oracle.truffle.r.nodes.unary.CastIntegerNodeGen; import com.oracle.truffle.r.runtime.builtins.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.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.model.RAbstractIntVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractVector; @RBuiltin(name = "as.integer", kind = PRIMITIVE, parameterNames = {"x", "..."}, behavior = PURE) public abstract class AsInteger extends RBuiltinNode { - @Child private CastIntegerNode castIntNode; + private final ConditionProfile noAttributes = ConditionProfile.createBinaryProfile(); - private void initCast() { - if (castIntNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - castIntNode = insert(CastIntegerNodeGen.create(false, false, false)); - } - } - - @Specialization - protected int asInteger(int value) { - return value; - } - - @Specialization - protected int asInteger(double value) { - initCast(); - return (int) castIntNode.executeInt(value); + @Override + protected void createCasts(CastBuilder casts) { + casts.arg("x").asIntegerVector(); } @Specialization - protected int asInteger(byte value) { - initCast(); - return (int) castIntNode.executeInt(value); - } - - @Specialization - protected int asInteger(RComplex value) { - initCast(); - return (int) castIntNode.executeInt(value); - } - - @Specialization - protected int asInteger(RRaw value) { - initCast(); - return (int) castIntNode.executeInt(value); - } - - @Specialization - protected int asInteger(String value) { - initCast(); - return (int) castIntNode.executeInt(value); - } - - @Specialization - protected RIntVector asInteger(@SuppressWarnings("unused") RNull value) { + protected RAbstractIntVector asInteger(@SuppressWarnings("unused") RNull n) { return RDataFactory.createEmptyIntVector(); } @Specialization - protected RIntVector asInteger(RIntVector vector) { - return RDataFactory.createIntVector(vector.getDataCopy(), vector.isComplete()); - } - - @Specialization - protected RIntVector asInteger(RIntSequence sequence) { - return (RIntVector) sequence.createVector(); - } - - @Specialization - protected RAbstractIntVector asInteger(RAbstractVector vector) { - initCast(); - return (RAbstractIntVector) castIntNode.executeInt(vector); + protected RAbstractIntVector asInteger(RAbstractIntVector v) { + if (noAttributes.profile(v.getAttributes() == null)) { + return v; + } else { + return (RAbstractIntVector) v.copyDropAttributes(); + } } @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/AsLogical.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsLogical.java index 640ce0cc091da04dbb221a7b92356d03ed43c468..d92ed1e1a988451b5bbc6501fb6d855bcb10d436 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsLogical.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsLogical.java @@ -25,76 +25,36 @@ package com.oracle.truffle.r.nodes.builtin.base; import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE; import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE; -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.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; -import com.oracle.truffle.r.nodes.unary.CastLogicalNode; -import com.oracle.truffle.r.nodes.unary.CastLogicalNodeGen; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RComplex; import com.oracle.truffle.r.runtime.data.RDataFactory; -import com.oracle.truffle.r.runtime.data.RLogicalVector; import com.oracle.truffle.r.runtime.data.RNull; -import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; +import com.oracle.truffle.r.runtime.data.model.RAbstractLogicalVector; @RBuiltin(name = "as.logical", kind = PRIMITIVE, parameterNames = {"x", "..."}, behavior = PURE) public abstract class AsLogical extends RBuiltinNode { - @Child private CastLogicalNode castLogicalNode; + private final ConditionProfile noAttributes = ConditionProfile.createBinaryProfile(); - private byte castLogical(Object o) { - if (castLogicalNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - castLogicalNode = insert(CastLogicalNodeGen.create(false, false, false)); - } - return (byte) castLogicalNode.execute(o); - } - - private RLogicalVector castLogicalVector(Object o) { - if (castLogicalNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - castLogicalNode = insert(CastLogicalNodeGen.create(false, false, false)); - } - return (RLogicalVector) castLogicalNode.execute(o); - } - - @Specialization - protected byte asLogical(byte value) { - return value; - } - - @Specialization - protected byte asLogical(int value) { - return castLogical(value); + @Override + protected void createCasts(CastBuilder casts) { + casts.arg("x").asLogicalVector(); } @Specialization - protected byte asLogical(double value) { - return castLogical(value); + protected RAbstractLogicalVector asLogicaleger(@SuppressWarnings("unused") RNull n) { + return RDataFactory.createEmptyLogicalVector(); } @Specialization - protected byte asLogical(RComplex value) { - return castLogical(value); - } - - @Specialization - protected byte asLogical(String value) { - return castLogical(value); - } - - @Specialization - protected RLogicalVector asLogical(@SuppressWarnings("unused") RNull vector) { - return RDataFactory.createLogicalVector(0); - } - - @Specialization - protected RLogicalVector asLogical(RLogicalVector vector) { - return RDataFactory.createLogicalVector(vector.getDataCopy(), vector.isComplete()); - } - - @Specialization - protected RLogicalVector asLogical(RAbstractContainer container) { - return castLogicalVector(container); + protected RAbstractLogicalVector asLogicaleger(RAbstractLogicalVector v) { + if (noAttributes.profile(v.getAttributes() == null)) { + return v; + } else { + return (RAbstractLogicalVector) v.copyDropAttributes(); + } } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsRaw.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsRaw.java index 4d03ae68c19173386b5d5fe3bd0fc8f2c07f16f0..1300bfa38b2addff31d700096f857731d464eda8 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsRaw.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/AsRaw.java @@ -25,93 +25,36 @@ package com.oracle.truffle.r.nodes.builtin.base; import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE; import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.PRIMITIVE; -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.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; -import com.oracle.truffle.r.nodes.unary.CastIntegerNode; -import com.oracle.truffle.r.nodes.unary.CastRawNode; -import com.oracle.truffle.r.nodes.unary.CastRawNodeGen; import com.oracle.truffle.r.runtime.builtins.RBuiltin; -import com.oracle.truffle.r.runtime.data.RComplex; 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.RRaw; -import com.oracle.truffle.r.runtime.data.RRawVector; -import com.oracle.truffle.r.runtime.data.model.RAbstractVector; +import com.oracle.truffle.r.runtime.data.model.RAbstractRawVector; @RBuiltin(name = "as.raw", kind = PRIMITIVE, parameterNames = {"x"}, behavior = PURE) public abstract class AsRaw extends RBuiltinNode { - @Child private CastIntegerNode castInteger; - @Child private CastRawNode castRawNode; + private final ConditionProfile noAttributes = ConditionProfile.createBinaryProfile(); - private void initCast() { - if (castRawNode == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - castRawNode = insert(CastRawNodeGen.create(false, false, false)); - } - } - - @Specialization - protected RRawVector asRaw(@SuppressWarnings("unused") RNull vector) { - return RDataFactory.createRawVector(0); - } - - @Specialization - protected RRaw asRaw(byte logical) { - initCast(); - return (RRaw) castRawNode.executeRaw(logical); - } - - @Specialization - protected RRaw asRaw(int value) { - initCast(); - return (RRaw) castRawNode.executeRaw(value); - } - - @Specialization - protected RRaw asRaw(double value) { - initCast(); - return (RRaw) castRawNode.executeRaw(value); + @Override + protected void createCasts(CastBuilder casts) { + casts.arg("x").asRawVector(); } @Specialization - protected RRaw asRaw(RComplex value) { - initCast(); - return (RRaw) castRawNode.executeRaw(value); + protected RAbstractRawVector asRaw(@SuppressWarnings("unused") RNull n) { + return RDataFactory.createEmptyRawVector(); } @Specialization - protected RRaw asRaw(String value) { - initCast(); - return (RRaw) castRawNode.executeRaw(value); - } - - @Specialization - protected RRaw asRaw(RRaw value) { - return value; - } - - @Specialization - protected RRawVector asRaw(RRawVector value) { - return RDataFactory.createRawVector(value.getDataCopy()); - } - - @Specialization - protected RRawVector asRaw(RList value) { - initCast(); - int length = value.getLength(); - RRawVector result = RDataFactory.createRawVector(length); - for (int i = 0; i < length; i++) { - result.updateDataAt(i, (RRaw) castRawNode.executeRaw(value.getDataAt(i))); + protected RAbstractRawVector asRaw(RAbstractRawVector v) { + if (noAttributes.profile(v.getAttributes() == null)) { + return v; + } else { + return (RAbstractRawVector) v.copyDropAttributes(); } - return result; - } - - @Specialization - protected RRawVector asRaw(RAbstractVector vector) { - initCast(); - return (RRawVector) castRawNode.executeRaw(vector); } } 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 77e3ff3f897bc2a370e4ddbfe8e3e31757d91254..0b2ccbc14eccadf9815d60c7143b773489712d2e 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 @@ -34,6 +34,7 @@ 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.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; @@ -57,6 +58,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.builtins.RBuiltin; +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.RDataFactory; @@ -118,41 +120,54 @@ public abstract class AsVector extends RBuiltinNode { public abstract Object execute(Object x, String mode); private final RAttributeProfiles attrProfiles = RAttributeProfiles.create(); + private final BranchProfile hasAttributes = BranchProfile.create(); + + private Object dropAttributesIfNeeded(Object o) { + Object res = o; + if (res instanceof RAttributable && ((RAttributable) res).getAttributes() != null) { + // the assertion should hold because of how cast works and it's only used for + // vectors (as per as.vector docs) + assert res instanceof RAbstractVector; + hasAttributes.enter(); + res = ((RAbstractVector) res).copyDropAttributes(); + } + return res; + } @Specialization(guards = "castToString(mode)") protected Object asVectorString(Object x, @SuppressWarnings("unused") String mode, // @Cached("createNonPreserving()") CastStringNode cast) { - return cast.execute(x); + return dropAttributesIfNeeded(cast.execute(x)); } @Specialization(guards = "castToInt(x, mode)") protected Object asVectorInt(RAbstractContainer x, @SuppressWarnings("unused") String mode, // @Cached("createNonPreserving()") CastIntegerNode cast) { - return cast.execute(x); + return dropAttributesIfNeeded(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); + return dropAttributesIfNeeded(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); + return dropAttributesIfNeeded(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); + return dropAttributesIfNeeded(cast.execute(x)); } @Specialization(guards = "castToRaw(x, mode)") protected Object asVectorRaw(RAbstractContainer x, @SuppressWarnings("unused") String mode, // @Cached("createNonPreserving()") CastRawNode cast) { - return cast.execute(x); + return dropAttributesIfNeeded(cast.execute(x)); } protected static CastListNode createListCast() { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DynLoadFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DynLoadFunctions.java index b02a20b452417ce0cc22054770b83dee658b682a..06b412f7ff1036479ec6735517bce5f188b53a8a 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DynLoadFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/DynLoadFunctions.java @@ -32,6 +32,7 @@ import java.util.ArrayList; 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.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RInternalError; @@ -56,6 +57,13 @@ public class DynLoadFunctions { @RBuiltin(name = "dyn.load", visibility = OFF, kind = INTERNAL, parameterNames = {"lib", "local", "now", "unused"}, behavior = COMPLEX) public abstract static class DynLoad extends RBuiltinNode { + + @Override + protected void createCasts(CastBuilder casts) { + // TODO: not sure if the behavior is 100% compliant + casts.arg("now").asLogicalVector().findFirst(); + } + @Specialization @TruffleBoundary protected RList doDynLoad(RAbstractStringVector libVec, RAbstractLogicalVector localVec, byte now, @SuppressWarnings("unused") String unused) { @@ -147,6 +155,12 @@ public class DynLoadFunctions { @RBuiltin(name = "getSymbolInfo", kind = INTERNAL, parameterNames = {"symbol", "package", "withReg"}, behavior = READS_STATE) public abstract static class GetSymbolInfo extends RBuiltinNode { + @Override + protected void createCasts(CastBuilder casts) { + // TODO: not sure if the behavior is 100% compliant + casts.arg("withReg").asLogicalVector().findFirst(); + } + @Specialization @TruffleBoundary protected Object getSymbolInfo(RAbstractStringVector symbolVec, String packageName, byte withReg) { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/HiddenInternalFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/HiddenInternalFunctions.java index 95b36bcc700b122afd4a35a94c4be94e0908b7e9..899f34632cfbc9570f8ca59d055e8179bf9bf4cc 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/HiddenInternalFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/HiddenInternalFunctions.java @@ -362,7 +362,9 @@ public class HiddenInternalFunctions { @Override protected void createCasts(CastBuilder casts) { - casts.toInteger(2).toInteger(3); + // TODO: not sure if the behavior is 100% compliant + casts.arg("ascii").asIntegerVector().findFirst(); + casts.arg("compsxp").asIntegerVector().findFirst(); } @Specialization diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Paste.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Paste.java index 699b9fe4219a49ab2dd8e3b8977e5dacf4125e7f..fef9305da7c55355d10060f099bf09024f8e2a32 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Paste.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Paste.java @@ -77,7 +77,7 @@ public abstract class Paste extends RBuiltinNode { } else if (ret == RNull.instance) { return RDataFactory.createEmptyStringVector(); } else { - return (RStringVector) ret; + return (RStringVector) ((RStringVector) ret).copyDropAttributes(); } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Strtoi.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Strtoi.java index 759459f1f09f5aec597075d536305be5d084bd9e..cbca860f401407a3c234193721821ec4f3a043b1 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Strtoi.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Strtoi.java @@ -27,6 +27,7 @@ import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; 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.runtime.RRuntime; import com.oracle.truffle.r.runtime.builtins.RBuiltin; @@ -37,6 +38,13 @@ import com.oracle.truffle.r.runtime.ffi.RFFIFactory; @RBuiltin(name = "strtoi", kind = INTERNAL, parameterNames = {"x", "base"}, behavior = PURE) public abstract class Strtoi extends RBuiltinNode { + + @Override + protected void createCasts(CastBuilder casts) { + // TODO: not sure if the behavior is 100% compliant + casts.arg("base").asIntegerVector().findFirst(); + } + @Specialization @TruffleBoundary protected RIntVector doStrtoi(RAbstractStringVector vec, int baseArg) { 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 d690fced48fa9dd4ebf4d1442f664e27ca4ec12e..764eed17c3384b043879dbbfb4e20e350ad72ecf 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 @@ -35,7 +35,9 @@ public abstract class Tabulate extends RBuiltinNode { @Override protected void createCasts(CastBuilder casts) { - casts.toInteger(1); + // TODO: not sure if the behavior is 100% compliant + casts.arg("bin").asIntegerVector(); + casts.arg("nbins").asIntegerVector().findFirst(); } @Specialization diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ToLowerOrUpper.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ToLowerOrUpper.java index 4010f36ea20ed08601c93d5b0f72456d7b58d100..0313cad4b98aec16177b01b33fe7021ffa3fa6ee 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ToLowerOrUpper.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/ToLowerOrUpper.java @@ -27,7 +27,6 @@ import static com.oracle.truffle.r.runtime.builtins.RBehavior.PURE; import static com.oracle.truffle.r.runtime.builtins.RBuiltinKind.INTERNAL; import java.util.function.BiFunction; -import java.util.function.Function; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Specialization; @@ -100,7 +99,7 @@ public abstract class ToLowerOrUpper { } @TruffleBoundary - private static String processElement(String value, int i) { + private static String processElement(String value, @SuppressWarnings("unused") int i) { return value.toLowerCase(); } @@ -126,7 +125,7 @@ public abstract class ToLowerOrUpper { } @TruffleBoundary - private static String processElement(String value, int i) { + private static String processElement(String value, @SuppressWarnings("unused") int i) { return value.toUpperCase(); } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateNames.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateNames.java index fd9b979a7964a6a0b0532c753bfff0a6e8d5c3f4..93587752d7411f1f797a66f85692de3cc0bf4dbf 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateNames.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/UpdateNames.java @@ -69,7 +69,7 @@ public abstract class UpdateNames extends RBuiltinNode { if (newNames instanceof String) { stringVector = RDataFactory.createStringVector((String) newNames); } else { - stringVector = (RStringVector) ((RAbstractVector) newNames).materialize(); + stringVector = (RStringVector) ((RAbstractVector) newNames).materialize().copyDropAttributes(); } RAbstractContainer result = (RAbstractContainer) container.getNonShared(); if (stringVector.getLength() < result.getLength()) { diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrcf.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrcf.java index b267d9521fcbcc765c10b5591a3e3bb734484085..b8dfa18b98a9656c6d2df0059a5589ebf7deda57 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrcf.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrcf.java @@ -33,11 +33,11 @@ public final class Dqrcf extends RExternalBuiltinNode { Object[] argValues = args.getArguments(); try { RAbstractDoubleVector xVec = (RAbstractDoubleVector) argValues[0]; - int n = (int) argValues[1]; + int n = argValues[1] instanceof Integer ? (int) argValues[1] : ((RAbstractIntVector) argValues[1]).getDataAt(0); RAbstractIntVector k = (RAbstractIntVector) argValues[2]; RAbstractDoubleVector qrauxVec = (RAbstractDoubleVector) argValues[3]; RAbstractDoubleVector yVec = (RAbstractDoubleVector) argValues[4]; - int ny = (int) argValues[5]; + int ny = argValues[5] instanceof Integer ? (int) argValues[5] : ((RAbstractIntVector) argValues[5]).getDataAt(0); RAbstractDoubleVector bVec = (RAbstractDoubleVector) argValues[6]; RAbstractIntVector infoVec = (RAbstractIntVector) argValues[7]; double[] x = xVec.materialize().getDataTemp(); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrdc2.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrdc2.java index 0e8a93f22444ba6bb03f37a69de841eae38e05e4..fb842d465d81c176cdc1f5aeadaab8f3d07326c0 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrdc2.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/foreign/Dqrdc2.java @@ -32,10 +32,10 @@ public final class Dqrdc2 extends RExternalBuiltinNode { Object[] argValues = args.getArguments(); try { RAbstractDoubleVector xVec = (RAbstractDoubleVector) argValues[0]; - int ldx = (int) argValues[1]; - int n = (int) argValues[2]; - int p = (int) argValues[3]; - double tol = (double) argValues[4]; + int ldx = argValues[1] instanceof Integer ? (int) argValues[1] : ((RAbstractIntVector) argValues[1]).getDataAt(0); + int n = argValues[2] instanceof Integer ? (int) argValues[2] : ((RAbstractIntVector) argValues[2]).getDataAt(0); + int p = argValues[3] instanceof Integer ? (int) argValues[3] : ((RAbstractIntVector) argValues[3]).getDataAt(0); + double tol = argValues[4] instanceof Double ? (double) argValues[4] : ((RAbstractDoubleVector) argValues[4]).getDataAt(0); RAbstractIntVector rankVec = (RAbstractIntVector) argValues[5]; RAbstractDoubleVector qrauxVec = (RAbstractDoubleVector) argValues[6]; RAbstractIntVector pivotVec = (RAbstractIntVector) argValues[7]; diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/builtin/CastBuilderTest.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/builtin/CastBuilderTest.java index 681a49131af2005f5d4f01561a6c8388dd4fad56..e9494ac30eb5871ff6f542787dbd6be94370146a 100644 --- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/builtin/CastBuilderTest.java +++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/builtin/CastBuilderTest.java @@ -675,7 +675,8 @@ public class CastBuilderTest { private void testPipeline(@SuppressWarnings("unused") boolean positiveMustNotBeEmpty) { CastNodeSampler<CastNode> sampler = CastNodeSampler.createSampler(cb.getCasts()[0]); - Samples<?> samples = sampler.collectSamples(); + sampler.collectSamples(); + // Samples<?> samples = sampler.collectSamples(); // // if (positiveMustNotBeEmpty) { // Assert.assertFalse(samples.positiveSamples().isEmpty()); diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/casts/ArgumentFilterSampler.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/casts/ArgumentFilterSampler.java index d3a51f559e4c4b4365265c7e451f1cda91118265..979813ce02f49487c5fb8184e851ffc1c7fa4bc7 100644 --- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/casts/ArgumentFilterSampler.java +++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/casts/ArgumentFilterSampler.java @@ -232,7 +232,6 @@ public interface ArgumentFilterSampler<T, R> extends ArgumentFilter<T, R> { return ArgumentTypeFilterSampler.this.trueBranchType().and(other.trueBranchType()); } - @SuppressWarnings("cast") @Override public Samples<R> collectSamples(TypeExpr inputType) { Samples<R> thisSamples = ArgumentTypeFilterSampler.this.collectSamples(inputType); @@ -269,7 +268,6 @@ public interface ArgumentFilterSampler<T, R> extends ArgumentFilter<T, R> { return orig.falseBranchType().not(); } - @SuppressWarnings("unchecked") @Override public Samples<Object> collectSamples(TypeExpr inputType) { Samples<? extends R> thisSamples = orig.collectSamples(inputType); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/CastBuilder.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/CastBuilder.java index b5ce331f08f10e4dc7964a04fb14f590bfe76997..564660b681f2661cfb9902918ce9f6fd945b3422 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/CastBuilder.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/builtin/CastBuilder.java @@ -30,6 +30,7 @@ import com.oracle.truffle.api.profiles.ConditionProfile; import com.oracle.truffle.r.nodes.binary.BoxPrimitiveNodeGen; import com.oracle.truffle.r.nodes.builtin.ArgumentFilter.ArgumentTypeFilter; import com.oracle.truffle.r.nodes.builtin.ArgumentFilter.ArgumentValueFilter; +import com.oracle.truffle.r.nodes.unary.CastComplexNodeGen; import com.oracle.truffle.r.nodes.unary.CastDoubleBaseNodeGen; import com.oracle.truffle.r.nodes.unary.CastDoubleNodeGen; import com.oracle.truffle.r.nodes.unary.CastIntegerBaseNodeGen; @@ -37,6 +38,7 @@ import com.oracle.truffle.r.nodes.unary.CastIntegerNodeGen; import com.oracle.truffle.r.nodes.unary.CastLogicalBaseNodeGen; import com.oracle.truffle.r.nodes.unary.CastLogicalNodeGen; import com.oracle.truffle.r.nodes.unary.CastNode; +import com.oracle.truffle.r.nodes.unary.CastRawNodeGen; import com.oracle.truffle.r.nodes.unary.CastStringBaseNodeGen; import com.oracle.truffle.r.nodes.unary.CastStringNodeGen; import com.oracle.truffle.r.nodes.unary.CastToAttributableNodeGen; @@ -136,6 +138,14 @@ public final class CastBuilder { return insert(index, CastStringNodeGen.create(preserveNames, dimensionsPreservation, attrPreservation)); } + public CastBuilder toComplex(int index) { + return insert(index, CastComplexNodeGen.create(false, false, false)); + } + + public CastBuilder toRaw(int index) { + return insert(index, CastRawNodeGen.create(false, false, false)); + } + public CastBuilder boxPrimitive(int index) { return insert(index, BoxPrimitiveNodeGen.create()); } @@ -707,6 +717,14 @@ public final class CastBuilder { return phaseBuilder -> CastStringNodeGen.create(false, false, false); } + public static <T> Function<ArgCastBuilder<T, ?>, CastNode> asComplexVector() { + return phaseBuilder -> CastComplexNodeGen.create(false, false, false); + } + + public static <T> Function<ArgCastBuilder<T, ?>, CastNode> asRawVector() { + return phaseBuilder -> CastRawNodeGen.create(false, false, false); + } + public static <T> Function<ArgCastBuilder<T, ?>, CastNode> asStringVector(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) { return phaseBuilder -> CastStringNodeGen.create(preserveNames, preserveDimensions, preserveAttributes); } @@ -1384,6 +1402,16 @@ public final class CastBuilder { return state().factory.newCoercedPhaseBuilder(this, String.class); } + default CoercedPhaseBuilder<RAbstractComplexVector, RComplex> asComplexVector() { + state().castBuilder().toComplex(state().index()); + return state().factory.newCoercedPhaseBuilder(this, RComplex.class); + } + + default CoercedPhaseBuilder<RAbstractRawVector, RRaw> asRawVector() { + state().castBuilder().toRaw(state().index()); + return state().factory.newCoercedPhaseBuilder(this, RRaw.class); + } + default CoercedPhaseBuilder<RAbstractVector, Object> asVector() { state().castBuilder().toVector(state().index()); return state().factory.newCoercedPhaseBuilder(this, Object.class); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastComplexNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastComplexNode.java index 2e6fae29105ba85c5233d5ed27c7ec804b8173a1..1ff2e13b0783bb648a3e3f246d8722b5a93a46ad 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastComplexNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastComplexNode.java @@ -24,6 +24,7 @@ package com.oracle.truffle.r.nodes.unary; import java.util.function.IntFunction; +import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.BranchProfile; @@ -34,6 +35,7 @@ import com.oracle.truffle.r.runtime.RType; 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.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; @@ -41,6 +43,7 @@ import com.oracle.truffle.r.runtime.data.RRawVector; 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.RAbstractListVector; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; import com.oracle.truffle.r.runtime.ops.na.NACheck; import com.oracle.truffle.r.runtime.ops.na.NAProfile; @@ -63,6 +66,16 @@ public abstract class CastComplexNode extends CastBaseNode { super(preserveNames, preserveDimensions, preserveAttributes); } + @Child private CastComplexNode recursiveCastComplex; + + private Object castComplexRecursive(Object o) { + if (recursiveCastComplex == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + recursiveCastComplex = insert(CastComplexNodeGen.create(preserveNames(), preserveDimensions(), preserveAttributes())); + } + return recursiveCastComplex.executeComplex(o); + } + @Override protected final RType getTargetType() { return RType.Complex; @@ -198,6 +211,50 @@ public abstract class CastComplexNode extends CastBaseNode { return createResultVector(operand, index -> RDataFactory.createComplex(operand.getDataAt(index).getValue(), 0)); } + @Specialization + protected RComplexVector doList(RAbstractListVector list) { + int length = list.getLength(); + double[] result = new double[length * 2]; + boolean seenNA = false; + for (int i = 0, j = 0; i < length; i++, j += 2) { + Object entry = list.getDataAt(i); + if (entry instanceof RList) { + result[j] = RRuntime.DOUBLE_NA; + result[j + 1] = RRuntime.DOUBLE_NA; + seenNA = true; + } else { + Object castEntry = castComplexRecursive(entry); + if (castEntry instanceof RComplex) { + RComplex value = (RComplex) castEntry; + result[j] = value.getRealPart(); + result[j + 1] = value.getImaginaryPart(); + seenNA = seenNA || RRuntime.isNA(value); + } else if (castEntry instanceof RComplexVector) { + RComplexVector complexVector = (RComplexVector) castEntry; + if (complexVector.getLength() == 1) { + RComplex value = complexVector.getDataAt(0); + result[j] = value.getRealPart(); + result[j + 1] = value.getImaginaryPart(); + seenNA = seenNA || RRuntime.isNA(value); + } else if (complexVector.getLength() == 0) { + result[j] = RRuntime.DOUBLE_NA; + result[j + 1] = RRuntime.DOUBLE_NA; + seenNA = true; + } else { + throw throwCannotCoerceListError("complex"); + } + } else { + throw throwCannotCoerceListError("complex"); + } + } + } + RComplexVector ret = RDataFactory.createComplexVector(result, !seenNA); + if (preserveAttributes()) { + ret.copyRegAttributesFrom(list); + } + return ret; + } + public static CastComplexNode create() { return CastComplexNodeGen.create(true, true, true); } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleNode.java index 47459c84f748ba2d2c43a1eaeb17820d77e69ecb..9e5e541a9d2839cd2ac67f88b782a58a864ec385 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleNode.java @@ -38,7 +38,9 @@ import com.oracle.truffle.r.runtime.data.RDoubleVector; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RRawVector; import com.oracle.truffle.r.runtime.data.RStringVector; +import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; +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.RAbstractVector; @@ -58,8 +60,8 @@ public abstract class CastDoubleNode extends CastDoubleBaseNode { return recursiveCastDouble.executeDouble(o); } - private RDoubleVector createResultVector(RAbstractVector operand, double[] ddata) { - RDoubleVector ret = RDataFactory.createDoubleVector(ddata, naCheck.neverSeenNA(), getPreservedDimensions(operand), getPreservedNames(operand)); + private RDoubleVector vectorCopy(RAbstractContainer operand, double[] data, boolean isComplete) { + RDoubleVector ret = RDataFactory.createDoubleVector(data, isComplete, getPreservedDimensions(operand), getPreservedNames(operand)); preserveDimensionNames(operand, ret); if (preserveAttributes()) { ret.copyRegAttributesFrom(operand); @@ -76,12 +78,7 @@ public abstract class CastDoubleNode extends CastDoubleBaseNode { ddata[i] = value; seenNA = seenNA || naProfile.isNA(value); } - RDoubleVector ret = RDataFactory.createDoubleVector(ddata, !seenNA, getPreservedDimensions(operand), getPreservedNames(operand)); - preserveDimensionNames(operand, ret); - if (preserveAttributes()) { - ret.copyRegAttributesFrom(operand); - } - return ret; + return vectorCopy(operand, ddata, !seenNA); } @Specialization @@ -146,7 +143,7 @@ public abstract class CastDoubleNode extends CastDoubleBaseNode { warningBranch.enter(); RError.warning(this, RError.Message.IMAGINARY_PARTS_DISCARDED_IN_COERCION); } - return createResultVector(operand, ddata); + return vectorCopy(operand, ddata, naCheck.neverSeenNA()); } @Specialization @@ -160,12 +157,13 @@ public abstract class CastDoubleNode extends CastDoubleBaseNode { } @Specialization - protected RDoubleSequence doDoubleSequence(RDoubleSequence operand) { + protected RDoubleSequence doDoubleVector(RDoubleSequence operand) { + // sequence does not have attributes - nothing to copy or drop return operand; } @Specialization - protected RDoubleVector doList(RList list) { + protected RDoubleVector doList(RAbstractListVector list) { int length = list.getLength(); double[] result = new double[length]; boolean seenNA = false; 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 60d21ca021724d29ff2cf57c4277b96bf3088208..59245636fa3c80316e0febe0fa94e27645bd9ebe 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 @@ -61,18 +61,24 @@ public abstract class CastIntegerNode extends CastIntegerBaseNode { public abstract Object executeInt(Object o); @Specialization - protected RAbstractIntVector doIntVector(RAbstractIntVector operand) { + protected RIntVector doIntVector(RIntVector operand) { + return operand; + } + + @Specialization + protected RIntSequence doIntVector(RIntSequence operand) { + // sequence does not have attributes - nothing to copy or drop return operand; } @Specialization protected RIntSequence doDoubleSequence(RDoubleSequence operand) { - naCheck.enable(operand); - return RDataFactory.createIntSequence(naCheck.convertDoubleToInt(operand.getStart()), naCheck.convertDoubleToInt(operand.getStride()), operand.getLength()); + // start and stride cannot be NA so no point checking + return RDataFactory.createIntSequence(RRuntime.double2intNoCheck(operand.getStart()), RRuntime.double2intNoCheck(operand.getStride()), operand.getLength()); } - private RIntVector createResultVector(RAbstractVector operand, int[] idata) { - RIntVector ret = RDataFactory.createIntVector(idata, naCheck.neverSeenNA(), getPreservedDimensions(operand), getPreservedNames(operand)); + private RIntVector vectorCopy(RAbstractVector operand, int[] idata, boolean isComplete) { + RIntVector ret = RDataFactory.createIntVector(idata, isComplete, getPreservedDimensions(operand), getPreservedNames(operand)); preserveDimensionNames(operand, ret); if (preserveAttributes()) { ret.copyRegAttributesFrom(operand); @@ -94,12 +100,7 @@ public abstract class CastIntegerNode extends CastIntegerBaseNode { idata[i] = value; seenNA = seenNA || naProfile.isNA(value); } - RIntVector ret = RDataFactory.createIntVector(idata, !seenNA, getPreservedDimensions(operand), getPreservedNames(operand)); - preserveDimensionNames(operand, ret); - if (preserveAttributes()) { - ret.copyRegAttributesFrom(operand); - } - return ret; + return vectorCopy(operand, idata, !seenNA); } @Specialization @@ -119,7 +120,7 @@ public abstract class CastIntegerNode extends CastIntegerBaseNode { warningBranch.enter(); RError.warning(this, RError.Message.IMAGINARY_PARTS_DISCARDED_IN_COERCION); } - return createResultVector(operand, idata); + return vectorCopy(operand, idata, naCheck.neverSeenNA()); } @Specialization @@ -150,12 +151,7 @@ public abstract class CastIntegerNode extends CastIntegerBaseNode { if (warning) { RError.warning(this, RError.Message.NA_INTRODUCED_COERCION); } - RIntVector ret = RDataFactory.createIntVector(idata, !seenNA, getPreservedDimensions(operand), getPreservedNames(operand)); - preserveDimensionNames(operand, ret); - if (preserveAttributes()) { - ret.copyRegAttributesFrom(operand); - } - return ret; + return vectorCopy(operand, idata, !seenNA); } @Specialization @@ -166,7 +162,7 @@ public abstract class CastIntegerNode extends CastIntegerBaseNode { @Specialization protected RIntVector doDoubleVector(RAbstractDoubleVector operand) { naCheck.enable(operand); - return createResultVector(operand, naCheck.convertDoubleVectorToIntData(operand)); + return vectorCopy(operand, naCheck.convertDoubleVectorToIntData(operand), naCheck.neverSeenNA()); } @Specialization 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 b7eac7f903810077889f3957e746be082c3a64c6..bb333f788f9fe878b320be956239f66f7cf84399 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 @@ -39,6 +39,7 @@ import com.oracle.truffle.r.runtime.data.RRawVector; 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.RAbstractListVector; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; import com.oracle.truffle.r.runtime.ops.na.NAProfile; @@ -79,6 +80,15 @@ public abstract class CastLogicalNode extends CastLogicalBaseNode { byte apply(int value); } + private RLogicalVector vectorCopy(RAbstractVector operand, byte[] bdata, boolean isComplete) { + RLogicalVector ret = RDataFactory.createLogicalVector(bdata, isComplete, getPreservedDimensions(operand), getPreservedNames(operand)); + preserveDimensionNames(operand, ret); + if (preserveAttributes()) { + ret.copyRegAttributesFrom(operand); + } + return ret; + } + private RLogicalVector createResultVector(RAbstractVector operand, IntToByteFunction elementFunction) { naCheck.enable(operand); byte[] bdata = new byte[operand.getLength()]; @@ -88,12 +98,7 @@ public abstract class CastLogicalNode extends CastLogicalBaseNode { bdata[i] = value; seenNA = seenNA || naProfile.isNA(value); } - RLogicalVector ret = RDataFactory.createLogicalVector(bdata, !seenNA, getPreservedDimensions(operand), getPreservedNames(operand)); - preserveDimensionNames(operand, ret); - if (preserveAttributes()) { - ret.copyRegAttributesFrom(operand); - } - return ret; + return vectorCopy(operand, bdata, !seenNA); } @Specialization @@ -134,7 +139,7 @@ public abstract class CastLogicalNode extends CastLogicalBaseNode { } @Specialization - protected RLogicalVector doList(RList list) { + protected RLogicalVector doList(RAbstractListVector list) { int length = list.getLength(); byte[] result = new byte[length]; boolean seenNA = false; diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastRawNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastRawNode.java index c4216503fa42031bb450494e4ca88ffeb4c3fad3..69d13990142a7dcd8d52515c28c579f65576df7a 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastRawNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastRawNode.java @@ -22,6 +22,7 @@ */ package com.oracle.truffle.r.nodes.unary; +import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.BranchProfile; @@ -39,6 +40,7 @@ import com.oracle.truffle.r.runtime.data.RRawVector; 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.RAbstractListVector; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; import com.oracle.truffle.r.runtime.ops.na.NACheck; import com.oracle.truffle.r.runtime.ops.na.NAProfile; @@ -52,11 +54,21 @@ public abstract class CastRawNode extends CastBaseNode { super(preserveNames, preserveDimensions, preserveAttributes); } + @Child private CastRawNode recursiveCastRaw; + @Override protected final RType getTargetType() { return RType.Raw; } + protected Object castRawRecursive(Object o) { + if (recursiveCastRaw == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + recursiveCastRaw = insert(CastRawNodeGen.create(preserveNames(), preserveDimensions(), preserveAttributes())); + } + return recursiveCastRaw.executeRaw(o); + } + public abstract Object executeRaw(int o); public abstract Object executeRaw(double o); @@ -135,7 +147,7 @@ public abstract class CastRawNode extends CastBaseNode { return RRaw.valueOf((byte) intRawValue); } - private RRawVector createResultVector(RAbstractVector operand, byte[] bdata) { + private RRawVector vectorCopy(RAbstractVector operand, byte[] bdata) { RRawVector ret = RDataFactory.createRawVector(bdata, getPreservedDimensions(operand), getPreservedNames(operand)); preserveDimensionNames(operand, ret); if (preserveAttributes()) { @@ -162,7 +174,7 @@ public abstract class CastRawNode extends CastBaseNode { if (warning) { RError.warning(this, RError.Message.OUT_OF_RANGE); } - return createResultVector(operand, bdata); + return vectorCopy(operand, bdata); } @Specialization @@ -182,7 +194,7 @@ public abstract class CastRawNode extends CastBaseNode { if (warning) { RError.warning(this, RError.Message.OUT_OF_RANGE); } - return createResultVector(operand, bdata); + return vectorCopy(operand, bdata); } @Specialization @@ -222,7 +234,7 @@ public abstract class CastRawNode extends CastBaseNode { if (outOfRangeWarning) { RError.warning(this, RError.Message.OUT_OF_RANGE); } - return createResultVector(operand, bdata); + return vectorCopy(operand, bdata); } @Specialization @@ -250,7 +262,7 @@ public abstract class CastRawNode extends CastBaseNode { if (outOfRangeWarning) { RError.warning(this, RError.Message.OUT_OF_RANGE); } - return createResultVector(operand, bdata); + return vectorCopy(operand, bdata); } @Specialization @@ -271,7 +283,7 @@ public abstract class CastRawNode extends CastBaseNode { if (warning) { RError.warning(this, RError.Message.OUT_OF_RANGE); } - return createResultVector(operand, bdata); + return vectorCopy(operand, bdata); } @Specialization @@ -279,6 +291,16 @@ public abstract class CastRawNode extends CastBaseNode { return operand; } + @Specialization + protected RRawVector doList(RAbstractListVector value) { + int length = value.getLength(); + RRawVector result = RDataFactory.createRawVector(length); + for (int i = 0; i < length; i++) { + result.updateDataAt(i, (RRaw) castRawRecursive(value.getDataAt(i))); + } + return result; + } + public static CastRawNode createNonPreserving() { return CastRawNodeGen.create(false, false, false); } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastStringNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastStringNode.java index d416956e4a2689e6f5f1098a9b7a4de604697d56..53e23e6e8be1b17af91843b85c673e5d2b31b082 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastStringNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastStringNode.java @@ -61,11 +61,7 @@ public abstract class CastStringNode extends CastStringBaseNode { @Specialization protected RStringVector doStringVector(RStringVector vector) { - if (preserveAttributes() && preserveDimensions() && preserveNames()) { - return vector; - } else { - return vectorCopy(vector, vector.getDataCopy()); - } + return vector; } @Specialization diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java index 7a1944f3ea0fffa3b0f70da0dc5bc55795507a71..d2f1b99c455dd2b9c2fb9dd0801f9a8fd92ea978 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/data/RPairList.java @@ -273,6 +273,12 @@ public class RPairList extends RSharingAttributeStorage implements RAbstractCont result = (RPairList) result.cdr; original = origList.cdr; } + if (getAttributes() != null) { + RAttributes newAttributes = result.initAttributes(); + for (RAttribute attr : getAttributes()) { + newAttributes.put(attr.getName(), attr.getValue()); + } + } return result; } 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 ea9e318c809ae60051f718f3956f08ed1b815ae1..01e3fcd48ae14532a5137cb0329f0b4184b4e46e 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 @@ -5578,6 +5578,20 @@ NAs introduced by coercion #{ as.complex(c(0/0, 0/0)) } [1] NA NA +##com.oracle.truffle.r.test.builtins.TestBuiltin_ascomplex.testAsComplex +#{ as.complex(list("foo")) } +[1] NA +Warning message: +NAs introduced by coercion + +##com.oracle.truffle.r.test.builtins.TestBuiltin_ascomplex.testAsComplex +#{ as.complex(list(42)) } +[1] 42+0i + +##com.oracle.truffle.r.test.builtins.TestBuiltin_ascomplex.testAsComplex +#{ as.complex(list(NULL)) } +Error: (list) object cannot be coerced to type 'complex' + ##com.oracle.truffle.r.test.builtins.TestBuiltin_ascomplex.testAsComplex #{ x<-c(a=1.1, b=2.2); dim(x)<-c(1,2); attr(x, "foo")<-"foo"; y<-as.complex(x); attributes(y) } NULL diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_ascomplex.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_ascomplex.java index bdd5b4596b80bf4a7e1a0946cb8cc34723925f20..5de58ac5216bb0d7f4864cc708a62889c1dc00bd 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_ascomplex.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_ascomplex.java @@ -96,5 +96,9 @@ public class TestBuiltin_ascomplex extends TestBase { assertEval(Ignored.Unknown, "{ as.complex(\"-.1e10+5i\") }"); assertEval(Ignored.Unknown, "{ as.complex(\"1e-2+3i\") }"); assertEval(Ignored.Unknown, "{ as.complex(\"+.1e+2-3i\") }"); + + assertEval("{ as.complex(list(42)) }"); + assertEval(Output.IgnoreErrorContext, "{ as.complex(list(NULL)) }"); + assertEval(Output.IgnoreWarningContext, "{ as.complex(list(\"foo\")) }"); } }