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 }