Mercurial > hg > graal-compiler
view graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/ObjectNodes.java @ 13556:44288fe54352
Ruby: fix some ?break? semantics.
author | Chris Seaton <chris.seaton@oracle.com> |
---|---|
date | Wed, 08 Jan 2014 17:42:10 +0000 |
parents | 0fbee3eb71f0 |
children |
line wrap: on
line source
/* * 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()); } } }