From da2c06d8335802ce14c73edc7be44c615791285f Mon Sep 17 00:00:00 2001 From: stepan <stepan.sindelar@oracle.com> Date: Tue, 19 Jun 2018 17:43:20 +0200 Subject: [PATCH] Do not rely on Java interop in ConsoleHandler --- .../truffle/r/launcher/ConsoleHandler.java | 73 +++++++++++++++++++ .../truffle/r/launcher/RAbstractLauncher.java | 2 +- .../truffle/r/runtime/context/RContext.java | 2 +- 3 files changed, 75 insertions(+), 2 deletions(-) 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 6d9f266be6..1c8751f429 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 399733398d..e3e043fe7e 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 5798954384..3efe69b56e 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); } } } -- GitLab