Mercurial > hg > graal-compiler
annotate graal/com.oracle.truffle.ruby.runtime/src/com/oracle/truffle/ruby/runtime/RubyContext.java @ 13645:497fada09efb
Ruby: remove versioning.
author | Chris Seaton <chris.seaton@oracle.com> |
---|---|
date | Wed, 15 Jan 2014 19:27:27 +0000 |
parents | fb846424299f |
children | 50c11b9a7fdf |
rev | line source |
---|---|
13514 | 1 /* |
13563
fb846424299f
Truffle/Ruby: extend Instrumentation framework with language-agnostic interfaces for access to AST printing utilities and a Ruby implementation
Michael Van De Vanter <michael.van.de.vanter@oracle.com>
parents:
13514
diff
changeset
|
2 * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved. This |
13514 | 3 * code is released under a tri EPL/GPL/LGPL license. You can use it, |
4 * redistribute it and/or modify it under the terms of the: | |
5 * | |
6 * Eclipse Public License version 1.0 | |
7 * GNU General Public License version 2 | |
8 * GNU Lesser General Public License version 2.1 | |
9 */ | |
10 package com.oracle.truffle.ruby.runtime; | |
11 | |
12 import java.math.*; | |
13 import java.util.concurrent.atomic.*; | |
14 | |
15 import jnr.posix.*; | |
16 | |
17 import com.oracle.truffle.api.*; | |
18 import com.oracle.truffle.api.frame.*; | |
19 import com.oracle.truffle.api.nodes.*; | |
20 import com.oracle.truffle.api.source.*; | |
21 import com.oracle.truffle.ruby.runtime.configuration.*; | |
22 import com.oracle.truffle.ruby.runtime.control.*; | |
23 import com.oracle.truffle.ruby.runtime.core.*; | |
24 import com.oracle.truffle.ruby.runtime.debug.*; | |
25 import com.oracle.truffle.ruby.runtime.methods.*; | |
26 import com.oracle.truffle.ruby.runtime.objects.*; | |
27 import com.oracle.truffle.ruby.runtime.subsystems.*; | |
28 | |
29 /** | |
30 * The global state of a running Ruby system. | |
31 */ | |
32 public class RubyContext implements ExecutionContext { | |
33 | |
34 private final Configuration configuration; | |
35 private final RubyParser parser; | |
36 private final CoreLibrary coreLibrary; | |
37 private final FeatureManager featureManager; | |
38 private final ObjectSpaceManager objectSpaceManager; | |
39 private final TraceManager traceManager; | |
40 private final ThreadManager threadManager; | |
41 private final FiberManager fiberManager; | |
42 private final AtExitManager atExitManager; | |
43 private final RubyDebugManager debugManager; | |
44 private final SourceManager sourceManager; | |
13563
fb846424299f
Truffle/Ruby: extend Instrumentation framework with language-agnostic interfaces for access to AST printing utilities and a Ruby implementation
Michael Van De Vanter <michael.van.de.vanter@oracle.com>
parents:
13514
diff
changeset
|
45 private final ASTPrinter astPrinter; |
13514 | 46 |
47 private AtomicLong nextObjectID = new AtomicLong(0); | |
48 | |
49 private String currentDirectory = System.getProperty("user.dir"); | |
50 | |
51 private POSIX posix = POSIXFactory.getPOSIX(); | |
52 | |
53 public RubyContext(RubyParser parser) { | |
13563
fb846424299f
Truffle/Ruby: extend Instrumentation framework with language-agnostic interfaces for access to AST printing utilities and a Ruby implementation
Michael Van De Vanter <michael.van.de.vanter@oracle.com>
parents:
13514
diff
changeset
|
54 this(new Configuration(new ConfigurationBuilder()), parser, null); |
13514 | 55 } |
56 | |
57 public RubyContext(Configuration configuration, RubyParser parser) { | |
13563
fb846424299f
Truffle/Ruby: extend Instrumentation framework with language-agnostic interfaces for access to AST printing utilities and a Ruby implementation
Michael Van De Vanter <michael.van.de.vanter@oracle.com>
parents:
13514
diff
changeset
|
58 this(configuration, parser, null); |
fb846424299f
Truffle/Ruby: extend Instrumentation framework with language-agnostic interfaces for access to AST printing utilities and a Ruby implementation
Michael Van De Vanter <michael.van.de.vanter@oracle.com>
parents:
13514
diff
changeset
|
59 } |
fb846424299f
Truffle/Ruby: extend Instrumentation framework with language-agnostic interfaces for access to AST printing utilities and a Ruby implementation
Michael Van De Vanter <michael.van.de.vanter@oracle.com>
parents:
13514
diff
changeset
|
60 |
fb846424299f
Truffle/Ruby: extend Instrumentation framework with language-agnostic interfaces for access to AST printing utilities and a Ruby implementation
Michael Van De Vanter <michael.van.de.vanter@oracle.com>
parents:
13514
diff
changeset
|
61 public RubyContext(Configuration configuration, RubyParser parser, ASTPrinter astPrinter) { |
13514 | 62 assert configuration != null; |
63 | |
64 this.configuration = configuration; | |
65 this.parser = parser; | |
13563
fb846424299f
Truffle/Ruby: extend Instrumentation framework with language-agnostic interfaces for access to AST printing utilities and a Ruby implementation
Michael Van De Vanter <michael.van.de.vanter@oracle.com>
parents:
13514
diff
changeset
|
66 this.astPrinter = astPrinter; |
13514 | 67 |
68 objectSpaceManager = new ObjectSpaceManager(this); | |
69 traceManager = new TraceManager(this); | |
70 | |
71 // See note in CoreLibrary#initialize to see why we need to break this into two statements | |
72 coreLibrary = new CoreLibrary(this); | |
73 coreLibrary.initialize(); | |
74 | |
75 featureManager = new FeatureManager(this); | |
76 atExitManager = new AtExitManager(); | |
77 sourceManager = new SourceManager(); | |
78 | |
79 debugManager = configuration.getDebug() ? new RubyDebugManager(this) : null; | |
80 | |
81 // Must initialize threads before fibers | |
82 | |
83 threadManager = new ThreadManager(this); | |
13645
497fada09efb
Ruby: remove versioning.
Chris Seaton <chris.seaton@oracle.com>
parents:
13563
diff
changeset
|
84 fiberManager = new FiberManager(this); |
13514 | 85 } |
86 | |
87 public String getLanguageShortName() { | |
13645
497fada09efb
Ruby: remove versioning.
Chris Seaton <chris.seaton@oracle.com>
parents:
13563
diff
changeset
|
88 return "Ruby"; |
13514 | 89 } |
90 | |
91 public RubyDebugManager getDebugManager() { | |
92 return debugManager; | |
93 } | |
94 | |
13563
fb846424299f
Truffle/Ruby: extend Instrumentation framework with language-agnostic interfaces for access to AST printing utilities and a Ruby implementation
Michael Van De Vanter <michael.van.de.vanter@oracle.com>
parents:
13514
diff
changeset
|
95 public ASTPrinter getASTPrinter() { |
fb846424299f
Truffle/Ruby: extend Instrumentation framework with language-agnostic interfaces for access to AST printing utilities and a Ruby implementation
Michael Van De Vanter <michael.van.de.vanter@oracle.com>
parents:
13514
diff
changeset
|
96 return astPrinter; |
fb846424299f
Truffle/Ruby: extend Instrumentation framework with language-agnostic interfaces for access to AST printing utilities and a Ruby implementation
Michael Van De Vanter <michael.van.de.vanter@oracle.com>
parents:
13514
diff
changeset
|
97 } |
fb846424299f
Truffle/Ruby: extend Instrumentation framework with language-agnostic interfaces for access to AST printing utilities and a Ruby implementation
Michael Van De Vanter <michael.van.de.vanter@oracle.com>
parents:
13514
diff
changeset
|
98 |
13514 | 99 public void implementationMessage(String format, Object... arguments) { |
100 System.err.println("rubytruffle: " + String.format(format, arguments)); | |
101 } | |
102 | |
103 public void load(Source source) { | |
104 execute(this, source, RubyParser.ParserContext.TOP_LEVEL, coreLibrary.getMainObject(), null); | |
105 } | |
106 | |
107 public void loadFile(String fileName) { | |
108 final Source source = sourceManager.get(fileName); | |
109 final String code = source.getCode(); | |
110 if (code == null) { | |
111 throw new RuntimeException("Can't read file " + fileName); | |
112 } | |
113 execute(this, source, RubyParser.ParserContext.TOP_LEVEL, coreLibrary.getMainObject(), null); | |
114 } | |
115 | |
116 /** | |
117 * Receives runtime notification that execution has halted. | |
118 */ | |
119 public void haltedAt(Node node, MaterializedFrame frame) { | |
120 runShell(node, frame); | |
121 } | |
122 | |
123 public Object eval(String code) { | |
124 final Source source = sourceManager.get("(eval)", code); | |
125 return execute(this, source, RubyParser.ParserContext.TOP_LEVEL, coreLibrary.getMainObject(), null); | |
126 } | |
127 | |
128 public Object eval(String code, RubyModule module) { | |
129 final Source source = sourceManager.get("(eval)", code); | |
130 return execute(this, source, RubyParser.ParserContext.MODULE, module, null); | |
131 } | |
132 | |
133 public Object eval(String code, RubyBinding binding) { | |
134 final Source source = sourceManager.get("(eval)", code); | |
135 return execute(this, source, RubyParser.ParserContext.TOP_LEVEL, binding.getSelf(), binding.getFrame()); | |
136 } | |
137 | |
138 public void runShell(Node node, MaterializedFrame frame) { | |
139 MaterializedFrame existingLocals = frame; | |
140 | |
141 String prompt = "Ruby> "; | |
142 if (node != null) { | |
143 final SourceSection src = node.getSourceSection(); | |
144 if (src != null) { | |
145 prompt = (src.getSource().getName() + ":" + src.getStartLine() + "> "); | |
146 } | |
147 } | |
148 | |
149 while (true) { | |
150 try { | |
151 final String line = configuration.getInputReader().readLine(prompt); | |
152 | |
153 final ShellResult result = evalShell(line, existingLocals); | |
154 | |
155 configuration.getStandardOut().println("=> " + result.getResult()); | |
156 | |
157 existingLocals = result.getFrame(); | |
158 } catch (BreakShellException e) { | |
159 return; | |
160 } catch (Exception e) { | |
161 e.printStackTrace(); | |
162 } | |
163 } | |
164 } | |
165 | |
166 public ShellResult evalShell(String code, MaterializedFrame existingLocals) { | |
167 final Source source = sourceManager.get("(shell)", code); | |
168 return (ShellResult) execute(this, source, RubyParser.ParserContext.SHELL, coreLibrary.getMainObject(), existingLocals); | |
169 } | |
170 | |
171 public Object execute(RubyContext context, Source source, RubyParser.ParserContext parserContext, Object self, MaterializedFrame parentFrame) { | |
172 if (configuration.getPrintExecutedFiles()) { | |
173 implementationMessage("executing: %s", source.getName()); | |
174 } | |
175 | |
176 try { | |
177 final RubyParserResult parseResult = parser.parse(context, source, parserContext, parentFrame); | |
178 final RubyArguments arguments = new RubyArguments(parentFrame, self, null); | |
179 final CallTarget callTarget = Truffle.getRuntime().createCallTarget(parseResult.getRootNode(), parseResult.getFrameDescriptor()); | |
180 | |
181 return callTarget.call(null, arguments); | |
182 } catch (RaiseException e) { | |
183 throw e; | |
184 } catch (ThrowException e) { | |
13645
497fada09efb
Ruby: remove versioning.
Chris Seaton <chris.seaton@oracle.com>
parents:
13563
diff
changeset
|
185 throw new RaiseException(context.getCoreLibrary().argumentErrorUncaughtThrow(e.getTag())); |
13514 | 186 } catch (BreakShellException | QuitException e) { |
187 throw e; | |
188 } catch (Throwable e) { | |
189 throw new RaiseException(ExceptionTranslator.translateException(this, e)); | |
190 } | |
191 } | |
192 | |
193 public long getNextObjectID() { | |
194 // TODO(CS): We can theoretically run out of long values | |
195 | |
196 final long id = nextObjectID.getAndIncrement(); | |
197 | |
198 if (id < 0) { | |
199 nextObjectID.set(Long.MIN_VALUE); | |
200 throw new RuntimeException("Object IDs exhausted"); | |
201 } | |
202 | |
203 return id; | |
204 } | |
205 | |
206 public void shutdown() { | |
207 atExitManager.run(); | |
208 | |
209 threadManager.leaveGlobalLock(); | |
210 | |
211 objectSpaceManager.shutdown(); | |
212 | |
213 if (fiberManager != null) { | |
214 fiberManager.shutdown(); | |
215 } | |
216 } | |
217 | |
218 public RubyString makeString(String string) { | |
219 return new RubyString(coreLibrary.getStringClass(), string); | |
220 } | |
221 | |
222 public RubyString makeString(char string) { | |
223 return makeString(Character.toString(string)); | |
224 } | |
225 | |
226 public Configuration getConfiguration() { | |
227 return configuration; | |
228 } | |
229 | |
230 public CoreLibrary getCoreLibrary() { | |
231 return coreLibrary; | |
232 } | |
233 | |
234 public FeatureManager getFeatureManager() { | |
235 return featureManager; | |
236 } | |
237 | |
238 public ObjectSpaceManager getObjectSpaceManager() { | |
239 return objectSpaceManager; | |
240 } | |
241 | |
242 public TraceManager getTraceManager() { | |
243 return traceManager; | |
244 } | |
245 | |
246 public FiberManager getFiberManager() { | |
247 return fiberManager; | |
248 } | |
249 | |
250 public ThreadManager getThreadManager() { | |
251 return threadManager; | |
252 } | |
253 | |
254 public RubyParser getParser() { | |
255 return parser; | |
256 } | |
257 | |
258 /** | |
259 * Utility method to check if an object should be visible in a Ruby program. Used in assertions | |
260 * at method boundaries to check that only values we want to be visible to the programmer become | |
261 * so. | |
262 */ | |
263 public static boolean shouldObjectBeVisible(Object object) { | |
264 // TODO(cs): RubyMethod should never be visible | |
265 | |
266 return object instanceof UndefinedPlaceholder || // | |
267 object instanceof Boolean || // | |
268 object instanceof Integer || // | |
269 object instanceof BigInteger || // | |
270 object instanceof Double || // | |
271 object instanceof RubyBasicObject || // | |
272 object instanceof RubyMethod || // | |
273 object instanceof NilPlaceholder || // | |
274 object instanceof RubyMethod; | |
275 } | |
276 | |
277 public static boolean shouldObjectsBeVisible(Object... objects) { | |
278 for (Object object : objects) { | |
279 if (!shouldObjectBeVisible(object)) { | |
280 return false; | |
281 } | |
282 } | |
283 | |
284 return true; | |
285 } | |
286 | |
287 public void setCurrentDirectory(String currentDirectory) { | |
288 this.currentDirectory = currentDirectory; | |
289 } | |
290 | |
291 public String getCurrentDirectory() { | |
292 return currentDirectory; | |
293 } | |
294 | |
295 public POSIX getPOSIX() { | |
296 return posix; | |
297 } | |
298 | |
299 public AtExitManager getAtExitManager() { | |
300 return atExitManager; | |
301 } | |
302 | |
303 public SourceManager getSourceManager() { | |
304 return sourceManager; | |
305 } | |
306 | |
307 } |