From a07d8cc7e998d0bd07e8c64f2ba78046caedb5f6 Mon Sep 17 00:00:00 2001 From: stepan <stepan.sindelar@oracle.com> Date: Fri, 10 Feb 2017 12:29:34 +0100 Subject: [PATCH] RFFI compatible mode for coercions (CastNodes) Adds a flag to CastBaseNode that indicates that it should behave in a way compatible with coercions exposed by the R native interface. --- .../truffle/r/nodes/unary/CastBaseNode.java | 43 ++++++++++++++++--- .../r/nodes/unary/CastComplexNode.java | 12 +++++- .../r/nodes/unary/CastDoubleBaseNode.java | 6 ++- .../truffle/r/nodes/unary/CastDoubleNode.java | 10 ++++- .../r/nodes/unary/CastExpressionNode.java | 13 +++++- .../r/nodes/unary/CastIntegerBaseNode.java | 6 ++- .../r/nodes/unary/CastIntegerNode.java | 10 ++++- .../truffle/r/nodes/unary/CastListNode.java | 12 +++++- .../r/nodes/unary/CastLogicalBaseNode.java | 6 ++- .../r/nodes/unary/CastLogicalNode.java | 12 +++++- .../truffle/r/nodes/unary/CastRawNode.java | 18 ++++++-- .../r/nodes/unary/CastStringBaseNode.java | 8 +++- .../truffle/r/nodes/unary/CastStringNode.java | 12 +++++- .../truffle/r/nodes/unary/CastSymbolNode.java | 24 ++++++++++- .../r/nodes/unary/CastToAttributableNode.java | 8 +++- .../r/nodes/unary/CastToContainerNode.java | 8 +++- .../com/oracle/truffle/r/runtime/RError.java | 2 +- 17 files changed, 177 insertions(+), 33 deletions(-) diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastBaseNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastBaseNode.java index 1f77dc7c61..f136727e66 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastBaseNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastBaseNode.java @@ -34,10 +34,12 @@ import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetNames import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.SetDimNamesAttributeNode; import com.oracle.truffle.r.runtime.NullProfile; import com.oracle.truffle.r.runtime.RError; +import com.oracle.truffle.r.runtime.RError.Message; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.RType; 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.RTypedValue; import com.oracle.truffle.r.runtime.data.RVector; @@ -62,21 +64,37 @@ public abstract class CastBaseNode extends CastNode { protected final RBaseNode messageCallObj; + /** + * GnuR provides several, sometimes incompatible, ways to coerce given value to given type. This + * flag tells the cast node that it should behave in a way compatible with functions exposed by + * the native interface. + */ + private final boolean forRFFI; + protected CastBaseNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, RBaseNode messageCallObj) { + this(preserveNames, preserveDimensions, preserveAttributes, false, messageCallObj); + } + + protected CastBaseNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) { + this(preserveNames, preserveDimensions, preserveAttributes, false, null); + } + + protected CastBaseNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, boolean forRFFI) { + this(preserveNames, preserveDimensions, preserveAttributes, forRFFI, null); + } + + protected CastBaseNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, boolean forRFFI, RBaseNode messageCallObj) { this.preserveNames = preserveNames; this.preserveDimensions = preserveDimensions; this.preserveAttributes = preserveAttributes; + this.forRFFI = forRFFI; if (preserveDimensions) { getDimNamesNode = GetDimNamesAttributeNode.create(); } this.messageCallObj = messageCallObj == null ? this : messageCallObj; } - protected CastBaseNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) { - this(preserveNames, preserveDimensions, preserveAttributes, null); - } - - public boolean preserveNames() { + public final boolean preserveNames() { return preserveNames; } @@ -84,7 +102,7 @@ public abstract class CastBaseNode extends CastNode { return preserveDimensions; } - public boolean preserveAttributes() { + public final boolean preserveAttributes() { return preserveAttributes; } @@ -132,6 +150,10 @@ public abstract class CastBaseNode extends CastNode { @TruffleBoundary protected Object doOther(Object value) { Object mappedValue = RRuntime.asAbstractVector(value); + return forRFFI ? doOtherRFFI(mappedValue) : doOtherDefault(mappedValue); + } + + protected Object doOtherDefault(Object mappedValue) { if (mappedValue instanceof REnvironment) { throw RError.error(RError.SHOW_CALLER, RError.Message.ENVIRONMENTS_COERCE); } else if (mappedValue instanceof RTypedValue) { @@ -142,4 +164,13 @@ public abstract class CastBaseNode extends CastNode { throw RInternalError.shouldNotReachHere("unexpected value of type " + (mappedValue == null ? "null" : mappedValue.getClass())); } } + + protected Object doOtherRFFI(Object mappedValue) { + if (mappedValue instanceof RTypedValue) { + RError.warning(RError.SHOW_CALLER2, Message.CANNOT_COERCE_RFFI, ((RTypedValue) mappedValue).getRType().getName(), getTargetType().getName()); + } else if (mappedValue instanceof TruffleObject) { + throw RError.error(RError.SHOW_CALLER2, RError.Message.CANNOT_COERCE, "truffleobject", getTargetType().getName()); + } + return RNull.instance; + } } 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 ac4c7257d2..3d8fb9edf3 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 @@ -68,7 +68,11 @@ public abstract class CastComplexNode extends CastBaseNode { } protected CastComplexNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) { - super(preserveNames, preserveDimensions, preserveAttributes); + this(preserveNames, preserveDimensions, preserveAttributes, false); + } + + protected CastComplexNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, boolean forRFFI) { + super(preserveNames, preserveDimensions, preserveAttributes, forRFFI); } @Child private CastComplexNode recursiveCastComplex; @@ -253,7 +257,7 @@ public abstract class CastComplexNode extends CastBaseNode { } } } - RComplexVector ret = RDataFactory.createComplexVector(result, !seenNA); + RComplexVector ret = RDataFactory.createComplexVector(result, !seenNA, getPreservedDimensions(list), getPreservedNames(list)); if (preserveAttributes()) { ret.copyRegAttributesFrom(list); } @@ -264,6 +268,10 @@ public abstract class CastComplexNode extends CastBaseNode { return CastComplexNodeGen.create(true, true, true); } + public static CastComplexNode createForRFFI(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) { + return CastComplexNodeGen.create(preserveNames, preserveDimensions, preserveAttributes, true); + } + public static CastComplexNode createNonPreserving() { return CastComplexNodeGen.create(false, false, false); } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleBaseNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleBaseNode.java index eee5c32934..6e1b66b740 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleBaseNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastDoubleBaseNode.java @@ -48,7 +48,11 @@ public abstract class CastDoubleBaseNode extends CastBaseNode { } protected CastDoubleBaseNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) { - this(preserveNames, preserveDimensions, preserveAttributes, null); + this(preserveNames, preserveDimensions, preserveAttributes, false); + } + + protected CastDoubleBaseNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, boolean forRFFI) { + super(preserveNames, preserveDimensions, preserveAttributes, forRFFI); } @Override 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 3b98bd3901..d937c07eef 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 @@ -48,7 +48,11 @@ import com.oracle.truffle.r.runtime.nodes.RBaseNode; public abstract class CastDoubleNode extends CastDoubleBaseNode { protected CastDoubleNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) { - super(preserveNames, preserveDimensions, preserveAttributes); + this(preserveNames, preserveDimensions, preserveAttributes, false); + } + + protected CastDoubleNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, boolean forRFFI) { + super(preserveNames, preserveDimensions, preserveAttributes, forRFFI); } protected CastDoubleNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, RBaseNode messageCallerObj) { @@ -211,6 +215,10 @@ public abstract class CastDoubleNode extends CastDoubleBaseNode { return CastDoubleNodeGen.create(true, true, true); } + public static CastDoubleNode createForRFFI(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) { + return CastDoubleNodeGen.create(preserveNames, preserveDimensions, preserveAttributes, true); + } + public static CastDoubleNode createNonPreserving() { return CastDoubleNodeGen.create(false, false, false); } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastExpressionNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastExpressionNode.java index 1178f3762e..a5a4c01397 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastExpressionNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastExpressionNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,7 +40,11 @@ public abstract class CastExpressionNode extends CastBaseNode { public abstract Object executeExpression(Object o); protected CastExpressionNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) { - super(preserveNames, preserveDimensions, preserveAttributes); + this(preserveNames, preserveDimensions, preserveAttributes, false); + } + + protected CastExpressionNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, boolean forRFFI) { + super(preserveNames, preserveDimensions, preserveAttributes, forRFFI); } @Override @@ -104,6 +108,11 @@ public abstract class CastExpressionNode extends CastBaseNode { return RDataFactory.createExpression(new Object[]{obj}); } + public static CastExpressionNode createForRFFI(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) { + // RFFI coercion to list unlike others does not preserve names it seems + return CastExpressionNodeGen.create(false, false, false, true); + } + public static CastExpressionNode createNonPreserving() { return CastExpressionNodeGen.create(false, false, false); } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerBaseNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerBaseNode.java index 14766f8e64..5a26f6d198 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerBaseNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastIntegerBaseNode.java @@ -45,7 +45,11 @@ public abstract class CastIntegerBaseNode extends CastBaseNode { @Child private CastIntegerNode recursiveCastInteger; protected CastIntegerBaseNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) { - super(preserveNames, preserveDimensions, preserveAttributes); + this(preserveNames, preserveDimensions, preserveAttributes, false); + } + + protected CastIntegerBaseNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, boolean forRFFI) { + super(preserveNames, preserveDimensions, preserveAttributes, forRFFI); } protected CastIntegerBaseNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, RBaseNode messageCallObj) { 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 796d7b5569..b0310c602b 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 @@ -50,7 +50,11 @@ public abstract class CastIntegerNode extends CastIntegerBaseNode { private final NAProfile naProfile = NAProfile.create(); protected CastIntegerNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) { - super(preserveNames, preserveDimensions, preserveAttributes); + this(preserveNames, preserveDimensions, preserveAttributes, false); + } + + protected CastIntegerNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, boolean forRFFI) { + super(preserveNames, preserveDimensions, preserveAttributes, forRFFI); } protected CastIntegerNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, RBaseNode messageCallObj) { @@ -229,6 +233,10 @@ public abstract class CastIntegerNode extends CastIntegerBaseNode { return CastIntegerNodeGen.create(true, true, true, null); } + public static CastIntegerNode createForRFFI(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) { + return CastIntegerNodeGen.create(preserveNames, preserveDimensions, preserveAttributes, true); + } + public static CastIntegerNode createNonPreserving() { return CastIntegerNodeGen.create(false, false, false, null); } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java index 606b54d966..1fc21b1956 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastListNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -52,7 +52,11 @@ public abstract class CastListNode extends CastBaseNode { public abstract RList executeList(Object o); protected CastListNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) { - super(preserveNames, preserveDimensions, preserveAttributes); + this(preserveNames, preserveDimensions, preserveAttributes, false); + } + + protected CastListNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, boolean forRFFI) { + super(preserveNames, preserveDimensions, preserveAttributes, forRFFI); } @Override @@ -143,4 +147,8 @@ public abstract class CastListNode extends CastBaseNode { public static CastListNode create() { return CastListNodeGen.create(true, true, true); } + + public static CastListNode createForRFFI(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) { + return CastListNodeGen.create(preserveNames, preserveDimensions, preserveAttributes, true); + } } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastLogicalBaseNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastLogicalBaseNode.java index d9883e2f08..94f484b2fc 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastLogicalBaseNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastLogicalBaseNode.java @@ -35,7 +35,11 @@ public abstract class CastLogicalBaseNode extends CastBaseNode { protected final NACheck naCheck = NACheck.create(); protected CastLogicalBaseNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) { - super(preserveNames, preserveDimensions, preserveAttributes); + this(preserveNames, preserveDimensions, preserveAttributes, false); + } + + protected CastLogicalBaseNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, boolean forRFFI) { + super(preserveNames, preserveDimensions, preserveAttributes, forRFFI); } protected CastLogicalBaseNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, RBaseNode messageCallObj) { 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 7cd9f32a97..6f15ddd3fc 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 @@ -56,7 +56,11 @@ public abstract class CastLogicalNode extends CastLogicalBaseNode { } protected CastLogicalNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) { - super(preserveNames, preserveDimensions, preserveAttributes); + this(preserveNames, preserveDimensions, preserveAttributes, false); + } + + protected CastLogicalNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, boolean forRFFI) { + super(preserveNames, preserveDimensions, preserveAttributes, forRFFI); } protected Object castLogicalRecursive(Object o) { @@ -176,7 +180,7 @@ public abstract class CastLogicalNode extends CastLogicalBaseNode { } } } - RLogicalVector ret = RDataFactory.createLogicalVector(result, !seenNA); + RLogicalVector ret = RDataFactory.createLogicalVector(result, !seenNA, getPreservedDimensions(list), getPreservedNames(list)); if (preserveAttributes()) { ret.copyRegAttributesFrom(list); } @@ -197,6 +201,10 @@ public abstract class CastLogicalNode extends CastLogicalBaseNode { return CastLogicalNodeGen.create(true, true, true); } + public static CastLogicalNode createForRFFI(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) { + return CastLogicalNodeGen.create(preserveNames, preserveDimensions, preserveAttributes, true); + } + public static CastLogicalNode createNonPreserving() { return CastLogicalNodeGen.create(false, false, 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 6592eb1d59..9471d88d7a 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 @@ -51,7 +51,11 @@ public abstract class CastRawNode extends CastBaseNode { private final BranchProfile warningBranch = BranchProfile.create(); protected CastRawNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) { - super(preserveNames, preserveDimensions, preserveAttributes); + this(preserveNames, preserveDimensions, preserveAttributes, false); + } + + protected CastRawNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, boolean forRFFI) { + super(preserveNames, preserveDimensions, preserveAttributes, forRFFI); } @Child private CastRawNode recursiveCastRaw; @@ -295,13 +299,21 @@ public abstract class CastRawNode extends CastBaseNode { @Specialization protected RRawVector doList(RAbstractListVector value) { int length = value.getLength(); - RRawVector result = RDataFactory.createRawVector(length); + byte[] data = new byte[length]; for (int i = 0; i < length; i++) { - result.updateDataAt(i, (RRaw) castRawRecursive(value.getDataAt(i))); + data[i] = ((RRaw) castRawRecursive(value.getDataAt(i))).getValue(); + } + RRawVector result = RDataFactory.createRawVector(data, getPreservedDimensions(value), getPreservedNames(value)); + if (preserveAttributes()) { + result.copyRegAttributesFrom(value); } return result; } + public static CastRawNode createForRFFI(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) { + return CastRawNodeGen.create(preserveNames, preserveDimensions, preserveAttributes, true); + } + 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/CastStringBaseNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastStringBaseNode.java index e5d9f51ef3..8d3a0456e3 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastStringBaseNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastStringBaseNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,11 @@ public abstract class CastStringBaseNode extends CastBaseNode { @Child private ToStringNode toString = ToStringNodeGen.create(); protected CastStringBaseNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) { - super(preserveNames, preserveDimensions, preserveAttributes); + this(preserveNames, preserveDimensions, preserveAttributes, false); + } + + protected CastStringBaseNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, boolean forRFFI) { + super(preserveNames, preserveDimensions, preserveAttributes, forRFFI); } @Override 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 2bdf51e02a..a59b45866a 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,11 @@ import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; public abstract class CastStringNode extends CastStringBaseNode { protected CastStringNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) { - super(preserveNames, preserveDimensions, preserveAttributes); + this(preserveNames, preserveDimensions, preserveAttributes, false); + } + + protected CastStringNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, boolean forRFFI) { + super(preserveNames, preserveDimensions, preserveAttributes, forRFFI); } public abstract Object executeString(int o); @@ -85,6 +89,10 @@ public abstract class CastStringNode extends CastStringBaseNode { return CastStringNodeGen.create(true, true, true); } + public static CastStringNode createForRFFI(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) { + return CastStringNodeGen.create(preserveNames, preserveDimensions, preserveAttributes, true); + } + public static CastStringNode createNonPreserving() { return CastStringNodeGen.create(false, false, false); } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastSymbolNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastSymbolNode.java index b8cc2b7251..31b0fea74e 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastSymbolNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastSymbolNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,21 +25,28 @@ package com.oracle.truffle.r.nodes.unary; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Specialization; 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.RDoubleVector; 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.RStringVector; import com.oracle.truffle.r.runtime.data.RSymbol; +import com.oracle.truffle.r.runtime.data.model.RAbstractVector; public abstract class CastSymbolNode extends CastBaseNode { @Child private ToStringNode toString = ToStringNodeGen.create(); protected CastSymbolNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) { - super(preserveNames, preserveDimensions, preserveAttributes); + this(preserveNames, preserveDimensions, preserveAttributes, false); + } + + protected CastSymbolNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, boolean forRFFI) { + super(preserveNames, preserveDimensions, preserveAttributes, forRFFI); } @Override @@ -121,6 +128,19 @@ public abstract class CastSymbolNode extends CastBaseNode { return RDataFactory.createSymbolInterned(s); } + @Override + protected Object doOtherRFFI(Object mappedValue) { + if (mappedValue instanceof RList) { + // to be compatible with GnuR + throw RError.error(RError.NO_CALLER, Message.INVALID_TYPE_LENGTH, "symbol", ((RList) mappedValue).getLength()); + } + return super.doOtherRFFI(mappedValue); + } + + public static CastSymbolNode createForRFFI(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) { + return CastSymbolNodeGen.create(preserveNames, preserveDimensions, preserveAttributes, true); + } + public static CastSymbolNode createNonPreserving() { return CastSymbolNodeGen.create(false, false, false); } diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToAttributableNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToAttributableNode.java index 92608cf7e3..790a649b00 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToAttributableNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/unary/CastToAttributableNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,11 @@ public abstract class CastToAttributableNode extends CastBaseNode { public abstract Object executeObject(Object value); protected CastToAttributableNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) { - super(preserveNames, preserveDimensions, preserveAttributes); + this(preserveNames, preserveDimensions, preserveAttributes, false); + } + + protected CastToAttributableNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, boolean forRFFI) { + super(preserveNames, preserveDimensions, preserveAttributes, forRFFI); } @Override 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 6446fb5726..383e4adb83 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,11 @@ public abstract class CastToContainerNode extends CastBaseNode { public abstract Object executeObject(Object value); protected CastToContainerNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes) { - super(preserveNames, preserveDimensions, preserveAttributes); + this(preserveNames, preserveDimensions, preserveAttributes, false); + } + + protected CastToContainerNode(boolean preserveNames, boolean preserveDimensions, boolean preserveAttributes, boolean forRFFI) { + super(preserveNames, preserveDimensions, preserveAttributes, forRFFI); } @Override diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java index c4bc15ba7f..da3597e880 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RError.java @@ -455,6 +455,7 @@ public final class RError extends RuntimeException { INVALID_SUBSCRIPT_TYPE("invalid subscript type '%s'"), ARGUMENT_NOT_VECTOR("argument %d is not a vector"), CANNOT_COERCE("cannot coerce type '%s' to vector of type '%s'"), + CANNOT_COERCE_RFFI("(%s) object cannot be coerced to type '%s'"), ARGUMENT_ONLY_FIRST("argument '%s' has length > 1 and only the first element will be used"), ARGUMENT_ONLY_FIRST_1("only the first element of '%s' argument used"), ARGUMENT_WRONG_LENGTH("wrong length for argument"), @@ -742,7 +743,6 @@ public final class RError extends RuntimeException { QUIT_INVALID_STATUS("invalid 'status', 0 assumed"), QUIT_INVALID_RUNLAST("invalid 'runLast', FALSE assumed"), ENVIRONMENTS_COERCE("environments cannot be coerced to other types"), - CLOSURE_COERCE("cannot coerce type 'closure' to vector of type 'integer'"), ROWSUM_NAMES_NOT_CHAR("row names are not character"), ROWSUM_NON_NUMERIC("non-numeric matrix in rowsum(): this should not happen"), ARGUMENTS_REQUIRED_COUNT("%d arguments to '%s' which requires %d"), -- GitLab