diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/AttributesPrinter.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/AttributesPrinter.java index 4bbcb27468b71522d67a5e1f00e30fb676b11e7c..6b0750ff92b1eea5ac6db59c0df824e136b4212c 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/AttributesPrinter.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/AttributesPrinter.java @@ -40,6 +40,8 @@ final class AttributesPrinter implements ValuePrinter<RAttributable> { return; } + final StringBuilder savedBuffer = printCtx.getTagBuffer(); + printCtx.resetTagBuffer(); for (RAttribute a : attrs) { if (useSlots && RRuntime.CLASS_SYMBOL.equals(a.getName())) { continue; @@ -85,8 +87,9 @@ final class AttributesPrinter implements ValuePrinter<RAttributable> { } out.println(tag); - int origLen = printCtx.getTagBuffer().length(); - printCtx.getTagBuffer().append(tag); + StringBuilder buff = printCtx.getOrCreateTagBuffer(); + int origLen = buff.length(); + buff.append(tag); if (RContext.getInstance().isMethodTableDispatchOn() && utils.isS4(a.getValue())) { S4ObjectPrinter.printS4(printCtx, a.getValue()); @@ -96,7 +99,9 @@ final class AttributesPrinter implements ValuePrinter<RAttributable> { } // restore tag buffer to its original value - printCtx.getTagBuffer().setLength(origLen); + buff.setLength(origLen); } + + printCtx.setTagBuffer(savedBuffer); } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ListPrinter.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ListPrinter.java index 1c6348673f7ef0b55cb112e18bd6810502c85f28..0d1eb278615243b701702dc3c2a2d963d5e4332f 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ListPrinter.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/ListPrinter.java @@ -159,7 +159,7 @@ final class ListPrinter extends AbstractValuePrinter<RAbstractListVector> { final PrintParameters pp = printCtx.parameters(); final PrintWriter out = printCtx.output(); - final StringBuffer tagbuf = printCtx.getTagBuffer(); + final StringBuilder tagbuf = printCtx.getOrCreateTagBuffer(); // save the original length so that we can restore the original value int taglen = tagbuf.length(); @@ -211,11 +211,7 @@ final class ListPrinter extends AbstractValuePrinter<RAbstractListVector> { out.println(tagbuf); Object si = s.getDataAtAsObject(i); - if (printCtx.printerNode().isObject(si)) { - ValuePrinters.INSTANCE.println(si, printCtx); - } else { - ValuePrinters.INSTANCE.println(si, printCtx); - } + ValuePrinters.INSTANCE.println(si, printCtx); tagbuf.setLength(taglen); // reset tag buffer to the original value } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/PrintContext.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/PrintContext.java index 8928eb787677ab45992fd34c39a89b39bb14b812..7b4eb5c7727a5589de0b44c2382bc001f5f37f7e 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/PrintContext.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/printer/PrintContext.java @@ -33,7 +33,7 @@ final class PrintContext { private final PrintParameters params; private final PrettyPrintWriter out; private final Map<String, Object> attrs = new HashMap<>(); - private StringBuffer tagbuf; + private StringBuilder tagbuf; private static final ThreadLocal<ArrayDeque<PrintContext>> printCtxTL = new ThreadLocal<>(); @@ -48,13 +48,29 @@ final class PrintContext { * before any value. This value reflects global variable {@code tagbuf} in GnuR. In FastR we can * have more parallel buffers. */ - public StringBuffer getTagBuffer() { + public StringBuilder getOrCreateTagBuffer() { if (tagbuf == null) { - tagbuf = new StringBuffer(); + tagbuf = new StringBuilder(); } return tagbuf; } + /** + * Version of {@link #getOrCreateTagBuffer()} that does not create the buffer if it is + * {@code null}. + */ + public StringBuilder getTagBuffer() { + return tagbuf; + } + + public void resetTagBuffer() { + tagbuf = null; + } + + public void setTagBuffer(StringBuilder buffer) { + tagbuf = buffer; + } + public PrintParameters parameters() { return params; } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test index a49d013cd185179a2ddaaad8d4555a72587aa04b..015e5d666bc7ea1a6c41e3b6d9cea09d9f063695 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/ExpectedTestOutput.test @@ -37528,6 +37528,16 @@ $n +##com.oracle.truffle.r.test.builtins.TestBuiltin_print.testPrint +#{ val <- 42L; attr(val, 'contrast') <- list(k=1); qr <- list(qr=val); qr } +$qr +[1] 42 +attr(,"contrast") +attr(,"contrast")$k +[1] 1 + + + ##com.oracle.truffle.r.test.builtins.TestBuiltin_print.testPrint #{ x <- 42; attr(x,'myattr') <- list(k=3); attributes(x) } $myattr diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_print.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_print.java index 592c5797c71b77ae46f4fc70cf43b55100d350ee..3a2ad114bac7ae377aed860e3efcd4c59448182b 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_print.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_print.java @@ -74,5 +74,6 @@ public class TestBuiltin_print extends TestBase { assertEval("{ n <- 17 ; fac <- factor(rep(1:3, length = n), levels = 1:5) ; y<-tapply(1:n, fac, sum); y }"); assertEval("{ nql <- noquote(letters); nql}"); assertEval("{ x <- 42; attr(x,'myattr') <- list(k=3); attributes(x) }"); + assertEval("{ val <- 42L; attr(val, 'contrast') <- list(k=1); qr <- list(qr=val); qr }"); } }