diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/access/vector/ExtractVectorNodeTest.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/access/vector/ExtractVectorNodeTest.java index 493c99a19620accd491332e806e1461c84abca13..46106945e5a2de13a94cbd614dd7ca9d589d014e 100644 --- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/access/vector/ExtractVectorNodeTest.java +++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/access/vector/ExtractVectorNodeTest.java @@ -77,36 +77,38 @@ public class ExtractVectorNodeTest extends TestBase { @Test public void testSubsetMultiDimension() { - RAbstractIntVector vector; - - // replace rectangle with rectangle indices - vector = generateInteger(20, true); - vector.setDimensions(new int[]{5, 4}); - vector = executeExtract(ElementAccessMode.SUBSET, vector, - RDataFactory.createIntVector(new int[]{2, 3, 4}, true), RDataFactory.createIntVector(new int[]{2, 3}, true)); - assertIndicies(vector, 6, 7, 8, 11, 12, 13); - - // replace box with box indices - vector = generateInteger(9, true); - vector.setDimensions(new int[]{3, 3}); - vector = executeExtract(ElementAccessMode.SUBSET, vector, - RDataFactory.createIntVector(new int[]{2, 3}, true), RDataFactory.createIntVector(new int[]{2, 3}, true)); - assertIndicies(vector, 4, 5, 7, 8); - - // replace three dimensions - vector = generateInteger(24, true); - vector.setDimensions(new int[]{2, 3, 4}); - vector = executeExtract(ElementAccessMode.SUBSET, vector, - RDataFactory.createIntVector(new int[]{2}, true), RDataFactory.createIntVector(new int[]{2}, true), RDataFactory.createIntVector(new int[]{2}, true)); - assertIndicies(vector, 9); - - // replace three dimensions - vector = generateInteger(24, true); - vector.setDimensions(new int[]{2, 3, 4}); - vector = executeExtract(ElementAccessMode.SUBSET, vector, - RDataFactory.createIntVector(new int[]{2}, true), RDataFactory.createIntVector(new int[]{2, 3}, true), RDataFactory.createIntVector(new int[]{2, 3, 4}, true)); - assertIndicies(vector, 9, 11, 15, 17, 21, 23); - + execInContext(() -> { + RAbstractIntVector vector; + + // replace rectangle with rectangle indices + vector = generateInteger(20, true); + vector.setDimensions(new int[]{5, 4}); + vector = executeExtract(ElementAccessMode.SUBSET, vector, + RDataFactory.createIntVector(new int[]{2, 3, 4}, true), RDataFactory.createIntVector(new int[]{2, 3}, true)); + assertIndicies(vector, 6, 7, 8, 11, 12, 13); + + // replace box with box indices + vector = generateInteger(9, true); + vector.setDimensions(new int[]{3, 3}); + vector = executeExtract(ElementAccessMode.SUBSET, vector, + RDataFactory.createIntVector(new int[]{2, 3}, true), RDataFactory.createIntVector(new int[]{2, 3}, true)); + assertIndicies(vector, 4, 5, 7, 8); + + // replace three dimensions + vector = generateInteger(24, true); + vector.setDimensions(new int[]{2, 3, 4}); + vector = executeExtract(ElementAccessMode.SUBSET, vector, + RDataFactory.createIntVector(new int[]{2}, true), RDataFactory.createIntVector(new int[]{2}, true), RDataFactory.createIntVector(new int[]{2}, true)); + assertIndicies(vector, 9); + + // replace three dimensions + vector = generateInteger(24, true); + vector.setDimensions(new int[]{2, 3, 4}); + vector = executeExtract(ElementAccessMode.SUBSET, vector, + RDataFactory.createIntVector(new int[]{2}, true), RDataFactory.createIntVector(new int[]{2, 3}, true), RDataFactory.createIntVector(new int[]{2, 3, 4}, true)); + assertIndicies(vector, 9, 11, 15, 17, 21, 23); + return null; + }); } private static void assertIndicies(RAbstractIntVector vector, int... expectedValues) { @@ -121,110 +123,125 @@ public class ExtractVectorNodeTest extends TestBase { @Test public void testSubsetSingleDimension() { - RAbstractIntVector vector; - - // extract scalar with logical vector with NA - vector = generateInteger(4, true); - vector = executeExtract(ElementAccessMode.SUBSET, vector, - new Object[]{RDataFactory.createLogicalVector(new byte[]{RRuntime.LOGICAL_TRUE, RRuntime.LOGICAL_NA}, false)}); - assertIndicies(vector, 0, RRuntime.INT_NA, 2, RRuntime.INT_NA); - - // extract scalar with sequence stride=1 - vector = generateInteger(9, true); - vector = executeExtract(ElementAccessMode.SUBSET, vector, new Object[]{RDataFactory.createIntSequence(5, 1, 3)}); - assertIndicies(vector, 4, 5, 6); - - // extract scalar with sequence stride>1 - vector = generateInteger(9, true); - vector = executeExtract(ElementAccessMode.SUBSET, vector, new Object[]{RDataFactory.createIntSequence(5, 2, 2)}); - assertIndicies(vector, 4, 6); - - // extract scalar with negative integer vector - vector = generateInteger(4, true); - vector = executeExtract(ElementAccessMode.SUBSET, vector, new Object[]{RDataFactory.createIntVector(new int[]{-2}, true)}); - assertIndicies(vector, 0, 2, 3); - - // extract scalar with logical scalar - vector = generateInteger(3, true); - vector = executeExtract(ElementAccessMode.SUBSET, vector, - new Object[]{RDataFactory.createLogicalVector(new byte[]{RRuntime.LOGICAL_TRUE}, true)}); - assertIndicies(vector, 0, 1, 2); - - // extract scalar with integer vector with NA - vector = generateInteger(4, true); - vector = executeExtract(ElementAccessMode.SUBSET, vector, - new Object[]{RDataFactory.createIntVector(new int[]{1, RRuntime.INT_NA}, false)}); - assertIndicies(vector, 0, RRuntime.INT_NA); - - // extract scalar with logical vector - vector = generateInteger(4, true); - vector = executeExtract(ElementAccessMode.SUBSET, vector, - new Object[]{RDataFactory.createLogicalVector(new byte[]{RRuntime.LOGICAL_TRUE, RRuntime.LOGICAL_FALSE}, true)}); - assertIndicies(vector, 0, 2); - - // extract vector indexed by logical vector - vector = generateInteger(4, true); - vector = executeExtract(ElementAccessMode.SUBSET, vector, - new Object[]{RDataFactory.createLogicalVector(new byte[]{RRuntime.LOGICAL_TRUE, RRuntime.LOGICAL_FALSE}, true)}); - assertIndicies(vector, 0, 2); - - // extract scalar with integer vector - vector = generateInteger(9, true); - vector = executeExtract(ElementAccessMode.SUBSET, vector, new Object[]{RDataFactory.createIntVector(new int[]{9, 8}, true)}); - assertIndicies(vector, 8, 7); - - // extract scalar with integer scalar - vector = generateInteger(9, true); - vector = executeExtract(ElementAccessMode.SUBSET, vector, new Object[]{RDataFactory.createIntVector(new int[]{9}, true)}); - assertIndicies(vector, 8); - + execInContext(() -> { + RAbstractIntVector vector; + + // extract scalar with logical vector with NA + vector = generateInteger(4, true); + vector = executeExtract(ElementAccessMode.SUBSET, vector, + new Object[]{RDataFactory.createLogicalVector(new byte[]{RRuntime.LOGICAL_TRUE, RRuntime.LOGICAL_NA}, false)}); + assertIndicies(vector, 0, RRuntime.INT_NA, 2, RRuntime.INT_NA); + + // extract scalar with sequence stride=1 + vector = generateInteger(9, true); + vector = executeExtract(ElementAccessMode.SUBSET, vector, new Object[]{RDataFactory.createIntSequence(5, 1, 3)}); + assertIndicies(vector, 4, 5, 6); + + // extract scalar with sequence stride>1 + vector = generateInteger(9, true); + vector = executeExtract(ElementAccessMode.SUBSET, vector, new Object[]{RDataFactory.createIntSequence(5, 2, 2)}); + assertIndicies(vector, 4, 6); + + // extract scalar with negative integer vector + vector = generateInteger(4, true); + vector = executeExtract(ElementAccessMode.SUBSET, vector, new Object[]{RDataFactory.createIntVector(new int[]{-2}, true)}); + assertIndicies(vector, 0, 2, 3); + + // extract scalar with logical scalar + vector = generateInteger(3, true); + vector = executeExtract(ElementAccessMode.SUBSET, vector, + new Object[]{RDataFactory.createLogicalVector(new byte[]{RRuntime.LOGICAL_TRUE}, true)}); + assertIndicies(vector, 0, 1, 2); + + // extract scalar with integer vector with NA + vector = generateInteger(4, true); + vector = executeExtract(ElementAccessMode.SUBSET, vector, + new Object[]{RDataFactory.createIntVector(new int[]{1, RRuntime.INT_NA}, false)}); + assertIndicies(vector, 0, RRuntime.INT_NA); + + // extract scalar with logical vector + vector = generateInteger(4, true); + vector = executeExtract(ElementAccessMode.SUBSET, vector, + new Object[]{RDataFactory.createLogicalVector(new byte[]{RRuntime.LOGICAL_TRUE, RRuntime.LOGICAL_FALSE}, true)}); + assertIndicies(vector, 0, 2); + + // extract vector indexed by logical vector + vector = generateInteger(4, true); + vector = executeExtract(ElementAccessMode.SUBSET, vector, + new Object[]{RDataFactory.createLogicalVector(new byte[]{RRuntime.LOGICAL_TRUE, RRuntime.LOGICAL_FALSE}, true)}); + assertIndicies(vector, 0, 2); + + // extract scalar with integer vector + vector = generateInteger(9, true); + vector = executeExtract(ElementAccessMode.SUBSET, vector, new Object[]{RDataFactory.createIntVector(new int[]{9, 8}, true)}); + assertIndicies(vector, 8, 7); + + // extract scalar with integer scalar + vector = generateInteger(9, true); + vector = executeExtract(ElementAccessMode.SUBSET, vector, new Object[]{RDataFactory.createIntVector(new int[]{9}, true)}); + assertIndicies(vector, 8); + return null; + }); } @Theory public void testNames(RType targetType) { - RAbstractVector vector = generateVector(targetType, 4, true); - - RStringVector names = (RStringVector) generateVector(RType.Character, 4, true); - vector.setNames(names); - RAbstractVector result = executeExtract(ElementAccessMode.SUBSET, vector, RInteger.valueOf(2)); - - RStringVector newNames = result.getNames(); - assertThat(newNames.getLength(), is(1)); - assertThat(newNames.getDataAt(0), is(names.getDataAt(1))); + execInContext(() -> { + RAbstractVector vector = generateVector(targetType, 4, true); + + RStringVector names = (RStringVector) generateVector(RType.Character, 4, true); + vector.setNames(names); + RAbstractVector result = executeExtract(ElementAccessMode.SUBSET, vector, RInteger.valueOf(2)); + + RStringVector newNames = result.getNames(); + assertThat(newNames.getLength(), is(1)); + assertThat(newNames.getDataAt(0), is(names.getDataAt(1))); + return null; + }); } @Theory public void testOutOfBoundsAccess(RType targetType) { - RAbstractVector vector = generateVector(targetType, 4, true); + execInContext(() -> { + RAbstractVector vector = generateVector(targetType, 4, true); - RAbstractVector result = executeExtract(ElementAccessMode.SUBSET, vector, RInteger.valueOf(5)); + RAbstractVector result = executeExtract(ElementAccessMode.SUBSET, vector, RInteger.valueOf(5)); - assertThat(vector.getRType(), is(result.getRType())); - assertThat(result.getLength(), is(1)); - Object expectedValue = targetType.create(1, true).getDataAtAsObject(0); - assertThat(result.getDataAtAsObject(0), is(expectedValue)); + assertThat(vector.getRType(), is(result.getRType())); + assertThat(result.getLength(), is(1)); + Object expectedValue = targetType.create(1, true).getDataAtAsObject(0); + assertThat(result.getDataAtAsObject(0), is(expectedValue)); + return null; + }); } @Theory public void testCompletenessOutOfBounds(RType targetType) { - RAbstractVector vector = generateVector(targetType, 4, true); + execInContext(() -> { + RAbstractVector vector = generateVector(targetType, 4, true); - assumeTrue(targetType != RType.Raw); + assumeTrue(targetType != RType.Raw); - RAbstractVector result = executeExtract(ElementAccessMode.SUBSET, vector, RInteger.valueOf(10)); + RAbstractVector result = executeExtract(ElementAccessMode.SUBSET, vector, RInteger.valueOf(10)); - assertThat(result.isComplete(), is(false)); + assertThat(result.isComplete(), is(false)); + return null; + }); } @Theory public void testCompletenessAfterScalarExtraction(RType targetType) { - RAbstractVector vector = generateVector(targetType, 4, false); + execInContext(() -> { + RAbstractVector vector = generateVector(targetType, 4, false); - assumeTrue(targetType != RType.List); - assumeThat(vector.isComplete(), is(false)); - RAbstractVector result = executeExtract(ElementAccessMode.SUBSET, vector, RInteger.valueOf(1)); + assumeTrue(targetType != RType.List); + assumeThat(vector.isComplete(), is(false)); + RAbstractVector result = executeExtract(ElementAccessMode.SUBSET, vector, RInteger.valueOf(1)); - assertThat(result.isComplete(), is(true)); + // TODO failing - how comes? + assertThat(result.isComplete(), is(true)); + return null; + }); } @Theory @@ -242,43 +259,55 @@ public class ExtractVectorNodeTest extends TestBase { @Theory public void testCompletenessAfterSelectAll(RType targetType) { - RAbstractVector vector = generateVector(targetType, 4, false); + execInContext(() -> { + RAbstractVector vector = generateVector(targetType, 4, false); - assumeThat(vector.isComplete(), is(false)); - RAbstractVector result = executeExtract(ElementAccessMode.SUBSET, vector, RLogical.valueOf(true)); + assumeThat(vector.isComplete(), is(false)); + RAbstractVector result = executeExtract(ElementAccessMode.SUBSET, vector, RLogical.valueOf(true)); - assertThat(result.isComplete(), is(false)); + assertThat(result.isComplete(), is(false)); + return null; + }); } @Theory public void testCompletenessPositionNA(RType targetType) { - RAbstractVector vector = generateVector(targetType, 4, true); + execInContext(() -> { + RAbstractVector vector = generateVector(targetType, 4, true); - RAbstractVector result = executeExtract(ElementAccessMode.SUBSET, vector, RLogical.NA); + RAbstractVector result = executeExtract(ElementAccessMode.SUBSET, vector, RLogical.NA); - assertThat(result.isComplete(), is(false)); + assertThat(result.isComplete(), is(false)); + return null; + }); } @Theory public void testSubsetSingleDimensionTheory(RType targetType, RAbstractVector position) { - assumeTrue(position.getLength() <= 4); - assumeTrue(position.getLength() >= 1); + execInContext(() -> { + assumeTrue(position.getLength() <= 4); + assumeTrue(position.getLength() >= 1); - RAbstractVector vector = generateVector(targetType, 4, true); + RAbstractVector vector = generateVector(targetType, 4, true); - executeExtract(ElementAccessMode.SUBSET, vector, position); + executeExtract(ElementAccessMode.SUBSET, vector, position); + return null; + }); } @Theory public void testSubscriptSingleDimensionTheory(RType targetType, RAbstractVector position) { - assumeTrue(position.getLength() == 1); - if (position instanceof RAbstractIntVector) { - assumeTrue(((RAbstractIntVector) position).getDataAt(0) > 0); - } + execInContext(() -> { + assumeTrue(position.getLength() == 1); + if (position instanceof RAbstractIntVector) { + assumeTrue(((RAbstractIntVector) position).getDataAt(0) > 0); + } - RAbstractVector vector = generateVector(targetType, 4, true); + RAbstractVector vector = generateVector(targetType, 4, true); - executeExtract(ElementAccessMode.SUBSCRIPT, vector, position); + executeExtract(ElementAccessMode.SUBSCRIPT, vector, position); + return null; + }); } private NodeHandle<ExtractVectorNode> handle; diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/access/vector/ReplaceVectorNodeTest.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/access/vector/ReplaceVectorNodeTest.java index c24a265ce6875dbf8b7ae9b5be152e2526f4b60c..d4ef52105a302c7278f335cd0f9f4d6e55753caa 100644 --- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/access/vector/ReplaceVectorNodeTest.java +++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/access/vector/ReplaceVectorNodeTest.java @@ -78,35 +78,38 @@ public class ReplaceVectorNodeTest extends TestBase { @Test public void testSubsetMultiDimension() { - RAbstractIntVector vector; - - // replace rectangle with rectangle indices - vector = generateInteger(20, true); - vector.setDimensions(new int[]{5, 4}); - executeReplace(ElementAccessMode.SUBSET, vector, RInteger.valueOf(-1), - RDataFactory.createIntVector(new int[]{2, 3, 4}, true), RDataFactory.createIntVector(new int[]{2, 3}, true)); - assertIndicies(vector, 0, 1, 2, 3, 4, 5, -1, -1, -1, 9, 10, -1, -1, -1, 14, 15, 16, 17, 18, 19); - - // replace box with box indices - vector = generateInteger(9, true); - vector.setDimensions(new int[]{3, 3}); - executeReplace(ElementAccessMode.SUBSET, vector, RInteger.valueOf(-1), - RDataFactory.createIntVector(new int[]{2, 3}, true), RDataFactory.createIntVector(new int[]{2, 3}, true)); - assertIndicies(vector, 0, 1, 2, 3, -1, -1, 6, -1, -1); - - // replace three dimensions - vector = generateInteger(24, true); - vector.setDimensions(new int[]{2, 3, 4}); - executeReplace(ElementAccessMode.SUBSET, vector, RInteger.valueOf(-1), - RDataFactory.createIntVector(new int[]{2}, true), RDataFactory.createIntVector(new int[]{2}, true), RDataFactory.createIntVector(new int[]{2}, true)); - assertIndicies(vector, 0, 1, 2, 3, 4, 5, 6, 7, 8, -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23); - - // replace three dimensions - vector = generateInteger(24, true); - vector.setDimensions(new int[]{2, 3, 4}); - executeReplace(ElementAccessMode.SUBSET, vector, RInteger.valueOf(-1), - RDataFactory.createIntVector(new int[]{2}, true), RDataFactory.createIntVector(new int[]{2, 3}, true), RDataFactory.createIntVector(new int[]{2, 3, 4}, true)); - assertIndicies(vector, 0, 1, 2, 3, 4, 5, 6, 7, 8, -1, 10, -1, 12, 13, 14, -1, 16, -1, 18, 19, 20, -1, 22, -1); + execInContext(() -> { + RAbstractIntVector vector; + + // replace rectangle with rectangle indices + vector = generateInteger(20, true); + vector.setDimensions(new int[]{5, 4}); + executeReplace(ElementAccessMode.SUBSET, vector, RInteger.valueOf(-1), + RDataFactory.createIntVector(new int[]{2, 3, 4}, true), RDataFactory.createIntVector(new int[]{2, 3}, true)); + assertIndicies(vector, 0, 1, 2, 3, 4, 5, -1, -1, -1, 9, 10, -1, -1, -1, 14, 15, 16, 17, 18, 19); + + // replace box with box indices + vector = generateInteger(9, true); + vector.setDimensions(new int[]{3, 3}); + executeReplace(ElementAccessMode.SUBSET, vector, RInteger.valueOf(-1), + RDataFactory.createIntVector(new int[]{2, 3}, true), RDataFactory.createIntVector(new int[]{2, 3}, true)); + assertIndicies(vector, 0, 1, 2, 3, -1, -1, 6, -1, -1); + + // replace three dimensions + vector = generateInteger(24, true); + vector.setDimensions(new int[]{2, 3, 4}); + executeReplace(ElementAccessMode.SUBSET, vector, RInteger.valueOf(-1), + RDataFactory.createIntVector(new int[]{2}, true), RDataFactory.createIntVector(new int[]{2}, true), RDataFactory.createIntVector(new int[]{2}, true)); + assertIndicies(vector, 0, 1, 2, 3, 4, 5, 6, 7, 8, -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23); + + // replace three dimensions + vector = generateInteger(24, true); + vector.setDimensions(new int[]{2, 3, 4}); + executeReplace(ElementAccessMode.SUBSET, vector, RInteger.valueOf(-1), + RDataFactory.createIntVector(new int[]{2}, true), RDataFactory.createIntVector(new int[]{2, 3}, true), RDataFactory.createIntVector(new int[]{2, 3, 4}, true)); + assertIndicies(vector, 0, 1, 2, 3, 4, 5, 6, 7, 8, -1, 10, -1, 12, 13, 14, -1, 16, -1, 18, 19, 20, -1, 22, -1); + return null; + }); } private static void assertIndicies(RAbstractIntVector vector, int... expectedValues) { @@ -120,154 +123,180 @@ public class ReplaceVectorNodeTest extends TestBase { @Test public void testSubsetSingleDimension() { - RAbstractIntVector vector; - - // replace scalar with sequence stride=1 - vector = generateInteger(9, true); - executeReplace(ElementAccessMode.SUBSET, vector, RInteger.valueOf(-1), new Object[]{RDataFactory.createIntSequence(5, 1, 3)}); - assertIndicies(vector, 0, 1, 2, 3, -1, -1, -1, 7, 8); - - // replace scalar with sequence stride>1 - vector = generateInteger(9, true); - executeReplace(ElementAccessMode.SUBSET, vector, RInteger.valueOf(-1), new Object[]{RDataFactory.createIntSequence(5, 2, 2)}); - assertIndicies(vector, 0, 1, 2, 3, -1, 5, -1, 7, 8); - - // replace scalar with negative integer vector - vector = generateInteger(4, true); - executeReplace(ElementAccessMode.SUBSET, vector, RInteger.valueOf(-1), new Object[]{RDataFactory.createIntVector(new int[]{-2}, true)}); - assertIndicies(vector, -1, 1, -1, -1); - - // replace scalar with logical scalar - vector = generateInteger(3, true); - executeReplace(ElementAccessMode.SUBSET, vector, RInteger.valueOf(-1), - new Object[]{RDataFactory.createLogicalVector(new byte[]{RRuntime.LOGICAL_TRUE}, true)}); - assertIndicies(vector, -1, -1, -1); - - // replace scalar with logical vector - vector = generateInteger(4, true); - executeReplace(ElementAccessMode.SUBSET, vector, RInteger.valueOf(-1), - new Object[]{RDataFactory.createLogicalVector(new byte[]{RRuntime.LOGICAL_TRUE, RRuntime.LOGICAL_FALSE}, true)}); - assertIndicies(vector, -1, 1, -1, 3); - - // replace vector indexed by logical vector - vector = generateInteger(4, true); - executeReplace(ElementAccessMode.SUBSET, vector, RDataFactory.createIntVector(new int[]{-1, -2}, true), - new Object[]{RDataFactory.createLogicalVector(new byte[]{RRuntime.LOGICAL_TRUE, RRuntime.LOGICAL_FALSE}, true)}); - assertIndicies(vector, -1, 1, -2, 3); - - // replace scalar with integer vector - vector = generateInteger(9, true); - executeReplace(ElementAccessMode.SUBSET, vector, RInteger.valueOf(-1), new Object[]{RDataFactory.createIntVector(new int[]{9, 8}, true)}); - assertIndicies(vector, 0, 1, 2, 3, 4, 5, 6, -1, -1); - - // replace scalar with integer scalar - vector = generateInteger(9, true); - executeReplace(ElementAccessMode.SUBSET, vector, RInteger.valueOf(-1), new Object[]{RDataFactory.createIntVector(new int[]{9}, true)}); - assertIndicies(vector, 0, 1, 2, 3, 4, 5, 6, 7, -1); + execInContext(() -> { + RAbstractIntVector vector; + + // replace scalar with sequence stride=1 + vector = generateInteger(9, true); + executeReplace(ElementAccessMode.SUBSET, vector, RInteger.valueOf(-1), new Object[]{RDataFactory.createIntSequence(5, 1, 3)}); + assertIndicies(vector, 0, 1, 2, 3, -1, -1, -1, 7, 8); + + // replace scalar with sequence stride>1 + vector = generateInteger(9, true); + executeReplace(ElementAccessMode.SUBSET, vector, RInteger.valueOf(-1), new Object[]{RDataFactory.createIntSequence(5, 2, 2)}); + assertIndicies(vector, 0, 1, 2, 3, -1, 5, -1, 7, 8); + + // replace scalar with negative integer vector + vector = generateInteger(4, true); + executeReplace(ElementAccessMode.SUBSET, vector, RInteger.valueOf(-1), new Object[]{RDataFactory.createIntVector(new int[]{-2}, true)}); + assertIndicies(vector, -1, 1, -1, -1); + + // replace scalar with logical scalar + vector = generateInteger(3, true); + executeReplace(ElementAccessMode.SUBSET, vector, RInteger.valueOf(-1), + new Object[]{RDataFactory.createLogicalVector(new byte[]{RRuntime.LOGICAL_TRUE}, true)}); + assertIndicies(vector, -1, -1, -1); + + // replace scalar with logical vector + vector = generateInteger(4, true); + executeReplace(ElementAccessMode.SUBSET, vector, RInteger.valueOf(-1), + new Object[]{RDataFactory.createLogicalVector(new byte[]{RRuntime.LOGICAL_TRUE, RRuntime.LOGICAL_FALSE}, true)}); + assertIndicies(vector, -1, 1, -1, 3); + + // replace vector indexed by logical vector + vector = generateInteger(4, true); + executeReplace(ElementAccessMode.SUBSET, vector, RDataFactory.createIntVector(new int[]{-1, -2}, true), + new Object[]{RDataFactory.createLogicalVector(new byte[]{RRuntime.LOGICAL_TRUE, RRuntime.LOGICAL_FALSE}, true)}); + assertIndicies(vector, -1, 1, -2, 3); + + // replace scalar with integer vector + vector = generateInteger(9, true); + executeReplace(ElementAccessMode.SUBSET, vector, RInteger.valueOf(-1), new Object[]{RDataFactory.createIntVector(new int[]{9, 8}, true)}); + assertIndicies(vector, 0, 1, 2, 3, 4, 5, 6, -1, -1); + + // replace scalar with integer scalar + vector = generateInteger(9, true); + executeReplace(ElementAccessMode.SUBSET, vector, RInteger.valueOf(-1), new Object[]{RDataFactory.createIntVector(new int[]{9}, true)}); + assertIndicies(vector, 0, 1, 2, 3, 4, 5, 6, 7, -1); + return null; + }); } @Theory public void testNames(RType targetType) { - RAbstractVector vector = generateVector(targetType, 4, true); - RStringVector names = (RStringVector) generateVector(RType.Character, 4, true); - vector.setNames(names); - - RAbstractVector value = generateVector(targetType, 4, true); - RStringVector valueNames = (RStringVector) generateVector(RType.Character, 4, true); - value.setNames(valueNames); - - RAbstractVector result = executeReplace(ElementAccessMode.SUBSET, vector, value, RLogical.TRUE); - - RStringVector newNames = result.getNames(); - assertThat(newNames.getLength(), is(names.getLength())); - assertThat(newNames.getDataAt(0), is(names.getDataAt(0))); - assertThat(newNames.getDataAt(1), is(names.getDataAt(1))); - assertThat(newNames.getDataAt(2), is(names.getDataAt(2))); - assertThat(newNames.getDataAt(3), is(names.getDataAt(3))); + execInContext(() -> { + RAbstractVector vector = generateVector(targetType, 4, true); + RStringVector names = (RStringVector) generateVector(RType.Character, 4, true); + vector.setNames(names); + + RAbstractVector value = generateVector(targetType, 4, true); + RStringVector valueNames = (RStringVector) generateVector(RType.Character, 4, true); + value.setNames(valueNames); + + RAbstractVector result = executeReplace(ElementAccessMode.SUBSET, vector, value, RLogical.TRUE); + + RStringVector newNames = result.getNames(); + assertThat(newNames.getLength(), is(names.getLength())); + assertThat(newNames.getDataAt(0), is(names.getDataAt(0))); + assertThat(newNames.getDataAt(1), is(names.getDataAt(1))); + assertThat(newNames.getDataAt(2), is(names.getDataAt(2))); + assertThat(newNames.getDataAt(3), is(names.getDataAt(3))); + return null; + }); } @Theory public void testCompletenessAfterReplace(RType targetType) { - RAbstractVector vector = generateVector(targetType, 4, false); - RAbstractVector replaceWith = generateVector(targetType, 1, true); - - assumeThat(vector.isComplete(), is(false)); - RAbstractVector result = executeReplace(ElementAccessMode.SUBSET, vector, replaceWith, RInteger.valueOf(1)); - assertThat(result.isComplete(), is(false)); + execInContext(() -> { + RAbstractVector vector = generateVector(targetType, 4, false); + RAbstractVector replaceWith = generateVector(targetType, 1, true); + + assumeThat(vector.isComplete(), is(false)); + RAbstractVector result = executeReplace(ElementAccessMode.SUBSET, vector, replaceWith, RInteger.valueOf(1)); + assertThat(result.isComplete(), is(false)); + return null; + }); } @Theory public void testCompletenessAfterReplaceAll(RType targetType) { - RAbstractVector vector = generateVector(targetType, 4, false); - RAbstractVector replaceWith = generateVector(targetType, 1, true); + execInContext(() -> { + RAbstractVector vector = generateVector(targetType, 4, false); + RAbstractVector replaceWith = generateVector(targetType, 1, true); - assumeThat(vector.isComplete(), is(false)); - executeReplace(ElementAccessMode.SUBSET, vector, replaceWith, RLogical.valueOf(true)); + assumeThat(vector.isComplete(), is(false)); + executeReplace(ElementAccessMode.SUBSET, vector, replaceWith, RLogical.valueOf(true)); - // TODO we would need to find out if we replace all elements. we should support this. - // assertThat(result.isComplete(), is(true)); + // TODO we would need to find out if we replace all elements. we should support this. + // assertThat(result.isComplete(), is(true)); + return null; + }); } @Theory public void testCompletenessPositionNA(RType targetType) { - RAbstractVector vector = generateVector(targetType, 4, true); - RAbstractVector replaceWith = generateVector(targetType, 1, true); + execInContext(() -> { + RAbstractVector vector = generateVector(targetType, 4, true); + RAbstractVector replaceWith = generateVector(targetType, 1, true); - RAbstractVector result = executeReplace(ElementAccessMode.SUBSET, vector, replaceWith, RLogical.NA); + RAbstractVector result = executeReplace(ElementAccessMode.SUBSET, vector, replaceWith, RLogical.NA); - assertThat(result.isComplete(), is(true)); + assertThat(result.isComplete(), is(true)); + return null; + }); } @Theory public void testCompletenessOutOfBounds(RType targetType) { - assumeTrue(targetType != RType.Raw); - RAbstractVector vector = generateVector(targetType, 4, true); - RAbstractVector replaceWith = generateVector(targetType, 1, true); + execInContext(() -> { + assumeTrue(targetType != RType.Raw); + RAbstractVector vector = generateVector(targetType, 4, true); + RAbstractVector replaceWith = generateVector(targetType, 1, true); - RAbstractVector result = executeReplace(ElementAccessMode.SUBSET, vector, replaceWith, RInteger.valueOf(10)); + RAbstractVector result = executeReplace(ElementAccessMode.SUBSET, vector, replaceWith, RInteger.valueOf(10)); - assertThat(result.isComplete(), is(false)); + assertThat(result.isComplete(), is(false)); + return null; + }); } @Theory public void testCasts(RType targetType, RType valueType) { - if (targetType != valueType) { - assumeTrue(targetType != RType.Raw && valueType != RType.Raw); - } - RType resultType = RType.maxPrecedence(targetType, valueType); - - RAbstractVector vector = generateVector(targetType, 4, true); - RAbstractVector value = generateVector(valueType, 4, true); - - RAbstractVector result = executeReplace(ElementAccessMode.SUBSET, vector, value, accessFirst); - assertThat(result.getRType(), is(resultType)); + execInContext(() -> { + if (targetType != valueType) { + assumeTrue(targetType != RType.Raw && valueType != RType.Raw); + } + RType resultType = RType.maxPrecedence(targetType, valueType); + + RAbstractVector vector = generateVector(targetType, 4, true); + RAbstractVector value = generateVector(valueType, 4, true); + + RAbstractVector result = executeReplace(ElementAccessMode.SUBSET, vector, value, accessFirst); + assertThat(result.getRType(), is(resultType)); + return null; + }); } @Theory public void testSubsetSingleDimensionTheory(RType targetType, RAbstractVector position) { - assumeTrue(position.getLength() <= 4); - assumeTrue(position.getLength() >= 1); - assumeTrue(position.isComplete()); - - RAbstractVector vector = generateVector(targetType, 4, true); - RAbstractVector value = generateVector(targetType, 4, true); - - RAbstractVector result = executeReplace(ElementAccessMode.SUBSET, vector, value, position); - assertThat(result, is(sameInstance(vector))); + execInContext(() -> { + assumeTrue(position.getLength() <= 4); + assumeTrue(position.getLength() >= 1); + assumeTrue(position.isComplete()); + + RAbstractVector vector = generateVector(targetType, 4, true); + RAbstractVector value = generateVector(targetType, 4, true); + + RAbstractVector result = executeReplace(ElementAccessMode.SUBSET, vector, value, position); + assertThat(result, is(sameInstance(vector))); + return null; + }); } @Theory public void testSubscriptSingleDimensionTheory(RType targetType, RAbstractVector position) { - assumeTrue(position.getLength() == 1); - if (position instanceof RAbstractIntVector) { - assumeTrue(((RAbstractIntVector) position).getDataAt(0) > 0); - } - - RAbstractVector vector = generateVector(targetType, 4, true); - RAbstractVector value = generateVector(targetType, 1, true); - - executeReplace(ElementAccessMode.SUBSCRIPT, vector, value, position); - + execInContext(() -> { + assumeTrue(position.getLength() == 1); + if (position instanceof RAbstractIntVector) { + assumeTrue(((RAbstractIntVector) position).getDataAt(0) > 0); + } + + RAbstractVector vector = generateVector(targetType, 4, true); + RAbstractVector value = generateVector(targetType, 1, true); + + executeReplace(ElementAccessMode.SUBSCRIPT, vector, value, position); + return null; + }); } private NodeHandle<ReplaceVectorNode> handle; diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/access/vector/StringCompareNodeTest.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/access/vector/StringCompareNodeTest.java index 2f6c991611688d85770fd5ba02941ad47293f980..92a9a38287ce6952ccf146b29986856edde796e4 100644 --- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/access/vector/StringCompareNodeTest.java +++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/access/vector/StringCompareNodeTest.java @@ -53,37 +53,49 @@ public class StringCompareNodeTest extends TestBase { @Theory public void testExactNA(String a, String b) { - assumeTrue(a == RRuntime.STRING_NA || b == RRuntime.STRING_NA); - try { - executeCompare(true, a, b); - Assert.fail(); - } catch (AssertionError e) { - } + execInContext(() -> { + assumeTrue(a == RRuntime.STRING_NA || b == RRuntime.STRING_NA); + try { + executeCompare(true, a, b); + Assert.fail(); + } catch (AssertionError e) { + } + return null; + }); } @Theory public void testNonExactNA(String a, String b) { - assumeTrue(a == RRuntime.STRING_NA || b == RRuntime.STRING_NA); - try { - executeCompare(false, a, b); - Assert.fail(); - } catch (AssertionError e) { - } + execInContext(() -> { + assumeTrue(a == RRuntime.STRING_NA || b == RRuntime.STRING_NA); + try { + executeCompare(false, a, b); + Assert.fail(); + } catch (AssertionError e) { + } + return null; + }); } @Theory public void testExact(String a, String b) { - assumeFalse(a == RRuntime.STRING_NA); - assumeFalse(b == RRuntime.STRING_NA); - assertThat(executeCompare(true, a, b), is(a.equals(b))); - assertThat(executeHashCompare(a, b), is(a.equals(b))); + execInContext(() -> { + assumeFalse(a == RRuntime.STRING_NA); + assumeFalse(b == RRuntime.STRING_NA); + assertThat(executeCompare(true, a, b), is(a.equals(b))); + assertThat(executeHashCompare(a, b), is(a.equals(b))); + return null; + }); } @Theory public void testNonExact(String a, String b) { - assumeFalse(a == RRuntime.STRING_NA); - assumeFalse(b == RRuntime.STRING_NA); - assertThat(executeCompare(false, a, b), is(a.startsWith(b))); + execInContext(() -> { + assumeFalse(a == RRuntime.STRING_NA); + assumeFalse(b == RRuntime.STRING_NA); + assertThat(executeCompare(false, a, b), is(a.startsWith(b))); + return null; + }); } private static boolean executeCompare(boolean exact, String a, String b) { diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/access/vector/StringSearchNodeTest.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/access/vector/StringSearchNodeTest.java index b21b9db9f9ccd197dd66130195cef4a90acabda7..e4be7c16f46bba9887b21971b3c69860e8a8d7ee 100644 --- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/access/vector/StringSearchNodeTest.java +++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/access/vector/StringSearchNodeTest.java @@ -51,26 +51,29 @@ public class StringSearchNodeTest extends TestBase { @Theory public void testTheory(String aString, String bString, String cString) { - create(); + execInContext(() -> { + create(); - RAbstractStringVector a; - RAbstractStringVector b; + RAbstractStringVector a; + RAbstractStringVector b; - a = createVector(aString); - b = createVector(bString); - assertResult(a, b, executeSearch(a, b)); + a = createVector(aString); + b = createVector(bString); + assertResult(a, b, executeSearch(a, b)); - a = createVector(aString, bString); - b = createVector(cString); - assertResult(a, b, executeSearch(a, b)); + a = createVector(aString, bString); + b = createVector(cString); + assertResult(a, b, executeSearch(a, b)); - a = createVector(aString); - b = createVector(bString, cString); - assertResult(a, b, executeSearch(a, b)); + a = createVector(aString); + b = createVector(bString, cString); + assertResult(a, b, executeSearch(a, b)); - a = createVector(aString, bString); - b = createVector(bString, cString); - assertResult(a, b, executeSearch(a, b)); + a = createVector(aString, bString); + b = createVector(bString, cString); + assertResult(a, b, executeSearch(a, b)); + return null; + }); } private static RAbstractStringVector createVector(String... elements) { diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/casts/TestCasts.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/casts/TestCasts.java index 400b54cc0e1517c9ea9a477da8fe39c7dd670d18..bbdb6a7d760fd3f30394b0e62bf90fb0c4fb1452 100644 --- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/casts/TestCasts.java +++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/casts/TestCasts.java @@ -67,7 +67,7 @@ import com.oracle.truffle.r.runtime.nodes.RSyntaxNode; /* * * example command line: - * mx --J @'-Dgraal.Dump=HighTier:1 -Dgraal.MethodFilter=*TestCasts* -Dgraal.TraceTruffleCompilation=true -Dgraal.PrintBackendCFG=false' junits --tests TestCasts + * mx --J @'-Dgraal.Dump=HighTier:1 -Dgraal.MethodFilter=*TestCasts* -Dgraal.TraceTruffleCompilation=true -Dgraal.PrintBackendCFG=false' unittest TestCasts * * of course, Graal needs to be imported for this to work: * DEFAULT_DYNAMIC_IMPORTS=compiler (or graal-enterprise) @@ -159,9 +159,12 @@ public class TestCasts extends TestBase { return new Integer((int) node.doCast(value)); } } - testCompilation(new Object[]{1, 2, 3}, new Root("FirstInteger")); - testCompilation(new Object[]{1, 2, RDataFactory.createIntVectorFromScalar(55)}, new Root("FirstIntegerWithVectors")); - testCompilation(new Object[]{1.2, 2, (byte) 1}, new Root("FirstIntegerWithCoerce")); + execInContext(() -> { + testCompilation(new Object[]{1, 2, 3}, new Root("FirstInteger")); + testCompilation(new Object[]{1, 2, RDataFactory.createIntVectorFromScalar(55)}, new Root("FirstIntegerWithVectors")); + testCompilation(new Object[]{1.2, 2, (byte) 1}, new Root("FirstIntegerWithCoerce")); + return null; + }); } @Test @@ -182,9 +185,12 @@ public class TestCasts extends TestBase { return null; } } - testCompilation(new Object[]{1}, new Root("FirstIntegerWithConstant", 1)); - testCompilation(new Object[]{1}, new Root("FirstIntegerWithConstant", 44.5)); - testCompilation(new Object[]{1}, new Root("FirstIntegerWithConstant", (byte) 1)); + execInContext(() -> { + testCompilation(new Object[]{1}, new Root("FirstIntegerWithConstant", 1)); + testCompilation(new Object[]{1}, new Root("FirstIntegerWithConstant", 44.5)); + testCompilation(new Object[]{1}, new Root("FirstIntegerWithConstant", (byte) 1)); + return null; + }); } @Test @@ -201,8 +207,11 @@ public class TestCasts extends TestBase { return res; } } - testCompilation(new Object[]{1, 2, 3}, new Root("MustBeInteger")); - testCompilation(new Object[]{1, 2, RDataFactory.createIntVectorFromScalar(55)}, new Root("MustBeIntegerWithVectors")); + execInContext(() -> { + testCompilation(new Object[]{1, 2, 3}, new Root("MustBeInteger")); + testCompilation(new Object[]{1, 2, RDataFactory.createIntVectorFromScalar(55)}, new Root("MustBeIntegerWithVectors")); + return null; + }); } @Test @@ -219,8 +228,11 @@ public class TestCasts extends TestBase { return res; } } - testCompilation(new Object[]{RNull.instance}, new Root("MapDefaultValueNull")); - testCompilation(new Object[]{1}, new Root("MapDefaultValueNonNull")); + execInContext(() -> { + testCompilation(new Object[]{RNull.instance}, new Root("MapDefaultValueNull")); + testCompilation(new Object[]{1}, new Root("MapDefaultValueNonNull")); + return null; + }); } @Test @@ -237,8 +249,11 @@ public class TestCasts extends TestBase { return res; } } - testCompilation(new Object[]{"abc"}, new Root("MapCharAt0NonEmptyString")); - testCompilation(new Object[]{""}, new Root("MapCharAt0EmptyString")); + execInContext(() -> { + testCompilation(new Object[]{"abc"}, new Root("MapCharAt0NonEmptyString")); + testCompilation(new Object[]{""}, new Root("MapCharAt0EmptyString")); + return null; + }); } @Test @@ -261,8 +276,11 @@ public class TestCasts extends TestBase { return res; } } - testCompilation(new Object[]{1, 2, 3}, new Root("MapConstantInt", true)); - testCompilation(new Object[]{"abc"}, new Root("MapConstantNoInt", false)); + execInContext(() -> { + testCompilation(new Object[]{1, 2, 3}, new Root("MapConstantInt", true)); + testCompilation(new Object[]{"abc"}, new Root("MapConstantNoInt", false)); + return null; + }); } @Test @@ -283,7 +301,10 @@ public class TestCasts extends TestBase { return null; } } - testCompilation(new Object[]{1}, new Root("MustBeWithConstant", 1)); + execInContext(() -> { + testCompilation(new Object[]{1}, new Root("MustBeWithConstant", 1)); + return null; + }); } @Test @@ -304,7 +325,10 @@ public class TestCasts extends TestBase { return null; } } - testCompilation(new Object[]{1}, new Root("optimizeBypass1", 1)); + execInContext(() -> { + testCompilation(new Object[]{1}, new Root("optimizeBypass1", 1)); + return null; + }); } @Test @@ -327,11 +351,14 @@ public class TestCasts extends TestBase { return null; } } - testCompilation(new Object[]{1}, new Root("ConditionalMapChainWithIntegerConstant", 1)); - testCompilation(new Object[]{1}, new Root("ConditionalMapChainWithStringConstant", "aaa")); - testCompilation(new Object[]{1}, new Root("ConditionalMapChainWithLogicalConstant", RRuntime.LOGICAL_TRUE)); - testCompilation(new Object[]{1}, new Root("ConditionalMapChainWithDoubleConstant1", 1.2)); - testCompilation(new Object[]{1}, new Root("ConditionalMapChainWithDoubleConstant2", Math.PI)); + execInContext(() -> { + testCompilation(new Object[]{1}, new Root("ConditionalMapChainWithIntegerConstant", 1)); + testCompilation(new Object[]{1}, new Root("ConditionalMapChainWithStringConstant", "aaa")); + testCompilation(new Object[]{1}, new Root("ConditionalMapChainWithLogicalConstant", RRuntime.LOGICAL_TRUE)); + testCompilation(new Object[]{1}, new Root("ConditionalMapChainWithDoubleConstant1", 1.2)); + testCompilation(new Object[]{1}, new Root("ConditionalMapChainWithDoubleConstant2", Math.PI)); + return null; + }); } @Test @@ -350,24 +377,27 @@ public class TestCasts extends TestBase { return null; } } - testCompilation(new Object[]{1, 2, 3}, new Root("ConditionalMapChainFedByInteger1"), 1.1, "abc", RRuntime.LOGICAL_FALSE); - testCompilation(new Object[]{1, RDataFactory.createIntVector(new int[]{55, 66}, true), - RDataFactory.createIntVectorFromScalar(77)}, new Root( - "ConditionalMapChainFedByInteger2"), - 1.1, "abc", RRuntime.LOGICAL_FALSE); - testCompilation(new Object[]{1.1, 2.2, 3.3}, new Root("ConditionalMapChainFedByDouble1"), 1, "abc", RRuntime.LOGICAL_FALSE); - testCompilation(new Object[]{1.1, RDataFactory.createDoubleVector(new double[]{55.55, 66.66}, - true), RDataFactory.createDoubleVectorFromScalar(77.77)}, new Root( - "ConditionalMapChainFedByDouble2"), - 1, "abc", RRuntime.LOGICAL_FALSE); - testCompilation(new Object[]{RRuntime.LOGICAL_TRUE, RRuntime.LOGICAL_FALSE, - RRuntime.LOGICAL_TRUE}, new Root("ConditionalMapChainFedByLogical1"), 1, "abc", 1.1); - testCompilation(new Object[]{RRuntime.LOGICAL_FALSE, RDataFactory.createLogicalVector(new byte[]{RRuntime.LOGICAL_FALSE, RRuntime.LOGICAL_TRUE}, true), - RDataFactory.createLogicalVectorFromScalar(RRuntime.LOGICAL_FALSE)}, new Root("ConditionalMapChainFedByLogical2"), 1, "abc", 1.1); - testCompilation(new Object[]{"", "abc", "xyz"}, new Root("ConditionalMapChainFedByString1"), 1.1, 1, RRuntime.LOGICAL_FALSE); - testCompilation(new Object[]{"abc", RDataFactory.createStringVector(new String[]{"", "xyz"}, - true), - RDataFactory.createStringVectorFromScalar("abc")}, new Root("ConditionalMapChainFedByString2"), 1.1, 1, RRuntime.LOGICAL_FALSE); + execInContext(() -> { + testCompilation(new Object[]{1, 2, 3}, new Root("ConditionalMapChainFedByInteger1"), 1.1, "abc", RRuntime.LOGICAL_FALSE); + testCompilation(new Object[]{1, RDataFactory.createIntVector(new int[]{55, 66}, true), + RDataFactory.createIntVectorFromScalar(77)}, new Root( + "ConditionalMapChainFedByInteger2"), + 1.1, "abc", RRuntime.LOGICAL_FALSE); + testCompilation(new Object[]{1.1, 2.2, 3.3}, new Root("ConditionalMapChainFedByDouble1"), 1, "abc", RRuntime.LOGICAL_FALSE); + testCompilation(new Object[]{1.1, RDataFactory.createDoubleVector(new double[]{55.55, 66.66}, + true), RDataFactory.createDoubleVectorFromScalar(77.77)}, new Root( + "ConditionalMapChainFedByDouble2"), + 1, "abc", RRuntime.LOGICAL_FALSE); + testCompilation(new Object[]{RRuntime.LOGICAL_TRUE, RRuntime.LOGICAL_FALSE, + RRuntime.LOGICAL_TRUE}, new Root("ConditionalMapChainFedByLogical1"), 1, "abc", 1.1); + testCompilation(new Object[]{RRuntime.LOGICAL_FALSE, RDataFactory.createLogicalVector(new byte[]{RRuntime.LOGICAL_FALSE, RRuntime.LOGICAL_TRUE}, true), + RDataFactory.createLogicalVectorFromScalar(RRuntime.LOGICAL_FALSE)}, new Root("ConditionalMapChainFedByLogical2"), 1, "abc", 1.1); + testCompilation(new Object[]{"", "abc", "xyz"}, new Root("ConditionalMapChainFedByString1"), 1.1, 1, RRuntime.LOGICAL_FALSE); + testCompilation(new Object[]{"abc", RDataFactory.createStringVector(new String[]{"", "xyz"}, + true), + RDataFactory.createStringVectorFromScalar("abc")}, new Root("ConditionalMapChainFedByString2"), 1.1, 1, RRuntime.LOGICAL_FALSE); + return null; + }); } @Test @@ -386,8 +416,11 @@ public class TestCasts extends TestBase { return null; } } - testCompilation(new Object[]{RDataFactory.createStringVectorFromScalar("")}, new Root("ComplexPipeline2EmptyString")); - testCompilation(new Object[]{RDataFactory.createStringVectorFromScalar("a")}, new Root("ComplexPipeline2OneCharString")); + execInContext(() -> { + testCompilation(new Object[]{RDataFactory.createStringVectorFromScalar("")}, new Root("ComplexPipeline2EmptyString")); + testCompilation(new Object[]{RDataFactory.createStringVectorFromScalar("a")}, new Root("ComplexPipeline2OneCharString")); + return null; + }); } @Test @@ -405,8 +438,11 @@ public class TestCasts extends TestBase { return null; } } - testCompilation(new Object[]{1, 2, 3}, new Root("FilterOrExpressionInt")); - testCompilation(new Object[]{"aaa", "bbb", "ccc"}, new Root("FilterOrString")); + execInContext(() -> { + testCompilation(new Object[]{1, 2, 3}, new Root("FilterOrExpressionInt")); + testCompilation(new Object[]{"aaa", "bbb", "ccc"}, new Root("FilterOrString")); + return null; + }); } @Test @@ -424,7 +460,10 @@ public class TestCasts extends TestBase { return null; } } - testCompilation(new Object[]{-1, 20, -3}, new Root("FilterAndExpressionOutOfRange")); + execInContext(() -> { + testCompilation(new Object[]{-1, 20, -3}, new Root("FilterAndExpressionOutOfRange")); + return null; + }); } @Test @@ -442,7 +481,10 @@ public class TestCasts extends TestBase { return null; } } - testCompilation(new Object[]{1, 2, 3}, new Root("FilterNotAndExpressionOutOfRange")); + execInContext(() -> { + testCompilation(new Object[]{1, 2, 3}, new Root("FilterNotAndExpressionOutOfRange")); + return null; + }); } @Test @@ -462,6 +504,9 @@ public class TestCasts extends TestBase { return null; } } - testCompilation(new Object[]{RDataFactory.createIntVectorFromScalar(1)}, new Root("ComplexPipeline3SingleInt")); + execInContext(() -> { + testCompilation(new Object[]{RDataFactory.createIntVectorFromScalar(1)}, new Root("ComplexPipeline3SingleInt")); + return null; + }); } } diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/BinaryArithmeticNodeTest.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/BinaryArithmeticNodeTest.java index 285845a82e7a1937886bc9016be8dbf157a3ddc7..9aa867627522d851b0dd6f8ac7535a75ad47312d 100644 --- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/BinaryArithmeticNodeTest.java +++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/BinaryArithmeticNodeTest.java @@ -94,67 +94,76 @@ public class BinaryArithmeticNodeTest extends BinaryVectorTest { @Theory public void testScalarUnboxing(BinaryArithmeticFactory factory, RScalarVector aOrig, RAbstractVector bOrig) { - RAbstractVector a = withinTestContext(() -> aOrig.copy()); - RAbstractVector b = copy(bOrig); - // unboxing cannot work if length is 1 - assumeThat(b.getLength(), is(1)); - - // if the right side is shareable these should be prioritized - assumeThat(b, is(not(instanceOf(RShareable.class)))); - - assumeArithmeticCompatible(factory, a, b); - Object result = executeArithmetic(factory, a, b); - Assert.assertTrue(isPrimitive(result)); + execInContext(() -> { + RAbstractVector a = withinTestContext(() -> aOrig.copy()); + RAbstractVector b = copy(bOrig); + // unboxing cannot work if length is 1 + assumeThat(b.getLength(), is(1)); + + // if the right side is shareable these should be prioritized + assumeThat(b, is(not(instanceOf(RShareable.class)))); + + assumeArithmeticCompatible(factory, a, b); + Object result = executeArithmetic(factory, a, b); + Assert.assertTrue(isPrimitive(result)); + return null; + }); } @Theory public void testVectorResult(BinaryArithmeticFactory factory, RAbstractVector aOrig, RAbstractVector bOrig) { - RAbstractVector a = copy(aOrig); - RAbstractVector b = copy(bOrig); - assumeThat(a, is(not(instanceOf(RScalarVector.class)))); - assumeThat(b, is(not(instanceOf(RScalarVector.class)))); - assumeArithmeticCompatible(factory, a, b); - - Object result = executeArithmetic(factory, a, b); - Assert.assertFalse(isPrimitive(result)); - assertLengthAndType(factory, a, b, (RAbstractVector) result); - - assumeThat(b, is(not(instanceOf(RScalarVector.class)))); - result = executeArithmetic(factory, b, a); - assertLengthAndType(factory, a, b, (RAbstractVector) result); + execInContext(() -> { + RAbstractVector a = copy(aOrig); + RAbstractVector b = copy(bOrig); + assumeThat(a, is(not(instanceOf(RScalarVector.class)))); + assumeThat(b, is(not(instanceOf(RScalarVector.class)))); + assumeArithmeticCompatible(factory, a, b); + + Object result = executeArithmetic(factory, a, b); + Assert.assertFalse(isPrimitive(result)); + assertLengthAndType(factory, a, b, (RAbstractVector) result); + + assumeThat(b, is(not(instanceOf(RScalarVector.class)))); + result = executeArithmetic(factory, b, a); + assertLengthAndType(factory, a, b, (RAbstractVector) result); + return null; + }); } @Theory public void testSharing(BinaryArithmeticFactory factory, RAbstractVector aOrig, RAbstractVector bOrig) { - RAbstractVector a = copy(aOrig); - RAbstractVector b = copy(bOrig); - assumeArithmeticCompatible(factory, a, b); - - // not part of this test, see #testEmptyArrays - assumeThat(a.getLength(), is(not(0))); - assumeThat(b.getLength(), is(not(0))); - - // sharing does not work if a is a scalar vector - assumeThat(a, is(not(instanceOf(RScalarVector.class)))); - - RType resultType = getResultType(factory, a, b); - int maxLength = Integer.max(a.getLength(), b.getLength()); - RAbstractVector sharedResult = null; - if (a.getLength() == maxLength && isShareable(a, resultType)) { - sharedResult = a; - } - if (sharedResult == null && b.getLength() == maxLength && isShareable(b, resultType)) { - sharedResult = b; - } + execInContext(() -> { + RAbstractVector a = copy(aOrig); + RAbstractVector b = copy(bOrig); + assumeArithmeticCompatible(factory, a, b); + + // not part of this test, see #testEmptyArrays + assumeThat(a.getLength(), is(not(0))); + assumeThat(b.getLength(), is(not(0))); + + // sharing does not work if a is a scalar vector + assumeThat(a, is(not(instanceOf(RScalarVector.class)))); + + RType resultType = getResultType(factory, a, b); + int maxLength = Integer.max(a.getLength(), b.getLength()); + RAbstractVector sharedResult = null; + if (a.getLength() == maxLength && isShareable(a, resultType)) { + sharedResult = a; + } + if (sharedResult == null && b.getLength() == maxLength && isShareable(b, resultType)) { + sharedResult = b; + } - Object result = executeArithmetic(factory, a, b); + Object result = executeArithmetic(factory, a, b); - if (sharedResult == null) { - Assert.assertNotSame(a, result); - Assert.assertNotSame(b, result); - } else { - Assert.assertSame(sharedResult, result); - } + if (sharedResult == null) { + Assert.assertNotSame(a, result); + Assert.assertNotSame(b, result); + } else { + Assert.assertSame(sharedResult, result); + } + return null; + }); } private static boolean isShareable(RAbstractVector a, RType resultType) { @@ -191,136 +200,156 @@ public class BinaryArithmeticNodeTest extends BinaryVectorTest { @Theory public void testEmptyArrays(BinaryArithmeticFactory factory, RAbstractVector originalVector) { - RAbstractVector vector = withinTestContext(() -> originalVector.copy()); - testEmptyArray(factory, vector, createEmptyLogicalVector()); - testEmptyArray(factory, vector, createEmptyIntVector()); - testEmptyArray(factory, vector, createEmptyDoubleVector()); - testEmptyArray(factory, vector, createEmptyComplexVector()); - + execInContext(() -> { + RAbstractVector vector = withinTestContext(() -> originalVector.copy()); + testEmptyArray(factory, vector, createEmptyLogicalVector()); + testEmptyArray(factory, vector, createEmptyIntVector()); + testEmptyArray(factory, vector, createEmptyDoubleVector()); + testEmptyArray(factory, vector, createEmptyComplexVector()); + return null; + }); } @Theory public void testRNullConstantResult(BinaryArithmeticFactory factory, RAbstractVector originalVector) { - RAbstractVector vector = withinTestContext(() -> originalVector.copy()); - - RType type = null; - RType rType = vector.getRType(); - if (rType == RType.Complex) { - type = RType.Complex; - } else { - if (rType == RType.Integer || rType == RType.Logical) { - if (factory == BinaryArithmetic.DIV || factory == BinaryArithmetic.POW) { + execInContext(() -> { + RAbstractVector vector = withinTestContext(() -> originalVector.copy()); + + RType type = null; + RType rType = vector.getRType(); + if (rType == RType.Complex) { + type = RType.Complex; + } else { + if (rType == RType.Integer || rType == RType.Logical) { + if (factory == BinaryArithmetic.DIV || factory == BinaryArithmetic.POW) { + type = RType.Double; + } else { + type = RType.Integer; + } + } else if (rType == RType.Double) { type = RType.Double; } else { - type = RType.Integer; + Assert.fail(); } - } else if (rType == RType.Double) { - type = RType.Double; - } else { - Assert.fail(); } - } - assertThat(executeArithmetic(factory, vector, RNull.instance), isEmptyVectorOf(type)); - assertThat(executeArithmetic(factory, RNull.instance, vector), isEmptyVectorOf(type)); + assertThat(executeArithmetic(factory, vector, RNull.instance), isEmptyVectorOf(type)); + assertThat(executeArithmetic(factory, RNull.instance, vector), isEmptyVectorOf(type)); + return null; + }); } @Theory public void testBothNull(BinaryArithmeticFactory factory) { - assertThat(executeArithmetic(factory, RNull.instance, RNull.instance), isEmptyVectorOf(factory == BinaryArithmetic.DIV || factory == BinaryArithmetic.POW ? RType.Double : RType.Integer)); + execInContext(() -> { + assertThat(executeArithmetic(factory, RNull.instance, RNull.instance), isEmptyVectorOf(factory == BinaryArithmetic.DIV || factory == BinaryArithmetic.POW ? RType.Double : RType.Integer)); + return null; + }); } @Theory public void testCompleteness(BinaryArithmeticFactory factory, RAbstractVector aOrig, RAbstractVector bOrig) { - RAbstractVector a = copy(aOrig); - RAbstractVector b = copy(bOrig); - assumeArithmeticCompatible(factory, a, b); + execInContext(() -> { + RAbstractVector a = copy(aOrig); + RAbstractVector b = copy(bOrig); + assumeArithmeticCompatible(factory, a, b); - // disable division they might produce NA values by division with 0 - assumeFalse(factory == BinaryArithmetic.DIV); - assumeFalse(factory == BinaryArithmetic.INTEGER_DIV); - assumeFalse(factory == BinaryArithmetic.MOD); + // disable division they might produce NA values by division with 0 + assumeFalse(factory == BinaryArithmetic.DIV); + assumeFalse(factory == BinaryArithmetic.INTEGER_DIV); + assumeFalse(factory == BinaryArithmetic.MOD); - Object result = executeArithmetic(factory, a, b); + Object result = executeArithmetic(factory, a, b); - boolean resultComplete = isPrimitive(result) ? true : ((RAbstractVector) result).isComplete(); + boolean resultComplete = isPrimitive(result) ? true : ((RAbstractVector) result).isComplete(); - if (a.getLength() == 0 || b.getLength() == 0) { - Assert.assertTrue(resultComplete); - } else { - boolean expectedComplete = a.isComplete() && b.isComplete(); - Assert.assertEquals(expectedComplete, resultComplete); - } + if (a.getLength() == 0 || b.getLength() == 0) { + Assert.assertTrue(resultComplete); + } else { + boolean expectedComplete = a.isComplete() && b.isComplete(); + Assert.assertEquals(expectedComplete, resultComplete); + } + return null; + }); } @Theory public void testCopyAttributes(BinaryArithmeticFactory factory, RAbstractVector aOrig, RAbstractVector bOrig) { - assumeArithmeticCompatible(factory, aOrig, bOrig); - - // we have to e careful not to change mutable vectors - RAbstractVector a = copy(aOrig); - RAbstractVector b = copy(bOrig); - if (a instanceof RShareable) { - assert ((RShareable) a).isTemporary(); - ((RShareable) a).incRefCount(); - } - if (b instanceof RShareable) { - assert ((RShareable) b).isTemporary(); - ((RShareable) b).incRefCount(); - } - - RVector<?> aMaterialized = withinTestContext(() -> a.copy().materialize()); - RVector<?> bMaterialized = withinTestContext(() -> b.copy().materialize()); - - aMaterialized.setAttr("a", "a"); - bMaterialized.setAttr("b", "b"); + execInContext(() -> { + assumeArithmeticCompatible(factory, aOrig, bOrig); + + // we have to e careful not to change mutable vectors + RAbstractVector a = copy(aOrig); + RAbstractVector b = copy(bOrig); + if (a instanceof RShareable) { + assert ((RShareable) a).isTemporary(); + ((RShareable) a).incRefCount(); + } + if (b instanceof RShareable) { + assert ((RShareable) b).isTemporary(); + ((RShareable) b).incRefCount(); + } - if (a.getLength() == 0 || b.getLength() == 0) { - assertAttributes(executeArithmetic(factory, copy(aMaterialized), copy(bMaterialized))); - assertAttributes(executeArithmetic(factory, a, copy(bMaterialized))); - assertAttributes(executeArithmetic(factory, copy(aMaterialized), b)); - } else if (a.getLength() == b.getLength()) { - assertAttributes(executeArithmetic(factory, copy(aMaterialized), copy(bMaterialized)), "a", "b"); - assertAttributes(executeArithmetic(factory, a, copy(bMaterialized)), "b"); - assertAttributes(executeArithmetic(factory, copy(aMaterialized), b), "a"); - } else if (a.getLength() > b.getLength()) { - assertAttributes(executeArithmetic(factory, copy(aMaterialized), copy(bMaterialized)), "a"); - assertAttributes(executeArithmetic(factory, a, copy(bMaterialized))); - assertAttributes(executeArithmetic(factory, copy(aMaterialized), b), "a"); - } else { - assert a.getLength() < b.getLength(); - assertAttributes(executeArithmetic(factory, copy(aMaterialized), copy(bMaterialized)), "b"); - assertAttributes(executeArithmetic(factory, a, copy(bMaterialized)), "b"); - assertAttributes(executeArithmetic(factory, copy(aMaterialized), b)); - } + RVector<?> aMaterialized = withinTestContext(() -> a.copy().materialize()); + RVector<?> bMaterialized = withinTestContext(() -> b.copy().materialize()); + + aMaterialized.setAttr("a", "a"); + bMaterialized.setAttr("b", "b"); + + if (a.getLength() == 0 || b.getLength() == 0) { + assertAttributes(executeArithmetic(factory, copy(aMaterialized), copy(bMaterialized))); + assertAttributes(executeArithmetic(factory, a, copy(bMaterialized))); + assertAttributes(executeArithmetic(factory, copy(aMaterialized), b)); + } else if (a.getLength() == b.getLength()) { + assertAttributes(executeArithmetic(factory, copy(aMaterialized), copy(bMaterialized)), "a", "b"); + assertAttributes(executeArithmetic(factory, a, copy(bMaterialized)), "b"); + assertAttributes(executeArithmetic(factory, copy(aMaterialized), b), "a"); + } else if (a.getLength() > b.getLength()) { + assertAttributes(executeArithmetic(factory, copy(aMaterialized), copy(bMaterialized)), "a"); + assertAttributes(executeArithmetic(factory, a, copy(bMaterialized))); + assertAttributes(executeArithmetic(factory, copy(aMaterialized), b), "a"); + } else { + assert a.getLength() < b.getLength(); + assertAttributes(executeArithmetic(factory, copy(aMaterialized), copy(bMaterialized)), "b"); + assertAttributes(executeArithmetic(factory, a, copy(bMaterialized)), "b"); + assertAttributes(executeArithmetic(factory, copy(aMaterialized), b)); + } + return null; + }); } @Test public void testSequenceFolding() { - assertFold(true, createIntSequence(1, 3, 10), createIntVectorFromScalar(5), ADD, SUBTRACT, MULTIPLY, INTEGER_DIV); - assertFold(true, createIntVectorFromScalar(5), createIntSequence(1, 3, 10), ADD, MULTIPLY); - assertFold(true, createIntSequence(1, 3, 10), createIntSequence(2, 5, 10), ADD, SUBTRACT); - assertFold(false, createIntVectorFromScalar(5), createIntSequence(1, 3, 10), SUBTRACT, INTEGER_DIV, MOD); - assertFold(false, createIntSequence(1, 3, 10), createIntSequence(2, 5, 5), ADD, SUBTRACT, MULTIPLY, INTEGER_DIV); - - assertFold(true, createDoubleSequence(1, 3, 10), createDoubleVectorFromScalar(5), ADD, SUBTRACT, MULTIPLY, INTEGER_DIV); - assertFold(true, createDoubleVectorFromScalar(5), createDoubleSequence(1, 3, 10), ADD, MULTIPLY); - assertFold(true, createDoubleSequence(1, 3, 10), createDoubleSequence(2, 5, 10), ADD, SUBTRACT); - assertFold(false, createDoubleVectorFromScalar(5), createDoubleSequence(1, 3, 10), SUBTRACT, INTEGER_DIV, MOD); - assertFold(false, createDoubleSequence(1, 3, 10), createDoubleSequence(2, 5, 5), ADD, SUBTRACT, MULTIPLY, INTEGER_DIV); + execInContext(() -> { + assertFold(true, createIntSequence(1, 3, 10), createIntVectorFromScalar(5), ADD, SUBTRACT, MULTIPLY, INTEGER_DIV); + assertFold(true, createIntVectorFromScalar(5), createIntSequence(1, 3, 10), ADD, MULTIPLY); + assertFold(true, createIntSequence(1, 3, 10), createIntSequence(2, 5, 10), ADD, SUBTRACT); + assertFold(false, createIntVectorFromScalar(5), createIntSequence(1, 3, 10), SUBTRACT, INTEGER_DIV, MOD); + assertFold(false, createIntSequence(1, 3, 10), createIntSequence(2, 5, 5), ADD, SUBTRACT, MULTIPLY, INTEGER_DIV); + + assertFold(true, createDoubleSequence(1, 3, 10), createDoubleVectorFromScalar(5), ADD, SUBTRACT, MULTIPLY, INTEGER_DIV); + assertFold(true, createDoubleVectorFromScalar(5), createDoubleSequence(1, 3, 10), ADD, MULTIPLY); + assertFold(true, createDoubleSequence(1, 3, 10), createDoubleSequence(2, 5, 10), ADD, SUBTRACT); + assertFold(false, createDoubleVectorFromScalar(5), createDoubleSequence(1, 3, 10), SUBTRACT, INTEGER_DIV, MOD); + assertFold(false, createDoubleSequence(1, 3, 10), createDoubleSequence(2, 5, 5), ADD, SUBTRACT, MULTIPLY, INTEGER_DIV); + return null; + }); } @Theory public void testGeneric(BinaryArithmeticFactory factory) { - // this should trigger the generic case - for (RAbstractVector vector : ALL_VECTORS) { - try { - assumeArithmeticCompatible(factory, vector, vector); - } catch (AssumptionViolatedException e) { - continue; + execInContext(() -> { + // this should trigger the generic case + for (RAbstractVector vector : ALL_VECTORS) { + try { + assumeArithmeticCompatible(factory, vector, vector); + } catch (AssumptionViolatedException e) { + continue; + } + executeArithmetic(factory, copy(vector), copy(vector)); } - executeArithmetic(factory, copy(vector), copy(vector)); - } + return null; + }); } private static void assertAttributes(Object value, String... keys) { diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/BinaryBooleanNodeTest.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/BinaryBooleanNodeTest.java index bf64977ae002ce67cbfd57ae6051136beedb1ed0..f0b8cf0f2dfbaeb52741edfff700154ae647a82b 100644 --- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/BinaryBooleanNodeTest.java +++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/BinaryBooleanNodeTest.java @@ -92,67 +92,76 @@ public class BinaryBooleanNodeTest extends BinaryVectorTest { @Theory public void testScalarUnboxing(BooleanOperationFactory factory, RScalarVector aOrig, RAbstractVector bOrig) { - RAbstractVector a = copy(aOrig); - RAbstractVector b = copy(bOrig); - // unboxing cannot work if length is 1 - assumeThat(b.getLength(), is(1)); - - // if the right side is shareable these should be prioritized - assumeThat(b, is(not(instanceOf(RShareable.class)))); - - assumeArithmeticCompatible(factory, a, b); - Object result = executeArithmetic(factory, a, b); - Assert.assertTrue(isPrimitive(result)); + execInContext(() -> { + RAbstractVector a = copy(aOrig); + RAbstractVector b = copy(bOrig); + // unboxing cannot work if length is 1 + assumeThat(b.getLength(), is(1)); + + // if the right side is shareable these should be prioritized + assumeThat(b, is(not(instanceOf(RShareable.class)))); + + assumeArithmeticCompatible(factory, a, b); + Object result = executeArithmetic(factory, a, b); + Assert.assertTrue(isPrimitive(result)); + return null; + }); } @Theory public void testVectorResult(BooleanOperationFactory factory, RAbstractVector aOrig, RAbstractVector bOrig) { - RAbstractVector a = copy(aOrig); - RAbstractVector b = copy(bOrig); - assumeThat(a, is(not(instanceOf(RScalarVector.class)))); - assumeThat(b, is(not(instanceOf(RScalarVector.class)))); - assumeArithmeticCompatible(factory, a, b); - - Object result = executeArithmetic(factory, a, b); - Assert.assertFalse(isPrimitive(result)); - assertLengthAndType(factory, a, b, (RAbstractVector) result); - - assumeThat(b, is(not(instanceOf(RScalarVector.class)))); - result = executeArithmetic(factory, b, a); - assertLengthAndType(factory, a, b, (RAbstractVector) result); + execInContext(() -> { + RAbstractVector a = copy(aOrig); + RAbstractVector b = copy(bOrig); + assumeThat(a, is(not(instanceOf(RScalarVector.class)))); + assumeThat(b, is(not(instanceOf(RScalarVector.class)))); + assumeArithmeticCompatible(factory, a, b); + + Object result = executeArithmetic(factory, a, b); + Assert.assertFalse(isPrimitive(result)); + assertLengthAndType(factory, a, b, (RAbstractVector) result); + + assumeThat(b, is(not(instanceOf(RScalarVector.class)))); + result = executeArithmetic(factory, b, a); + assertLengthAndType(factory, a, b, (RAbstractVector) result); + return null; + }); } @Theory public void testSharing(BooleanOperationFactory factory, RAbstractVector aOrig, RAbstractVector bOrig) { - RAbstractVector a = copy(aOrig); - RAbstractVector b = copy(bOrig); - assumeArithmeticCompatible(factory, aOrig, bOrig); - - // not part of this test, see #testEmptyArrays - assumeThat(a.getLength(), is(not(0))); - assumeThat(b.getLength(), is(not(0))); - - // sharing does not work if a is a scalar vector - assumeThat(a, is(not(instanceOf(RScalarVector.class)))); - - RType resultType = getResultType(factory, a, b); - int maxLength = Integer.max(a.getLength(), b.getLength()); - RAbstractVector sharedResult = null; - if (a.getLength() == maxLength && isShareable(a, resultType)) { - sharedResult = a; - } - if (sharedResult == null && b.getLength() == maxLength && isShareable(b, resultType)) { - sharedResult = b; - } + execInContext(() -> { + RAbstractVector a = copy(aOrig); + RAbstractVector b = copy(bOrig); + assumeArithmeticCompatible(factory, aOrig, bOrig); + + // not part of this test, see #testEmptyArrays + assumeThat(a.getLength(), is(not(0))); + assumeThat(b.getLength(), is(not(0))); + + // sharing does not work if a is a scalar vector + assumeThat(a, is(not(instanceOf(RScalarVector.class)))); + + RType resultType = getResultType(factory, a, b); + int maxLength = Integer.max(a.getLength(), b.getLength()); + RAbstractVector sharedResult = null; + if (a.getLength() == maxLength && isShareable(a, resultType)) { + sharedResult = a; + } + if (sharedResult == null && b.getLength() == maxLength && isShareable(b, resultType)) { + sharedResult = b; + } - Object result = executeArithmetic(factory, a, b); + Object result = executeArithmetic(factory, a, b); - if (sharedResult == null) { - Assert.assertNotSame(a, result); - Assert.assertNotSame(b, result); - } else { - Assert.assertSame(sharedResult, result); - } + if (sharedResult == null) { + Assert.assertNotSame(a, result); + Assert.assertNotSame(b, result); + } else { + Assert.assertSame(sharedResult, result); + } + return null; + }); } private static boolean isShareable(RAbstractVector a, RType resultType) { @@ -195,63 +204,77 @@ public class BinaryBooleanNodeTest extends BinaryVectorTest { @Theory public void testEmptyArrays(BooleanOperationFactory factory, RAbstractVector originalVector) { - RAbstractVector vector = copy(originalVector); - assumeArithmeticCompatible(factory, vector, createEmptyLogicalVector()); - assumeArithmeticCompatible(factory, vector, createEmptyIntVector()); - assumeArithmeticCompatible(factory, vector, createEmptyDoubleVector()); - assumeArithmeticCompatible(factory, vector, createEmptyComplexVector()); - - testEmptyArray(factory, vector, createEmptyLogicalVector()); - testEmptyArray(factory, vector, createEmptyIntVector()); - testEmptyArray(factory, vector, createEmptyDoubleVector()); - testEmptyArray(factory, vector, createEmptyComplexVector()); - + execInContext(() -> { + RAbstractVector vector = copy(originalVector); + assumeArithmeticCompatible(factory, vector, createEmptyLogicalVector()); + assumeArithmeticCompatible(factory, vector, createEmptyIntVector()); + assumeArithmeticCompatible(factory, vector, createEmptyDoubleVector()); + assumeArithmeticCompatible(factory, vector, createEmptyComplexVector()); + + testEmptyArray(factory, vector, createEmptyLogicalVector()); + testEmptyArray(factory, vector, createEmptyIntVector()); + testEmptyArray(factory, vector, createEmptyDoubleVector()); + testEmptyArray(factory, vector, createEmptyComplexVector()); + return null; + }); } @Theory public void testRNullConstantResult(BooleanOperationFactory factory, RAbstractVector originalVector) { - RAbstractVector vector = copy(originalVector); - assumeFalse(isLogicOp(factory)); - assumeFalse(vector.getRType() == RType.Raw); - assertThat(executeArithmetic(factory, vector, RNull.instance), isEmptyVectorOf(RType.Logical)); - assertThat(executeArithmetic(factory, RNull.instance, vector), isEmptyVectorOf(RType.Logical)); + execInContext(() -> { + RAbstractVector vector = copy(originalVector); + assumeFalse(isLogicOp(factory)); + assumeFalse(vector.getRType() == RType.Raw); + assertThat(executeArithmetic(factory, vector, RNull.instance), isEmptyVectorOf(RType.Logical)); + assertThat(executeArithmetic(factory, RNull.instance, vector), isEmptyVectorOf(RType.Logical)); + return null; + }); } @Theory public void testBothNull(BooleanOperationFactory factory) { - assumeFalse(isLogicOp(factory)); - assertThat(executeArithmetic(factory, RNull.instance, RNull.instance), isEmptyVectorOf(RType.Logical)); + execInContext(() -> { + assumeFalse(isLogicOp(factory)); + assertThat(executeArithmetic(factory, RNull.instance, RNull.instance), isEmptyVectorOf(RType.Logical)); + return null; + }); } @Theory public void testCompleteness(BooleanOperationFactory factory, RAbstractVector aOrig, RAbstractVector bOrig) { - RAbstractVector a = copy(aOrig); - RAbstractVector b = copy(bOrig); - assumeArithmeticCompatible(factory, a, b); + execInContext(() -> { + RAbstractVector a = copy(aOrig); + RAbstractVector b = copy(bOrig); + assumeArithmeticCompatible(factory, a, b); - Object result = executeArithmetic(factory, a, b); + Object result = executeArithmetic(factory, a, b); - boolean resultComplete = isPrimitive(result) ? true : ((RAbstractVector) result).isComplete(); + boolean resultComplete = isPrimitive(result) ? true : ((RAbstractVector) result).isComplete(); - if (a.getLength() == 0 || b.getLength() == 0) { - Assert.assertTrue(resultComplete); - } else { - boolean expectedComplete = a.isComplete() && b.isComplete(); - Assert.assertEquals(expectedComplete, resultComplete); - } + if (a.getLength() == 0 || b.getLength() == 0) { + Assert.assertTrue(resultComplete); + } else { + boolean expectedComplete = a.isComplete() && b.isComplete(); + Assert.assertEquals(expectedComplete, resultComplete); + } + return null; + }); } @Theory public void testGeneric(BooleanOperationFactory factory) { - // this should trigger the generic case - for (RAbstractVector vector : ALL_VECTORS) { - try { - assumeArithmeticCompatible(factory, vector, vector); - } catch (AssumptionViolatedException e) { - continue; + execInContext(() -> { + // this should trigger the generic case + for (RAbstractVector vector : ALL_VECTORS) { + try { + assumeArithmeticCompatible(factory, vector, vector); + } catch (AssumptionViolatedException e) { + continue; + } + executeArithmetic(factory, copy(vector), copy(vector)); } - executeArithmetic(factory, copy(vector), copy(vector)); - } + return null; + }); } private static void assumeArithmeticCompatible(BooleanOperationFactory factory, RAbstractVector a, RAbstractVector b) { diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/ChimneySweeping.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/ChimneySweeping.java index bd4a571e6d9cffc765558f12e16526f9634a202e..0179868d91a1ebf293df0ddab6135e13c1e7d944 100644 --- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/ChimneySweeping.java +++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/ChimneySweeping.java @@ -22,8 +22,6 @@ */ package com.oracle.truffle.r.nodes.test; -import static org.junit.Assert.fail; - import java.io.File; import java.io.IOException; import java.lang.reflect.Method; @@ -42,8 +40,6 @@ import java.util.stream.Collectors; import org.junit.Assert; import com.oracle.truffle.api.dsl.UnsupportedSpecializationException; -import com.oracle.truffle.api.vm.PolyglotEngine; -import com.oracle.truffle.api.vm.PolyglotEngine.Value; import com.oracle.truffle.r.nodes.builtin.casts.fluent.PipelineBuilder; import com.oracle.truffle.r.nodes.casts.Samples; import com.oracle.truffle.r.nodes.casts.SamplesCollector; @@ -65,6 +61,11 @@ import com.oracle.truffle.r.test.generate.FastRSession; import com.oracle.truffle.r.test.generate.GnuROneShotRSession; import com.oracle.truffle.r.test.generate.TestOutputManager; import com.oracle.truffle.r.test.generate.TestOutputManager.TestInfo; +import org.graalvm.polyglot.Context; +import org.graalvm.polyglot.Value; +import org.graalvm.polyglot.proxy.ProxyExecutable; +import static org.junit.Assert.fail; +import static com.oracle.truffle.r.test.generate.FastRSession.execInContext; /** * Use the following command to sweep all builtins @@ -224,14 +225,16 @@ class ChimneySweeping extends SingleBuiltinDiagnostics { @Override SingleBuiltinDiagnostics init() throws Throwable { super.init(); - - this.castNodes = builtinFactory.getCastNodes(); - - print(0, "\n*** Chimney-sweeping of '" + builtinName + "' (" + builtinFactory.getBuiltinMetaClass().getName() + ") ***"); - - this.validArgsList = extractValidArgsForBuiltin(); - this.argSamples = createSamples(); - + try (Context context = diagSuite.fastRSession.createContext()) { + execInContext(context, () -> { + this.castNodes = builtinFactory.getCastNodes(); + print(0, "\n*** Chimney-sweeping of '" + builtinName + "' (" + builtinFactory.getBuiltinMetaClass().getName() + ") ***"); + + this.validArgsList = extractValidArgsForBuiltin(context); + this.argSamples = createSamples(); + return null; + }); + } return this; } @@ -358,41 +361,34 @@ class ChimneySweeping extends SingleBuiltinDiagnostics { } } - private Set<RList> extractValidArgsForBuiltin() { - final PolyglotEngine vm = diagSuite.fastRSession.checkContext(null).createVM(); - - try { - String snippetAnchor; - switch (kind) { - case INTERNAL: - snippetAnchor = ".Internal(" + builtinName + "("; - break; - default: - snippetAnchor = builtinName + "("; - break; - } - - String builtinNameSimple = builtinName.replace(".", ""); - Map<String, SortedMap<String, TestInfo>> snippets = diagSuite.outputManager.getTestMaps().entrySet().stream().filter( - e -> e.getKey().startsWith(TEST_PREFIX + builtinName) || e.getKey().startsWith(TEST_PREFIX + builtinNameSimple)).collect( - Collectors.toMap(e -> e.getKey(), e -> e.getValue())); - Set<String> flatSnippets = snippets.entrySet().stream().flatMap( - e -> e.getValue().keySet().stream()).collect(Collectors.toSet()); - Set<String> filteredSnippets = flatSnippets.stream().filter(a -> a.contains(snippetAnchor)).collect(Collectors.toSet()); - Set<String> validArgs = filteredSnippets.stream().map(a -> cutOffInvocation(a, snippetAnchor)).filter( - a -> a != null && !"".equals(a)).collect(Collectors.toSet()); - Set<RList> args = validArgs.stream().map(a -> evalValidArgs(a, vm)).filter(a -> a != null).collect(Collectors.toSet()); - - return args; - } finally { - vm.dispose(); + private Set<RList> extractValidArgsForBuiltin(Context context) { + String snippetAnchor; + switch (kind) { + case INTERNAL: + snippetAnchor = ".Internal(" + builtinName + "("; + break; + default: + snippetAnchor = builtinName + "("; + break; } + + String builtinNameSimple = builtinName.replace(".", ""); + Map<String, SortedMap<String, TestInfo>> snippets = diagSuite.outputManager.getTestMaps().entrySet().stream().filter( + e -> e.getKey().startsWith(TEST_PREFIX + builtinName) || e.getKey().startsWith(TEST_PREFIX + builtinNameSimple)).collect( + Collectors.toMap(e -> e.getKey(), e -> e.getValue())); + Set<String> flatSnippets = snippets.entrySet().stream().flatMap( + e -> e.getValue().keySet().stream()).collect(Collectors.toSet()); + Set<String> filteredSnippets = flatSnippets.stream().filter(a -> a.contains(snippetAnchor)).collect(Collectors.toSet()); + Set<String> validArgs = filteredSnippets.stream().map(a -> cutOffInvocation(a, snippetAnchor)).filter( + a -> a != null && !"".equals(a)).collect(Collectors.toSet()); + Set<RList> args = validArgs.stream().map(a -> evalValidArgs(a, context)).filter(a -> a != null).collect(Collectors.toSet()); + return args; } - private RList evalValidArgs(String argsExpr, PolyglotEngine vm) { + private RList evalValidArgs(String argsExpr, Context context) { try { - Value eval = vm.eval(RSource.fromTextInternal(argsExpr, RSource.Internal.UNIT_TEST)); - Object res = eval.get(); + Value eval = context.eval(FastRSession.createSource(argsExpr, RSource.Internal.UNIT_TEST.string)); + Object res = FastRSession.getReceiver(eval); // TODO: do not use reflection here Method getter = res.getClass().getDeclaredMethod("getDelegate"); getter.setAccessible(true); diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/DefaultArgsExtractor.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/DefaultArgsExtractor.java index 3b9c62f6dd6b6495a7f8b8d086e4c1a9cee5834e..de6153e10db2b5d26cc56a79e5e6068024ba5a2b 100644 --- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/DefaultArgsExtractor.java +++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/DefaultArgsExtractor.java @@ -28,9 +28,6 @@ import java.util.HashSet; import java.util.Map; import java.util.function.Consumer; -import com.oracle.truffle.api.source.Source; -import com.oracle.truffle.api.vm.PolyglotEngine; -import com.oracle.truffle.api.vm.PolyglotEngine.Value; import com.oracle.truffle.r.nodes.casts.Samples; import com.oracle.truffle.r.runtime.RDeparse; import com.oracle.truffle.r.runtime.RSource; @@ -41,6 +38,9 @@ import com.oracle.truffle.r.runtime.data.RStringVector; import com.oracle.truffle.r.runtime.data.RSymbol; import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; import com.oracle.truffle.r.test.generate.FastRSession; +import org.graalvm.polyglot.Context; +import org.graalvm.polyglot.Source; +import org.graalvm.polyglot.Value; /** * This helper class extracts default argument values from an R function. @@ -56,17 +56,17 @@ class DefaultArgsExtractor { } Map<String, Samples<?>> extractDefaultArgs(String functionName) { - final PolyglotEngine vm = fastRSession.checkContext(null).createVM(); + final Context context = fastRSession.createContext(); HashMap<String, Samples<?>> samplesMap = new HashMap<>(); try { - Source source = RSource.fromTextInternal("formals(" + functionName + ")", RSource.Internal.UNIT_TEST); + Source source = FastRSession.createSource("formals(" + functionName + ")", RSource.Internal.UNIT_TEST.string); - Value defArgVal = vm.eval(source); + Value defArgVal = context.eval(source); try { - RPairList formals = defArgVal.as(RPairList.class); + RPairList formals = (RPairList) FastRSession.getReceiver(defArgVal); RStringVector names = formals.getNames(); for (int i = 0; i < names.getLength(); i++) { @@ -76,8 +76,8 @@ class DefaultArgsExtractor { if (defVal instanceof RLanguage) { String deparsedDefVal = RDeparse.deparse(defVal); try { - Value eval = vm.eval(RSource.fromTextInternal(deparsedDefVal, RSource.Internal.UNIT_TEST)); - defVal = eval.get(); + Value eval = context.eval(FastRSession.createSource(deparsedDefVal, RSource.Internal.UNIT_TEST.string)); + defVal = FastRSession.getReceiver(eval); } catch (Throwable t) { printer.accept("Warning: Unable to evaluate the default value of argument " + name + ". Expression: " + deparsedDefVal); continue; @@ -111,7 +111,7 @@ class DefaultArgsExtractor { } catch (Throwable t) { printer.accept("Warning: Unable to evaluate formal arguments of function " + functionName); } finally { - vm.dispose(); + context.close(); } return samplesMap; diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/SpecialCallTest.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/SpecialCallTest.java index 5c254881f4a0f3a4297d47eaa84b00e5b36427b0..a6d4cfd2fc01d32062205eb99598bfdda1c20858 100644 --- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/SpecialCallTest.java +++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/SpecialCallTest.java @@ -155,104 +155,125 @@ public class SpecialCallTest extends TestBase { @Test public void testBasic() { - // check a case with no calls - assertCallCounts("library(stats)", 0, 1, 0, 1); + execInContext(() -> { + // check a case with no calls + assertCallCounts("library(stats)", 0, 1, 0, 1); + return null; + }); } @Test public void testArithmetic() { - assertCallCounts("1 + 1", 1, 0, 1, 0); - assertCallCounts("1 + 1 * 2 + 4", 3, 0, 3, 0); + execInContext(() -> { + assertCallCounts("1 + 1", 1, 0, 1, 0); + assertCallCounts("1 + 1 * 2 + 4", 3, 0, 3, 0); - assertCallCounts("a <- 1; b <- 2", "a + b", 1, 0, 1, 0); - assertCallCounts("a <- 1; b <- 2; c <- 3", "a + b * 2 * c", 3, 0, 3, 0); + assertCallCounts("a <- 1; b <- 2", "a + b", 1, 0, 1, 0); + assertCallCounts("a <- 1; b <- 2; c <- 3", "a + b * 2 * c", 3, 0, 3, 0); - assertCallCounts("a <- data.frame(a=1); b <- 2; c <- 3", "a + b * 2 * c", 3, 0, 2, 1); - assertCallCounts("a <- 1; b <- data.frame(a=1); c <- 3", "a + b * 2 * c", 3, 0, 0, 3); + assertCallCounts("a <- data.frame(a=1); b <- 2; c <- 3", "a + b * 2 * c", 3, 0, 2, 1); + assertCallCounts("a <- 1; b <- data.frame(a=1); c <- 3", "a + b * 2 * c", 3, 0, 0, 3); - assertCallCounts("1 %*% 1", 0, 1, 0, 1); + assertCallCounts("1 %*% 1", 0, 1, 0, 1); + return null; + }); } @Test public void testSubset() { - assertCallCounts("a <- 1:10", "a[1]", 1, 0, 1, 0); - assertCallCounts("a <- c(1,2,3,4)", "a[2]", 1, 0, 1, 0); - assertCallCounts("a <- c(1,2,3,4)", "a[4]", 1, 0, 1, 0); - assertCallCounts("a <- list(c(1,2,3,4),2,3)", "a[1]", 1, 0, 1, 0); - assertCallCounts("a <- c(1,2,3,4)", "a[0.1]", 1, 0, 1, 0); - assertCallCounts("a <- c(1,2,3,4)", "a[5]", 1, 0, 1, 0); - assertCallCounts("a <- c(1,2,3,4)", "a[0]", 1, 0, 1, 0); - assertCallCounts("a <- c(1,2,3,4); b <- -1", "a[b]", 1, 0, 1, 0); - assertCallCounts("a <- c(1,2,3,4)", "a[NA_integer_]", 1, 0, 1, 0); - assertCallCounts("a <- c(1,2,3,4)", "a[-1]", 2, 0, 2, 0); - - assertCallCounts("a <- c(1,2,3,4)", "a[drop=T, 1]", 0, 1, 0, 1); - assertCallCounts("a <- c(1,2,3,4)", "a[drop=F, 1]", 0, 1, 0, 1); - assertCallCounts("a <- c(1,2,3,4)", "a[1, drop=F]", 0, 1, 0, 1); + execInContext(() -> { + assertCallCounts("a <- 1:10", "a[1]", 1, 0, 1, 0); + assertCallCounts("a <- c(1,2,3,4)", "a[2]", 1, 0, 1, 0); + assertCallCounts("a <- c(1,2,3,4)", "a[4]", 1, 0, 1, 0); + assertCallCounts("a <- list(c(1,2,3,4),2,3)", "a[1]", 1, 0, 1, 0); + assertCallCounts("a <- c(1,2,3,4)", "a[0.1]", 1, 0, 1, 0); + assertCallCounts("a <- c(1,2,3,4)", "a[5]", 1, 0, 1, 0); + assertCallCounts("a <- c(1,2,3,4)", "a[0]", 1, 0, 1, 0); + assertCallCounts("a <- c(1,2,3,4); b <- -1", "a[b]", 1, 0, 1, 0); + assertCallCounts("a <- c(1,2,3,4)", "a[NA_integer_]", 1, 0, 1, 0); + assertCallCounts("a <- c(1,2,3,4)", "a[-1]", 2, 0, 2, 0); + + assertCallCounts("a <- c(1,2,3,4)", "a[drop=T, 1]", 0, 1, 0, 1); + assertCallCounts("a <- c(1,2,3,4)", "a[drop=F, 1]", 0, 1, 0, 1); + assertCallCounts("a <- c(1,2,3,4)", "a[1, drop=F]", 0, 1, 0, 1); + return null; + }); } @Test public void testSubscript() { - assertCallCounts("a <- 1:10", "a[[1]]", 1, 0, 1, 0); - assertCallCounts("a <- c(1,2,3,4)", "a[[2]]", 1, 0, 1, 0); - assertCallCounts("a <- c(1,2,3,4)", "a[[4]]", 1, 0, 1, 0); - assertCallCounts("a <- list(c(1,2,3,4),2,3)", "a[[1]]", 1, 0, 1, 0); - assertCallCounts("a <- list(a=c(1,2,3,4),2,3)", "a[[1]]", 1, 0, 1, 0); - assertCallCounts("a <- c(1,2,3,4)", "a[[0.1]]", 1, 0, 1, 0); - assertCallCounts("a <- c(1,2,3,4)", "a[[5]]", 1, 0, 1, 0); - assertCallCounts("a <- c(1,2,3,4)", "a[[0]]", 1, 0, 1, 0); - assertCallCounts("a <- c(1,2,3,4); b <- -1", "a[[b]]", 1, 0, 1, 0); - assertCallCounts("a <- c(1,2,3,4)", "a[[NA_integer_]]", 1, 0, 1, 0); - - assertCallCounts("a <- c(1,2,3,4)", "a[[drop=T, 1]]", 0, 1, 0, 1); - assertCallCounts("a <- c(1,2,3,4)", "a[[drop=F, 1]]", 0, 1, 0, 1); - assertCallCounts("a <- c(1,2,3,4)", "a[[1, drop=F]]", 0, 1, 0, 1); + execInContext(() -> { + assertCallCounts("a <- 1:10", "a[[1]]", 1, 0, 1, 0); + assertCallCounts("a <- c(1,2,3,4)", "a[[2]]", 1, 0, 1, 0); + assertCallCounts("a <- c(1,2,3,4)", "a[[4]]", 1, 0, 1, 0); + assertCallCounts("a <- list(c(1,2,3,4),2,3)", "a[[1]]", 1, 0, 1, 0); + assertCallCounts("a <- list(a=c(1,2,3,4),2,3)", "a[[1]]", 1, 0, 1, 0); + assertCallCounts("a <- c(1,2,3,4)", "a[[0.1]]", 1, 0, 1, 0); + assertCallCounts("a <- c(1,2,3,4)", "a[[5]]", 1, 0, 1, 0); + assertCallCounts("a <- c(1,2,3,4)", "a[[0]]", 1, 0, 1, 0); + assertCallCounts("a <- c(1,2,3,4); b <- -1", "a[[b]]", 1, 0, 1, 0); + assertCallCounts("a <- c(1,2,3,4)", "a[[NA_integer_]]", 1, 0, 1, 0); + + assertCallCounts("a <- c(1,2,3,4)", "a[[drop=T, 1]]", 0, 1, 0, 1); + assertCallCounts("a <- c(1,2,3,4)", "a[[drop=F, 1]]", 0, 1, 0, 1); + assertCallCounts("a <- c(1,2,3,4)", "a[[1, drop=F]]", 0, 1, 0, 1); + return null; + }); } @Test public void testUpdateSubset() { - assertCallCounts("a <- 1:10", "a[1] <- 1", 1, 0, 1, 1); // sequence - assertCallCounts("a <- c(1,2,3,4)", "a[2] <- 1", 1, 0, 2, 0); - assertCallCounts("a <- c(1,2,3,4)", "a[4] <- 1", 1, 0, 2, 0); - assertCallCounts("a <- list(c(1,2,3,4),2,3)", "a[1] <- 1", 1, 0, 2, 0); - assertCallCounts("a <- c(1,2,3,4)", "a[0.1] <- 1", 1, 0, 1, 1); - assertCallCounts("a <- c(1,2,3,4)", "a[5] <- 1", 1, 0, 1, 1); - assertCallCounts("a <- c(1,2,3,4)", "a[0] <- 1", 1, 0, 1, 1); - assertCallCounts("a <- c(1,2,3,4); b <- -1", "a[b] <- 1", 1, 0, 1, 1); - assertCallCounts("a <- c(1,2,3,4)", "a[NA_integer_] <- 1", 1, 0, 1, 1); - - assertCallCounts("a <- c(1,2,3,4)", "a[-1] <- 1", 2, 0, 2, 1); - assertCallCounts("a <- c(1,2,3,4)", "a[drop=T, 1] <- 1", 0, 1, 0, 2); - assertCallCounts("a <- c(1,2,3,4)", "a[drop=F, 1] <- 1", 0, 1, 0, 2); - assertCallCounts("a <- c(1,2,3,4)", "a[1, drop=F] <- 1", 0, 1, 0, 2); + execInContext(() -> { + assertCallCounts("a <- 1:10", "a[1] <- 1", 1, 0, 1, 1); // sequence + assertCallCounts("a <- c(1,2,3,4)", "a[2] <- 1", 1, 0, 2, 0); + assertCallCounts("a <- c(1,2,3,4)", "a[4] <- 1", 1, 0, 2, 0); + assertCallCounts("a <- list(c(1,2,3,4),2,3)", "a[1] <- 1", 1, 0, 2, 0); + assertCallCounts("a <- c(1,2,3,4)", "a[0.1] <- 1", 1, 0, 1, 1); + assertCallCounts("a <- c(1,2,3,4)", "a[5] <- 1", 1, 0, 1, 1); + assertCallCounts("a <- c(1,2,3,4)", "a[0] <- 1", 1, 0, 1, 1); + assertCallCounts("a <- c(1,2,3,4); b <- -1", "a[b] <- 1", 1, 0, 1, 1); + assertCallCounts("a <- c(1,2,3,4)", "a[NA_integer_] <- 1", 1, 0, 1, 1); + + assertCallCounts("a <- c(1,2,3,4)", "a[-1] <- 1", 2, 0, 2, 1); + assertCallCounts("a <- c(1,2,3,4)", "a[drop=T, 1] <- 1", 0, 1, 0, 2); + assertCallCounts("a <- c(1,2,3,4)", "a[drop=F, 1] <- 1", 0, 1, 0, 2); + assertCallCounts("a <- c(1,2,3,4)", "a[1, drop=F] <- 1", 0, 1, 0, 2); + return null; + }); } @Test public void testUpdateSubscript() { - assertCallCounts("a <- 1:10", "a[[1]] <- 1", 1, 0, 1, 1); // sequence - assertCallCounts("a <- c(1,2,3,4)", "a[[2]] <- 1", 1, 0, 2, 0); - assertCallCounts("a <- c(1,2,3,4)", "a[[4]] <- 1", 1, 0, 2, 0); - assertCallCounts("a <- list(c(1,2,3,4),2,3)", "a[[1]] <- 1", 1, 0, 2, 0); - assertCallCounts("a <- list(a=c(1,2,3,4),2,3)", "a[[1]] <- 1", 1, 0, 2, 0); - assertCallCounts("a <- c(1,2,3,4)", "a[[0.1]] <- 1", 1, 0, 1, 1); - assertCallCounts("a <- c(1,2,3,4)", "a[[5]] <- 1", 1, 0, 1, 1); - assertCallCounts("a <- c(1,2,3,4)", "a[[0]] <- 1", 1, 0, 1, 1); - assertCallCounts("a <- c(1,2,3,4); b <- -1", "a[[b]] <- 1", 1, 0, 1, 1); - assertCallCounts("a <- c(1,2,3,4)", "a[[NA_integer_]] <- 1", 1, 0, 1, 1); - - assertCallCounts("a <- c(1,2,3,4)", "a[[drop=T, 1]] <- 1", 0, 1, 0, 2); - assertCallCounts("a <- c(1,2,3,4)", "a[[drop=F, 1]] <- 1", 0, 1, 0, 2); - assertCallCounts("a <- c(1,2,3,4)", "a[[1, drop=F]] <- 1", 0, 1, 0, 2); + execInContext(() -> { + assertCallCounts("a <- 1:10", "a[[1]] <- 1", 1, 0, 1, 1); // sequence + assertCallCounts("a <- c(1,2,3,4)", "a[[2]] <- 1", 1, 0, 2, 0); + assertCallCounts("a <- c(1,2,3,4)", "a[[4]] <- 1", 1, 0, 2, 0); + assertCallCounts("a <- list(c(1,2,3,4),2,3)", "a[[1]] <- 1", 1, 0, 2, 0); + assertCallCounts("a <- list(a=c(1,2,3,4),2,3)", "a[[1]] <- 1", 1, 0, 2, 0); + assertCallCounts("a <- c(1,2,3,4)", "a[[0.1]] <- 1", 1, 0, 1, 1); + assertCallCounts("a <- c(1,2,3,4)", "a[[5]] <- 1", 1, 0, 1, 1); + assertCallCounts("a <- c(1,2,3,4)", "a[[0]] <- 1", 1, 0, 1, 1); + assertCallCounts("a <- c(1,2,3,4); b <- -1", "a[[b]] <- 1", 1, 0, 1, 1); + assertCallCounts("a <- c(1,2,3,4)", "a[[NA_integer_]] <- 1", 1, 0, 1, 1); + + assertCallCounts("a <- c(1,2,3,4)", "a[[drop=T, 1]] <- 1", 0, 1, 0, 2); + assertCallCounts("a <- c(1,2,3,4)", "a[[drop=F, 1]] <- 1", 0, 1, 0, 2); + assertCallCounts("a <- c(1,2,3,4)", "a[[1, drop=F]] <- 1", 0, 1, 0, 2); + return null; + }); } @Test public void testParens() { - assertCallCounts("a <- 1", "(a)", 1, 0, 1, 0); - assertCallCounts("a <- 1", "(55)", 1, 0, 1, 0); - assertCallCounts("a <- 1", "('asdf')", 1, 0, 1, 0); - assertCallCounts("a <- 1; b <- 2", "(a + b)", 2, 0, 2, 0); - assertCallCounts("a <- 1; b <- 2; c <- 3", "a + (b + c)", 3, 0, 3, 0); - assertCallCounts("a <- 1; b <- 2; c <- 1:5", "a + (b + c)", 3, 0, 3, 0); + execInContext(() -> { + assertCallCounts("a <- 1", "(a)", 1, 0, 1, 0); + assertCallCounts("a <- 1", "(55)", 1, 0, 1, 0); + assertCallCounts("a <- 1", "('asdf')", 1, 0, 1, 0); + assertCallCounts("a <- 1; b <- 2", "(a + b)", 2, 0, 2, 0); + assertCallCounts("a <- 1; b <- 2; c <- 3", "a + (b + c)", 3, 0, 3, 0); + assertCallCounts("a <- 1; b <- 2; c <- 1:5", "a + (b + c)", 3, 0, 3, 0); + return null; + }); } private static void assertCallCounts(String test, int initialSpecialCount, int initialNormalCount, int finalSpecialCount, int finalNormalCount) { diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/TestBase.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/TestBase.java index fb3d6438bb838b249a65d8e67901278432d03ce1..6b1b8c05690626993fd4d083fdf94b861320c25b 100644 --- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/TestBase.java +++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/TestBase.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 @@ -22,32 +22,39 @@ */ package com.oracle.truffle.r.nodes.test; +import com.oracle.truffle.r.runtime.RSource; +import com.oracle.truffle.r.runtime.context.RContext; import org.junit.AfterClass; import org.junit.BeforeClass; -import com.oracle.truffle.api.source.Source; -import com.oracle.truffle.api.vm.PolyglotEngine; -import com.oracle.truffle.r.runtime.RSource; -import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.test.generate.FastRSession; +import org.graalvm.polyglot.Context; +import org.graalvm.polyglot.Source; +import java.util.concurrent.Callable; +import org.junit.internal.AssumptionViolatedException; public class TestBase { - private static PolyglotEngine testVM; static RContext testVMContext; + // clear out warnings (which are stored in shared base env) + private static final Source CLEAR_WARNINGS = FastRSession.createSource("assign('last.warning', NULL, envir = baseenv())", RSource.Internal.CLEAR_WARNINGS.string); + private static Context context; + @BeforeClass public static void setupClass() { - testVM = FastRSession.create().checkContext(null).createVM(); - testVMContext = testVM.eval(FastRSession.GET_CONTEXT).as(RContext.class); + FastRSession session = FastRSession.create(); + testVMContext = session.getContext(); + context = session.createContext(); } - // clear out warnings (which are stored in shared base env) - private static final Source CLEAR_WARNINGS = RSource.fromTextInternal("assign('last.warning', NULL, envir = baseenv())", RSource.Internal.CLEAR_WARNINGS); - @AfterClass public static void finishClass() { - testVM.eval(CLEAR_WARNINGS); - testVM.dispose(); + context.eval(CLEAR_WARNINGS); + context.close(); + } + + protected void execInContext(Callable<Object> c) { + FastRSession.execInContext(context, c, AssumptionViolatedException.class); } } diff --git a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/UnaryArithmeticNodeTest.java b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/UnaryArithmeticNodeTest.java index ffee9580cf61c3e3f9b117dc0bc13fe7d8802efa..4e60445f84ce5b6249308966a3f4db52c9feccc1 100644 --- a/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/UnaryArithmeticNodeTest.java +++ b/com.oracle.truffle.r.nodes.test/src/com/oracle/truffle/r/nodes/test/UnaryArithmeticNodeTest.java @@ -84,35 +84,41 @@ public class UnaryArithmeticNodeTest extends BinaryVectorTest { @Theory public void testVectorResult(UnaryArithmeticFactory factory, RAbstractVector originalOperand) { - RAbstractVector operand = copy(originalOperand); - assumeThat(operand, is(not(instanceOf(RScalarVector.class)))); + execInContext(() -> { + RAbstractVector operand = copy(originalOperand); + assumeThat(operand, is(not(instanceOf(RScalarVector.class)))); - Object result = executeArithmetic(factory, operand); - Assert.assertFalse(isPrimitive(result)); - assumeThat(result, is(instanceOf(RAbstractVector.class))); - RAbstractVector resultCast = (RAbstractVector) result; + Object result = executeArithmetic(factory, operand); + Assert.assertFalse(isPrimitive(result)); + assumeThat(result, is(instanceOf(RAbstractVector.class))); + RAbstractVector resultCast = (RAbstractVector) result; - assertThat(resultCast.getLength(), is(equalTo(operand.getLength()))); + assertThat(resultCast.getLength(), is(equalTo(operand.getLength()))); + return null; + }); } @Theory public void testSharing(UnaryArithmeticFactory factory, RAbstractVector originalOperand) { - RAbstractVector operand = copy(originalOperand); - // sharing does not work if a is a scalar vector - assumeThat(true, is(isShareable(operand, operand.getRType()))); - - RType resultType = getArgumentType(factory, operand); - Object sharedResult = null; - if (isShareable(operand, resultType)) { - sharedResult = operand; - } + execInContext(() -> { + RAbstractVector operand = copy(originalOperand); + // sharing does not work if a is a scalar vector + assumeThat(true, is(isShareable(operand, operand.getRType()))); + + RType resultType = getArgumentType(factory, operand); + Object sharedResult = null; + if (isShareable(operand, resultType)) { + sharedResult = operand; + } - Object result = executeArithmetic(factory, operand); - if (sharedResult == null) { - Assert.assertNotSame(operand, result); - } else { - Assert.assertSame(sharedResult, result); - } + Object result = executeArithmetic(factory, operand); + if (sharedResult == null) { + Assert.assertNotSame(operand, result); + } else { + Assert.assertSame(sharedResult, result); + } + return null; + }); } private static boolean isShareable(RAbstractVector a, RType resultType) { @@ -131,58 +137,73 @@ public class UnaryArithmeticNodeTest extends BinaryVectorTest { @Theory public void testCompleteness(UnaryArithmeticFactory factory, RAbstractVector originalOperand) { - RAbstractVector operand = copy(originalOperand); - Object result = executeArithmetic(factory, operand); + execInContext(() -> { + RAbstractVector operand = copy(originalOperand); + Object result = executeArithmetic(factory, operand); - boolean resultComplete = isPrimitive(result) ? true : ((RAbstractVector) result).isComplete(); + boolean resultComplete = isPrimitive(result) ? true : ((RAbstractVector) result).isComplete(); - if (operand.getLength() == 0) { - Assert.assertTrue(resultComplete); - } else { - boolean expectedComplete = operand.isComplete(); - Assert.assertEquals(expectedComplete, resultComplete); - } + if (operand.getLength() == 0) { + Assert.assertTrue(resultComplete); + } else { + boolean expectedComplete = operand.isComplete(); + Assert.assertEquals(expectedComplete, resultComplete); + } + return null; + }); } @Theory public void testCopyAttributes(UnaryArithmeticFactory factory, RAbstractVector originalOperand) { - RAbstractVector operand = copy(originalOperand); - // we have to e careful not to change mutable vectors - RAbstractVector a = copy(operand); - if (a instanceof RShareable) { - ((RShareable) a).incRefCount(); - } + execInContext(() -> { + RAbstractVector operand = copy(originalOperand); + // we have to e careful not to change mutable vectors + RAbstractVector a = copy(operand); + if (a instanceof RShareable) { + ((RShareable) a).incRefCount(); + } - RVector<?> aMaterialized = withinTestContext(() -> a.copy().materialize()); - aMaterialized.setAttr("a", "a"); - assertAttributes(executeArithmetic(factory, copy(aMaterialized)), "a"); + RVector<?> aMaterialized = withinTestContext(() -> a.copy().materialize()); + aMaterialized.setAttr("a", "a"); + assertAttributes(executeArithmetic(factory, copy(aMaterialized)), "a"); + return null; + }); } @Theory public void testPlusFolding(RAbstractVector originalOperand) { - RAbstractVector operand = copy(originalOperand); - assumeThat(operand, is(not(instanceOf(RScalarVector.class)))); - if (operand.getRType() == getArgumentType(PLUS, operand)) { - assertFold(true, operand, PLUS); - } else { - assertFold(false, operand, PLUS); - } + execInContext(() -> { + RAbstractVector operand = copy(originalOperand); + assumeThat(operand, is(not(instanceOf(RScalarVector.class)))); + if (operand.getRType() == getArgumentType(PLUS, operand)) { + assertFold(true, operand, PLUS); + } else { + assertFold(false, operand, PLUS); + } + return null; + }); } @Test public void testSequenceFolding() { - assertFold(true, createIntSequence(1, 3, 10), NEGATE); - assertFold(true, createDoubleSequence(1, 3, 10), NEGATE); - assertFold(false, createIntSequence(1, 3, 10), Floor.FLOOR, Ceiling.CEILING); - assertFold(false, createDoubleSequence(1, 3, 10), Floor.FLOOR, Ceiling.CEILING); + execInContext(() -> { + assertFold(true, createIntSequence(1, 3, 10), NEGATE); + assertFold(true, createDoubleSequence(1, 3, 10), NEGATE); + assertFold(false, createIntSequence(1, 3, 10), Floor.FLOOR, Ceiling.CEILING); + assertFold(false, createDoubleSequence(1, 3, 10), Floor.FLOOR, Ceiling.CEILING); + return null; + }); } @Theory public void testGeneric(UnaryArithmeticFactory factory) { - // this should trigger the generic case - for (RAbstractVector vector : ALL_VECTORS) { - executeArithmetic(factory, copy(vector)); - } + execInContext(() -> { + // this should trigger the generic case + for (RAbstractVector vector : ALL_VECTORS) { + executeArithmetic(factory, copy(vector)); + } + return null; + }); } private static void assertAttributes(Object value, String... keys) { diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RContext.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RContext.java index 8fdd42975a8cd6407c02e6e67277355409e03b1b..1f9abdcb988641968f28c180c739c19345d3d989 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RContext.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/RContext.java @@ -126,6 +126,7 @@ import com.oracle.truffle.r.runtime.rng.RRNG; public final class RContext { public static final int CONSOLE_WIDTH = 80; + public static ChildContextInfo childInfo; public enum ContextKind { /** @@ -394,6 +395,9 @@ public final class RContext { } Object initialInfo = env.getConfig().get(ChildContextInfo.CONFIG_KEY); + if (initialInfo == null) { + initialInfo = childInfo; + } Map<String, String> initialEnvVars; if (initialInfo == null) { /* diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/TestBase.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/TestBase.java index e80bad8eb7a0d98abbdaea9c0b1f53b913b1382b..0e511773b480359b2e848061e1123c660f86efd6 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/TestBase.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/TestBase.java @@ -42,7 +42,6 @@ import org.junit.Test; import org.junit.runner.Description; import org.junit.runner.Result; -import com.oracle.truffle.api.vm.PolyglotEngine; import com.oracle.truffle.r.runtime.FastROptions; import com.oracle.truffle.r.runtime.RInternalError; import com.oracle.truffle.r.runtime.ResourceHandlerFactory; @@ -53,6 +52,7 @@ import com.oracle.truffle.r.runtime.context.RContext.ContextKind; import com.oracle.truffle.r.test.generate.FastRSession; import com.oracle.truffle.r.test.generate.GnuROneShotRSession; import com.oracle.truffle.r.test.generate.TestOutputManager; +import org.graalvm.polyglot.Engine; /** * Base class for all unit tests. The unit tests are actually arranged as a collection of @@ -1070,10 +1070,10 @@ public class TestBase { } /** - * Tests that require additional {@link PolyglotEngine} global symbols should override this, - * which will be called just prior to the evaluation. + * Tests that require additional {@link Engine} global symbols should override this, which will + * be called just prior to the evaluation. */ - public void addPolyglotSymbols(@SuppressWarnings("unused") PolyglotEngine.Builder builder) { + public void addPolyglotSymbols(@SuppressWarnings("unused") org.graalvm.polyglot.Context context) { } private static final LocalDiagnosticHandler localDiagnosticHandler = new LocalDiagnosticHandler(); diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/AbstractMRTest.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/AbstractMRTest.java index d3060412fb3488fd7936308f9df4915d800cbe7f..f626efc8100388adda3b0d4ef817e611fb00120b 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/AbstractMRTest.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/AbstractMRTest.java @@ -31,7 +31,6 @@ import java.util.Set; import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; -import org.junit.Test; import com.oracle.truffle.api.interop.ForeignAccess; import com.oracle.truffle.api.interop.InteropException; @@ -40,24 +39,32 @@ import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.interop.UnknownIdentifierException; import com.oracle.truffle.api.interop.UnsupportedMessageException; import com.oracle.truffle.api.interop.UnsupportedTypeException; -import com.oracle.truffle.api.vm.PolyglotEngine; import com.oracle.truffle.r.ffi.impl.interop.NativePointer; import com.oracle.truffle.r.runtime.data.RNull; +import com.oracle.truffle.r.test.generate.FastRSession; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import org.graalvm.polyglot.Context; +import org.junit.Test; +import static com.oracle.truffle.r.test.generate.FastRSession.execInContext; +import java.util.concurrent.Callable; public abstract class AbstractMRTest { - protected static PolyglotEngine engine; + protected static Context context; @BeforeClass public static void before() { - engine = PolyglotEngine.newBuilder().build(); + context = Context.newBuilder("R").build(); } @AfterClass public static void after() { - engine.dispose(); + context.close(); + } + + protected void execInContext(Callable<Object> c) { + FastRSession.execInContext(context, c); } /** @@ -100,79 +107,97 @@ public abstract class AbstractMRTest { @Test public void testIsNull() throws Exception { - for (TruffleObject obj : createTruffleObjects()) { - assertEquals(isNull(obj), ForeignAccess.sendIsNull(Message.IS_NULL.createNode(), obj)); - } + execInContext(() -> { + for (TruffleObject obj : createTruffleObjects()) { + assertEquals(isNull(obj), ForeignAccess.sendIsNull(Message.IS_NULL.createNode(), obj)); + } + return null; + }); } @Test public void testExecutable() throws Exception { - for (TruffleObject obj : createTruffleObjects()) { - try { - // TODO if the need appears, also provide for args for execute - ForeignAccess.sendExecute(Message.createExecute(0).createNode(), obj); - assertEquals(obj.getClass().getSimpleName() + " " + obj + " IS_EXECUTABLE", true, ForeignAccess.sendIsExecutable(Message.IS_EXECUTABLE.createNode(), obj)); - } catch (UnsupportedTypeException | ArityException e) { - throw e; - } catch (UnsupportedMessageException e) { - assertEquals(obj.getClass().getSimpleName() + " " + obj + " IS_EXECUTABLE", false, ForeignAccess.sendIsExecutable(Message.IS_EXECUTABLE.createNode(), obj)); + execInContext(() -> { + for (TruffleObject obj : createTruffleObjects()) { + try { + // TODO if the need appears, also provide for args for execute + ForeignAccess.sendExecute(Message.createExecute(0).createNode(), obj); + assertEquals(obj.getClass().getSimpleName() + " " + obj + " IS_EXECUTABLE", true, ForeignAccess.sendIsExecutable(Message.IS_EXECUTABLE.createNode(), obj)); + } catch (UnsupportedTypeException | ArityException e) { + throw e; + } catch (UnsupportedMessageException e) { + assertEquals(obj.getClass().getSimpleName() + " " + obj + " IS_EXECUTABLE", false, ForeignAccess.sendIsExecutable(Message.IS_EXECUTABLE.createNode(), obj)); + } } - } + return null; + }); } @Test public void testInstantiable() throws Exception { - for (TruffleObject obj : createTruffleObjects()) { - try { - // TODO if the need appears, also provide for args for new - ForeignAccess.sendNew(Message.createNew(0).createNode(), obj); - assertEquals(obj.getClass().getSimpleName() + " " + obj + " IS_INSTANTIABLE", true, ForeignAccess.sendIsInstantiable(Message.IS_INSTANTIABLE.createNode(), obj)); - } catch (UnsupportedTypeException | ArityException e) { - throw e; - } catch (UnsupportedMessageException e) { - assertEquals(obj.getClass().getSimpleName() + " " + obj + " IS_INSTANTIABLE", false, ForeignAccess.sendIsInstantiable(Message.IS_INSTANTIABLE.createNode(), obj)); + execInContext(() -> { + for (TruffleObject obj : createTruffleObjects()) { + try { + // TODO if the need appears, also provide for args for new + ForeignAccess.sendNew(Message.createNew(0).createNode(), obj); + assertEquals(obj.getClass().getSimpleName() + " " + obj + " IS_INSTANTIABLE", true, ForeignAccess.sendIsInstantiable(Message.IS_INSTANTIABLE.createNode(), obj)); + } catch (UnsupportedTypeException | ArityException e) { + throw e; + } catch (UnsupportedMessageException e) { + assertEquals(obj.getClass().getSimpleName() + " " + obj + " IS_INSTANTIABLE", false, ForeignAccess.sendIsInstantiable(Message.IS_INSTANTIABLE.createNode(), obj)); + } } - } + return null; + }); } @Test public void testAsNativePointer() throws Exception { - for (TruffleObject obj : createTruffleObjects()) { - try { - assertNotNull(obj.getClass().getSimpleName(), ForeignAccess.sendToNative(Message.AS_POINTER.createNode(), obj)); - assertEquals(obj.getClass().getSimpleName() + " " + obj + " IS_POINTER", true, ForeignAccess.sendIsPointer(Message.IS_POINTER.createNode(), obj)); - } catch (UnsupportedMessageException e) { - assertEquals(obj.getClass().getSimpleName() + " " + obj + " IS_POINTER", false, ForeignAccess.sendIsPointer(Message.IS_POINTER.createNode(), obj)); + execInContext(() -> { + for (TruffleObject obj : createTruffleObjects()) { + try { + assertNotNull(obj.getClass().getSimpleName(), ForeignAccess.sendToNative(Message.AS_POINTER.createNode(), obj)); + assertEquals(obj.getClass().getSimpleName() + " " + obj + " IS_POINTER", true, ForeignAccess.sendIsPointer(Message.IS_POINTER.createNode(), obj)); + } catch (UnsupportedMessageException e) { + assertEquals(obj.getClass().getSimpleName() + " " + obj + " IS_POINTER", false, ForeignAccess.sendIsPointer(Message.IS_POINTER.createNode(), obj)); + } } - } + return null; + }); } @Test public void testNativePointer() throws Exception { - for (TruffleObject obj : createTruffleObjects()) { - if (!testToNative(obj)) { - continue; - } - try { - if (obj == RNull.instance) { - assertTrue(obj.getClass().getSimpleName(), ForeignAccess.sendToNative(Message.TO_NATIVE.createNode(), obj) == NativePointer.NULL_NATIVEPOINTER); - } else { - assertTrue(obj.getClass().getSimpleName(), ForeignAccess.sendToNative(Message.TO_NATIVE.createNode(), obj) == obj); + execInContext(() -> { + for (TruffleObject obj : createTruffleObjects()) { + if (!testToNative(obj)) { + continue; + } + try { + if (obj == RNull.instance) { + assertTrue(obj.getClass().getSimpleName(), ForeignAccess.sendToNative(Message.TO_NATIVE.createNode(), obj) == NativePointer.NULL_NATIVEPOINTER); + } else { + assertTrue(obj.getClass().getSimpleName(), ForeignAccess.sendToNative(Message.TO_NATIVE.createNode(), obj) == obj); + } + } catch (UnsupportedMessageException e) { } - } catch (UnsupportedMessageException e) { } - } + return null; + }); } @Test public void testSize() throws Exception { - for (TruffleObject obj : createTruffleObjects()) { - testSize(obj); - } - TruffleObject empty = createEmptyTruffleObject(); - if (empty != null) { - testSize(empty); - } + execInContext(() -> { + for (TruffleObject obj : createTruffleObjects()) { + testSize(obj); + } + TruffleObject empty = createEmptyTruffleObject(); + if (empty != null) { + testSize(empty); + } + return null; + }); } private void testSize(TruffleObject obj) { @@ -187,13 +212,16 @@ public abstract class AbstractMRTest { @Test public void testBoxed() throws Exception { - for (TruffleObject obj : createTruffleObjects()) { - testUnboxed(obj); - } - TruffleObject empty = createEmptyTruffleObject(); - if (empty != null) { - testUnboxed(empty); - } + execInContext(() -> { + for (TruffleObject obj : createTruffleObjects()) { + testUnboxed(obj); + } + TruffleObject empty = createEmptyTruffleObject(); + if (empty != null) { + testUnboxed(empty); + } + return null; + }); } private void testUnboxed(TruffleObject obj) { @@ -208,13 +236,16 @@ public abstract class AbstractMRTest { @Test public void testKeys() throws Exception { - for (TruffleObject obj : createTruffleObjects()) { - testKeys(obj); - } - TruffleObject empty = createEmptyTruffleObject(); - if (empty != null) { - testKeys(empty); - } + execInContext(() -> { + for (TruffleObject obj : createTruffleObjects()) { + testKeys(obj); + } + TruffleObject empty = createEmptyTruffleObject(); + if (empty != null) { + testKeys(empty); + } + return null; + }); } private void testKeys(TruffleObject obj) throws UnknownIdentifierException, UnsupportedMessageException { @@ -232,17 +263,14 @@ public abstract class AbstractMRTest { for (String key : keys) { assertTrue(set.contains(key)); } + assertEquals(obj.getClass().getSimpleName() + " " + obj + " HAS_KEYS", true, ForeignAccess.sendHasKeys(Message.HAS_KEYS.createNode(), obj)); } catch (UnsupportedMessageException e) { assertEquals(obj.getClass().getSimpleName() + " " + obj + " HAS_KEYS", false, ForeignAccess.sendHasKeys(Message.HAS_KEYS.createNode(), obj)); } } - protected interface ForeignCall { - void call() throws Exception; - } - - protected void assertInteropException(ForeignCall c, Class<? extends InteropException> expectedClazz) { + protected void assertInteropException(Callable<Object> c, Class<? extends InteropException> expectedClazz) { boolean ie = false; try { c.call(); @@ -266,5 +294,4 @@ public abstract class AbstractMRTest { } } } - } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/ActiveBindingMRTest.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/ActiveBindingMRTest.java index 67876824be7055c2dbdb90e86f4c6fd95148662d..7a614f4e2a563876baacf9f94e85eca5f0300779 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/ActiveBindingMRTest.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/ActiveBindingMRTest.java @@ -23,11 +23,12 @@ package com.oracle.truffle.r.test.engine.interop; import com.oracle.truffle.api.interop.TruffleObject; -import com.oracle.truffle.api.source.Source; -import com.oracle.truffle.api.vm.PolyglotEngine; import com.oracle.truffle.r.runtime.RType; import com.oracle.truffle.r.runtime.data.RFunction; import com.oracle.truffle.r.runtime.env.frame.ActiveBinding; +import com.oracle.truffle.r.test.generate.FastRSession; +import org.graalvm.polyglot.Source; +import org.graalvm.polyglot.Value; import org.junit.Test; public class ActiveBindingMRTest extends AbstractMRTest { @@ -45,9 +46,9 @@ public class ActiveBindingMRTest extends AbstractMRTest { @Override protected TruffleObject[] createTruffleObjects() throws Exception { - Source src = Source.newBuilder("f=function() {}").mimeType("text/x-r").name("test.R").build(); - PolyglotEngine.Value result = engine.eval(src); - RFunction fn = result.as(RFunction.class); + Source src = Source.newBuilder("R", "f=function() {}", "<testfunction>").internal(true).buildLiteral(); + Value result = context.eval(src); + RFunction fn = (RFunction) FastRSession.getReceiver(result); return new TruffleObject[]{new ActiveBinding(RType.Any, fn)}; } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/ListMRTest.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/ListMRTest.java index 4830226aa9939392d3286e8b2cf2c18affa1f64f..7d810d68edf0319463a16a0b631ad8ca1b9c8e9b 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/ListMRTest.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/ListMRTest.java @@ -36,12 +36,12 @@ import com.oracle.truffle.api.interop.UnknownIdentifierException; import com.oracle.truffle.api.interop.UnsupportedMessageException; import com.oracle.truffle.api.interop.UnsupportedTypeException; import com.oracle.truffle.api.interop.java.JavaInterop; -import com.oracle.truffle.api.source.Source; -import com.oracle.truffle.api.vm.PolyglotEngine; import com.oracle.truffle.r.runtime.data.RList; import com.oracle.truffle.r.runtime.data.RNull; import com.oracle.truffle.r.runtime.data.RPairList; import com.oracle.truffle.r.runtime.data.model.RAbstractContainer; +import com.oracle.truffle.r.test.generate.FastRSession; +import org.graalvm.polyglot.Value; public class ListMRTest extends AbstractMRTest { @@ -62,39 +62,41 @@ public class ListMRTest extends AbstractMRTest { } private void testKeysReadWrite(String createFun) throws UnsupportedMessageException, UnknownIdentifierException, UnsupportedTypeException { + execInContext(() -> { + RAbstractContainer l = create(createFun, testValues); - RAbstractContainer l = create(createFun, testValues); + assertEquals(1, ForeignAccess.sendRead(Message.READ.createNode(), l, "i")); + assertEquals(2.1, ForeignAccess.sendRead(Message.READ.createNode(), l, "d")); + assertEquals(true, ForeignAccess.sendRead(Message.READ.createNode(), l, "b")); + assertTrue(ForeignAccess.sendRead(Message.READ.createNode(), l, "n") instanceof RNull); - assertEquals(1, ForeignAccess.sendRead(Message.READ.createNode(), l, "i")); - assertEquals(2.1, ForeignAccess.sendRead(Message.READ.createNode(), l, "d")); - assertEquals(true, ForeignAccess.sendRead(Message.READ.createNode(), l, "b")); - assertTrue(ForeignAccess.sendRead(Message.READ.createNode(), l, "n") instanceof RNull); + assertEquals(1, ForeignAccess.sendRead(Message.READ.createNode(), l, 0)); + assertEquals(2.1, ForeignAccess.sendRead(Message.READ.createNode(), l, 1)); + assertEquals(4d, ForeignAccess.sendRead(Message.READ.createNode(), l, 5d)); + assertEquals(true, ForeignAccess.sendRead(Message.READ.createNode(), l, 2)); + assertTrue(ForeignAccess.sendRead(Message.READ.createNode(), l, 4) instanceof RNull); - assertEquals(1, ForeignAccess.sendRead(Message.READ.createNode(), l, 0)); - assertEquals(2.1, ForeignAccess.sendRead(Message.READ.createNode(), l, 1)); - assertEquals(4d, ForeignAccess.sendRead(Message.READ.createNode(), l, 5d)); - assertEquals(true, ForeignAccess.sendRead(Message.READ.createNode(), l, 2)); - assertTrue(ForeignAccess.sendRead(Message.READ.createNode(), l, 4) instanceof RNull); + assertInteropException(() -> ForeignAccess.sendRead(Message.READ.createNode(), l, -1), UnknownIdentifierException.class); + assertInteropException(() -> ForeignAccess.sendRead(Message.READ.createNode(), l, 0f), UnknownIdentifierException.class); - assertInteropException(() -> ForeignAccess.sendRead(Message.READ.createNode(), l, -1), UnknownIdentifierException.class); - assertInteropException(() -> ForeignAccess.sendRead(Message.READ.createNode(), l, 0f), UnknownIdentifierException.class); + assertInteropException(() -> ForeignAccess.sendRead(Message.READ.createNode(), l, "nnnoooonnne"), UnknownIdentifierException.class); + assertInteropException(() -> ForeignAccess.sendRead(Message.READ.createNode(), l, 100), UnknownIdentifierException.class); - assertInteropException(() -> ForeignAccess.sendRead(Message.READ.createNode(), l, "nnnoooonnne"), UnknownIdentifierException.class); - assertInteropException(() -> ForeignAccess.sendRead(Message.READ.createNode(), l, 100), UnknownIdentifierException.class); + TruffleObject obj = (TruffleObject) ForeignAccess.sendWrite(Message.WRITE.createNode(), l, "d", 123.1); + assertEquals(123.1, ForeignAccess.sendRead(Message.READ.createNode(), obj, "d")); - TruffleObject obj = (TruffleObject) ForeignAccess.sendWrite(Message.WRITE.createNode(), l, "d", 123.1); - assertEquals(123.1, ForeignAccess.sendRead(Message.READ.createNode(), obj, "d")); + obj = (TruffleObject) ForeignAccess.sendWrite(Message.WRITE.createNode(), l, 2, false); + RAbstractContainer returnedList = JavaInterop.asJavaObject(RAbstractContainer.class, obj); + assertEquals((byte) 0, returnedList.getDataAtAsObject(2)); + assertEquals(false, ForeignAccess.sendRead(Message.READ.createNode(), obj, "b")); - obj = (TruffleObject) ForeignAccess.sendWrite(Message.WRITE.createNode(), l, 2, false); - RAbstractContainer returnedList = JavaInterop.asJavaObject(RAbstractContainer.class, obj); - assertEquals((byte) 0, returnedList.getDataAtAsObject(2)); - assertEquals(false, ForeignAccess.sendRead(Message.READ.createNode(), obj, "b")); + obj = (TruffleObject) ForeignAccess.sendWrite(Message.WRITE.createNode(), l, "newnew", "nneeww"); + assertEquals("nneeww", ForeignAccess.sendRead(Message.READ.createNode(), obj, "newnew")); - obj = (TruffleObject) ForeignAccess.sendWrite(Message.WRITE.createNode(), l, "newnew", "nneeww"); - assertEquals("nneeww", ForeignAccess.sendRead(Message.READ.createNode(), obj, "newnew")); - - assertInteropException(() -> ForeignAccess.sendWrite(Message.WRITE.createNode(), l, 0f, false), UnknownIdentifierException.class); - assertInteropException(() -> ForeignAccess.sendWrite(Message.WRITE.createNode(), l, 0d, false), UnknownIdentifierException.class); + assertInteropException(() -> ForeignAccess.sendWrite(Message.WRITE.createNode(), l, 0f, false), UnknownIdentifierException.class); + assertInteropException(() -> ForeignAccess.sendWrite(Message.WRITE.createNode(), l, 0d, false), UnknownIdentifierException.class); + return null; + }); } @Test @@ -104,58 +106,60 @@ public class ListMRTest extends AbstractMRTest { } public void testKeysInfo(String createFun) { - - RAbstractContainer l = create(createFun, testValues); - - int info = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), l, "nnoonnee"); - assertFalse(KeyInfo.isExisting(info)); - assertFalse(KeyInfo.isReadable(info)); - assertFalse(KeyInfo.isWritable(info)); - assertFalse(KeyInfo.isInvocable(info)); - assertFalse(KeyInfo.isInternal(info)); - - info = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), l, "d"); - assertTrue(KeyInfo.isExisting(info)); - assertTrue(KeyInfo.isReadable(info)); - assertTrue(KeyInfo.isWritable(info)); - assertFalse(KeyInfo.isInvocable(info)); - assertFalse(KeyInfo.isInternal(info)); - - info = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), l, "fn"); - assertTrue(KeyInfo.isExisting(info)); - assertTrue(KeyInfo.isReadable(info)); - assertTrue(KeyInfo.isWritable(info)); - assertTrue(KeyInfo.isInvocable(info)); - assertFalse(KeyInfo.isInternal(info)); - - info = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), l, -1); - assertFalse(KeyInfo.isExisting(info)); - - info = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), l, l.getLength()); - assertFalse(KeyInfo.isExisting(info)); - - info = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), l, 1f); - assertFalse(KeyInfo.isExisting(info)); - - info = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), l, 0); - assertTrue(KeyInfo.isExisting(info)); - assertTrue(KeyInfo.isReadable(info)); - assertTrue(KeyInfo.isWritable(info)); - assertFalse(KeyInfo.isInvocable(info)); - assertFalse(KeyInfo.isInternal(info)); - - info = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), l, 1d); - assertTrue(KeyInfo.isExisting(info)); - assertTrue(KeyInfo.isReadable(info)); - assertTrue(KeyInfo.isWritable(info)); - assertFalse(KeyInfo.isInvocable(info)); - assertFalse(KeyInfo.isInternal(info)); + execInContext(() -> { + RAbstractContainer l = create(createFun, testValues); + + int info = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), l, "nnoonnee"); + assertFalse(KeyInfo.isExisting(info)); + assertFalse(KeyInfo.isReadable(info)); + assertFalse(KeyInfo.isWritable(info)); + assertFalse(KeyInfo.isInvocable(info)); + assertFalse(KeyInfo.isInternal(info)); + + info = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), l, "d"); + assertTrue(KeyInfo.isExisting(info)); + assertTrue(KeyInfo.isReadable(info)); + assertTrue(KeyInfo.isWritable(info)); + assertFalse(KeyInfo.isInvocable(info)); + assertFalse(KeyInfo.isInternal(info)); + + info = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), l, "fn"); + assertTrue(KeyInfo.isExisting(info)); + assertTrue(KeyInfo.isReadable(info)); + assertTrue(KeyInfo.isWritable(info)); + assertTrue(KeyInfo.isInvocable(info)); + assertFalse(KeyInfo.isInternal(info)); + + info = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), l, -1); + assertFalse(KeyInfo.isExisting(info)); + + info = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), l, l.getLength()); + assertFalse(KeyInfo.isExisting(info)); + + info = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), l, 1f); + assertFalse(KeyInfo.isExisting(info)); + + info = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), l, 0); + assertTrue(KeyInfo.isExisting(info)); + assertTrue(KeyInfo.isReadable(info)); + assertTrue(KeyInfo.isWritable(info)); + assertFalse(KeyInfo.isInvocable(info)); + assertFalse(KeyInfo.isInternal(info)); + + info = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), l, 1d); + assertTrue(KeyInfo.isExisting(info)); + assertTrue(KeyInfo.isReadable(info)); + assertTrue(KeyInfo.isWritable(info)); + assertFalse(KeyInfo.isInvocable(info)); + assertFalse(KeyInfo.isInternal(info)); + return null; + }); } private static RAbstractContainer create(String createFun, String values) { - Source src = Source.newBuilder(createFun + "(" + values + ")").mimeType("text/x-r").name("test.R").build(); - PolyglotEngine.Value result = engine.eval(src); - return result.as(RAbstractContainer.class); + org.graalvm.polyglot.Source src = org.graalvm.polyglot.Source.newBuilder("R", createFun + "(" + values + ")", "<testrlist>").internal(true).buildLiteral(); + Value result = context.eval(src); + return (RAbstractContainer) FastRSession.getReceiver(result); } @Override diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/RArgsValuesAndNamesMRTest.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/RArgsValuesAndNamesMRTest.java index 7c81adcfafdda40bcb94ce911414375c343f9df9..04e48b22218dc6f851e86fb6fe0b07c849309f5f 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/RArgsValuesAndNamesMRTest.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/RArgsValuesAndNamesMRTest.java @@ -28,13 +28,14 @@ import com.oracle.truffle.api.interop.Message; import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.interop.UnknownIdentifierException; import com.oracle.truffle.api.interop.UnsupportedMessageException; -import com.oracle.truffle.api.source.Source; -import com.oracle.truffle.api.vm.PolyglotEngine; import com.oracle.truffle.r.runtime.ArgumentsSignature; import com.oracle.truffle.r.runtime.RRuntime; import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; import com.oracle.truffle.r.runtime.data.RFunction; import com.oracle.truffle.r.runtime.data.RNull; +import com.oracle.truffle.r.test.generate.FastRSession; +import org.graalvm.polyglot.Source; +import org.graalvm.polyglot.Value; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -132,9 +133,9 @@ public class RArgsValuesAndNamesMRTest extends AbstractMRTest { @Override protected TruffleObject[] createTruffleObjects() throws Exception { - Source src = Source.newBuilder("f=function() {}").mimeType("text/x-r").name("test.R").build(); - PolyglotEngine.Value result = engine.eval(src); - RFunction fn = result.as(RFunction.class); + Source src = Source.newBuilder("R", "f=function() {}", "<testfunction>").internal(true).buildLiteral(); + Value result = context.eval(src); + RFunction fn = (RFunction) FastRSession.getReceiver(result); Object[] values = {"abc", 123, 1.1, RRuntime.asLogical(true), fn, RNull.instance}; return new TruffleObject[]{new RArgsValuesAndNames(values, ArgumentsSignature.get(names))}; } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/REnvironmentMRTest.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/REnvironmentMRTest.java index f84dd63dec2e8211d21b86bb0a2817729b9472fb..b18b2fc68b2a7bb59186b01136e1361441a0edda 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/REnvironmentMRTest.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/REnvironmentMRTest.java @@ -35,9 +35,9 @@ import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.interop.UnknownIdentifierException; import com.oracle.truffle.api.interop.UnsupportedMessageException; import com.oracle.truffle.api.interop.java.JavaInterop; -import com.oracle.truffle.api.source.Source; -import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.env.REnvironment; +import com.oracle.truffle.r.test.generate.FastRSession; +import org.graalvm.polyglot.Source; public class REnvironmentMRTest extends AbstractMRTest { @@ -133,9 +133,9 @@ public class REnvironmentMRTest extends AbstractMRTest { @Override protected TruffleObject[] createTruffleObjects() throws Exception { - Source src = Source.newBuilder("e <- new.env(); e$s <- 'aaa'; e$i <- 123L; e$d <- 123.1; e$b <- TRUE; e$fn <- function() {}; e$n <- NULL; e$l <- 666; lockBinding('l', e); e").mimeType( - "text/x-r").name("test.R").build(); - return new TruffleObject[]{engine.eval(src).as(REnvironment.class)}; + Source src = Source.newBuilder("R", "e <- new.env(); e$s <- 'aaa'; e$i <- 123L; e$d <- 123.1; e$b <- TRUE; e$fn <- function() {}; e$n <- NULL; e$l <- 666; lockBinding('l', e); e", + "<testenv>").internal(true).buildLiteral(); + return new TruffleObject[]{(TruffleObject) FastRSession.getReceiver(context.eval(src))}; } @Override diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/RFunctionMRTest.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/RFunctionMRTest.java index 86b260ec4b60f5b99cbf1eb37b57114c21aee416..a4068db583ae2d5be1489d0c5a362cca92161d92 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/RFunctionMRTest.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/RFunctionMRTest.java @@ -33,9 +33,10 @@ import com.oracle.truffle.api.interop.Message; import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.interop.UnsupportedMessageException; import com.oracle.truffle.api.interop.UnsupportedTypeException; -import com.oracle.truffle.api.source.Source; -import com.oracle.truffle.api.vm.PolyglotEngine; import com.oracle.truffle.r.runtime.data.RFunction; +import com.oracle.truffle.r.test.generate.FastRSession; +import org.graalvm.polyglot.Source; +import org.graalvm.polyglot.Value; public class RFunctionMRTest extends AbstractMRTest { @@ -73,9 +74,9 @@ public class RFunctionMRTest extends AbstractMRTest { } private static RFunction create(String fun) { - Source src = Source.newBuilder(fun).mimeType("text/x-r").name("test.R").build(); - PolyglotEngine.Value result = engine.eval(src); - return result.as(RFunction.class); + Source src = Source.newBuilder("R", fun, "<testrfunction>").internal(true).buildLiteral(); + Value result = context.eval(src); + return (RFunction) FastRSession.getReceiver(result); } @Override diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/RInteropScalarMRTest.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/RInteropScalarMRTest.java index 745c81dee1913eb598ee2d1bd6261407b129254b..38283b935412ad28af30034f10540ec8d79641de 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/RInteropScalarMRTest.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/RInteropScalarMRTest.java @@ -38,10 +38,13 @@ public class RInteropScalarMRTest extends AbstractMRTest { @Test public void testRInteroptScalar() throws Exception { - for (TruffleObject obj : createTruffleObjects()) { - RInteropScalar is = (RInteropScalar) obj; - testRIS(obj, is.getJavaType()); - } + execInContext(() -> { + for (TruffleObject obj : createTruffleObjects()) { + RInteropScalar is = (RInteropScalar) obj; + testRIS(obj, is.getJavaType()); + } + return null; + }); } private static void testRIS(TruffleObject obj, Class<?> unboxedType) throws Exception { diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/RLanguageMRTest.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/RLanguageMRTest.java index 592989add2aafc6ece1add6385f496f2ac00f7ae..66e0ff602c8c224e24604e50c80fcd8212d28247 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/RLanguageMRTest.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/RLanguageMRTest.java @@ -34,9 +34,10 @@ import com.oracle.truffle.api.interop.Message; import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.interop.UnknownIdentifierException; import com.oracle.truffle.api.interop.UnsupportedMessageException; -import com.oracle.truffle.api.source.Source; -import com.oracle.truffle.api.vm.PolyglotEngine; import com.oracle.truffle.r.runtime.data.RLanguage; +import com.oracle.truffle.r.test.generate.FastRSession; +import org.graalvm.polyglot.Source; +import org.graalvm.polyglot.Value; public class RLanguageMRTest extends AbstractMRTest { @@ -95,9 +96,9 @@ public class RLanguageMRTest extends AbstractMRTest { protected TruffleObject[] createTruffleObjects() { // TODO any simpler way to create a RLanguage ? String srcTxt = "ne <- new.env(); delayedAssign('x', 1 + 2, assign.env = ne); substitute(x, ne)"; - Source src = Source.newBuilder(srcTxt).mimeType("text/x-r").name("test.R").build(); - PolyglotEngine.Value result = engine.eval(src); - return new TruffleObject[]{result.as(RLanguage.class)}; + Source src = Source.newBuilder("R", srcTxt, "<testrlanguage>").internal(true).buildLiteral(); + Value result = context.eval(src); + return new TruffleObject[]{(TruffleObject) FastRSession.getReceiver(result)}; } @Override diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/RS4ObjectMRTest.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/RS4ObjectMRTest.java index 858f2687b92cd9ea4b17300951cbe52599720041..ed13362b0484d3b79d51ee6bf3ecc32eb0cdf549 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/RS4ObjectMRTest.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/RS4ObjectMRTest.java @@ -34,9 +34,10 @@ import com.oracle.truffle.api.interop.Message; import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.interop.UnknownIdentifierException; import com.oracle.truffle.api.interop.UnsupportedMessageException; -import com.oracle.truffle.api.source.Source; -import com.oracle.truffle.api.vm.PolyglotEngine; import com.oracle.truffle.r.runtime.data.RS4Object; +import com.oracle.truffle.r.test.generate.FastRSession; +import org.graalvm.polyglot.Source; +import org.graalvm.polyglot.Value; public class RS4ObjectMRTest extends AbstractMRTest { @@ -118,9 +119,9 @@ public class RS4ObjectMRTest extends AbstractMRTest { protected TruffleObject[] createTruffleObjects() { String srcTxt = "setClass('test', representation(s = 'character', d = 'numeric', i = 'integer', b = 'logical', fn = 'function'));" + "new('test', s = 'aaa', d = 1.1, i=123L, b = TRUE, fn = function() {})"; - Source src = Source.newBuilder(srcTxt).mimeType("text/x-r").name("test.R").build(); - PolyglotEngine.Value result = engine.eval(src); - RS4Object s4 = result.as(RS4Object.class); + Source src = Source.newBuilder("R", srcTxt, "<testS4object>").internal(true).buildLiteral(); + Value result = context.eval(src); + RS4Object s4 = (RS4Object) FastRSession.getReceiver(result); return new TruffleObject[]{s4}; } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/VectorMRTest.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/VectorMRTest.java index 67c3f0c75676ad68e80352b938929d8ee61d4cda..13d804ae68ac7faa36085f67136bbed8c1a0a5b4 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/VectorMRTest.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/engine/interop/VectorMRTest.java @@ -22,7 +22,6 @@ */ package com.oracle.truffle.r.test.engine.interop; -import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -35,71 +34,77 @@ import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.interop.UnknownIdentifierException; import com.oracle.truffle.api.interop.UnsupportedMessageException; import com.oracle.truffle.api.interop.java.JavaInterop; -import com.oracle.truffle.api.source.Source; import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RObject; import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector; import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; import com.oracle.truffle.r.runtime.data.model.RAbstractVector; +import static org.junit.Assert.assertEquals; public class VectorMRTest extends AbstractMRTest { @Test public void testReadWrite() throws Exception { - final TruffleObject vi = create("1L:10L"); - assertEquals(3, ForeignAccess.sendRead(Message.READ.createNode(), vi, 2)); - assertEquals(3, ForeignAccess.sendRead(Message.READ.createNode(), vi, 2L)); - - assertInteropException(() -> ForeignAccess.sendRead(Message.READ.createNode(), vi, "a"), UnknownIdentifierException.class); - assertInteropException(() -> ForeignAccess.sendRead(Message.READ.createNode(), vi, 100), UnknownIdentifierException.class); - assertInteropException(() -> ForeignAccess.sendWrite(Message.WRITE.createNode(), vi, "s", "abc"), UnknownIdentifierException.class); - - TruffleObject vd = create("1.1:10.1"); - assertEquals(1.1, ForeignAccess.sendRead(Message.READ.createNode(), vd, 0)); - - TruffleObject vb = create("c(TRUE, FALSE, TRUE)"); - assertEquals(true, ForeignAccess.sendRead(Message.READ.createNode(), vb, 0)); - - TruffleObject nvi = (TruffleObject) ForeignAccess.sendWrite(Message.WRITE.createNode(), vi, 0, 123); - RAbstractIntVector returnedVec = JavaInterop.asJavaObject(RAbstractIntVector.class, nvi); - assertEquals(123, returnedVec.getDataAt(0)); - assertEquals(123, ForeignAccess.sendRead(Message.READ.createNode(), nvi, 0)); - - assertEquals(10, ForeignAccess.sendGetSize(Message.GET_SIZE.createNode(), nvi)); - nvi = (TruffleObject) ForeignAccess.sendWrite(Message.WRITE.createNode(), nvi, 100, 321); - assertEquals(101, ForeignAccess.sendGetSize(Message.GET_SIZE.createNode(), nvi)); - assertEquals(321, ForeignAccess.sendRead(Message.READ.createNode(), nvi, 100)); - - nvi = (TruffleObject) ForeignAccess.sendWrite(Message.WRITE.createNode(), nvi, 0, "abc"); - RAbstractVector vec = JavaInterop.asJavaObject(RAbstractVector.class, nvi); - assertTrue(vec instanceof RAbstractStringVector); - assertEquals("abc", ForeignAccess.sendRead(Message.READ.createNode(), nvi, 0)); + execInContext(() -> { + final TruffleObject vi = RDataFactory.createIntSequence(1, 1, 10); + assertEquals(3, ForeignAccess.sendRead(Message.READ.createNode(), vi, 2)); + assertEquals(3, ForeignAccess.sendRead(Message.READ.createNode(), vi, 2L)); + + assertInteropException(() -> ForeignAccess.sendRead(Message.READ.createNode(), vi, "a"), UnknownIdentifierException.class); + assertInteropException(() -> ForeignAccess.sendRead(Message.READ.createNode(), vi, 100), UnknownIdentifierException.class); + assertInteropException(() -> ForeignAccess.sendWrite(Message.WRITE.createNode(), vi, "s", "abc"), UnknownIdentifierException.class); + + TruffleObject vd = RDataFactory.createDoubleSequence(1.1, 1, 10); + assertEquals(1.1, ForeignAccess.sendRead(Message.READ.createNode(), vd, 0)); + + TruffleObject vb = RDataFactory.createLogicalVector(new byte[]{1, 0, 1}, true); + assertEquals(true, ForeignAccess.sendRead(Message.READ.createNode(), vb, 0)); + + TruffleObject nvi = (TruffleObject) ForeignAccess.sendWrite(Message.WRITE.createNode(), vi, 0, 123); + RAbstractIntVector returnedVec = JavaInterop.asJavaObject(RAbstractIntVector.class, nvi); + assertEquals(123, returnedVec.getDataAt(0)); + assertEquals(123, ForeignAccess.sendRead(Message.READ.createNode(), nvi, 0)); + + assertEquals(10, ForeignAccess.sendGetSize(Message.GET_SIZE.createNode(), nvi)); + nvi = (TruffleObject) ForeignAccess.sendWrite(Message.WRITE.createNode(), nvi, 100, 321); + assertEquals(101, ForeignAccess.sendGetSize(Message.GET_SIZE.createNode(), nvi)); + assertEquals(321, ForeignAccess.sendRead(Message.READ.createNode(), nvi, 100)); + + nvi = (TruffleObject) ForeignAccess.sendWrite(Message.WRITE.createNode(), nvi, 0, "abc"); + RAbstractVector vec = JavaInterop.asJavaObject(RAbstractVector.class, nvi); + assertTrue(vec instanceof RAbstractStringVector); + assertEquals("abc", ForeignAccess.sendRead(Message.READ.createNode(), nvi, 0)); + return null; + }); } @Test public void testKeyInfo() throws Exception { - TruffleObject v = create("c(TRUE, FALSE, TRUE)"); - assertInteropException(() -> ForeignAccess.sendKeys(Message.KEYS.createNode(), v), UnsupportedMessageException.class); - - int keyInfo = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), v, 0); - assertTrue(KeyInfo.isExisting(keyInfo)); - assertTrue(KeyInfo.isReadable(keyInfo)); - assertTrue(KeyInfo.isWritable(keyInfo)); - assertFalse(KeyInfo.isInvocable(keyInfo)); - assertFalse(KeyInfo.isInternal(keyInfo)); - - keyInfo = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), v, 100); - assertFalse(KeyInfo.isExisting(keyInfo)); + execInContext(() -> { + TruffleObject v = RDataFactory.createLogicalVector(new byte[]{1, 0, 1}, true); + assertInteropException(() -> ForeignAccess.sendKeys(Message.KEYS.createNode(), v), UnsupportedMessageException.class); + + int keyInfo = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), v, 0); + assertTrue(KeyInfo.isExisting(keyInfo)); + assertTrue(KeyInfo.isReadable(keyInfo)); + assertTrue(KeyInfo.isWritable(keyInfo)); + assertFalse(KeyInfo.isInvocable(keyInfo)); + assertFalse(KeyInfo.isInternal(keyInfo)); + + keyInfo = ForeignAccess.sendKeyInfo(Message.KEY_INFO.createNode(), v, 100); + assertFalse(KeyInfo.isExisting(keyInfo)); + return null; + }); } @Override protected TruffleObject[] createTruffleObjects() throws Exception { - return new TruffleObject[]{RDataFactory.createDoubleVector(new double[]{1}, true), create("c(1:10)"), create("as.numeric()")}; + return new TruffleObject[]{RDataFactory.createDoubleVector(new double[]{1}, true), RDataFactory.createDoubleSequence(1, 1, 10), createEmptyTruffleObject()}; } @Override protected TruffleObject createEmptyTruffleObject() throws Exception { - return create("as.numeric()"); + return RDataFactory.createDoubleVector(new double[]{}, true); } @Override @@ -118,8 +123,4 @@ public class VectorMRTest extends AbstractMRTest { return ((RAbstractVector) obj).getLength(); } - private static TruffleObject create(String createTxt) throws Exception { - Source src = Source.newBuilder(createTxt).mimeType("text/x-r").name("test.R").build(); - return engine.eval(src).as(RAbstractVector.class); - } } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/generate/FastRSession.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/generate/FastRSession.java index b03e4a7ac0b900141e3d85fbb33ac7dc3232e026..7f094f6f47d21b33e9391a8792138c2398279124 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/generate/FastRSession.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/generate/FastRSession.java @@ -38,13 +38,10 @@ import java.util.TimerTask; import com.oracle.truffle.api.debug.Debugger; import com.oracle.truffle.api.debug.SuspendedCallback; import com.oracle.truffle.api.debug.SuspendedEvent; -import com.oracle.truffle.api.source.Source; -import com.oracle.truffle.api.vm.PolyglotEngine; import com.oracle.truffle.r.launcher.RCmdOptions; import com.oracle.truffle.r.launcher.RCmdOptions.Client; import com.oracle.truffle.r.launcher.RStartParams; import com.oracle.truffle.r.runtime.ExitException; -import com.oracle.truffle.r.runtime.FastROptions; import com.oracle.truffle.r.runtime.JumpToTopLevelException; import com.oracle.truffle.r.runtime.RError; import com.oracle.truffle.r.runtime.RInternalError; @@ -55,9 +52,28 @@ import com.oracle.truffle.r.runtime.context.Engine.ParseException; import com.oracle.truffle.r.runtime.context.RContext; import com.oracle.truffle.r.runtime.context.RContext.ContextKind; import com.oracle.truffle.r.test.TestBase; +import com.oracle.truffle.r.test.engine.interop.AbstractMRTest; +import com.oracle.truffle.r.test.engine.interop.VectorMRTest; +import java.io.IOException; +import java.lang.reflect.AccessibleObject; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.concurrent.Callable; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.graalvm.polyglot.Context; +import org.graalvm.polyglot.Engine; +import org.graalvm.polyglot.Instrument; +import org.graalvm.polyglot.PolyglotException; +import org.graalvm.polyglot.Source; +import org.graalvm.polyglot.Value; +import org.graalvm.polyglot.proxy.ProxyExecutable; +import static org.junit.Assert.fail; public final class FastRSession implements RSession { + public static final Source GET_CONTEXT = createSource("invisible(.fastr.context.get())", RSource.Internal.GET_CONTEXT.string); + private static final String TEST_TIMEOUT_PROPERTY = "fastr.test.timeout"; private static int timeoutValue = 10000; /** @@ -66,6 +82,14 @@ public final class FastRSession implements RSession { */ private static int longTimeoutValue = 300000; + private static FastRSession singleton; + + private final ByteArrayOutputStream output = new ByteArrayOutputStream(); + private final TestByteArrayInputStream input = new TestByteArrayInputStream(); + + private Context mainContext; + private RContext mainRContext; + private static final class TestByteArrayInputStream extends ByteArrayInputStream { TestByteArrayInputStream() { @@ -84,25 +108,24 @@ public final class FastRSession implements RSession { } } - private static FastRSession singleton; - - private final ByteArrayOutputStream output = new ByteArrayOutputStream(); - private final TestByteArrayInputStream input = new TestByteArrayInputStream(); - private final PolyglotEngine main; - private final RContext mainContext; - public static FastRSession create() { if (singleton == null) { - FastROptions.setValue("SpawnUsesPolyglot", true); singleton = new FastRSession(); } return singleton; } - public static final Source GET_CONTEXT = RSource.fromTextInternal("invisible(.fastr.context.get())", RSource.Internal.GET_CONTEXT); + public static Source createSource(String txt, String name) { + try { + return Source.newBuilder("R", txt, name).internal(true).interactive(true).build(); + } catch (IOException ex) { + Logger.getLogger(FastRSession.class.getName()).log(Level.SEVERE, null, ex); + assert false; + } + return null; + } public ChildContextInfo checkContext(ChildContextInfo contextInfoArg) { - create(); ChildContextInfo contextInfo; if (contextInfoArg == null) { contextInfo = createContextInfo(ContextKind.SHARE_PARENT_RW); @@ -116,7 +139,13 @@ public final class FastRSession implements RSession { RStartParams params = new RStartParams(RCmdOptions.parseArguments(Client.R, new String[]{"R", "--vanilla", "--slave", "--silent", "--no-restore"}, false), false); Map<String, String> env = new HashMap<>(); env.put("TZ", "GMT"); - return ChildContextInfo.create(params, env, contextKind, mainContext, input, output, output); + ChildContextInfo ctx = ChildContextInfo.create(params, env, contextKind, mainRContext, input, output, output); + RContext.childInfo = ctx; + return ctx; + } + + public Context createContext() { + return Context.newBuilder("R").in(input).out(output).err(output).build(); } private FastRSession() { @@ -134,8 +163,9 @@ public final class FastRSession implements RSession { try { RStartParams params = new RStartParams(RCmdOptions.parseArguments(Client.R, new String[]{"R", "--vanilla", "--slave", "--silent", "--no-restore"}, false), false); ChildContextInfo info = ChildContextInfo.create(params, null, ContextKind.SHARE_NOTHING, null, input, output, output); - main = info.createVM(); - mainContext = main.eval(GET_CONTEXT).as(RContext.class); + RContext.childInfo = info; + mainContext = createContext(); + mainRContext = mainContext.eval(GET_CONTEXT).asHostObject(); } finally { try { System.out.print(output.toString("UTF-8")); @@ -153,7 +183,7 @@ public final class FastRSession implements RSession { } public RContext getContext() { - return mainContext; + return mainRContext; } private String readLine() { @@ -195,28 +225,25 @@ public final class FastRSession implements RSession { output.reset(); input.setContents(expression); try { - ChildContextInfo actualContextInfo = checkContext(contextInfo); + checkContext(contextInfo); + Context evalContext = createContext(); // set up some interop objects used by fastr-specific tests: - PolyglotEngine.Builder builder = PolyglotEngine.newBuilder(); if (testClass != null) { - testClass.addPolyglotSymbols(builder); + testClass.addPolyglotSymbols(evalContext); } - PolyglotEngine vm = actualContextInfo.createVM(builder); - timer = scheduleTimeBoxing(vm, longTimeout ? longTimeoutValue : timeoutValue); + timer = scheduleTimeBoxing(evalContext.getEngine(), longTimeout ? longTimeoutValue : timeoutValue); try { String consoleInput = readLine(); while (consoleInput != null) { - Source source = RSource.fromTextInternal(consoleInput, RSource.Internal.UNIT_TEST); try { try { - vm.eval(source); - // checked exceptions are wrapped in RuntimeExceptions - } catch (RuntimeException e) { - if (e.getCause() instanceof com.oracle.truffle.api.vm.IncompleteSourceException) { - throw e.getCause().getCause(); - } else { - throw e; - } + Source src = createSource(consoleInput, RSource.Internal.UNIT_TEST.string); + evalContext.eval(src); + // checked exceptions are wrapped in PolyglotException + } catch (PolyglotException e) { + // TODO need the wrapped exception for special handling of: + // ParseException, RError, ... see bellow + throw getWrappedThrowable(e); } consoleInput = readLine(); } catch (IncompleteSourceException e) { @@ -228,7 +255,7 @@ public final class FastRSession implements RSession { } } } finally { - vm.dispose(); + evalContext.close(); } } catch (ParseException e) { e.report(output); @@ -258,12 +285,19 @@ public final class FastRSession implements RSession { } } - private static Timer scheduleTimeBoxing(PolyglotEngine engine, long timeout) { + private Throwable getWrappedThrowable(PolyglotException e) { + Object f = getField(e, "impl"); + return (Throwable) getField(f, "exception"); + } + + private static Timer scheduleTimeBoxing(Engine engine, long timeout) { Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { - Debugger.find(engine).startSession(new SuspendedCallback() { + Instrument i = engine.getInstruments().get("debugger"); + Debugger debugger = i.lookup(Debugger.class); + debugger.startSession(new SuspendedCallback() { @Override public void onSuspend(SuspendedEvent event) { event.prepareKill(); @@ -278,4 +312,87 @@ public final class FastRSession implements RSession { public String name() { return "FastR"; } + + public static Object getReceiver(Value value) { + return getField(value, "receiver"); + } + + // Copied from ReflectionUtils. + // TODO we need better support to access the TruffleObject in Value + private static Object getField(Object value, String name) { + try { + Field f = value.getClass().getDeclaredField(name); + setAccessible(f, true); + return f.get(value); + } catch (Exception e) { + throw new AssertionError(e); + } + } + + private static final boolean Java8OrEarlier = System.getProperty("java.specification.version").compareTo("1.9") < 0; + + private static void setAccessible(Field field, boolean flag) { + if (!Java8OrEarlier) { + openForReflectionTo(field.getDeclaringClass(), FastRSession.class); + } + field.setAccessible(flag); + } + + /** + * Opens {@code declaringClass}'s package to allow a method declared in {@code accessor} to call + * {@link AccessibleObject#setAccessible(boolean)} on an {@link AccessibleObject} representing a + * field or method declared by {@code declaringClass}. + */ + private static void openForReflectionTo(Class<?> declaringClass, Class<?> accessor) { + try { + Method getModule = Class.class.getMethod("getModule"); + Class<?> moduleClass = getModule.getReturnType(); + Class<?> modulesClass = Class.forName("jdk.internal.module.Modules"); + Method addOpens = maybeGetAddOpensMethod(moduleClass, modulesClass); + if (addOpens != null) { + Object moduleToOpen = getModule.invoke(declaringClass); + Object accessorModule = getModule.invoke(accessor); + if (moduleToOpen != accessorModule) { + addOpens.invoke(null, moduleToOpen, declaringClass.getPackage().getName(), accessorModule); + } + } + } catch (Exception e) { + throw new AssertionError(e); + } + } + + private static Method maybeGetAddOpensMethod(Class<?> moduleClass, Class<?> modulesClass) { + try { + return modulesClass.getDeclaredMethod("addOpens", moduleClass, String.class, moduleClass); + } catch (NoSuchMethodException e) { + // This method was introduced by JDK-8169069 + return null; + } + } + + public static void execInContext(Context context, Callable<Object> c) { + execInContext(context, c, (Class<?>) null); + } + + public static <E extends Exception> void execInContext(Context context, Callable<Object> c, Class<?>... acceptExceptions) { + context.eval(FastRSession.GET_CONTEXT); // ping creation of TruffleRLanguage + context.exportSymbol("testSymbol", (ProxyExecutable) (Value... args) -> { + try { + c.call(); + } catch (Exception ex) { + if (acceptExceptions != null) { + for (Class<?> cs : acceptExceptions) { + if (cs.isAssignableFrom(ex.getClass())) { + return null; + } + } + } + Logger.getLogger(VectorMRTest.class.getName()).log(Level.SEVERE, null, ex); + fail(); + } + return null; + }); + context.importSymbol("testSymbol").execute(); + } + } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/fastr/TestInterop.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/fastr/TestInterop.java index 2b58e81d5cebe875eb4013fdfe3c62c562d4acdb..ed097f703a71c7c03fb737b4c7885bb0071ef9bc 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/fastr/TestInterop.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/fastr/TestInterop.java @@ -29,7 +29,6 @@ import org.junit.Assert; import org.junit.Test; import com.oracle.truffle.api.interop.java.JavaInterop; -import com.oracle.truffle.api.vm.PolyglotEngine; import com.oracle.truffle.r.runtime.conn.SeekableMemoryByteChannel; import com.oracle.truffle.r.test.TestBase; import java.io.File; @@ -132,11 +131,11 @@ public class TestInterop extends TestBase { new TestJavaObject("testStringArray", new String[]{"a", "", "foo"})}; @Override - public void addPolyglotSymbols(PolyglotEngine.Builder builder) { + public void addPolyglotSymbols(org.graalvm.polyglot.Context context) { for (TestJavaObject t : TestInterop.testJavaObjects) { - builder.globalSymbol(t.name, JavaInterop.asTruffleObject(t.object)); + context.exportSymbol(t.name, JavaInterop.asTruffleObject(t.object)); } - builder.globalSymbol(CHANNEL_NAME, JavaInterop.asTruffleObject(CHANNEL)); + context.exportSymbol(CHANNEL_NAME, JavaInterop.asTruffleObject(CHANNEL)); } @Test diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/utils/TestInteractiveDebug.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/utils/TestInteractiveDebug.java index a6ffafd41c5dd209885cd199227edb9051ffae27..316a9fc7f77e5d57f98196fabd2da265d0aefdb7 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/utils/TestInteractiveDebug.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/utils/TestInteractiveDebug.java @@ -22,23 +22,45 @@ */ package com.oracle.truffle.r.test.library.utils; +import com.oracle.truffle.r.nodes.builtin.helpers.DebugHandling; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardOpenOption; -import org.junit.After; import org.junit.BeforeClass; import org.junit.Test; -import com.oracle.truffle.r.nodes.builtin.helpers.DebugHandling; import com.oracle.truffle.r.test.TestBase; +import com.oracle.truffle.r.test.generate.FastRSession; +import org.graalvm.polyglot.Value; +import org.graalvm.polyglot.proxy.ProxyExecutable; +import org.junit.After; +import static com.oracle.truffle.r.test.generate.FastRSession.execInContext; // Checkstyle: stop line length check public class TestInteractiveDebug extends TestBase { + private static Path debugFile; + + @BeforeClass + public static void setup() throws IOException { + Path testDir = TestBase.createTestDir("com.oracle.truffle.r.test.library.utils.rsrc"); + String content = "bar <- function(x) print(x)\n\nfun <- function(x) {\nprint('Hello')\nfor(i in seq(3)) print(i)\nbar('World')\nprint(x)\n}"; + debugFile = testDir.resolve("debug.r"); + Files.write(debugFile, content.getBytes(), StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); + } + @After public void cleanupDebugListeners() { - DebugHandling.dispose(); + + try (org.graalvm.polyglot.Context context = org.graalvm.polyglot.Context.newBuilder("R").build()) { + // a context has to be around when calling DebugHandling.dispose(); + execInContext(context, () -> { + DebugHandling.dispose(); + return null; + + }); + } } @Test @@ -113,16 +135,6 @@ public class TestInteractiveDebug extends TestBase { assertEval("options(error=browser); prod('a')\nwhere\nc\n"); } - private static Path debugFile; - - @BeforeClass - public static void setup() throws IOException { - Path testDir = TestBase.createTestDir("com.oracle.truffle.r.test.library.utils.rsrc"); - String content = "bar <- function(x) print(x)\n\nfun <- function(x) {\nprint('Hello')\nfor(i in seq(3)) print(i)\nbar('World')\nprint(x)\n}"; - debugFile = testDir.resolve("debug.r"); - Files.write(debugFile, content.getBytes(), StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); - } - @Test public void testSetBreakpoint() { assertEval(Output.IgnoreDebugCallString, Output.IgnoreDebugPath, String.format("source('%s'); setBreakpoint('%s', 4, verbose=F); fun(10)\n\n\n\n\n\n\n\n", debugFile, debugFile)); diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/tck/FastRDebugTest.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/tck/FastRDebugTest.java index 2c75a9d661537d6889d8ffeb1099a0e1016a388f..7840f6cb87e8653eea17ecfa02d6e7bc35afd854 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/tck/FastRDebugTest.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/tck/FastRDebugTest.java @@ -38,7 +38,6 @@ import java.util.concurrent.atomic.AtomicInteger; import org.junit.After; import org.junit.Assert; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import com.oracle.truffle.api.debug.Breakpoint; @@ -49,17 +48,15 @@ import com.oracle.truffle.api.debug.Debugger; import com.oracle.truffle.api.debug.DebuggerSession; import com.oracle.truffle.api.debug.SuspendedEvent; import com.oracle.truffle.api.debug.SuspensionFilter; -import com.oracle.truffle.api.source.Source; import com.oracle.truffle.api.source.SourceSection; -import com.oracle.truffle.api.vm.PolyglotEngine; -import com.oracle.truffle.api.vm.PolyglotEngine.Value; -import com.oracle.truffle.r.launcher.RCmdOptions.Client; -import com.oracle.truffle.r.runtime.RRuntime; -import com.oracle.truffle.r.runtime.context.ChildContextInfo; -import com.oracle.truffle.r.runtime.context.RContext.ContextKind; import com.oracle.truffle.r.runtime.data.RPromise.EagerPromise; import com.oracle.truffle.r.runtime.env.REnvironment; import com.oracle.truffle.r.runtime.env.frame.RFrameSlot; +import com.oracle.truffle.tck.DebuggerTester; +import org.graalvm.polyglot.Context; +import org.graalvm.polyglot.Source; +import org.graalvm.polyglot.Value; +import org.junit.Ignore; public class FastRDebugTest { private Debugger debugger; @@ -67,7 +64,7 @@ public class FastRDebugTest { private final LinkedList<Runnable> run = new LinkedList<>(); private SuspendedEvent suspendedEvent; private Throwable ex; - protected PolyglotEngine engine; + private Context context; protected final ByteArrayOutputStream out = new ByteArrayOutputStream(); protected final ByteArrayOutputStream err = new ByteArrayOutputStream(); @@ -75,9 +72,8 @@ public class FastRDebugTest { public void before() { suspendedEvent = null; - ChildContextInfo info = ChildContextInfo.createNoRestore(Client.R, null, ContextKind.SHARE_NOTHING, null, System.in, out, err); - engine = info.createVM(PolyglotEngine.newBuilder().setOut(out).setErr(err)); - debugger = Debugger.find(engine); + context = Context.newBuilder("R").in(System.in).out(out).err(err).build(); + debugger = context.getEngine().getInstruments().get("debugger").lookup(Debugger.class); debuggerSession = debugger.startSession(event -> { suspendedEvent = event; performWork(); @@ -89,17 +85,15 @@ public class FastRDebugTest { @After public void dispose() { + context.close(); debuggerSession.close(); - if (engine != null) { - engine.dispose(); - } } - private static Source sourceFromText(String code, String name) { - return Source.newBuilder(code).name(name).language("R").mimeType(RRuntime.R_APP_MIME).interactive().build(); + private static Source sourceFromText(String code, String name) throws IOException { + return Source.newBuilder("R", code, name).interactive(true).build(); } - private static Source createFactorial() { + private static Source createFactorial() throws IOException { return sourceFromText("main <- function() {\n" + " res = fac(2)\n" + " res\n" + @@ -117,7 +111,7 @@ public class FastRDebugTest { "factorial.r"); } - private static Source createRStatements() { + private static Source createRStatements() throws IOException { return sourceFromText("foo <- function(a) {\n" + " x = 2L * a\n" + "}\n" + @@ -150,12 +144,12 @@ public class FastRDebugTest { run.addLast(() -> { assertNull(suspendedEvent); assertNotNull(debuggerSession); - Breakpoint breakpoint = Breakpoint.newBuilder(factorial).lineIs(9).build(); + Breakpoint breakpoint = Breakpoint.newBuilder(DebuggerTester.getSourceImpl(factorial)).lineIs(9).build(); debuggerSession.install(breakpoint); }); // Init before eval: performWork(); - engine.eval(factorial); + context.eval(factorial); assertExecutedOK(); assertLocation(9, "nMinusOne = n - 1", @@ -163,12 +157,11 @@ public class FastRDebugTest { continueExecution(); final Source evalSrc = sourceFromText("main()\n", "test.r"); - final Value value = engine.eval(evalSrc); + final Value value = context.eval(evalSrc); assertExecutedOK(); Assert.assertEquals("[1] 2\n", getOut()); - final Number n = value.as(Number.class); - assertNotNull(n); - assertEquals("Factorial computed OK", 2, n.intValue()); + final int i = value.asInt(); + assertEquals("Factorial computed OK", 2, i); } /** @@ -183,12 +176,12 @@ public class FastRDebugTest { " }\n" + "}\n", "test.r"); - engine.eval(source); + context.eval(source); run.addLast(() -> { assertNull(suspendedEvent); assertNotNull(debuggerSession); - Breakpoint breakpoint = Breakpoint.newBuilder(source).lineIs(3).build(); + Breakpoint breakpoint = Breakpoint.newBuilder(DebuggerTester.getSourceImpl(source)).lineIs(3).build(); breakpoint.setCondition("i == 5"); debuggerSession.install(breakpoint); }); @@ -200,14 +193,14 @@ public class FastRDebugTest { performWork(); final Source evalSrc = sourceFromText("main()\n", "test.r"); - engine.eval(evalSrc); + context.eval(evalSrc); assertExecutedOK(); } @Test public void stepInStepOver() throws Throwable { final Source factorial = createFactorial(); - engine.eval(factorial); + context.eval(factorial); // @formatter:on run.addLast(() -> { @@ -245,25 +238,24 @@ public class FastRDebugTest { // Init before eval: performWork(); final Source evalSource = sourceFromText("main()\n", "evaltest.r"); - final Value value = engine.eval(evalSource); + final Value value = context.eval(evalSource); assertExecutedOK(); Assert.assertEquals("[1] 2\n", getOut()); - final Number n = value.as(Number.class); - assertNotNull(n); - assertEquals("Factorial computed OK", 2, n.intValue()); + final int i = value.asInt(); + assertEquals("Factorial computed OK", 2, i); } @Test public void testFindMetaObjectAndSourceLocation() throws Throwable { final Source source = sourceFromText("main <- function() {\n" + - " i = 3L\n" + - " n = 15\n" + - " str = 'hello'\n" + - " i <- i + 1L\n" + - " i\n" + + " i = 3L\n" + + " n = 15\n" + + " str = 'hello'\n" + + " i <- i + 1L\n" + + " i\n" + "}\n", "test.r"); - engine.eval(source); + context.eval(source); // @formatter:on run.addLast(() -> { @@ -280,7 +272,7 @@ public class FastRDebugTest { performWork(); final Source evalSource = sourceFromText("main()\n", "evaltest.r"); - engine.eval(evalSource); + context.eval(evalSource); assertExecutedOK(); } @@ -299,7 +291,7 @@ public class FastRDebugTest { "makeActiveBinding('ab', function(v) { if(missing(v)) x else x <<- v }, .GlobalEnv)\n" + "main <- " + srcFunMain.getCharacters() + "\n", "test.r"); - engine.eval(source); + context.eval(source); // @formatter:on run.addLast(() -> { @@ -326,7 +318,7 @@ public class FastRDebugTest { performWork(); final Source evalSource = sourceFromText("main()\n", "evaltest.r"); - engine.eval(evalSource); + context.eval(evalSource); assertExecutedOK(); } @@ -334,17 +326,17 @@ public class FastRDebugTest { @Test public void testScopePromise() throws Throwable { final Source source = sourceFromText("main <- function(e) {\n" + - " x <- 10L\n" + - " e()\n" + - " x\n" + + " x <- 10L\n" + + " e()\n" + + " x\n" + "}\n" + "closure <- function() {\n" + - " x <<- 123L\n" + - " x\n" + + " x <<- 123L\n" + + " x\n" + "}\n", "test.r"); - engine.eval(source); + context.eval(source); // @formatter:on run.addLast(() -> { @@ -366,7 +358,7 @@ public class FastRDebugTest { performWork(); final Source evalSource = sourceFromText("x <- 0L\nmain(closure)\n", "evaltest.r"); - engine.eval(evalSource); + context.eval(evalSource); assertExecutedOK(); } @@ -374,15 +366,15 @@ public class FastRDebugTest { @Test public void testScopeArguments() throws Throwable { final Source source = sourceFromText("main <- function(a, b, c, d) {\n" + - " x <- 10L\n" + + " x <- 10L\n" + "}\n" + "closure <- function() {\n" + - " x <<- 123L\n" + - " x\n" + + " x <<- 123L\n" + + " x\n" + "}\n", "test.r"); - engine.eval(source); + context.eval(source); // @formatter:on run.addLast(() -> { @@ -399,7 +391,7 @@ public class FastRDebugTest { performWork(); final Source evalSource = sourceFromText("main(1, 2, 3, 4)\n", "evaltest.r"); - engine.eval(evalSource); + context.eval(evalSource); assertExecutedOK(); } @@ -407,17 +399,17 @@ public class FastRDebugTest { @Test public void testChangedScopeChain() throws Throwable { final Source source = sourceFromText("main <- function(e) {\n" + - " x <- 10L\n" + - " environment(e) <- environment()\n" + - " e()\n" + - " x\n" + + " x <- 10L\n" + + " environment(e) <- environment()\n" + + " e()\n" + + " x\n" + "}\n" + "closure <- function() {\n" + - " x <<- 123L\n" + - " x\n" + + " x <<- 123L\n" + + " x\n" + "}\n", "test.r"); - engine.eval(source); + context.eval(source); // @formatter:on run.addLast(() -> { @@ -443,7 +435,7 @@ public class FastRDebugTest { performWork(); final Source evalSource = sourceFromText("x <- 0L\nmain(closure)\n", "evaltest.r"); - engine.eval(evalSource); + context.eval(evalSource); assertExecutedOK(); } @@ -473,14 +465,14 @@ public class FastRDebugTest { assertLocation(10, "print(foo(z))"); continueExecution(); performWork(); - engine.eval(createRStatements()); + context.eval(createRStatements()); assertExecutedOK(); } @Test public void testValueToString() throws Throwable { Source source = createFactorial(); - engine.eval(source); + context.eval(source); run.addLast(() -> { assertNull(suspendedEvent); @@ -499,7 +491,7 @@ public class FastRDebugTest { performWork(); final Source evalSource = sourceFromText("main()\n", "evaltest.r"); - engine.eval(evalSource); + context.eval(evalSource); assertExecutedOK(); } @@ -614,7 +606,7 @@ public class FastRDebugTest { DebugScope scope = frame.getScope(); if (scope == null) { - scope = suspendedEvent.getSession().getTopScope("application/x-r"); + scope = suspendedEvent.getSession().getTopScope("R"); } Set<String> actualIdentifiers = new HashSet<>(); @@ -670,7 +662,7 @@ public class FastRDebugTest { } if (value == null) { // Ask the top scope: - scope = suspendedEvent.getSession().getTopScope("application/x-r"); + scope = suspendedEvent.getSession().getTopScope("R"); do { value = scope.getDeclaredValue(expectedIdentifier); scope = scope.getParent(); @@ -738,7 +730,7 @@ public class FastRDebugTest { // Trigger findSourceLocation() call SourceSection sourceLocation = value.getSourceLocation(); if (sourceLocation != null) { - Assert.assertSame("Sources differ", expectedSource, sourceLocation.getSource()); + Assert.assertSame("Sources differ", DebuggerTester.getSourceImpl(expectedSource), sourceLocation.getSource()); } } }