diff --git a/com.oracle.truffle.r.launcher/src/com/oracle/truffle/r/launcher/ConsoleHandler.java b/com.oracle.truffle.r.launcher/src/com/oracle/truffle/r/launcher/ConsoleHandler.java index 6d9f266be6af8b9b5bf7d2a3c829a609379d9982..1c8751f429813ce950212c512f21515d182da04f 100644 --- a/com.oracle.truffle.r.launcher/src/com/oracle/truffle/r/launcher/ConsoleHandler.java +++ b/com.oracle.truffle.r.launcher/src/com/oracle/truffle/r/launcher/ConsoleHandler.java @@ -27,6 +27,9 @@ import java.io.InputStream; import java.nio.charset.StandardCharsets; import org.graalvm.polyglot.Context; +import org.graalvm.polyglot.Value; +import org.graalvm.polyglot.proxy.ProxyExecutable; +import org.graalvm.polyglot.proxy.ProxyObject; /** * The interface to a source of input/output for the context, which may have different @@ -60,6 +63,10 @@ public abstract class ConsoleHandler { // ignore by default } + public Object getPolyglotWrapper() { + return new PolyglotWrapper(this); + } + public InputStream createInputStream() { return new InputStream() { byte[] buffer = null; @@ -84,4 +91,70 @@ public abstract class ConsoleHandler { } }; } + + private static class PolyglotWrapper implements ProxyObject { + private static final String GET_PROMPT_KEY = "getPrompt"; + private static final String SET_PROMPT_KEY = "setPrompt"; + private static final String[] keys = new String[] { GET_PROMPT_KEY, SET_PROMPT_KEY }; + private final GetPromptWrapper getPrompt; + private final SetPromptWrapper setPrompt; + + private PolyglotWrapper(ConsoleHandler target) { + getPrompt = new GetPromptWrapper(target); + setPrompt = new SetPromptWrapper(target); + } + + @Override + public Object getMember(String key) { + if (GET_PROMPT_KEY.equals(key)) { + return getPrompt; + } else if (SET_PROMPT_KEY.equals(key)) { + return setPrompt; + } else { + return null; + } + } + + @Override + public Object getMemberKeys() { + return keys; + } + + @Override + public boolean hasMember(String key) { + return key.contains(key); + } + + @Override + public void putMember(String key, Value value) { + throw new UnsupportedOperationException("putMember"); + } + } + + private static class GetPromptWrapper implements ProxyExecutable { + private final ConsoleHandler target; + + private GetPromptWrapper(ConsoleHandler target) { + this.target = target; + } + + @Override + public Object execute(Value... arguments) { + return target.getPrompt(); + } + } + + private static class SetPromptWrapper implements ProxyExecutable { + private final ConsoleHandler target; + + private SetPromptWrapper(ConsoleHandler target) { + this.target = target; + } + + @Override + public Object execute(Value... arguments) { + target.setPrompt(arguments[0].asString()); + return null; + } + } } diff --git a/com.oracle.truffle.r.launcher/src/com/oracle/truffle/r/launcher/RAbstractLauncher.java b/com.oracle.truffle.r.launcher/src/com/oracle/truffle/r/launcher/RAbstractLauncher.java index 399733398de2e5713425cf2742dbd528321f1853..e3e043fe7ea9ef132bdb0022d8badf2af08aebc2 100644 --- a/com.oracle.truffle.r.launcher/src/com/oracle/truffle/r/launcher/RAbstractLauncher.java +++ b/com.oracle.truffle.r.launcher/src/com/oracle/truffle/r/launcher/RAbstractLauncher.java @@ -92,7 +92,7 @@ public abstract class RAbstractLauncher extends AbstractLanguageLauncher impleme this.consoleHandler.setContext(context); try { Source src = Source.newBuilder("R", ".fastr.set.consoleHandler", "<set-console-handler>").internal(true).build(); - context.eval(src).execute(consoleHandler); + context.eval(src).execute(consoleHandler.getPolyglotWrapper()); } catch (IOException e) { throw fatal(e, "error while setting console handler"); } 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 5798954384a11fbcacd64a1ecc42b73256b61b8c..3efe69b56e1940f2b862392577ecf7a59515672f 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 @@ -981,7 +981,7 @@ public final class RContext { Object f = ForeignAccess.sendRead(read, handler, "setPrompt"); ForeignAccess.sendExecute(execute, (TruffleObject) f, prompt); } catch (UnknownIdentifierException | UnsupportedMessageException | UnsupportedTypeException | ArityException | ClassCastException e) { - throw new RInternalError(e, "error while writing prompt"); + throw new RInternalError(e, "error while writing prompt from object " + handler); } } }