diff --git a/com.oracle.truffle.r.launcher/src/com/oracle/truffle/r/launcher/RCommand.java b/com.oracle.truffle.r.launcher/src/com/oracle/truffle/r/launcher/RCommand.java index 11e4450e7b3e8194b1ffbd3d0d007b3f5452b43e..0901e341ed7968d6bd23a261cc6ee89e9fa31920 100644 --- a/com.oracle.truffle.r.launcher/src/com/oracle/truffle/r/launcher/RCommand.java +++ b/com.oracle.truffle.r.launcher/src/com/oracle/truffle/r/launcher/RCommand.java @@ -213,10 +213,10 @@ public class RCommand { return input.replace("~+~", " "); } - private static final String GET_ECHO = "invisible(getOption('echo'))"; - private static final String QUIT_EOF = "quit(\"default\", 0L, TRUE)"; - private static final String GET_PROMPT = "invisible(getOption('prompt'))"; - private static final String GET_CONTINUE_PROMPT = "invisible(getOption('continue'))"; + private static final Source GET_ECHO = Source.newBuilder("R", ".Internal(getOption('echo'))", "<echo>").internal(true).buildLiteral(); + private static final Source QUIT_EOF = Source.newBuilder("R", ".Internal(quit('default', 0L, TRUE))", "<quit-on-eof>").internal(true).buildLiteral(); + private static final Source GET_PROMPT = Source.newBuilder("R", ".Internal(getOption('prompt'))", "<prompt>").internal(true).buildLiteral(); + private static final Source GET_CONTINUE_PROMPT = Source.newBuilder("R", ".Internal(getOption('continue'))", "<continue-prompt>").internal(true).buildLiteral(); /** * The read-eval-print loop, which can take input from a console, command line expression or a @@ -285,7 +285,7 @@ public class RCommand { } } catch (EOFException e) { try { - context.eval("R", QUIT_EOF); + context.eval(QUIT_EOF); } catch (PolyglotException e2) { if (e2.isExit()) { return e2.getExitStatus(); @@ -309,7 +309,7 @@ public class RCommand { private static boolean doEcho(Context context) { try { - return context.eval("R", GET_ECHO).asBoolean(); + return context.eval(GET_ECHO).asBoolean(); } catch (PolyglotException e) { if (e.isExit()) { throw new ExitException(e.getExitStatus()); @@ -320,7 +320,7 @@ public class RCommand { private static String getPrompt(Context context) { try { - return context.eval("R", GET_PROMPT).asString(); + return context.eval(GET_PROMPT).asString(); } catch (PolyglotException e) { if (e.isExit()) { throw new ExitException(e.getExitStatus()); @@ -331,7 +331,7 @@ public class RCommand { private static String getContinuePrompt(Context context) { try { - return context.eval("R", GET_CONTINUE_PROMPT).asString(); + return context.eval(GET_CONTINUE_PROMPT).asString(); } catch (PolyglotException e) { if (e.isExit()) { throw new ExitException(e.getExitStatus()); diff --git a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Names.java b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Names.java index 659212324dd25b285ec30292c7736785cd716a13..cc09614f38e9b177055a10306df953c5685e74c0 100644 --- a/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Names.java +++ b/com.oracle.truffle.r.nodes.builtin/src/com/oracle/truffle/r/nodes/builtin/base/Names.java @@ -96,8 +96,7 @@ public abstract class Names extends RBuiltinNode.Arg1 { String[] staticNames = new String[0]; try { if (JavaInterop.isJavaObject(Object.class, obj)) { - TruffleObject clazz = JavaInterop.toJavaClass(obj); - staticNames = readKeys(keysNode, clazz, getSizeNode, readNode, isBoxedNode, unboxNode); + staticNames = readKeys(keysNode, toJavaClass(obj), getSizeNode, readNode, isBoxedNode, unboxNode); } } catch (UnknownIdentifierException | NoSuchFieldError | UnsupportedMessageException e) { // because it is a class ... ? @@ -114,6 +113,11 @@ public abstract class Names extends RBuiltinNode.Arg1 { } } + @TruffleBoundary + private static TruffleObject toJavaClass(TruffleObject obj) { + return JavaInterop.toJavaClass(obj); + } + private static String[] readKeys(Node keysNode, TruffleObject obj, Node getSizeNode, Node readNode, Node isBoxedNode, Node unboxNode) throws UnknownIdentifierException, InteropException, UnsupportedMessageException { TruffleObject keys = (TruffleObject) ForeignAccess.send(keysNode, obj); diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/ExtractVectorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/ExtractVectorNode.java index 540740532ea6d6368dcc873eb3065cb858465019..e6017cd2746fa9853aa2c871c72e8e69550f7e36 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/ExtractVectorNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/ExtractVectorNode.java @@ -177,7 +177,7 @@ public abstract class ExtractVectorNode extends RBaseNode { if (KeyInfo.isReadable(info)) { return ForeignAccess.sendRead(foreignRead, object, pos); } else if (pos instanceof String && !KeyInfo.isExisting(info) && JavaInterop.isJavaObject(Object.class, object)) { - TruffleObject clazz = JavaInterop.toJavaClass(object); + TruffleObject clazz = toJavaClass(object); info = ForeignAccess.sendKeyInfo(keyInfoNode, clazz, pos); if (KeyInfo.isReadable(info)) { return ForeignAccess.sendRead(foreignRead, clazz, pos); @@ -186,6 +186,11 @@ public abstract class ExtractVectorNode extends RBaseNode { throw caller.error(RError.Message.GENERIC, "invalid index/identifier during foreign access: " + pos); } + @TruffleBoundary + private static TruffleObject toJavaClass(TruffleObject obj) { + return JavaInterop.toJavaClass(obj); + } + @Specialization(guards = {"cached != null", "cached.isSupported(vector, positions)"}) protected Object doExtractSameDimensions(VirtualFrame frame, RAbstractVector vector, Object[] positions, Object exact, Object dropDimensions, // @Cached("createRecursiveCache(vector, positions)") RecursiveExtractSubscriptNode cached) { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/ReplaceVectorNode.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/ReplaceVectorNode.java index be2aeca6132a03a751aabf4b37785dd88bd0ee73..574f7f314cfd6b4f65c91fb6ec1eb0124a3ca073 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/ReplaceVectorNode.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/access/vector/ReplaceVectorNode.java @@ -146,7 +146,7 @@ public abstract class ReplaceVectorNode extends RBaseNode { ForeignAccess.sendWrite(foreignWrite, object, pos, r2Foreign.execute(writtenValue)); return; } else if (pos instanceof String && !KeyInfo.isExisting(info) && JavaInterop.isJavaObject(Object.class, object)) { - TruffleObject clazz = JavaInterop.toJavaClass(object); + TruffleObject clazz = toJavaClass(object); info = ForeignAccess.sendKeyInfo(keyInfoNode, clazz, pos); if (KeyInfo.isWritable(info)) { ForeignAccess.sendWrite(foreignWrite, clazz, pos, r2Foreign.execute(writtenValue)); @@ -156,6 +156,11 @@ public abstract class ReplaceVectorNode extends RBaseNode { throw error(RError.Message.GENERIC, "invalid index/identifier during foreign access: " + pos); } + @TruffleBoundary + private static TruffleObject toJavaClass(TruffleObject obj) { + return JavaInterop.toJavaClass(obj); + } + @Specialization(limit = "CACHE_LIMIT", guards = {"cached != null", "cached.isSupported(vector, positions)"}) protected Object doRecursive(VirtualFrame frame, RAbstractListVector vector, Object[] positions, Object value, // @Cached("createRecursiveCache(vector, positions)") RecursiveReplaceSubscriptNode cached) { diff --git a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SpecialAttributesFunctions.java b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SpecialAttributesFunctions.java index 77cb4bb1ea1f8c668f5ecac08ac2b68d7e22d7cc..9a3ada865ce54def12b11b86acf8f475580fe95b 100644 --- a/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SpecialAttributesFunctions.java +++ b/com.oracle.truffle.r.nodes/src/com/oracle/truffle/r/nodes/attributes/SpecialAttributesFunctions.java @@ -764,7 +764,7 @@ public final class SpecialAttributesFunctions { for (int i = 0; loopProfile.inject(i < newDimNamesLength); i++) { Object dimObject = newDimNames.getDataAt(i); - if (dimObject == RNull.instance || (dimObject instanceof RStringVector && ((RStringVector) dimObject).getLength() == 0)) { + if (dimObject instanceof RStringVector && ((RStringVector) dimObject).getLength() == 0) { nullDimProfile.enter(); newDimNames.updateDataAt(i, RNull.instance, null); } else if ((dimObject instanceof String && dimensions[i] != 1) || diff --git a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RInternalError.java b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RInternalError.java index ccab1b58ed13bf1433c194847bdf4809cfb8e2b7..05cbf60199af40a84500f1c03bf8633d4ff5ec4f 100644 --- a/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RInternalError.java +++ b/com.oracle.truffle.r.runtime/src/com/oracle/truffle/r/runtime/RInternalError.java @@ -25,7 +25,6 @@ package com.oracle.truffle.r.runtime; import java.io.BufferedWriter; import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.io.OutputStream; import java.io.PrintStream; import java.io.PrintWriter; import java.io.StringWriter; @@ -37,9 +36,8 @@ import java.util.Date; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; -import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.TruffleException; -import com.oracle.truffle.r.launcher.ConsoleHandler; +import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.r.runtime.context.RContext; /** @@ -160,43 +158,48 @@ public final class RInternalError extends Error implements TruffleException { } private static void reportError(Throwable throwable, int contextId) { - Throwable t = throwable; - if (FastROptions.PrintErrorStacktracesToFile.getBooleanValue() || FastROptions.PrintErrorStacktraces.getBooleanValue()) { - - ByteArrayOutputStream out = new ByteArrayOutputStream(); - t.printStackTrace(new PrintStream(out)); - String verboseStackTrace; - if (t instanceof IOException) { - t = t.getCause(); - } - if (t instanceof RInternalError) { - verboseStackTrace = ((RInternalError) t).getVerboseStackTrace(); - } else if (t instanceof RError) { - verboseStackTrace = ((RError) t).getVerboseStackTrace(); - } else { - verboseStackTrace = ""; - } - if (FastROptions.PrintErrorStacktraces.getBooleanValue()) { - System.err.println(out.toString()); - System.err.println(verboseStackTrace); - } - if (FastROptions.PrintErrorStacktracesToFile.getBooleanValue()) { - String suffix = contextId == 0 ? "" : "-" + Integer.toString(contextId); - Path logfile = Utils.getLogPath("fastr_errors.log" + suffix); - try (BufferedWriter writer = Files.newBufferedWriter(logfile, StandardCharsets.UTF_8, StandardOpenOption.APPEND, - StandardOpenOption.CREATE)) { - writer.append(new Date().toString()).append('\n'); - writer.append(out.toString()).append('\n'); - writer.append(verboseStackTrace).append("\n\n"); - } catch (IOException e) { - e.printStackTrace(); + try { + Throwable t = throwable; + if (FastROptions.PrintErrorStacktracesToFile.getBooleanValue() || FastROptions.PrintErrorStacktraces.getBooleanValue()) { + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + t.printStackTrace(new PrintStream(out)); + String verboseStackTrace; + if (t instanceof IOException) { + t = t.getCause(); + } + if (t instanceof RInternalError) { + verboseStackTrace = ((RInternalError) t).getVerboseStackTrace(); + } else if (t instanceof RError) { + verboseStackTrace = ((RError) t).getVerboseStackTrace(); + } else { + verboseStackTrace = ""; + } + if (FastROptions.PrintErrorStacktraces.getBooleanValue()) { + System.err.println(out.toString()); + System.err.println(verboseStackTrace); } - String message = t instanceof RInternalError && t.getMessage() != null && !t.getMessage().isEmpty() ? t.getMessage() : "internal error: " + t.getClass().getSimpleName(); - System.out.println(message + " (see fastr_errors.log" + suffix + ")"); - if (RContext.isEmbedded()) { - Utils.rSuicide("FastR internal error"); + if (FastROptions.PrintErrorStacktracesToFile.getBooleanValue()) { + String suffix = contextId == 0 ? "" : "-" + Integer.toString(contextId); + Path logfile = Utils.getLogPath("fastr_errors.log" + suffix); + try (BufferedWriter writer = Files.newBufferedWriter(logfile, StandardCharsets.UTF_8, StandardOpenOption.APPEND, + StandardOpenOption.CREATE)) { + writer.append(new Date().toString()).append('\n'); + writer.append(out.toString()).append('\n'); + writer.append(verboseStackTrace).append("\n\n"); + } catch (IOException e) { + e.printStackTrace(); + } + String message = t instanceof RInternalError && t.getMessage() != null && !t.getMessage().isEmpty() ? t.getMessage() : "internal error: " + t.getClass().getSimpleName(); + System.out.println(message + " (see fastr_errors.log" + suffix + ")"); + if (RContext.isEmbedded()) { + Utils.rSuicide("FastR internal error"); + } } } + } catch (Throwable t) { + System.err.println("error while reporting internal error:"); + t.printStackTrace(); } }