diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ObjectNodes.java	Tue Jan 07 18:53:04 2014 +0100
@@ -0,0 +1,514 @@
+/*
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
+ * code is released under a tri EPL/GPL/LGPL license. You can use it,
+ * redistribute it and/or modify it under the terms of the:
+ *
+ * Eclipse Public License version 1.0
+ * GNU General Public License version 2
+ * GNU Lesser General Public License version 2.1
+ */
+package com.oracle.truffle.ruby.nodes.core;
+
+import java.math.*;
+import java.util.*;
+
+import com.oracle.truffle.api.*;
+import com.oracle.truffle.api.dsl.*;
+import com.oracle.truffle.api.frame.*;
+import com.oracle.truffle.ruby.runtime.*;
+import com.oracle.truffle.ruby.runtime.core.*;
+import com.oracle.truffle.ruby.runtime.core.array.*;
+import com.oracle.truffle.ruby.runtime.methods.*;
+import com.oracle.truffle.ruby.runtime.objects.*;
+
+@CoreClass(name = "Object")
+public abstract class ObjectNodes {
+
+    @CoreMethod(names = "class", maxArgs = 0)
+    public abstract static class ClassNode extends CoreMethodNode {
+
+        public ClassNode(RubyContext context, SourceSection sourceSection) {
+            super(context, sourceSection);
+        }
+
+        public ClassNode(ClassNode prev) {
+            super(prev);
+        }
+
+        @Specialization
+        public RubyClass getClass(boolean value) {
+            if (value) {
+                return getContext().getCoreLibrary().getTrueClass();
+            } else {
+                return getContext().getCoreLibrary().getFalseClass();
+            }
+        }
+
+        @Specialization
+        public RubyClass getClass(@SuppressWarnings("unused") int value) {
+            return getContext().getCoreLibrary().getFixnumClass();
+        }
+
+        @Specialization
+        public RubyClass getClass(@SuppressWarnings("unused") BigInteger value) {
+            return getContext().getCoreLibrary().getBignumClass();
+        }
+
+        @Specialization
+        public RubyClass getClass(@SuppressWarnings("unused") double value) {
+            return getContext().getCoreLibrary().getFloatClass();
+        }
+
+        @Specialization
+        public RubyClass getClass(RubyBasicObject self) {
+            return self.getRubyClass();
+        }
+
+    }
+
+    @CoreMethod(names = "dup", maxArgs = 0)
+    public abstract static class DupNode extends CoreMethodNode {
+
+        public DupNode(RubyContext context, SourceSection sourceSection) {
+            super(context, sourceSection);
+        }
+
+        public DupNode(DupNode prev) {
+            super(prev);
+        }
+
+        @Specialization
+        public Object dup(RubyObject self) {
+            return self.dup();
+        }
+
+    }
+
+    @CoreMethod(names = "extend", isSplatted = true, minArgs = 1)
+    public abstract static class ExtendNode extends CoreMethodNode {
+
+        public ExtendNode(RubyContext context, SourceSection sourceSection) {
+            super(context, sourceSection);
+        }
+
+        public ExtendNode(ExtendNode prev) {
+            super(prev);
+        }
+
+        @Specialization
+        public RubyBasicObject extend(RubyBasicObject self, Object[] args) {
+            for (int n = 0; n < args.length; n++) {
+                self.extend((RubyModule) args[n]);
+            }
+
+            return self;
+        }
+
+    }
+
+    @CoreMethod(names = "freeze", maxArgs = 0)
+    public abstract static class FreezeNode extends CoreMethodNode {
+
+        public FreezeNode(RubyContext context, SourceSection sourceSection) {
+            super(context, sourceSection);
+        }
+
+        public FreezeNode(FreezeNode prev) {
+            super(prev);
+        }
+
+        @Specialization
+        public RubyObject freeze(RubyObject self) {
+            self.frozen = true;
+            return self;
+        }
+
+    }
+
+    @CoreMethod(names = "frozen?", maxArgs = 0)
+    public abstract static class FrozenNode extends CoreMethodNode {
+
+        public FrozenNode(RubyContext context, SourceSection sourceSection) {
+            super(context, sourceSection);
+        }
+
+        public FrozenNode(FrozenNode prev) {
+            super(prev);
+        }
+
+        @Specialization
+        public boolean isFrozen(RubyObject self) {
+            return self.frozen;
+        }
+
+    }
+
+    @CoreMethod(names = "inspect", maxArgs = 0)
+    public abstract static class InspectNode extends CoreMethodNode {
+
+        public InspectNode(RubyContext context, SourceSection sourceSection) {
+            super(context, sourceSection);
+        }
+
+        public InspectNode(InspectNode prev) {
+            super(prev);
+        }
+
+        @Specialization
+        public RubyString inspect(boolean value) {
+            return getContext().makeString(Boolean.toString(value));
+        }
+
+        @Specialization
+        public RubyString inspect(int value) {
+            return getContext().makeString(Integer.toString(value));
+        }
+
+        @Specialization
+        public RubyString inspect(BigInteger value) {
+            return getContext().makeString(value.toString());
+        }
+
+        @Specialization
+        public RubyString inspect(double value) {
+            return getContext().makeString(Double.toString(value));
+        }
+
+        @Specialization
+        public RubyString inspect(RubyObject self) {
+            return getContext().makeString(self.inspect());
+        }
+
+    }
+
+    @CoreMethod(names = "instance_eval", needsBlock = true, maxArgs = 0)
+    public abstract static class InstanceEvalNode extends CoreMethodNode {
+
+        public InstanceEvalNode(RubyContext context, SourceSection sourceSection) {
+            super(context, sourceSection);
+        }
+
+        public InstanceEvalNode(InstanceEvalNode prev) {
+            super(prev);
+        }
+
+        @Specialization
+        public Object instanceEval(VirtualFrame frame, RubyObject self, RubyProc block) {
+            return block.callWithModifiedSelf(frame.pack(), self);
+        }
+
+    }
+
+    @CoreMethod(names = "instance_variable_defined?", minArgs = 1, maxArgs = 1)
+    public abstract static class InstanceVariableDefinedNode extends CoreMethodNode {
+
+        public InstanceVariableDefinedNode(RubyContext context, SourceSection sourceSection) {
+            super(context, sourceSection);
+        }
+
+        public InstanceVariableDefinedNode(InstanceVariableDefinedNode prev) {
+            super(prev);
+        }
+
+        @Specialization
+        public boolean isInstanceVariableDefined(RubyBasicObject object, RubyString name) {
+            return object.isInstanceVariableDefined(RubyObject.checkInstanceVariableName(getContext(), name.toString()));
+        }
+
+        @Specialization
+        public boolean isInstanceVariableDefined(RubyBasicObject object, RubySymbol name) {
+            return object.isInstanceVariableDefined(RubyObject.checkInstanceVariableName(getContext(), name.toString()));
+        }
+
+    }
+
+    @CoreMethod(names = "instance_variable_get", minArgs = 1, maxArgs = 1)
+    public abstract static class InstanceVariableGetNode extends CoreMethodNode {
+
+        public InstanceVariableGetNode(RubyContext context, SourceSection sourceSection) {
+            super(context, sourceSection);
+        }
+
+        public InstanceVariableGetNode(InstanceVariableGetNode prev) {
+            super(prev);
+        }
+
+        @Specialization
+        public Object isInstanceVariableGet(RubyBasicObject object, RubyString name) {
+            return object.getInstanceVariable(RubyObject.checkInstanceVariableName(getContext(), name.toString()));
+        }
+
+        @Specialization
+        public Object isInstanceVariableGet(RubyBasicObject object, RubySymbol name) {
+            return object.getInstanceVariable(RubyObject.checkInstanceVariableName(getContext(), name.toString()));
+        }
+
+    }
+
+    @CoreMethod(names = "instance_variable_set", minArgs = 2, maxArgs = 2)
+    public abstract static class InstanceVariableSetNode extends CoreMethodNode {
+
+        public InstanceVariableSetNode(RubyContext context, SourceSection sourceSection) {
+            super(context, sourceSection);
+        }
+
+        public InstanceVariableSetNode(InstanceVariableSetNode prev) {
+            super(prev);
+        }
+
+        @Specialization
+        public Object isInstanceVariableSet(RubyBasicObject object, RubyString name, Object value) {
+            object.setInstanceVariable(RubyObject.checkInstanceVariableName(getContext(), name.toString()), value);
+            return value;
+        }
+
+        @Specialization
+        public Object isInstanceVariableSet(RubyBasicObject object, RubySymbol name, Object value) {
+            object.setInstanceVariable(RubyObject.checkInstanceVariableName(getContext(), name.toString()), value);
+            return value;
+        }
+
+    }
+
+    @CoreMethod(names = "instance_variables", maxArgs = 0)
+    public abstract static class InstanceVariablesNode extends CoreMethodNode {
+
+        public InstanceVariablesNode(RubyContext context, SourceSection sourceSection) {
+            super(context, sourceSection);
+        }
+
+        public InstanceVariablesNode(InstanceVariablesNode prev) {
+            super(prev);
+        }
+
+        @Specialization
+        public RubyArray instanceVariables(RubyObject self) {
+            final String[] instanceVariableNames = self.getInstanceVariableNames();
+
+            Arrays.sort(instanceVariableNames);
+
+            final RubyArray array = new RubyArray(getContext().getCoreLibrary().getArrayClass());
+
+            for (String name : instanceVariableNames) {
+                array.push(new RubyString(getContext().getCoreLibrary().getStringClass(), name));
+            }
+
+            return array;
+        }
+
+    }
+
+    @CoreMethod(names = {"is_a?", "instance_of?", "kind_of?"}, minArgs = 1, maxArgs = 1)
+    public abstract static class IsANode extends CoreMethodNode {
+
+        public IsANode(RubyContext context, SourceSection sourceSection) {
+            super(context, sourceSection);
+        }
+
+        public IsANode(IsANode prev) {
+            super(prev);
+        }
+
+        @Specialization
+        public boolean isA(@SuppressWarnings("unused") RubyObject self, @SuppressWarnings("unused") NilPlaceholder nil) {
+            return false;
+        }
+
+        @Specialization
+        public boolean isA(RubyObject self, RubyClass rubyClass) {
+            return self.getRubyClass().assignableTo(rubyClass);
+        }
+
+    }
+
+    @CoreMethod(names = "methods", minArgs = 0, maxArgs = 1)
+    public abstract static class MethodsNode extends CoreMethodNode {
+
+        public MethodsNode(RubyContext context, SourceSection sourceSection) {
+            super(context, sourceSection);
+        }
+
+        public MethodsNode(MethodsNode prev) {
+            super(prev);
+        }
+
+        @Specialization
+        public RubyArray methods(RubyObject self, boolean includeInherited) {
+            if (!includeInherited) {
+                self.getRubyClass().getContext().implementationMessage("Object#methods always returns inherited methods at the moment");
+            }
+
+            return methods(self, UndefinedPlaceholder.INSTANCE);
+        }
+
+        @Specialization
+        public RubyArray methods(RubyObject self, @SuppressWarnings("unused") UndefinedPlaceholder includeInherited) {
+            final RubyArray array = new RubyArray(self.getRubyClass().getContext().getCoreLibrary().getArrayClass());
+
+            final Map<String, RubyMethod> methods = new HashMap<>();
+
+            self.getLookupNode().getMethods(methods);
+
+            for (RubyMethod method : methods.values()) {
+                if (method.getVisibility() == Visibility.PUBLIC || method.getVisibility() == Visibility.PROTECTED) {
+                    array.push(new RubySymbol(self.getRubyClass().getContext().getCoreLibrary().getSymbolClass(), method.getName()));
+                }
+            }
+
+            return array;
+        }
+
+    }
+
+    @CoreMethod(names = "nil?", needsSelf = false, maxArgs = 0)
+    public abstract static class NilNode extends CoreMethodNode {
+
+        public NilNode(RubyContext context, SourceSection sourceSection) {
+            super(context, sourceSection);
+        }
+
+        public NilNode(NilNode prev) {
+            super(prev);
+        }
+
+        @Specialization
+        public boolean nil() {
+            return false;
+        }
+    }
+
+    @CoreMethod(names = "object_id", needsSelf = true, maxArgs = 0)
+    public abstract static class ObjectIDNode extends CoreMethodNode {
+
+        public ObjectIDNode(RubyContext context, SourceSection sourceSection) {
+            super(context, sourceSection);
+        }
+
+        public ObjectIDNode(ObjectIDNode prev) {
+            super(prev);
+        }
+
+        @Specialization
+        public Object objectID(RubyBasicObject object) {
+            return GeneralConversions.fixnumOrBignum(object.getObjectID());
+        }
+
+    }
+
+    @CoreMethod(names = "respond_to?", minArgs = 1, maxArgs = 2)
+    public abstract static class RespondToNode extends CoreMethodNode {
+
+        public RespondToNode(RubyContext context, SourceSection sourceSection) {
+            super(context, sourceSection);
+        }
+
+        public RespondToNode(RespondToNode prev) {
+            super(prev);
+        }
+
+        @Specialization(order = 1)
+        public boolean doesRespondTo(Object object, RubyString name, @SuppressWarnings("unused") UndefinedPlaceholder checkVisibility) {
+            return doesRespondTo(getContext().getCoreLibrary().box(object), name.toString(), false);
+        }
+
+        @Specialization(order = 2)
+        public boolean doesRespondTo(Object object, RubyString name, boolean dontCheckVisibility) {
+            return doesRespondTo(getContext().getCoreLibrary().box(object), name.toString(), dontCheckVisibility);
+        }
+
+        @Specialization(order = 3)
+        public boolean doesRespondTo(Object object, RubySymbol name, @SuppressWarnings("unused") UndefinedPlaceholder checkVisibility) {
+            return doesRespondTo(getContext().getCoreLibrary().box(object), name.toString(), false);
+        }
+
+        @Specialization(order = 4)
+        public boolean doesRespondTo(Object object, RubySymbol name, boolean dontCheckVisibility) {
+            return doesRespondTo(getContext().getCoreLibrary().box(object), name.toString(), dontCheckVisibility);
+        }
+
+        private static boolean doesRespondTo(RubyBasicObject object, String name, boolean dontCheckVisibility) {
+            final RubyMethod method = object.getLookupNode().lookupMethod(name);
+
+            if (method == null || method.isUndefined()) {
+                return false;
+            }
+
+            if (dontCheckVisibility) {
+                return true;
+            } else {
+                return method.getVisibility() == Visibility.PUBLIC;
+            }
+        }
+
+    }
+
+    @CoreMethod(names = "singleton_class", maxArgs = 0)
+    public abstract static class SingletonClassNode extends CoreMethodNode {
+
+        public SingletonClassNode(RubyContext context, SourceSection sourceSection) {
+            super(context, sourceSection);
+        }
+
+        public SingletonClassNode(SingletonClassNode prev) {
+            super(prev);
+        }
+
+        @Specialization
+        public RubyClass singletonClass(RubyBasicObject self) {
+            return self.getSingletonClass();
+        }
+
+    }
+
+    @CoreMethod(names = "singleton_methods", minArgs = 0, maxArgs = 1)
+    public abstract static class SingletonMethodsNode extends CoreMethodNode {
+
+        public SingletonMethodsNode(RubyContext context, SourceSection sourceSection) {
+            super(context, sourceSection);
+        }
+
+        public SingletonMethodsNode(SingletonMethodsNode prev) {
+            super(prev);
+        }
+
+        @Specialization
+        public RubyArray singletonMethods(RubyObject self, boolean includeInherited) {
+            if (!includeInherited) {
+                self.getRubyClass().getContext().implementationMessage("Object#singleton_methods always returns inherited methods at the moment");
+            }
+
+            return singletonMethods(self, UndefinedPlaceholder.INSTANCE);
+        }
+
+        @Specialization
+        public RubyArray singletonMethods(RubyObject self, @SuppressWarnings("unused") UndefinedPlaceholder includeInherited) {
+            final RubyArray array = new RubyArray(self.getRubyClass().getContext().getCoreLibrary().getArrayClass());
+
+            for (RubyMethod method : self.getSingletonClass().getDeclaredMethods()) {
+                array.push(new RubySymbol(self.getRubyClass().getContext().getCoreLibrary().getSymbolClass(), method.getName()));
+            }
+
+            return array;
+        }
+
+    }
+
+    @CoreMethod(names = "to_s", maxArgs = 0)
+    public abstract static class ToSNode extends CoreMethodNode {
+
+        public ToSNode(RubyContext context, SourceSection sourceSection) {
+            super(context, sourceSection);
+        }
+
+        public ToSNode(ToSNode prev) {
+            super(prev);
+        }
+
+        @Specialization
+        public RubyString toS(RubyObject self) {
+            return getContext().makeString(self.toString());
+        }
+
+    }
+
+}