Mercurial > hg > graal-compiler
comparison graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ObjectNodes.java @ 13529:856c2c294f84
Merge.
author | Christian Humer <christian.humer@gmail.com> |
---|---|
date | Tue, 07 Jan 2014 18:53:04 +0100 |
parents | 0fbee3eb71f0 |
children |
comparison
equal
deleted
inserted
replaced
13528:5a0c694ef735 | 13529:856c2c294f84 |
---|---|
1 /* | |
2 * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This | |
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.nodes.core; | |
11 | |
12 import java.math.*; | |
13 import java.util.*; | |
14 | |
15 import com.oracle.truffle.api.*; | |
16 import com.oracle.truffle.api.dsl.*; | |
17 import com.oracle.truffle.api.frame.*; | |
18 import com.oracle.truffle.ruby.runtime.*; | |
19 import com.oracle.truffle.ruby.runtime.core.*; | |
20 import com.oracle.truffle.ruby.runtime.core.array.*; | |
21 import com.oracle.truffle.ruby.runtime.methods.*; | |
22 import com.oracle.truffle.ruby.runtime.objects.*; | |
23 | |
24 @CoreClass(name = "Object") | |
25 public abstract class ObjectNodes { | |
26 | |
27 @CoreMethod(names = "class", maxArgs = 0) | |
28 public abstract static class ClassNode extends CoreMethodNode { | |
29 | |
30 public ClassNode(RubyContext context, SourceSection sourceSection) { | |
31 super(context, sourceSection); | |
32 } | |
33 | |
34 public ClassNode(ClassNode prev) { | |
35 super(prev); | |
36 } | |
37 | |
38 @Specialization | |
39 public RubyClass getClass(boolean value) { | |
40 if (value) { | |
41 return getContext().getCoreLibrary().getTrueClass(); | |
42 } else { | |
43 return getContext().getCoreLibrary().getFalseClass(); | |
44 } | |
45 } | |
46 | |
47 @Specialization | |
48 public RubyClass getClass(@SuppressWarnings("unused") int value) { | |
49 return getContext().getCoreLibrary().getFixnumClass(); | |
50 } | |
51 | |
52 @Specialization | |
53 public RubyClass getClass(@SuppressWarnings("unused") BigInteger value) { | |
54 return getContext().getCoreLibrary().getBignumClass(); | |
55 } | |
56 | |
57 @Specialization | |
58 public RubyClass getClass(@SuppressWarnings("unused") double value) { | |
59 return getContext().getCoreLibrary().getFloatClass(); | |
60 } | |
61 | |
62 @Specialization | |
63 public RubyClass getClass(RubyBasicObject self) { | |
64 return self.getRubyClass(); | |
65 } | |
66 | |
67 } | |
68 | |
69 @CoreMethod(names = "dup", maxArgs = 0) | |
70 public abstract static class DupNode extends CoreMethodNode { | |
71 | |
72 public DupNode(RubyContext context, SourceSection sourceSection) { | |
73 super(context, sourceSection); | |
74 } | |
75 | |
76 public DupNode(DupNode prev) { | |
77 super(prev); | |
78 } | |
79 | |
80 @Specialization | |
81 public Object dup(RubyObject self) { | |
82 return self.dup(); | |
83 } | |
84 | |
85 } | |
86 | |
87 @CoreMethod(names = "extend", isSplatted = true, minArgs = 1) | |
88 public abstract static class ExtendNode extends CoreMethodNode { | |
89 | |
90 public ExtendNode(RubyContext context, SourceSection sourceSection) { | |
91 super(context, sourceSection); | |
92 } | |
93 | |
94 public ExtendNode(ExtendNode prev) { | |
95 super(prev); | |
96 } | |
97 | |
98 @Specialization | |
99 public RubyBasicObject extend(RubyBasicObject self, Object[] args) { | |
100 for (int n = 0; n < args.length; n++) { | |
101 self.extend((RubyModule) args[n]); | |
102 } | |
103 | |
104 return self; | |
105 } | |
106 | |
107 } | |
108 | |
109 @CoreMethod(names = "freeze", maxArgs = 0) | |
110 public abstract static class FreezeNode extends CoreMethodNode { | |
111 | |
112 public FreezeNode(RubyContext context, SourceSection sourceSection) { | |
113 super(context, sourceSection); | |
114 } | |
115 | |
116 public FreezeNode(FreezeNode prev) { | |
117 super(prev); | |
118 } | |
119 | |
120 @Specialization | |
121 public RubyObject freeze(RubyObject self) { | |
122 self.frozen = true; | |
123 return self; | |
124 } | |
125 | |
126 } | |
127 | |
128 @CoreMethod(names = "frozen?", maxArgs = 0) | |
129 public abstract static class FrozenNode extends CoreMethodNode { | |
130 | |
131 public FrozenNode(RubyContext context, SourceSection sourceSection) { | |
132 super(context, sourceSection); | |
133 } | |
134 | |
135 public FrozenNode(FrozenNode prev) { | |
136 super(prev); | |
137 } | |
138 | |
139 @Specialization | |
140 public boolean isFrozen(RubyObject self) { | |
141 return self.frozen; | |
142 } | |
143 | |
144 } | |
145 | |
146 @CoreMethod(names = "inspect", maxArgs = 0) | |
147 public abstract static class InspectNode extends CoreMethodNode { | |
148 | |
149 public InspectNode(RubyContext context, SourceSection sourceSection) { | |
150 super(context, sourceSection); | |
151 } | |
152 | |
153 public InspectNode(InspectNode prev) { | |
154 super(prev); | |
155 } | |
156 | |
157 @Specialization | |
158 public RubyString inspect(boolean value) { | |
159 return getContext().makeString(Boolean.toString(value)); | |
160 } | |
161 | |
162 @Specialization | |
163 public RubyString inspect(int value) { | |
164 return getContext().makeString(Integer.toString(value)); | |
165 } | |
166 | |
167 @Specialization | |
168 public RubyString inspect(BigInteger value) { | |
169 return getContext().makeString(value.toString()); | |
170 } | |
171 | |
172 @Specialization | |
173 public RubyString inspect(double value) { | |
174 return getContext().makeString(Double.toString(value)); | |
175 } | |
176 | |
177 @Specialization | |
178 public RubyString inspect(RubyObject self) { | |
179 return getContext().makeString(self.inspect()); | |
180 } | |
181 | |
182 } | |
183 | |
184 @CoreMethod(names = "instance_eval", needsBlock = true, maxArgs = 0) | |
185 public abstract static class InstanceEvalNode extends CoreMethodNode { | |
186 | |
187 public InstanceEvalNode(RubyContext context, SourceSection sourceSection) { | |
188 super(context, sourceSection); | |
189 } | |
190 | |
191 public InstanceEvalNode(InstanceEvalNode prev) { | |
192 super(prev); | |
193 } | |
194 | |
195 @Specialization | |
196 public Object instanceEval(VirtualFrame frame, RubyObject self, RubyProc block) { | |
197 return block.callWithModifiedSelf(frame.pack(), self); | |
198 } | |
199 | |
200 } | |
201 | |
202 @CoreMethod(names = "instance_variable_defined?", minArgs = 1, maxArgs = 1) | |
203 public abstract static class InstanceVariableDefinedNode extends CoreMethodNode { | |
204 | |
205 public InstanceVariableDefinedNode(RubyContext context, SourceSection sourceSection) { | |
206 super(context, sourceSection); | |
207 } | |
208 | |
209 public InstanceVariableDefinedNode(InstanceVariableDefinedNode prev) { | |
210 super(prev); | |
211 } | |
212 | |
213 @Specialization | |
214 public boolean isInstanceVariableDefined(RubyBasicObject object, RubyString name) { | |
215 return object.isInstanceVariableDefined(RubyObject.checkInstanceVariableName(getContext(), name.toString())); | |
216 } | |
217 | |
218 @Specialization | |
219 public boolean isInstanceVariableDefined(RubyBasicObject object, RubySymbol name) { | |
220 return object.isInstanceVariableDefined(RubyObject.checkInstanceVariableName(getContext(), name.toString())); | |
221 } | |
222 | |
223 } | |
224 | |
225 @CoreMethod(names = "instance_variable_get", minArgs = 1, maxArgs = 1) | |
226 public abstract static class InstanceVariableGetNode extends CoreMethodNode { | |
227 | |
228 public InstanceVariableGetNode(RubyContext context, SourceSection sourceSection) { | |
229 super(context, sourceSection); | |
230 } | |
231 | |
232 public InstanceVariableGetNode(InstanceVariableGetNode prev) { | |
233 super(prev); | |
234 } | |
235 | |
236 @Specialization | |
237 public Object isInstanceVariableGet(RubyBasicObject object, RubyString name) { | |
238 return object.getInstanceVariable(RubyObject.checkInstanceVariableName(getContext(), name.toString())); | |
239 } | |
240 | |
241 @Specialization | |
242 public Object isInstanceVariableGet(RubyBasicObject object, RubySymbol name) { | |
243 return object.getInstanceVariable(RubyObject.checkInstanceVariableName(getContext(), name.toString())); | |
244 } | |
245 | |
246 } | |
247 | |
248 @CoreMethod(names = "instance_variable_set", minArgs = 2, maxArgs = 2) | |
249 public abstract static class InstanceVariableSetNode extends CoreMethodNode { | |
250 | |
251 public InstanceVariableSetNode(RubyContext context, SourceSection sourceSection) { | |
252 super(context, sourceSection); | |
253 } | |
254 | |
255 public InstanceVariableSetNode(InstanceVariableSetNode prev) { | |
256 super(prev); | |
257 } | |
258 | |
259 @Specialization | |
260 public Object isInstanceVariableSet(RubyBasicObject object, RubyString name, Object value) { | |
261 object.setInstanceVariable(RubyObject.checkInstanceVariableName(getContext(), name.toString()), value); | |
262 return value; | |
263 } | |
264 | |
265 @Specialization | |
266 public Object isInstanceVariableSet(RubyBasicObject object, RubySymbol name, Object value) { | |
267 object.setInstanceVariable(RubyObject.checkInstanceVariableName(getContext(), name.toString()), value); | |
268 return value; | |
269 } | |
270 | |
271 } | |
272 | |
273 @CoreMethod(names = "instance_variables", maxArgs = 0) | |
274 public abstract static class InstanceVariablesNode extends CoreMethodNode { | |
275 | |
276 public InstanceVariablesNode(RubyContext context, SourceSection sourceSection) { | |
277 super(context, sourceSection); | |
278 } | |
279 | |
280 public InstanceVariablesNode(InstanceVariablesNode prev) { | |
281 super(prev); | |
282 } | |
283 | |
284 @Specialization | |
285 public RubyArray instanceVariables(RubyObject self) { | |
286 final String[] instanceVariableNames = self.getInstanceVariableNames(); | |
287 | |
288 Arrays.sort(instanceVariableNames); | |
289 | |
290 final RubyArray array = new RubyArray(getContext().getCoreLibrary().getArrayClass()); | |
291 | |
292 for (String name : instanceVariableNames) { | |
293 array.push(new RubyString(getContext().getCoreLibrary().getStringClass(), name)); | |
294 } | |
295 | |
296 return array; | |
297 } | |
298 | |
299 } | |
300 | |
301 @CoreMethod(names = {"is_a?", "instance_of?", "kind_of?"}, minArgs = 1, maxArgs = 1) | |
302 public abstract static class IsANode extends CoreMethodNode { | |
303 | |
304 public IsANode(RubyContext context, SourceSection sourceSection) { | |
305 super(context, sourceSection); | |
306 } | |
307 | |
308 public IsANode(IsANode prev) { | |
309 super(prev); | |
310 } | |
311 | |
312 @Specialization | |
313 public boolean isA(@SuppressWarnings("unused") RubyObject self, @SuppressWarnings("unused") NilPlaceholder nil) { | |
314 return false; | |
315 } | |
316 | |
317 @Specialization | |
318 public boolean isA(RubyObject self, RubyClass rubyClass) { | |
319 return self.getRubyClass().assignableTo(rubyClass); | |
320 } | |
321 | |
322 } | |
323 | |
324 @CoreMethod(names = "methods", minArgs = 0, maxArgs = 1) | |
325 public abstract static class MethodsNode extends CoreMethodNode { | |
326 | |
327 public MethodsNode(RubyContext context, SourceSection sourceSection) { | |
328 super(context, sourceSection); | |
329 } | |
330 | |
331 public MethodsNode(MethodsNode prev) { | |
332 super(prev); | |
333 } | |
334 | |
335 @Specialization | |
336 public RubyArray methods(RubyObject self, boolean includeInherited) { | |
337 if (!includeInherited) { | |
338 self.getRubyClass().getContext().implementationMessage("Object#methods always returns inherited methods at the moment"); | |
339 } | |
340 | |
341 return methods(self, UndefinedPlaceholder.INSTANCE); | |
342 } | |
343 | |
344 @Specialization | |
345 public RubyArray methods(RubyObject self, @SuppressWarnings("unused") UndefinedPlaceholder includeInherited) { | |
346 final RubyArray array = new RubyArray(self.getRubyClass().getContext().getCoreLibrary().getArrayClass()); | |
347 | |
348 final Map<String, RubyMethod> methods = new HashMap<>(); | |
349 | |
350 self.getLookupNode().getMethods(methods); | |
351 | |
352 for (RubyMethod method : methods.values()) { | |
353 if (method.getVisibility() == Visibility.PUBLIC || method.getVisibility() == Visibility.PROTECTED) { | |
354 array.push(new RubySymbol(self.getRubyClass().getContext().getCoreLibrary().getSymbolClass(), method.getName())); | |
355 } | |
356 } | |
357 | |
358 return array; | |
359 } | |
360 | |
361 } | |
362 | |
363 @CoreMethod(names = "nil?", needsSelf = false, maxArgs = 0) | |
364 public abstract static class NilNode extends CoreMethodNode { | |
365 | |
366 public NilNode(RubyContext context, SourceSection sourceSection) { | |
367 super(context, sourceSection); | |
368 } | |
369 | |
370 public NilNode(NilNode prev) { | |
371 super(prev); | |
372 } | |
373 | |
374 @Specialization | |
375 public boolean nil() { | |
376 return false; | |
377 } | |
378 } | |
379 | |
380 @CoreMethod(names = "object_id", needsSelf = true, maxArgs = 0) | |
381 public abstract static class ObjectIDNode extends CoreMethodNode { | |
382 | |
383 public ObjectIDNode(RubyContext context, SourceSection sourceSection) { | |
384 super(context, sourceSection); | |
385 } | |
386 | |
387 public ObjectIDNode(ObjectIDNode prev) { | |
388 super(prev); | |
389 } | |
390 | |
391 @Specialization | |
392 public Object objectID(RubyBasicObject object) { | |
393 return GeneralConversions.fixnumOrBignum(object.getObjectID()); | |
394 } | |
395 | |
396 } | |
397 | |
398 @CoreMethod(names = "respond_to?", minArgs = 1, maxArgs = 2) | |
399 public abstract static class RespondToNode extends CoreMethodNode { | |
400 | |
401 public RespondToNode(RubyContext context, SourceSection sourceSection) { | |
402 super(context, sourceSection); | |
403 } | |
404 | |
405 public RespondToNode(RespondToNode prev) { | |
406 super(prev); | |
407 } | |
408 | |
409 @Specialization(order = 1) | |
410 public boolean doesRespondTo(Object object, RubyString name, @SuppressWarnings("unused") UndefinedPlaceholder checkVisibility) { | |
411 return doesRespondTo(getContext().getCoreLibrary().box(object), name.toString(), false); | |
412 } | |
413 | |
414 @Specialization(order = 2) | |
415 public boolean doesRespondTo(Object object, RubyString name, boolean dontCheckVisibility) { | |
416 return doesRespondTo(getContext().getCoreLibrary().box(object), name.toString(), dontCheckVisibility); | |
417 } | |
418 | |
419 @Specialization(order = 3) | |
420 public boolean doesRespondTo(Object object, RubySymbol name, @SuppressWarnings("unused") UndefinedPlaceholder checkVisibility) { | |
421 return doesRespondTo(getContext().getCoreLibrary().box(object), name.toString(), false); | |
422 } | |
423 | |
424 @Specialization(order = 4) | |
425 public boolean doesRespondTo(Object object, RubySymbol name, boolean dontCheckVisibility) { | |
426 return doesRespondTo(getContext().getCoreLibrary().box(object), name.toString(), dontCheckVisibility); | |
427 } | |
428 | |
429 private static boolean doesRespondTo(RubyBasicObject object, String name, boolean dontCheckVisibility) { | |
430 final RubyMethod method = object.getLookupNode().lookupMethod(name); | |
431 | |
432 if (method == null || method.isUndefined()) { | |
433 return false; | |
434 } | |
435 | |
436 if (dontCheckVisibility) { | |
437 return true; | |
438 } else { | |
439 return method.getVisibility() == Visibility.PUBLIC; | |
440 } | |
441 } | |
442 | |
443 } | |
444 | |
445 @CoreMethod(names = "singleton_class", maxArgs = 0) | |
446 public abstract static class SingletonClassNode extends CoreMethodNode { | |
447 | |
448 public SingletonClassNode(RubyContext context, SourceSection sourceSection) { | |
449 super(context, sourceSection); | |
450 } | |
451 | |
452 public SingletonClassNode(SingletonClassNode prev) { | |
453 super(prev); | |
454 } | |
455 | |
456 @Specialization | |
457 public RubyClass singletonClass(RubyBasicObject self) { | |
458 return self.getSingletonClass(); | |
459 } | |
460 | |
461 } | |
462 | |
463 @CoreMethod(names = "singleton_methods", minArgs = 0, maxArgs = 1) | |
464 public abstract static class SingletonMethodsNode extends CoreMethodNode { | |
465 | |
466 public SingletonMethodsNode(RubyContext context, SourceSection sourceSection) { | |
467 super(context, sourceSection); | |
468 } | |
469 | |
470 public SingletonMethodsNode(SingletonMethodsNode prev) { | |
471 super(prev); | |
472 } | |
473 | |
474 @Specialization | |
475 public RubyArray singletonMethods(RubyObject self, boolean includeInherited) { | |
476 if (!includeInherited) { | |
477 self.getRubyClass().getContext().implementationMessage("Object#singleton_methods always returns inherited methods at the moment"); | |
478 } | |
479 | |
480 return singletonMethods(self, UndefinedPlaceholder.INSTANCE); | |
481 } | |
482 | |
483 @Specialization | |
484 public RubyArray singletonMethods(RubyObject self, @SuppressWarnings("unused") UndefinedPlaceholder includeInherited) { | |
485 final RubyArray array = new RubyArray(self.getRubyClass().getContext().getCoreLibrary().getArrayClass()); | |
486 | |
487 for (RubyMethod method : self.getSingletonClass().getDeclaredMethods()) { | |
488 array.push(new RubySymbol(self.getRubyClass().getContext().getCoreLibrary().getSymbolClass(), method.getName())); | |
489 } | |
490 | |
491 return array; | |
492 } | |
493 | |
494 } | |
495 | |
496 @CoreMethod(names = "to_s", maxArgs = 0) | |
497 public abstract static class ToSNode extends CoreMethodNode { | |
498 | |
499 public ToSNode(RubyContext context, SourceSection sourceSection) { | |
500 super(context, sourceSection); | |
501 } | |
502 | |
503 public ToSNode(ToSNode prev) { | |
504 super(prev); | |
505 } | |
506 | |
507 @Specialization | |
508 public RubyString toS(RubyObject self) { | |
509 return getContext().makeString(self.toString()); | |
510 } | |
511 | |
512 } | |
513 | |
514 } |