changeset 22165:67f75f61c974

Certain languages (like FastR) prefer access to raw byte streams. Offering it. One always has an option to wrap Input and Output Streams into character based Readers and Writers
author Jaroslav Tulach <jaroslav.tulach@oracle.com>
date Mon, 21 Sep 2015 12:36:30 +0200
parents 567d324c306c
children d2c32a9a5f27
files truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/TruffleVM.java truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleLanguage.java truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/Accessor.java truffle/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SLTestRunner.java truffle/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/instrument/SLInstrumentTestRunner.java truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLLanguage.java
diffstat 6 files changed, 91 insertions(+), 45 deletions(-) [+]
line wrap: on
line diff
--- a/truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/TruffleVM.java	Mon Sep 21 11:30:33 2015 +0200
+++ b/truffle/com.oracle.truffle.api.vm/src/com/oracle/truffle/api/vm/TruffleVM.java	Mon Sep 21 12:36:30 2015 +0200
@@ -41,9 +41,9 @@
 import java.io.Closeable;
 import java.io.File;
 import java.io.IOException;
-import java.io.InputStreamReader;
+import java.io.InputStream;
 import java.io.InterruptedIOException;
-import java.io.OutputStreamWriter;
+import java.io.OutputStream;
 import java.io.Reader;
 import java.io.Writer;
 import java.lang.reflect.InvocationHandler;
@@ -104,9 +104,9 @@
     private final Thread initThread;
     private final Executor executor;
     private final Map<String, Language> langs;
-    private final Reader in;
-    private final Writer err;
-    private final Writer out;
+    private final InputStream in;
+    private final OutputStream err;
+    private final OutputStream out;
     private final EventConsumer<?>[] handlers;
     private final Map<String, Object> globals;
     private Debugger debugger;
@@ -128,7 +128,7 @@
     /**
      * Real constructor used from the builder.
      */
-    private TruffleVM(Executor executor, Map<String, Object> globals, Writer out, Writer err, Reader in, EventConsumer<?>[] handlers) {
+    private TruffleVM(Executor executor, Map<String, Object> globals, OutputStream out, OutputStream err, InputStream in, EventConsumer<?>[] handlers) {
         this.executor = executor;
         this.out = out;
         this.err = err;
@@ -175,16 +175,16 @@
      *
      * <pre>
      * {@link TruffleVM} vm = {@link TruffleVM}.{@link TruffleVM#newVM() newVM()}
-     *     .{@link Builder#stdOut(java.io.Writer) stdOut}({@link Writer yourWriter})
-     *     .{@link Builder#stdErr(java.io.Writer) stdErr}({@link Writer yourWriter})
-     *     .{@link Builder#stdIn(java.io.Reader) stdIn}({@link Reader yourReader})
+     *     .{@link Builder#setOut(java.io.Writer) setOut}({@link OutputStream yourOutput})
+     *     .{@link Builder#setErr(java.io.Writer) setrr}({@link OutputStream yourOutput})
+     *     .{@link Builder#setIn(java.io.Reader) setIn}({@link InputStream yourInput})
      *     .{@link Builder#build() build()};
      * </pre>
      */
     public final class Builder {
-        private Writer out;
-        private Writer err;
-        private Reader in;
+        private OutputStream out;
+        private OutputStream err;
+        private InputStream in;
         private final List<EventConsumer<?>> handlers = new ArrayList<>();
         private final Map<String, Object> globals = new HashMap<>();
         private Executor executor;
@@ -196,11 +196,19 @@
          * Changes the default output for languages running in <em>to be created</em>
          * {@link TruffleVM virtual machine}. The default is to use {@link System#out}.
          *
-         * @param w the writer to use as output
+         * @param os the stream to use as output
          * @return instance of this builder
          */
+        public Builder setOut(OutputStream os) {
+            out = os;
+            return this;
+        }
+
+        /**
+         * @deprecated does nothing
+         */
+        @Deprecated
         public Builder stdOut(Writer w) {
-            out = w;
             return this;
         }
 
@@ -208,23 +216,39 @@
          * Changes the error output for languages running in <em>to be created</em>
          * {@link TruffleVM virtual machine}. The default is to use {@link System#err}.
          *
-         * @param w the writer to use as output
+         * @param os the stream to use as output
          * @return instance of this builder
          */
+        public Builder setErr(OutputStream os) {
+            err = os;
+            return this;
+        }
+
+        /**
+         * @deprecated does nothing
+         */
+        @Deprecated
         public Builder stdErr(Writer w) {
-            err = w;
             return this;
         }
 
         /**
          * Changes the default input for languages running in <em>to be created</em>
-         * {@link TruffleVM virtual machine}. The default is to use {@link System#out}.
+         * {@link TruffleVM virtual machine}. The default is to use {@link System#in}.
          *
-         * @param r the reader to use as input
+         * @param is the stream to use as input
          * @return instance of this builder
          */
+        public Builder setIn(InputStream is) {
+            in = is;
+            return this;
+        }
+
+        /**
+         * @deprecated does nothing
+         */
+        @Deprecated
         public Builder stdIn(Reader r) {
-            in = r;
             return this;
         }
 
@@ -288,13 +312,13 @@
          */
         public TruffleVM build() {
             if (out == null) {
-                out = new OutputStreamWriter(System.out);
+                out = System.out;
             }
             if (err == null) {
-                err = new OutputStreamWriter(System.err);
+                err = System.err;
             }
             if (in == null) {
-                in = new InputStreamReader(System.in);
+                in = System.in;
             }
             Executor nonNullExecutor = executor != null ? executor : new Executor() {
                 @Override
@@ -851,7 +875,7 @@
         }
 
         @Override
-        public Env attachEnv(Object obj, TruffleLanguage<?> language, Writer stdOut, Writer stdErr, Reader stdIn) {
+        protected Env attachEnv(Object obj, TruffleLanguage<?> language, OutputStream stdOut, OutputStream stdErr, InputStream stdIn) {
             TruffleVM vm = (TruffleVM) obj;
             return super.attachEnv(vm, language, stdOut, stdErr, stdIn);
         }
--- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleLanguage.java	Mon Sep 21 11:30:33 2015 +0200
+++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleLanguage.java	Mon Sep 21 12:36:30 2015 +0200
@@ -31,6 +31,10 @@
 import com.oracle.truffle.api.nodes.Node;
 import com.oracle.truffle.api.source.Source;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
 import java.io.Reader;
 import java.io.Writer;
 import java.lang.annotation.ElementType;
@@ -246,11 +250,11 @@
         private final Object vm;
         private final TruffleLanguage<?> lang;
         private final LangCtx<?> langCtx;
-        private final Reader in;
-        private final Writer err;
-        private final Writer out;
+        private final InputStream in;
+        private final OutputStream err;
+        private final OutputStream out;
 
-        Env(Object vm, TruffleLanguage<?> lang, Writer out, Writer err, Reader in) {
+        Env(Object vm, TruffleLanguage<?> lang, OutputStream out, OutputStream err, InputStream in) {
             this.vm = vm;
             this.in = in;
             this.err = err;
@@ -278,8 +282,13 @@
          *
          * @return reader, never <code>null</code>
          */
+        public InputStream in() {
+            return in;
+        }
+
+        @Deprecated
         public Reader stdIn() {
-            return in;
+            return new InputStreamReader(in);
         }
 
         /**
@@ -288,8 +297,13 @@
          *
          * @return writer, never <code>null</code>
          */
+        public OutputStream out() {
+            return out;
+        }
+
+        @Deprecated
         public Writer stdOut() {
-            return out;
+            return new OutputStreamWriter(out);
         }
 
         /**
@@ -298,8 +312,13 @@
          *
          * @return writer, never <code>null</code>
          */
+        public OutputStream err() {
+            return err;
+        }
+
+        @Deprecated
         public Writer stdErr() {
-            return err;
+            return new OutputStreamWriter(err);
         }
     }
 
@@ -308,7 +327,7 @@
     @SuppressWarnings("rawtypes")
     private static final class AccessAPI extends Accessor {
         @Override
-        protected Env attachEnv(Object vm, TruffleLanguage<?> language, Writer stdOut, Writer stdErr, Reader stdIn) {
+        protected Env attachEnv(Object vm, TruffleLanguage<?> language, OutputStream stdOut, OutputStream stdErr, InputStream stdIn) {
             Env env = new Env(vm, language, stdOut, stdErr, stdIn);
             return env;
         }
--- a/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/Accessor.java	Mon Sep 21 11:30:33 2015 +0200
+++ b/truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/impl/Accessor.java	Mon Sep 21 12:36:30 2015 +0200
@@ -38,8 +38,8 @@
 import com.oracle.truffle.api.source.Source;
 import java.io.Closeable;
 import java.io.IOException;
-import java.io.Reader;
-import java.io.Writer;
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.lang.ref.Reference;
 import java.lang.ref.WeakReference;
 
@@ -132,7 +132,7 @@
         }
     }
 
-    protected Env attachEnv(Object vm, TruffleLanguage<?> language, Writer stdOut, Writer stdErr, Reader stdIn) {
+    protected Env attachEnv(Object vm, TruffleLanguage<?> language, OutputStream stdOut, OutputStream stdErr, InputStream stdIn) {
         return API.attachEnv(vm, language, stdOut, stdErr, stdIn);
     }
 
--- a/truffle/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SLTestRunner.java	Mon Sep 21 11:30:33 2015 +0200
+++ b/truffle/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/SLTestRunner.java	Mon Sep 21 12:36:30 2015 +0200
@@ -46,6 +46,7 @@
 import com.oracle.truffle.sl.builtins.SLBuiltinNode;
 import com.oracle.truffle.sl.test.SLTestRunner.TestCase;
 import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileNotFoundException;
@@ -229,14 +230,15 @@
         notifier.fireTestStarted(testCase.name);
 
         ByteArrayOutputStream out = new ByteArrayOutputStream();
-        PrintWriter printer = new PrintWriter(out);
         try {
-            TruffleVM vm = TruffleVM.newVM().stdIn(new BufferedReader(new StringReader(repeat(testCase.testInput, repeats)))).stdOut(printer).build();
+            TruffleVM vm = TruffleVM.newVM().setIn(new ByteArrayInputStream(repeat(testCase.testInput, repeats).getBytes("UTF-8"))).setOut(out).build();
 
             String script = readAllLines(testCase.path);
-            SLLanguage.run(vm, testCase.path, null, printer, repeats, builtins);
 
+            PrintWriter printer = new PrintWriter(out);
+            SLLanguage.run(vm, testCase.path, null, printer, repeats, builtins);
             printer.flush();
+
             String actualOutput = new String(out.toByteArray());
             Assert.assertEquals(script, repeat(testCase.expectedOutput, repeats), actualOutput);
         } catch (Throwable ex) {
--- a/truffle/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/instrument/SLInstrumentTestRunner.java	Mon Sep 21 11:30:33 2015 +0200
+++ b/truffle/com.oracle.truffle.sl.test/src/com/oracle/truffle/sl/test/instrument/SLInstrumentTestRunner.java	Mon Sep 21 12:36:30 2015 +0200
@@ -51,12 +51,11 @@
 import com.oracle.truffle.sl.nodes.local.SLWriteLocalVariableNode;
 import com.oracle.truffle.sl.test.SLTestRunner;
 import com.oracle.truffle.sl.test.instrument.SLInstrumentTestRunner.InstrumentTestCase;
-import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.PrintWriter;
-import java.io.StringReader;
 import java.nio.charset.Charset;
 import java.nio.file.FileSystems;
 import java.nio.file.FileVisitResult;
@@ -235,21 +234,22 @@
         notifier.fireTestStarted(testCase.name);
 
         ByteArrayOutputStream out = new ByteArrayOutputStream();
-        PrintWriter printer = new PrintWriter(out);
         final ASTProber prober = new SLStandardASTProber();
         Probe.registerASTProber(prober);
         try {
             // We use the name of the file to determine what visitor to attach to it.
             if (testCase.baseName.endsWith(ASSIGNMENT_VALUE_SUFFIX)) {
                 // Set up the execution context for Simple and register our two listeners
-                TruffleVM vm = TruffleVM.newVM().stdIn(new BufferedReader(new StringReader(testCase.testInput))).stdOut(printer).build();
+                TruffleVM vm = TruffleVM.newVM().setIn(new ByteArrayInputStream(testCase.testInput.getBytes("UTF-8"))).setOut(out).build();
 
                 final String src = readAllLines(testCase.path);
                 vm.eval(Source.fromText(src, testCase.path.toString()).withMimeType("application/x-sl"));
 
                 // Attach an instrument to every probe tagged as an assignment
                 for (Probe probe : Probe.findProbesTaggedAs(StandardSyntaxTag.ASSIGNMENT)) {
-                    SLPrintAssigmentValueListener slPrintAssigmentValueListener = new SLPrintAssigmentValueListener(printer);
+                    PrintWriter pw = new PrintWriter(out);
+                    SLPrintAssigmentValueListener slPrintAssigmentValueListener = new SLPrintAssigmentValueListener(pw);
+                    pw.close();
                     probe.attach(Instrument.create(slPrintAssigmentValueListener, "SL print assignment value"));
                 }
 
@@ -258,8 +258,7 @@
             } else {
                 notifier.fireTestFailure(new Failure(testCase.name, new UnsupportedOperationException("No instrumentation found.")));
             }
-
-            printer.flush();
+            out.flush();
             String actualOutput = new String(out.toByteArray());
             Assert.assertEquals(testCase.expectedOutput, actualOutput);
         } catch (Throwable ex) {
--- a/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLLanguage.java	Mon Sep 21 11:30:33 2015 +0200
+++ b/truffle/com.oracle.truffle.sl/src/com/oracle/truffle/sl/SLLanguage.java	Mon Sep 21 12:36:30 2015 +0200
@@ -208,7 +208,9 @@
 
     @Override
     protected SLContext createContext(Env env) {
-        SLContext context = new SLContext(this, new BufferedReader(env.stdIn()), new PrintWriter(env.stdOut(), true));
+        final BufferedReader in = new BufferedReader(new InputStreamReader(env.in()));
+        final PrintWriter out = new PrintWriter(env.out(), true);
+        SLContext context = new SLContext(this, in, out);
         for (NodeFactory<? extends SLBuiltinNode> builtin : builtins) {
             context.installBuiltin(builtin, true);
         }