Skip to content

Commit d23f69f

Browse files
committed
TruffleRLanguage#toString: treat primitive values from promises as R vectors
1 parent edd867f commit d23f69f

File tree

5 files changed

+43
-31
lines changed

5 files changed

+43
-31
lines changed

com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/TruffleRLanguageImpl.java

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@
4747
import com.oracle.truffle.r.nodes.instrumentation.RSyntaxTags.FunctionBodyBlockTag;
4848
import com.oracle.truffle.r.runtime.ArgumentsSignature;
4949
import com.oracle.truffle.r.runtime.ExitException;
50-
import com.oracle.truffle.r.runtime.RInternalError;
5150
import com.oracle.truffle.r.runtime.context.FastROptions;
5251
import com.oracle.truffle.r.runtime.RAccuracyInfo;
5352
import com.oracle.truffle.r.runtime.RCaller;
@@ -142,6 +141,15 @@ protected void disposeContext(RContext context) {
142141

143142
@Override
144143
protected String toString(RContext context, Object value) {
144+
// primitive values are never produced by FastR so we don't print them as R vectors
145+
if (value instanceof Boolean) {
146+
// boolean constants are capitalized like in R
147+
return (boolean) value ? "TRUE" : "FALSE";
148+
}
149+
if (value instanceof Number || value instanceof String || value instanceof Character) {
150+
return value.toString();
151+
}
152+
145153
// the debugger also passes result of TruffleRLanguage.findMetaObject() to this method
146154
Object unwrapped = value;
147155
// print promises by other means than the "print" function to avoid evaluating them
@@ -157,14 +165,14 @@ protected String toString(RContext context, Object value) {
157165
if (RMissingHelper.isMissing(unwrapped)) {
158166
return "missing";
159167
}
160-
// primitive values are never produced by FastR so we don't print them as R vectors
161-
if (unwrapped instanceof Number || unwrapped instanceof String || unwrapped instanceof Boolean || unwrapped instanceof Character) {
162-
return unwrapped.toString();
163-
}
164168
// special class designated to exchange NA values with the outside world
165169
if (unwrapped instanceof RInteropNA) {
166170
unwrapped = ((RInteropNA) unwrapped).getValue();
167171
}
172+
173+
// the value unwrapped from an RPromise can be primitive Java type, but now we know that we
174+
// are dealing with primitive that is supposed to be treated as R vector
175+
unwrapped = RRuntime.asAbstractVector(unwrapped);
168176
if (!(unwrapped instanceof TruffleObject)) {
169177
throw RError.error(RError.NO_CALLER, Message.GENERIC, String.format("Printing value of type '%s' is not supported by the R language.", unwrapped.getClass().getSimpleName()));
170178
}

com.oracle.truffle.r.launcher/src/com/oracle/truffle/r/launcher/RMain.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@
3636
import org.graalvm.options.OptionCategory;
3737
import org.graalvm.polyglot.Context;
3838
import org.graalvm.polyglot.Context.Builder;
39-
import org.graalvm.polyglot.HostAccess;
4039
import org.graalvm.polyglot.PolyglotException;
4140
import org.graalvm.polyglot.Source;
4241

com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/tck/FastRDebugTest.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -650,6 +650,7 @@ private void assertLocation(final int line, final String code, final Object... e
650650
}
651651

652652
private void assertLocation(final int line, final int column, final SuspendAnchor anchor, final String code, boolean includeAncestors, boolean completeMatch, final Object... expectedFrame) {
653+
final RuntimeException trace = new RuntimeException();
653654
run.addLast(() -> {
654655
try {
655656
assertNotNull(suspendedEvent);
@@ -685,6 +686,7 @@ private void assertLocation(final int line, final int column, final SuspendAncho
685686
frame.getScope().getDeclaredValues().forEach(var -> {
686687
System.out.println(var);
687688
});
689+
trace.printStackTrace();
688690
throw e;
689691
}
690692
});
@@ -702,6 +704,7 @@ private void assertLocation(final int line, final int column, final SuspendAncho
702704
* @param expectedFrame the key-value pairs (e.g. {@code "id0", 1, "id1", "strValue"})
703705
*/
704706
private void assertScope(final int line, final String code, boolean includeAncestors, boolean completeMatch, final Object... expectedFrame) {
707+
final RuntimeException trace = new RuntimeException();
705708
run.addLast(() -> {
706709
try {
707710
compareScope(line, code, includeAncestors, completeMatch, expectedFrame);
@@ -711,12 +714,14 @@ private void assertScope(final int line, final String code, boolean includeAnces
711714
frame.getScope().getDeclaredValues().forEach(var -> {
712715
System.out.println(var);
713716
});
717+
trace.printStackTrace();
714718
throw e;
715719
}
716720
});
717721
}
718722

719723
private void assertArguments(final int line, final String code, final Object... expectedArgs) {
724+
final RuntimeException trace = new RuntimeException();
720725
run.addLast(() -> {
721726
final DebugStackFrame frame = suspendedEvent.getTopStackFrame();
722727
DebugScope scope = frame.getScope();
@@ -746,6 +751,7 @@ private void assertArguments(final int line, final String code, final Object...
746751
scope.getDeclaredValues().forEach(var -> {
747752
System.out.println(var);
748753
});
754+
trace.printStackTrace();
749755
throw e;
750756
}
751757
});
@@ -838,6 +844,7 @@ private void assertExecutedOK() throws Throwable {
838844
* @param nameAndValuePairs name followed by value (arbitrary number of times).
839845
*/
840846
private void assertMetaObjectsOrStringValues(final Source expectedSource, boolean metaObjects, final String... nameAndValuePairs) {
847+
final RuntimeException trace = new RuntimeException();
841848
run.addLast((Runnable) () -> {
842849
try {
843850
DebugStackFrame frame = suspendedEvent.getTopStackFrame();
@@ -877,6 +884,7 @@ private void assertMetaObjectsOrStringValues(final Source expectedSource, boolea
877884
frame.getScope().getDeclaredValues().forEach(var -> {
878885
System.out.println(var);
879886
});
887+
trace.printStackTrace();
880888
throw e;
881889
}
882890
});

com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/tck/ToStringTesterInstrument.java

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -23,42 +23,38 @@
2323
package com.oracle.truffle.r.test.tck;
2424

2525
import com.oracle.truffle.api.frame.VirtualFrame;
26-
import com.oracle.truffle.api.instrumentation.EventContext;
2726
import com.oracle.truffle.api.instrumentation.ExecutionEventNode;
28-
import com.oracle.truffle.api.instrumentation.ExecutionEventNodeFactory;
2927
import com.oracle.truffle.api.instrumentation.SourceSectionFilter;
3028
import com.oracle.truffle.api.instrumentation.TruffleInstrument;
3129
import com.oracle.truffle.api.nodes.LanguageInfo;
32-
import com.oracle.truffle.r.test.tck.ToStringTesterInstrument.Initialize;
30+
import com.oracle.truffle.r.test.tck.ToStringTesterInstrument.TestData;
3331

34-
@TruffleInstrument.Registration(id = ToStringTesterInstrument.ID, name = ToStringTesterInstrument.ID, version = "1.0", services = Initialize.class)
32+
@TruffleInstrument.Registration(id = ToStringTesterInstrument.ID, name = ToStringTesterInstrument.ID, version = "1.0", services = TestData.class)
3533
public class ToStringTesterInstrument extends TruffleInstrument {
3634
public static final String ID = "ToStringTester";
3735

38-
static String intAsString;
39-
static String byteAsString;
40-
static String doubleAsString;
41-
static String stringAsString;
42-
static String booleanAsString;
43-
4436
@Override
4537
protected void onCreate(Env env) {
46-
env.registerService(new Initialize() {
47-
});
48-
38+
TestData testData = new TestData();
39+
env.registerService(testData);
4940
env.getInstrumenter().attachExecutionEventFactory(SourceSectionFilter.ANY, context -> new ExecutionEventNode() {
5041
@Override
5142
protected void onEnter(VirtualFrame frame) {
5243
LanguageInfo rLanguage = env.getLanguages().get("R");
53-
intAsString = env.toString(rLanguage, 42);
54-
byteAsString = env.toString(rLanguage, (byte) 42);
55-
doubleAsString = env.toString(rLanguage, 42.5);
56-
stringAsString = env.toString(rLanguage, "Hello");
57-
booleanAsString = env.toString(rLanguage, true);
44+
testData.intAsString = env.toString(rLanguage, 42);
45+
testData.byteAsString = env.toString(rLanguage, (byte) 42);
46+
testData.doubleAsString = env.toString(rLanguage, 42.5);
47+
testData.stringAsString = env.toString(rLanguage, "Hello");
48+
testData.booleanAsString = env.toString(rLanguage, true);
5849
}
5950
});
6051
}
6152

62-
public interface Initialize {
53+
public static final class TestData {
54+
public String intAsString;
55+
public String byteAsString;
56+
public String doubleAsString;
57+
public String stringAsString;
58+
public String booleanAsString;
6359
}
6460
}

com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/tck/TruffleRLanguageTest.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
import com.oracle.truffle.r.test.TestBase;
3232
import com.oracle.truffle.r.test.generate.FastRSession;
33+
import com.oracle.truffle.r.test.tck.ToStringTesterInstrument.TestData;
3334

3435
public class TruffleRLanguageTest extends TestBase {
3536

@@ -47,13 +48,13 @@ public void dispose() {
4748

4849
@Test
4950
public void testToString() {
50-
context.getEngine().getInstruments().get(ToStringTesterInstrument.ID).lookup(ToStringTesterInstrument.Initialize.class);
51+
TestData testData = context.getEngine().getInstruments().get(ToStringTesterInstrument.ID).lookup(TestData.class);
5152
context.eval("R", "1+1"); // to trigger the instrument
52-
assertEquals("42", ToStringTesterInstrument.intAsString);
53-
assertEquals("42", ToStringTesterInstrument.byteAsString);
54-
assertEquals("42.5", ToStringTesterInstrument.doubleAsString);
55-
assertEquals("Hello", ToStringTesterInstrument.stringAsString);
56-
assertEquals("true", ToStringTesterInstrument.booleanAsString);
53+
assertEquals("42", testData.intAsString);
54+
assertEquals("42", testData.byteAsString);
55+
assertEquals("42.5", testData.doubleAsString);
56+
assertEquals("Hello", testData.stringAsString);
57+
assertEquals("true", testData.booleanAsString);
5758
}
5859

5960
}

0 commit comments

Comments
 (0)