Mercurial > hg > graal-compiler
diff graal/com.oracle.truffle.api/src/com/oracle/truffle/api/vm/TruffleVM.java @ 21557:31fc2fce38f3
Merge.
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Wed, 27 May 2015 13:32:18 +0200 |
parents | b1530a6cce8c 3286fb5fea4a |
children | 1c76a5662753 |
line wrap: on
line diff
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/vm/TruffleVM.java Wed May 27 00:36:16 2015 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/vm/TruffleVM.java Wed May 27 13:32:18 2015 +0200 @@ -38,10 +38,10 @@ import com.oracle.truffle.api.source.*; /** - * Virtual machine for Truffle based languages. Use {@link #create()} to instantiate new isolated - * virtual machine ready for execution of various languages. All the languages in a single virtual - * machine see each other exported global symbols and can co-operate. Use {@link #create()} multiple - * times to create different, isolated virtual machines completely separated from each other. + * Virtual machine for Truffle based languages. Use {@link #newVM()} to create new isolated virtual + * machine ready for execution of various languages. All the languages in a single virtual machine + * see each other exported global symbols and can co-operate. Use {@link #newVM()} multiple times to + * create different, isolated virtual machines completely separated from each other. * <p> * Once instantiated use {@link #eval(java.net.URI)} with a reference to a file or URL or directly * pass code snippet into the virtual machine via {@link #eval(java.lang.String, java.lang.String)}. @@ -50,17 +50,41 @@ * initialized, it remains so, until the virtual machine isn't garbage collected. * <p> * The <code>TruffleVM</code> is single-threaded and tries to enforce that. It records the thread it - * has been {@link #create() created} by and checks that all subsequent calls are coming from the - * same thread. + * has been {@link Builder#build() created} by and checks that all subsequent calls are coming from + * the same thread. */ public final class TruffleVM { private static final Logger LOG = Logger.getLogger(TruffleVM.class.getName()); private static final SPIAccessor SPI = new SPIAccessor(); private final Thread initThread; private final Map<String, Language> langs; + private final Reader in; + private final Writer err; + private final Writer out; + /** + * Private & temporary only constructor. + */ private TruffleVM() { - initThread = Thread.currentThread(); + this.initThread = null; + this.in = null; + this.err = null; + this.out = null; + this.langs = null; + } + + /** + * Real constructor used from the builder. + * + * @param out stdout + * @param err stderr + * @param in stdin + */ + private TruffleVM(Writer out, Writer err, Reader in) { + this.out = out; + this.err = err; + this.in = in; + this.initThread = Thread.currentThread(); this.langs = new HashMap<>(); Enumeration<URL> en; try { @@ -96,14 +120,105 @@ } /** - * Creates new Truffle virtual machine. It searches for {@link Registration languages - * registered} in the system class loader and makes them available for later evaluation via + * Creation of new Truffle virtual machine. Use the {@link Builder} methods to configure your + * virtual machine and then create one using {@link Builder#build()}: + * + * <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#build() build()}; + * </pre> + * + * It searches for {@link Registration languages registered} in the system class loader and + * makes them available for later evaluation via * {@link #eval(java.lang.String, java.lang.String)} methods. * * @return new, isolated virtual machine with pre-registered languages */ - public static TruffleVM create() { - return new TruffleVM(); + public static TruffleVM.Builder newVM() { + // making Builder non-static inner class is a + // nasty trick to avoid the Builder class to appear + // in Javadoc next to TruffleVM class + TruffleVM vm = new TruffleVM(); + return vm.new Builder(); + } + + /** + * Builder for a new {@link TruffleVM}. Call various configuration methods in a chain and at the + * end create new {@link TruffleVM virtual machine}: + * + * <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#build() build()}; + * </pre> + */ + public final class Builder { + private Writer out; + private Writer err; + private Reader in; + + Builder() { + } + + /** + * Changes the defaut 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 + * @return instance of this builder + */ + public Builder stdOut(Writer w) { + out = w; + return this; + } + + /** + * 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 + * @return instance of this builder + */ + public Builder stdErr(Writer w) { + err = w; + return this; + } + + /** + * Changes the defaut input for languages running in <em>to be created</em> + * {@link TruffleVM virtual machine}. The default is to use {@link System#out}. + * + * @param r the reader to use as input + * @return instance of this builder + */ + public Builder stdIn(Reader r) { + in = r; + return this; + } + + /** + * Creates the {@link TruffleVM Truffle virtual machine}. The configuration is taken from + * values passed into configuration methods in this class. + * + * @return new, isolated virtual machine with pre-registered languages + */ + public TruffleVM build() { + if (out == null) { + out = new OutputStreamWriter(System.out); + } + if (err == null) { + err = new OutputStreamWriter(System.err); + } + if (in == null) { + in = new InputStreamReader(System.in); + } + return new TruffleVM(out, err, in); + } } /** @@ -321,7 +436,7 @@ try { Class<?> langClazz = Class.forName(n, true, loader()); Constructor<?> constructor = langClazz.getConstructor(Env.class); - impl = SPI.attachEnv(TruffleVM.this, constructor); + impl = SPI.attachEnv(TruffleVM.this, constructor, out, err, in); } catch (Exception ex) { throw new IllegalStateException("Cannot initialize " + getName() + " language with implementation " + n, ex); } @@ -353,8 +468,8 @@ } @Override - public TruffleLanguage attachEnv(TruffleVM vm, Constructor<?> langClazz) { - return super.attachEnv(vm, langClazz); + public TruffleLanguage attachEnv(TruffleVM vm, Constructor<?> langClazz, Writer stdOut, Writer stdErr, Reader stdIn) { + return super.attachEnv(vm, langClazz, stdOut, stdErr, stdIn); } @Override