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