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