Mercurial > hg > graal-compiler
comparison graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleLanguage.java @ 21522:28cbfacd0518
Merge
author | Gilles Duboscq <gilles.m.duboscq@oracle.com> |
---|---|
date | Thu, 28 May 2015 17:44:05 +0200 |
parents | 3286fb5fea4a |
children | 31fc2fce38f3 |
comparison
equal
deleted
inserted
replaced
21521:107300758a4e | 21522:28cbfacd0518 |
---|---|
1 /* | |
2 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. | |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. Oracle designates this | |
8 * particular file as subject to the "Classpath" exception as provided | |
9 * by Oracle in the LICENSE file that accompanied this code. | |
10 * | |
11 * This code is distributed in the hope that it will be useful, but WITHOUT | |
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
14 * version 2 for more details (a copy is included in the LICENSE file that | |
15 * accompanied this code). | |
16 * | |
17 * You should have received a copy of the GNU General Public License version | |
18 * 2 along with this work; if not, write to the Free Software Foundation, | |
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
20 * | |
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
22 * or visit www.oracle.com if you need additional information or have any | |
23 * questions. | |
24 */ | |
25 package com.oracle.truffle.api; | |
26 | |
27 import com.oracle.truffle.api.impl.Accessor; | |
28 import com.oracle.truffle.api.source.Source; | |
29 import com.oracle.truffle.api.vm.TruffleVM; | |
30 import com.oracle.truffle.api.vm.TruffleVM.Language; | |
31 import java.io.IOException; | |
32 import java.io.Reader; | |
33 import java.io.Writer; | |
34 import java.lang.annotation.ElementType; | |
35 import java.lang.annotation.Retention; | |
36 import java.lang.annotation.RetentionPolicy; | |
37 import java.lang.annotation.Target; | |
38 import java.lang.reflect.Constructor; | |
39 | |
40 /** | |
41 * An entry point for everyone who wants to implement a Truffle based language. By providing | |
42 * implementation of this type and registering it using {@link Registration} annotation, your | |
43 * language becomes accessible to users of the {@link TruffleVM Truffle virtual machine} - all they | |
44 * will need to do is to include your JAR into their application and all the Truffle goodies (multi | |
45 * language support, multi tennat hosting, debugging, etc.) will be made available to them. | |
46 */ | |
47 public abstract class TruffleLanguage { | |
48 private final Env env; | |
49 | |
50 /** | |
51 * Constructor to be called by subclasses. | |
52 * | |
53 * @param env language environment that will be available via {@link #env()} method to | |
54 * subclasses. | |
55 */ | |
56 protected TruffleLanguage(Env env) { | |
57 this.env = env; | |
58 } | |
59 | |
60 /** | |
61 * The annotation to use to register your language to the {@link TruffleVM Truffle} system. By | |
62 * annotating your implementation of {@link TruffleLanguage} by this annotation you are just a | |
63 * <em>one JAR drop to the classpath</em> away from your users. Once they include your JAR in | |
64 * their application, your language will be available to the {@link TruffleVM Truffle virtual | |
65 * machine}. | |
66 */ | |
67 @Retention(RetentionPolicy.SOURCE) | |
68 @Target(ElementType.TYPE) | |
69 public @interface Registration { | |
70 /** | |
71 * Unique name of your language. This name will be exposed to users via the | |
72 * {@link Language#getName()} getter. | |
73 * | |
74 * @return identifier of your language | |
75 */ | |
76 String name(); | |
77 | |
78 /** | |
79 * List of mimetypes associated with your language. Users will use them (directly or | |
80 * inderectly) when {@link TruffleVM#eval(java.lang.String, java.lang.String) executing} | |
81 * their code snippets or their {@link TruffleVM#eval(java.net.URI) files}. | |
82 * | |
83 * @return array of mime types assigned to your language files | |
84 */ | |
85 String[] mimeType(); | |
86 } | |
87 | |
88 protected final Env env() { | |
89 if (this.env == null) { | |
90 throw new NullPointerException("Accessing env before initialization is finished"); | |
91 } | |
92 return this.env; | |
93 } | |
94 | |
95 protected abstract Object eval(Source code) throws IOException; | |
96 | |
97 /** | |
98 * Called when some other language is seeking for a global symbol. This method is supposed to do | |
99 * lazy binding, e.g. there is no need to export symbols in advance, it is fine to wait until | |
100 * somebody asks for it (by calling this method). | |
101 * <p> | |
102 * The exported object can either be <code>TruffleObject</code> (e.g. a native object from the | |
103 * other language) to support interoperability between languages or one of Java primitive | |
104 * wrappers ( {@link Integer}, {@link Double}, {@link Short}, etc.). | |
105 * | |
106 * @param globalName the name of the global symbol to find | |
107 * @return an exported object or <code>null</code>, if the symbol does not represent anything | |
108 * meaningful in this language | |
109 */ | |
110 protected abstract Object findExportedSymbol(String globalName); | |
111 | |
112 /** | |
113 * Returns global object for the language. | |
114 * <p> | |
115 * The object is expected to be <code>TruffleObject</code> (e.g. a native object from the other | |
116 * language) but technically it can be one of Java primitive wrappers ({@link Integer}, | |
117 * {@link Double}, {@link Short}, etc.). | |
118 * | |
119 * @return the global object or <code>null</code> if the language does not support such concept | |
120 */ | |
121 protected abstract Object getLanguageGlobal(); | |
122 | |
123 /** | |
124 * Checks whether the object is provided by this language. | |
125 * | |
126 * @param object the object to check | |
127 * @return <code>true</code> if this language can deal with such object in native way | |
128 */ | |
129 protected abstract boolean isObjectOfLanguage(Object object); | |
130 | |
131 /** | |
132 * Represents execution environment of the {@link TruffleLanguage}. Each active | |
133 * {@link TruffleLanguage} receives instance of the environment before any code is executed upon | |
134 * it. The environment has knowledge of all active languages and can exchange symbols between | |
135 * them. | |
136 */ | |
137 public static final class Env { | |
138 private final TruffleVM vm; | |
139 private final TruffleLanguage lang; | |
140 private final Reader in; | |
141 private final Writer err; | |
142 private final Writer out; | |
143 | |
144 Env(TruffleVM vm, Constructor<?> langConstructor, Writer out, Writer err, Reader in) { | |
145 this.vm = vm; | |
146 this.in = in; | |
147 this.err = err; | |
148 this.out = out; | |
149 try { | |
150 this.lang = (TruffleLanguage) langConstructor.newInstance(this); | |
151 } catch (Exception ex) { | |
152 throw new IllegalStateException("Cannot construct language " + langConstructor.getDeclaringClass().getName(), ex); | |
153 } | |
154 } | |
155 | |
156 /** | |
157 * Asks the environment to go through other registered languages and find whether they | |
158 * export global symbol of specified name. The expected return type is either | |
159 * <code>TruffleObject</code>, or one of wrappers of Java primitive types ({@link Integer}, | |
160 * {@link Double}). | |
161 * | |
162 * @param globalName the name of the symbol to search for | |
163 * @return object representing the symbol or <code>null</code> | |
164 */ | |
165 public Object importSymbol(String globalName) { | |
166 return API.importSymbol(vm, lang, globalName); | |
167 } | |
168 | |
169 /** | |
170 * Input associated with this {@link TruffleVM}. | |
171 * | |
172 * @return reader, never <code>null</code> | |
173 */ | |
174 public Reader stdIn() { | |
175 return in; | |
176 } | |
177 | |
178 /** | |
179 * Standard output writer for this {@link TruffleVM}. | |
180 * | |
181 * @return writer, never <code>null</code> | |
182 */ | |
183 public Writer stdOut() { | |
184 return out; | |
185 } | |
186 | |
187 /** | |
188 * Standard error writer for this {@link TruffleVM}. | |
189 * | |
190 * @return writer, never <code>null</code> | |
191 */ | |
192 public Writer stdErr() { | |
193 return err; | |
194 } | |
195 } | |
196 | |
197 private static final AccessAPI API = new AccessAPI(); | |
198 | |
199 private static final class AccessAPI extends Accessor { | |
200 @Override | |
201 protected TruffleLanguage attachEnv(TruffleVM vm, Constructor<?> langClazz, Writer stdOut, Writer stdErr, Reader stdIn) { | |
202 Env env = new Env(vm, langClazz, stdOut, stdErr, stdIn); | |
203 return env.lang; | |
204 } | |
205 | |
206 @Override | |
207 public Object importSymbol(TruffleVM vm, TruffleLanguage queryingLang, String globalName) { | |
208 return super.importSymbol(vm, queryingLang, globalName); | |
209 } | |
210 | |
211 @Override | |
212 protected Object eval(TruffleLanguage l, Source s) throws IOException { | |
213 return l.eval(s); | |
214 } | |
215 | |
216 @Override | |
217 protected Object findExportedSymbol(TruffleLanguage l, String globalName) { | |
218 return l.findExportedSymbol(globalName); | |
219 } | |
220 | |
221 @Override | |
222 protected Object languageGlobal(TruffleLanguage l) { | |
223 return l.getLanguageGlobal(); | |
224 } | |
225 } | |
226 } |