diff --git a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java index 8548fd442c15ecd31ca37bedcb274c3f4eeb39d7..324acbd6cba2cbf408769fdf21415dba05efc0f2 100644 --- a/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java +++ b/com.oracle.truffle.r.engine/src/com/oracle/truffle/r/engine/REngine.java @@ -544,13 +544,10 @@ final class REngine implements Engine, Engine.Timings { @Override @TruffleBoundary - public void printResult(Object result) { - // this supports printing of non-R values (via toString for now) - if (result == null || result instanceof TruffleObject && !(result instanceof RTypedValue)) { - RContext.getInstance().getConsoleHandler().println(toString(result)); - } else if (result instanceof CharSequence && !(result instanceof String)) { - RContext.getInstance().getConsoleHandler().println(toString(result)); - } else { + public void printResult(Object originalResult) { + Object result = evaluatePromise(originalResult); + result = RRuntime.asAbstractVector(result); + if (result instanceof RTypedValue) { Object resultValue = evaluatePromise(result); Object printMethod = REnvironment.globalEnv().findFunction("print"); RFunction function = (RFunction) evaluatePromise(printMethod); @@ -562,19 +559,27 @@ final class REngine implements Engine, Engine.Timings { if (resultValue instanceof RShareable && !((RShareable) resultValue).isSharedPermanent()) { ((RShareable) resultValue).decRefCount(); } + } else { + // this supports printing of non-R values (via toString for now) + RContext.getInstance().getConsoleHandler().println(toString(result)); } } - @Override - public String toString(Object result) { + private static String toString(Object originalResult) { + Object result = evaluatePromise(originalResult); + result = RRuntime.asAbstractVector(result); // this supports printing of non-R values (via toString for now) - if (result == null || (result instanceof TruffleObject && !(result instanceof RTypedValue))) { - return "foreign()"; - } else if (result instanceof CharSequence && !(result instanceof String)) { + if (result instanceof RTypedValue) { + return PrettyPrinterNode.prettyPrintDefault(result); + } else if (result == null) { + return "[external object (null)]"; + } else if (result instanceof TruffleObject) { + assert !(result instanceof RTypedValue); + return "[external object]"; + } else if (result instanceof CharSequence) { return "[1] \"" + String.valueOf(result) + "\""; } else { - Object resultValue = evaluatePromise(result); - return PrettyPrinterNode.prettyPrintDefault(resultValue); + return String.valueOf(result); } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GetText.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GetText.java index a10b07fcea151125b4ad0143c1b94dd937906a3a..6c760541d6afbb78f8937eca0b1c86c31b78ec53 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GetText.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/GetText.java @@ -24,69 +24,29 @@ package com.oracle.truffle.r.nodes.builtin.base; import static com.oracle.truffle.r.runtime.RBuiltinKind.INTERNAL; -import java.util.Arrays; - -import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.r.nodes.builtin.CastBuilder; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; -import com.oracle.truffle.r.nodes.unary.CastStringNode; -import com.oracle.truffle.r.nodes.unary.CastStringNodeGen; -import com.oracle.truffle.r.nodes.unary.CastToVectorNode; -import com.oracle.truffle.r.nodes.unary.CastToVectorNodeGen; import com.oracle.truffle.r.runtime.RBuiltin; -import com.oracle.truffle.r.runtime.Utils; -import com.oracle.truffle.r.runtime.data.RArgsValuesAndNames; -import com.oracle.truffle.r.runtime.data.RDataFactory; import com.oracle.truffle.r.runtime.data.RNull; -import com.oracle.truffle.r.runtime.data.RStringVector; -import com.oracle.truffle.r.runtime.ops.na.NACheck; +import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector; -@SuppressWarnings("unused") -@RBuiltin(name = "gettext", kind = INTERNAL, parameterNames = {"...", "domain"}) +@RBuiltin(name = "gettext", kind = INTERNAL, parameterNames = {"domain", "args"}) public abstract class GetText extends RBuiltinNode { - @Child private CastToVectorNode castVector; - @Child private CastStringNode castString; - - private final NACheck elementNACheck = NACheck.create(); - - private Object castString(Object operand) { - if (castString == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - castString = insert(CastStringNodeGen.create(false, true, false, false)); - } - return castString.execute(operand); + @Override + protected void createCasts(CastBuilder casts) { + casts.arg("domain").asStringVector().findFirst(""); + casts.arg("args").asStringVector(); } - private Object castVector(Object value) { - if (castVector == null) { - CompilerDirectives.transferToInterpreterAndInvalidate(); - castVector = insert(CastToVectorNodeGen.create(false)); - } - return castVector.execute(value); + @Specialization + protected RAbstractStringVector getText(@SuppressWarnings("unused") String domain, RAbstractStringVector texts) { + return texts; } @Specialization - protected RStringVector getText(RArgsValuesAndNames varargs, Object domain) { - Object[] argValues = varargs.getArguments(); - String[] a = new String[0]; - int aLength = 0; - int index = 0; - for (int i = 0; i < argValues.length; i++) { - Object v = castVector(argValues[i]); - if (v != RNull.instance) { - RStringVector vector = (RStringVector) castString(v); - elementNACheck.enable(vector); - aLength += vector.getLength(); - a = Utils.resizeArray(a, Math.max(aLength, a.length * 2)); - for (int j = 0; j < vector.getLength(); j++) { - a[index] = vector.getDataAt(j); - elementNACheck.check(a[index]); - index++; - } - } - } - - return RDataFactory.createStringVector(a.length == aLength ? a : Arrays.copyOf(a, aLength), elementNACheck.neverSeenNA()); + protected RNull getText(@SuppressWarnings("unused") String domain, RNull texts) { + return texts; } } diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsTypeFunctions.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsTypeFunctions.java index 974f03a544a12645a49aaeb563aea932d74b95c4..96e8752dacb9cf509caa265b5ba7e3865c68ab2c 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsTypeFunctions.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/IsTypeFunctions.java @@ -25,10 +25,12 @@ package com.oracle.truffle.r.nodes.builtin.base; import static com.oracle.truffle.r.runtime.RBuiltinKind.INTERNAL; import static com.oracle.truffle.r.runtime.RBuiltinKind.PRIMITIVE; +import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.ConditionProfile; +import com.oracle.truffle.api.profiles.ValueProfile; import com.oracle.truffle.r.nodes.builtin.RBuiltinNode; import com.oracle.truffle.r.nodes.helpers.InheritsCheckNode; import com.oracle.truffle.r.runtime.RBuiltin; @@ -426,8 +428,9 @@ public class IsTypeFunctions { public abstract byte execute(Object value); @Specialization - protected byte isObject(RAttributable arg) { - return arg.isObject(attrProfiles) ? RRuntime.LOGICAL_TRUE : RRuntime.LOGICAL_FALSE; + protected byte isObject(RAttributable arg, // + @Cached("createClassProfile()") ValueProfile profile) { + return RRuntime.asLogical(profile.profile(arg).isObject(attrProfiles)); } @Specialization(guards = {"!isRMissing(value)", "!isRAttributable(value)"}) diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallNode.java index ab6cf1fa132e13d465796a91e14d4e860d083c6e..bd3c3078e25be7ef5849a272ed077fc85d12c302 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/function/RCallNode.java @@ -164,6 +164,8 @@ public abstract class RCallNode extends RCallBaseNode implements RSyntaxNode, RS @Child private ReadVariableNode lookupVarArgs; protected final LocalReadVariableNode explicitArgs; + private final ConditionProfile nullBuiltinProfile = ConditionProfile.createBinaryProfile(); + // needed for INTERNAL_GENERIC calls: @Child private FunctionDispatch internalDispatchCall; @@ -270,7 +272,7 @@ public abstract class RCallNode extends RCallBaseNode implements RSyntaxNode, RS * special dispatch logic. */ protected boolean isDefaultDispatch(RFunction function) { - return (signature != null && signature.isEmpty()) || function.getRBuiltin() == null || function.getRBuiltin().getDispatch() == RDispatch.DEFAULT; + return (signature != null && signature.isEmpty()) || nullBuiltinProfile.profile(function.getRBuiltin() == null) || function.getRBuiltin().getDispatch() == RDispatch.DEFAULT; } @Specialization(guards = "isDefaultDispatch(function)") diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/Utils.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/Utils.java index 061d1f60e025fc4c4537791421d1746b8e0f352f..b579ea12dd32c1d3848008d6d0ef04e9a15c3287 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/Utils.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/Utils.java @@ -95,11 +95,11 @@ public final class Utils { try { URL url = ResourceHandlerFactory.getHandler().getResource(clazz, resourceName); if (url == null) { - throw new IOException(); + throw RInternalError.shouldNotReachHere("resource " + resourceName + " not found, context: " + clazz); } - return RSource.fromFileName(url.getPath()); + return RSource.fromURL(url, resourceName); } catch (IOException ex) { - throw Utils.fail("resource " + resourceName + " not found"); + throw RInternalError.shouldNotReachHere("resource " + resourceName + " not found, context: " + clazz); } } diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/Engine.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/Engine.java index d80fe6fc61d4656305192dfc3435fe8d935b81e6..e8363e5a00435d101d9e1a99987924ec2a96fb2b 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/Engine.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/context/Engine.java @@ -195,8 +195,6 @@ public interface Engine { */ void printResult(Object value); - String toString(Object value); - /** * This function a special fast path to create functions from code directly, without executing * the intermediate "function" expression. 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 1b8c13bb988ac325cc264bd8d9283fff0ad6ebf5..478ac346fb42ee04ab52e6b90a6cdbed069428ef 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 @@ -20410,6 +20410,14 @@ list() [1] FALSE +##com.oracle.truffle.r.test.builtins.TestBuiltin_gettext.testgettext +#gettext('Loading required package: %s') +[1] "Loading required package: %s" + +##com.oracle.truffle.r.test.builtins.TestBuiltin_gettext.testgettext +#gettext(domain='foo', 'bar') +[1] "bar" + ##com.oracle.truffle.r.test.builtins.TestBuiltin_gettext.testgettext1 #argv <- list(NULL, 'Loading required package: %s'); .Internal(gettext(argv[[1]], argv[[2]])) [1] "Loading required package: %s" diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_gettext.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_gettext.java index acaf7cf063366fa5d427f8e9c5c3ace329d87d69..dd9e60ad1156b241c4d7a3e81a20b113db8cacf2 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_gettext.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_gettext.java @@ -44,6 +44,12 @@ public class TestBuiltin_gettext extends TestBase { @Test public void testgettext6() { - assertEval(Ignored.Unknown, "argv <- list(NULL, NULL); .Internal(gettext(argv[[1]], argv[[2]]))"); + assertEval("argv <- list(NULL, NULL); .Internal(gettext(argv[[1]], argv[[2]]))"); + } + + @Test + public void testgettext() { + assertEval("gettext('Loading required package: %s')"); + assertEval("gettext(domain='foo', 'bar')"); } } diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_seq.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_seq.java index 05ada21434b7443978acbcdcea2b1319869cf174..c0f8879bb9f6508b104c7b5fce1dce3ebabb098e 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_seq.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/builtins/TestBuiltin_seq.java @@ -175,9 +175,9 @@ public class TestBuiltin_seq extends TestBase { assertEval("{ seq(0L,0L) }"); assertEval("{ seq(0,0,1i) }"); assertEval(Output.IgnoreErrorContext, "{ seq(integer(), 7) }"); - assertEval(Output.IgnoreErrorContext, "{ seq(c(1,2), 7) }"); + assertEval(Output.MayIgnoreErrorContext, "{ seq(c(1,2), 7) }"); assertEval(Output.IgnoreErrorContext, "{ seq(7, integer()) }"); - assertEval(Output.IgnoreErrorContext, "{ seq(7, c(41,42)) }"); + assertEval(Output.MayIgnoreErrorContext, "{ seq(7, c(41,42)) }"); assertEval("{ seq(integer()) }"); assertEval("{ seq(double()) }"); assertEval("{ seq(from=3L, length.out=3L) }"); diff --git a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestSimpleDataFrames.java b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestSimpleDataFrames.java index 44de44352dc6984559644d9073e60c728e88ba05..0d7d4d7dcbdf65acfb16e40de5b71b3deca0b7ee 100644 --- a/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestSimpleDataFrames.java +++ b/com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/library/base/TestSimpleDataFrames.java @@ -87,7 +87,7 @@ public class TestSimpleDataFrames extends TestBase { public void testAsDataFrame() { assertEval("{ x<-list(1,2); class(x)<-\"data.frame\"; row.names(x)<-\"r1\"; y<-as.data.frame(x, \"r2\"); attributes(x) }"); assertEval("{ x<-list(1,2); class(x)<-\"data.frame\"; row.names(x)<-\"r1\"; y<-as.data.frame(x, \"r2\"); attributes(y) }"); - assertEval(Output.IgnoreErrorContext, "{ x<-list(1,2); class(x)<-\"data.frame\"; row.names(x)<-\"r1\"; y<-as.data.frame(x, c(\"r1\", \"r2\")); attributes(y) }"); + assertEval("{ x<-list(1,2); class(x)<-\"data.frame\"; row.names(x)<-\"r1\"; y<-as.data.frame(x, c(\"r1\", \"r2\")); attributes(y) }"); assertEval("{ x<-c(7L,42L); y<-as.data.frame(x, row.names=NULL, nm=\"x\"); attributes(y); }"); assertEval("{ x<-as.double(c(7L,42L)); y<-as.data.frame(x, row.names=NULL, nm=\"x\"); attributes(y); }"); assertEval("{ x<-as.logical(c(7L,42L)); y<-as.data.frame(x, row.names=NULL, nm=\"x\"); attributes(y); }"); @@ -105,7 +105,7 @@ public class TestSimpleDataFrames extends TestBase { assertEval(Output.IgnoreWarningContext, "{ x<-c(7L,42L); y<-as.data.frame(x, row.names=c(\"r1\", \"r2\", \"r3\"), nm=\"x\"); attributes(y); }"); assertEval("{ x<-matrix(c(1,2,3,4), nrow=2); y<-as.data.frame(x, row.names=NULL, optional=FALSE); attributes(y); }"); assertEval("{ x<-matrix(c(1,2,3,4), nrow=2); y<-as.data.frame(x, row.names=\"r1\", optional=FALSE); attributes(y); }"); - assertEval(Output.IgnoreErrorContext, "{ x<-1; class(x)<-\"foo\"; y<-as.data.frame(x) }"); + assertEval("{ x<-1; class(x)<-\"foo\"; y<-as.data.frame(x) }"); } @Test