Mercurial > hg > graal-compiler
comparison 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 |
comparison
equal
deleted
inserted
replaced
21556:48c1ebd24120 | 21557:31fc2fce38f3 |
---|---|
36 import com.oracle.truffle.api.TruffleLanguage.Registration; | 36 import com.oracle.truffle.api.TruffleLanguage.Registration; |
37 import com.oracle.truffle.api.impl.*; | 37 import com.oracle.truffle.api.impl.*; |
38 import com.oracle.truffle.api.source.*; | 38 import com.oracle.truffle.api.source.*; |
39 | 39 |
40 /** | 40 /** |
41 * Virtual machine for Truffle based languages. Use {@link #create()} to instantiate new isolated | 41 * Virtual machine for Truffle based languages. Use {@link #newVM()} to create new isolated virtual |
42 * virtual machine ready for execution of various languages. All the languages in a single virtual | 42 * machine ready for execution of various languages. All the languages in a single virtual machine |
43 * machine see each other exported global symbols and can co-operate. Use {@link #create()} multiple | 43 * see each other exported global symbols and can co-operate. Use {@link #newVM()} multiple times to |
44 * times to create different, isolated virtual machines completely separated from each other. | 44 * create different, isolated virtual machines completely separated from each other. |
45 * <p> | 45 * <p> |
46 * Once instantiated use {@link #eval(java.net.URI)} with a reference to a file or URL or directly | 46 * Once instantiated use {@link #eval(java.net.URI)} with a reference to a file or URL or directly |
47 * pass code snippet into the virtual machine via {@link #eval(java.lang.String, java.lang.String)}. | 47 * pass code snippet into the virtual machine via {@link #eval(java.lang.String, java.lang.String)}. |
48 * Support for individual languages is initialized on demand - e.g. once a file of certain mime type | 48 * Support for individual languages is initialized on demand - e.g. once a file of certain mime type |
49 * is about to be processed, its appropriate engine (if found), is initialized. Once an engine gets | 49 * is about to be processed, its appropriate engine (if found), is initialized. Once an engine gets |
50 * initialized, it remains so, until the virtual machine isn't garbage collected. | 50 * initialized, it remains so, until the virtual machine isn't garbage collected. |
51 * <p> | 51 * <p> |
52 * The <code>TruffleVM</code> is single-threaded and tries to enforce that. It records the thread it | 52 * The <code>TruffleVM</code> is single-threaded and tries to enforce that. It records the thread it |
53 * has been {@link #create() created} by and checks that all subsequent calls are coming from the | 53 * has been {@link Builder#build() created} by and checks that all subsequent calls are coming from |
54 * same thread. | 54 * the same thread. |
55 */ | 55 */ |
56 public final class TruffleVM { | 56 public final class TruffleVM { |
57 private static final Logger LOG = Logger.getLogger(TruffleVM.class.getName()); | 57 private static final Logger LOG = Logger.getLogger(TruffleVM.class.getName()); |
58 private static final SPIAccessor SPI = new SPIAccessor(); | 58 private static final SPIAccessor SPI = new SPIAccessor(); |
59 private final Thread initThread; | 59 private final Thread initThread; |
60 private final Map<String, Language> langs; | 60 private final Map<String, Language> langs; |
61 | 61 private final Reader in; |
62 private final Writer err; | |
63 private final Writer out; | |
64 | |
65 /** | |
66 * Private & temporary only constructor. | |
67 */ | |
62 private TruffleVM() { | 68 private TruffleVM() { |
63 initThread = Thread.currentThread(); | 69 this.initThread = null; |
70 this.in = null; | |
71 this.err = null; | |
72 this.out = null; | |
73 this.langs = null; | |
74 } | |
75 | |
76 /** | |
77 * Real constructor used from the builder. | |
78 * | |
79 * @param out stdout | |
80 * @param err stderr | |
81 * @param in stdin | |
82 */ | |
83 private TruffleVM(Writer out, Writer err, Reader in) { | |
84 this.out = out; | |
85 this.err = err; | |
86 this.in = in; | |
87 this.initThread = Thread.currentThread(); | |
64 this.langs = new HashMap<>(); | 88 this.langs = new HashMap<>(); |
65 Enumeration<URL> en; | 89 Enumeration<URL> en; |
66 try { | 90 try { |
67 en = loader().getResources("META-INF/truffle/language"); | 91 en = loader().getResources("META-INF/truffle/language"); |
68 } catch (IOException ex) { | 92 } catch (IOException ex) { |
94 } | 118 } |
95 return l; | 119 return l; |
96 } | 120 } |
97 | 121 |
98 /** | 122 /** |
99 * Creates new Truffle virtual machine. It searches for {@link Registration languages | 123 * Creation of new Truffle virtual machine. Use the {@link Builder} methods to configure your |
100 * registered} in the system class loader and makes them available for later evaluation via | 124 * virtual machine and then create one using {@link Builder#build()}: |
125 * | |
126 * <pre> | |
127 * {@link TruffleVM} vm = {@link TruffleVM}.{@link TruffleVM#newVM() newVM()} | |
128 * .{@link Builder#stdOut(java.io.Writer) stdOut}({@link Writer yourWriter}) | |
129 * .{@link Builder#stdErr(java.io.Writer) stdErr}({@link Writer yourWriter}) | |
130 * .{@link Builder#stdIn(java.io.Reader) stdIn}({@link Reader yourReader}) | |
131 * .{@link Builder#build() build()}; | |
132 * </pre> | |
133 * | |
134 * It searches for {@link Registration languages registered} in the system class loader and | |
135 * makes them available for later evaluation via | |
101 * {@link #eval(java.lang.String, java.lang.String)} methods. | 136 * {@link #eval(java.lang.String, java.lang.String)} methods. |
102 * | 137 * |
103 * @return new, isolated virtual machine with pre-registered languages | 138 * @return new, isolated virtual machine with pre-registered languages |
104 */ | 139 */ |
105 public static TruffleVM create() { | 140 public static TruffleVM.Builder newVM() { |
106 return new TruffleVM(); | 141 // making Builder non-static inner class is a |
142 // nasty trick to avoid the Builder class to appear | |
143 // in Javadoc next to TruffleVM class | |
144 TruffleVM vm = new TruffleVM(); | |
145 return vm.new Builder(); | |
146 } | |
147 | |
148 /** | |
149 * Builder for a new {@link TruffleVM}. Call various configuration methods in a chain and at the | |
150 * end create new {@link TruffleVM virtual machine}: | |
151 * | |
152 * <pre> | |
153 * {@link TruffleVM} vm = {@link TruffleVM}.{@link TruffleVM#newVM() newVM()} | |
154 * .{@link Builder#stdOut(java.io.Writer) stdOut}({@link Writer yourWriter}) | |
155 * .{@link Builder#stdErr(java.io.Writer) stdErr}({@link Writer yourWriter}) | |
156 * .{@link Builder#stdIn(java.io.Reader) stdIn}({@link Reader yourReader}) | |
157 * .{@link Builder#build() build()}; | |
158 * </pre> | |
159 */ | |
160 public final class Builder { | |
161 private Writer out; | |
162 private Writer err; | |
163 private Reader in; | |
164 | |
165 Builder() { | |
166 } | |
167 | |
168 /** | |
169 * Changes the defaut output for languages running in <em>to be created</em> | |
170 * {@link TruffleVM virtual machine}. The default is to use {@link System#out}. | |
171 * | |
172 * @param w the writer to use as output | |
173 * @return instance of this builder | |
174 */ | |
175 public Builder stdOut(Writer w) { | |
176 out = w; | |
177 return this; | |
178 } | |
179 | |
180 /** | |
181 * Changes the error output for languages running in <em>to be created</em> | |
182 * {@link TruffleVM virtual machine}. The default is to use {@link System#err}. | |
183 * | |
184 * @param w the writer to use as output | |
185 * @return instance of this builder | |
186 */ | |
187 public Builder stdErr(Writer w) { | |
188 err = w; | |
189 return this; | |
190 } | |
191 | |
192 /** | |
193 * Changes the defaut input for languages running in <em>to be created</em> | |
194 * {@link TruffleVM virtual machine}. The default is to use {@link System#out}. | |
195 * | |
196 * @param r the reader to use as input | |
197 * @return instance of this builder | |
198 */ | |
199 public Builder stdIn(Reader r) { | |
200 in = r; | |
201 return this; | |
202 } | |
203 | |
204 /** | |
205 * Creates the {@link TruffleVM Truffle virtual machine}. The configuration is taken from | |
206 * values passed into configuration methods in this class. | |
207 * | |
208 * @return new, isolated virtual machine with pre-registered languages | |
209 */ | |
210 public TruffleVM build() { | |
211 if (out == null) { | |
212 out = new OutputStreamWriter(System.out); | |
213 } | |
214 if (err == null) { | |
215 err = new OutputStreamWriter(System.err); | |
216 } | |
217 if (in == null) { | |
218 in = new InputStreamReader(System.in); | |
219 } | |
220 return new TruffleVM(out, err, in); | |
221 } | |
107 } | 222 } |
108 | 223 |
109 /** | 224 /** |
110 * Descriptions of languages supported in this Truffle virtual machine. | 225 * Descriptions of languages supported in this Truffle virtual machine. |
111 * | 226 * |
319 if (impl == null) { | 434 if (impl == null) { |
320 String n = props.getProperty("className"); | 435 String n = props.getProperty("className"); |
321 try { | 436 try { |
322 Class<?> langClazz = Class.forName(n, true, loader()); | 437 Class<?> langClazz = Class.forName(n, true, loader()); |
323 Constructor<?> constructor = langClazz.getConstructor(Env.class); | 438 Constructor<?> constructor = langClazz.getConstructor(Env.class); |
324 impl = SPI.attachEnv(TruffleVM.this, constructor); | 439 impl = SPI.attachEnv(TruffleVM.this, constructor, out, err, in); |
325 } catch (Exception ex) { | 440 } catch (Exception ex) { |
326 throw new IllegalStateException("Cannot initialize " + getName() + " language with implementation " + n, ex); | 441 throw new IllegalStateException("Cannot initialize " + getName() + " language with implementation " + n, ex); |
327 } | 442 } |
328 } | 443 } |
329 return impl; | 444 return impl; |
351 } | 466 } |
352 return null; | 467 return null; |
353 } | 468 } |
354 | 469 |
355 @Override | 470 @Override |
356 public TruffleLanguage attachEnv(TruffleVM vm, Constructor<?> langClazz) { | 471 public TruffleLanguage attachEnv(TruffleVM vm, Constructor<?> langClazz, Writer stdOut, Writer stdErr, Reader stdIn) { |
357 return super.attachEnv(vm, langClazz); | 472 return super.attachEnv(vm, langClazz, stdOut, stdErr, stdIn); |
358 } | 473 } |
359 | 474 |
360 @Override | 475 @Override |
361 public Object eval(TruffleLanguage l, Source s) throws IOException { | 476 public Object eval(TruffleLanguage l, Source s) throws IOException { |
362 return super.eval(l, s); | 477 return super.eval(l, s); |