Skip to content

Commit

Permalink
[Truffle] Work on Struct.
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisseaton committed Dec 16, 2014
1 parent ae8e0aa commit 8d38b3e
Show file tree
Hide file tree
Showing 36 changed files with 119 additions and 106 deletions.
67 changes: 23 additions & 44 deletions core/src/main/java/org/jruby/truffle/nodes/core/KernelNodes.java
Original file line number Diff line number Diff line change
Expand Up @@ -374,22 +374,22 @@ public RubyClass getClass(boolean value) {
}

@Specialization
public RubyClass getClass(@SuppressWarnings("unused") int value) {
public RubyClass getClass(int value) {
return getContext().getCoreLibrary().getFixnumClass();
}

@Specialization
public RubyClass getClass(@SuppressWarnings("unused") long value) {
public RubyClass getClass(long value) {
return getContext().getCoreLibrary().getFixnumClass();
}

@Specialization
public RubyClass getClass(@SuppressWarnings("unused") RubyBignum value) {
public RubyClass getClass(RubyBignum value) {
return getContext().getCoreLibrary().getBignumClass();
}

@Specialization
public RubyClass getClass(@SuppressWarnings("unused") double value) {
public RubyClass getClass(double value) {
return getContext().getCoreLibrary().getFloatClass();
}

Expand Down Expand Up @@ -501,7 +501,7 @@ protected RubyBinding getCallerBinding(VirtualFrame frame) {
}

@Specialization
public Object eval(VirtualFrame frame, RubyString source, @SuppressWarnings("unused") UndefinedPlaceholder binding) {
public Object eval(VirtualFrame frame, RubyString source, UndefinedPlaceholder binding) {
notDesignedForCompilation();

return eval(source, getCallerBinding(frame));
Expand All @@ -515,7 +515,7 @@ public Object eval(RubyString source, RubyBinding binding) {
}

@Specialization(guards = "!isRubyString(arguments[0])")
public Object eval(VirtualFrame frame, RubyBasicObject object, @SuppressWarnings("unused") UndefinedPlaceholder binding) {
public Object eval(VirtualFrame frame, RubyBasicObject object, UndefinedPlaceholder binding) {
notDesignedForCompilation();

return eval(frame, object, getCallerBinding(frame));
Expand Down Expand Up @@ -554,7 +554,7 @@ public Object eval(VirtualFrame frame, RubyBasicObject object, RubyBinding bindi
}

@Specialization(guards = "!isRubyBinding(arguments[1])")
public Object eval(@SuppressWarnings("unused") RubyBasicObject source, RubyBasicObject badBinding) {
public Object eval(RubyBasicObject source, RubyBasicObject badBinding) {
throw new RaiseException(
getContext().getCoreLibrary().typeError(
String.format("wrong argument type %s (expected binding)",
Expand Down Expand Up @@ -638,7 +638,7 @@ public ExitNode(ExitNode prev) {
}

@Specialization
public Object exit(@SuppressWarnings("unused") UndefinedPlaceholder exitCode) {
public Object exit(UndefinedPlaceholder exitCode) {
notDesignedForCompilation();

getContext().shutdown();
Expand Down Expand Up @@ -1113,7 +1113,7 @@ public IsANode(IsANode prev) {
public abstract boolean executeBoolean(Object self, RubyClass rubyClass);

@Specialization
public boolean isA(@SuppressWarnings("unused") RubyBasicObject self, @SuppressWarnings("unused") RubyNilClass nil) {
public boolean isA(RubyBasicObject self, RubyNilClass nil) {
return false;
}

Expand Down Expand Up @@ -1232,7 +1232,7 @@ public MethodsNode(MethodsNode prev) {
}

@Specialization
public RubyArray methods(RubyBasicObject self, @SuppressWarnings("unused") UndefinedPlaceholder unused) {
public RubyArray methods(RubyBasicObject self, UndefinedPlaceholder unused) {
return methods(self, true);
}

Expand Down Expand Up @@ -1403,7 +1403,7 @@ public PrivateMethodsNode(PrivateMethodsNode prev) {
}

@Specialization
public RubyArray private_methods(RubyBasicObject self, @SuppressWarnings("unused") UndefinedPlaceholder unused) {
public RubyArray private_methods(RubyBasicObject self, UndefinedPlaceholder unused) {
return private_methods(self, true);
}

Expand Down Expand Up @@ -1476,7 +1476,7 @@ public RubyArray methods(RubyBasicObject self, boolean includeInherited) {
}

@Specialization
public RubyArray methods(RubyBasicObject self, @SuppressWarnings("unused") UndefinedPlaceholder includeInherited) {
public RubyArray methods(RubyBasicObject self, UndefinedPlaceholder includeInherited) {
notDesignedForCompilation();

final RubyArray array = new RubyArray(self.getContext().getCoreLibrary().getArrayClass());
Expand All @@ -1494,7 +1494,7 @@ public RubyArray methods(RubyBasicObject self, @SuppressWarnings("unused") Undef

}

@CoreMethod(names = "raise", isModuleFunction = true, optional = 2)
@CoreMethod(names = "raise", isModuleFunction = true, optional = 3)
public abstract static class RaiseNode extends CoreMethodNode {

@Child protected DispatchHeadNode initialize;
Expand All @@ -1510,28 +1510,28 @@ public RaiseNode(RaiseNode prev) {
}

@Specialization
public Object raise(VirtualFrame frame, UndefinedPlaceholder undefined1, @SuppressWarnings("unused") UndefinedPlaceholder undefined2) {
public Object raise(VirtualFrame frame, UndefinedPlaceholder undefined1, UndefinedPlaceholder undefined2, Object undefined3) {
notDesignedForCompilation();

return raise(frame, getContext().getCoreLibrary().getRuntimeErrorClass(), getContext().makeString("re-raised - don't have the current exception yet!"));
return raise(frame, getContext().getCoreLibrary().getRuntimeErrorClass(), getContext().makeString("re-raised - don't have the current exception yet!"), undefined1);
}

@Specialization
public Object raise(VirtualFrame frame, RubyString message, @SuppressWarnings("unused") UndefinedPlaceholder undefined) {
public Object raise(VirtualFrame frame, RubyString message, UndefinedPlaceholder undefined1, Object undefined2) {
notDesignedForCompilation();

return raise(frame, getContext().getCoreLibrary().getRuntimeErrorClass(), message);
return raise(frame, getContext().getCoreLibrary().getRuntimeErrorClass(), message, undefined1);
}

@Specialization
public Object raise(VirtualFrame frame, RubyClass exceptionClass, @SuppressWarnings("unused") UndefinedPlaceholder undefined) {
public Object raise(VirtualFrame frame, RubyClass exceptionClass, UndefinedPlaceholder undefined1, Object undefined2) {
notDesignedForCompilation();

return raise(frame, exceptionClass, getContext().makeString(""));
return raise(frame, exceptionClass, getContext().makeString(""), undefined1);
}

@Specialization
public Object raise(VirtualFrame frame, RubyClass exceptionClass, RubyString message) {
public Object raise(VirtualFrame frame, RubyClass exceptionClass, RubyString message, Object undefined1) {
notDesignedForCompilation();

if (!(exceptionClass instanceof RubyException.RubyExceptionClass)) {
Expand Down Expand Up @@ -1660,7 +1660,7 @@ public RespondToNode(RespondToNode prev) {
}

@Specialization
public boolean doesRespondTo(VirtualFrame frame, Object object, RubyString name, @SuppressWarnings("unused") UndefinedPlaceholder checkVisibility) {
public boolean doesRespondTo(VirtualFrame frame, Object object, RubyString name, UndefinedPlaceholder checkVisibility) {
return dispatch.doesRespondTo(frame, name, object);
}

Expand All @@ -1674,7 +1674,7 @@ public boolean doesRespondTo(VirtualFrame frame, Object object, RubyString name,
}

@Specialization
public boolean doesRespondTo(VirtualFrame frame, Object object, RubySymbol name, @SuppressWarnings("unused") UndefinedPlaceholder checkVisibility) {
public boolean doesRespondTo(VirtualFrame frame, Object object, RubySymbol name, UndefinedPlaceholder checkVisibility) {
return dispatch.doesRespondTo(frame, name, object);
}

Expand Down Expand Up @@ -1850,7 +1850,7 @@ public RubyArray singletonMethods(RubyBasicObject self, boolean includeInherited
}

@Specialization
public RubyArray singletonMethods(RubyBasicObject self, @SuppressWarnings("unused") UndefinedPlaceholder includeInherited) {
public RubyArray singletonMethods(RubyBasicObject self, UndefinedPlaceholder includeInherited) {
return singletonMethods(self, false);
}

Expand Down Expand Up @@ -2085,25 +2085,4 @@ public UndefinedPlaceholder undefined() {

}

// Rubinius API
@CoreMethod(names = "StringValue", isModuleFunction = true, required = 1)
public abstract static class StringValueNode extends CoreMethodNode {
@Child
protected DispatchHeadNode argToStringNode;

public StringValueNode(RubyContext context, SourceSection sourceSection) {
super(context, sourceSection);
argToStringNode = new DispatchHeadNode(context);
}

public StringValueNode(StringValueNode prev) {
super(prev);
argToStringNode = prev.argToStringNode;
}

@Specialization
public RubyString StringValue(VirtualFrame frame, Object arg) {
return (RubyString) argToStringNode.call(frame, arg, "to_s", null);
}
}
}
16 changes: 10 additions & 6 deletions core/src/main/ruby/jruby/truffle/core.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,16 @@
require_relative 'core/float'
require_relative 'core/math'

require_relative 'core/rubinius/api/bootstrap/channel'
require_relative 'core/rubinius/api/common/bytearray'
require_relative 'core/rubinius/api/common/channel'
require_relative 'core/rubinius/api/common/thread'
require_relative 'core/rubinius/api/common/tuple'
require_relative 'core/rubinius/api/common/type'
require_relative 'core/rubinius/api/compat/type'

require_relative 'core/rubinius/api/kernel/bootstrap/channel'
require_relative 'core/rubinius/api/kernel/common/bytearray'
require_relative 'core/rubinius/api/kernel/common/channel'
require_relative 'core/rubinius/api/kernel/common/thread'
require_relative 'core/rubinius/api/kernel/common/tuple'
require_relative 'core/rubinius/api/kernel/common/type'

require_relative 'core/rubinius/kernel/common/kernel'
require_relative 'core/rubinius/kernel/common/struct'

require_relative 'core/shims'
6 changes: 5 additions & 1 deletion core/src/main/ruby/jruby/truffle/core/rubinius/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,8 @@ We try not to modify files, so that they can easily be merged from upstream in
the future, but we have found it easier to modify inline in a few cases, rather
than somehow patch things from within JRuby+Truffle.

We have also directly attached copyright and license information to each file.
We have also tried to keep files from `rubinius-core-api` and Rubinius itself
separate and to be consistent about what we're using, but in the end it's a bit
of a mix from the two that works for us.

We have directly attached copyright and license information to each file.
33 changes: 33 additions & 0 deletions core/src/main/ruby/jruby/truffle/core/rubinius/api/compat/type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Copyright (c) 2011, Evan Phoenix
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * Neither the name of the Evan Phoenix nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

module Rubinius
module Type
def self.object_kind_of?(obj, cls)
obj.class <= cls
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,14 @@ module Type

def self.coerce_to(obj, cls, meth)
return obj if object_kind_of?(obj, cls)

begin
ret = obj.__send__(meth)
rescue Exception => orig
raise TypeError,
"Coercion error: #{obj.inspect}.#{meth} => #{cls} failed",
orig
end

return ret if object_kind_of?(ret, cls)

msg = "Coercion error: obj.#{meth} did NOT return a #{cls} (was #{object_class(ret)})"
raise TypeError, msg
end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Copyright (c) 2007-2014, Evan Phoenix and contributors
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * Neither the name of Rubinius nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

module Kernel

##
# MRI uses a macro named StringValue which has essentially the same
# semantics as obj.coerce_to(String, :to_str), but rather than using that
# long construction everywhere, we define a private method similar to
# String().
#
# Another possibility would be to change String() as follows:
#
# String(obj, sym=:to_s)
#
# and use String(obj, :to_str) instead of StringValue(obj)

def StringValue(obj)
Rubinius::Type.coerce_to obj, String, :to_str
end
module_function :StringValue

end
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ def self.new(klass_name, *attrs, &block)
if klass_name
begin
klass_name = StringValue klass_name
p klass_name
rescue TypeError
attrs.unshift klass_name
klass_name = nil
Expand Down
2 changes: 0 additions & 2 deletions spec/truffle/tags/core/struct/each_pair_tags.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
fails:Struct#each_pair passes each key value pair to the given block
fails:Struct#each_pair returns self if passed a block
fails:Struct#each_pair returns an Enumerator if not passed a block
fails:Struct#each_pair does not override the instance accessor method
2 changes: 0 additions & 2 deletions spec/truffle/tags/core/struct/each_tags.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
fails:Struct#each passes each value to the given block
fails:Struct#each returns self if passed a block
fails:Struct#each returns an Enumerator if not passed a block
fails:Struct#each does not override the instance accessor method
4 changes: 0 additions & 4 deletions spec/truffle/tags/core/struct/element_reference_tags.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,2 @@
fails:Struct[] is a synonym for new
fails:Struct#[] returns the attribute referenced
fails:Struct#[] fails when it does not know about the requested attribute
fails:Struct#[] fails if passed too many arguments
fails:Struct#[] fails if not passed a string, symbol, or integer
fails:Struct#[] returns attribute names that contain hyphens
1 change: 0 additions & 1 deletion spec/truffle/tags/core/struct/element_set_tags.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
fails:Struct#[]= assigns the passed value
fails:Struct#[]= fails when trying to assign attributes which don't exist
1 change: 0 additions & 1 deletion spec/truffle/tags/core/struct/eql_tags.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
fails:Struct#eql? returns true if the other is the same object
fails:Struct#eql? returns true if the other has all the same fields
fails:Struct#eql? returns false if the other is a different object or has different fields
fails:Struct#eql? handles recursive structures by returning false if a difference can be found
Expand Down
2 changes: 0 additions & 2 deletions spec/truffle/tags/core/struct/hash_tags.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
fails:Struct#hash returns the same fixnum for structs with the same content
fails:Struct#hash returns the same value if structs are #eql?
fails:Struct#hash allows for overriding methods in an included module
fails:Struct#hash returns the same hash for recursive structs
fails:Struct#hash does not override the instance accessor method
2 changes: 0 additions & 2 deletions spec/truffle/tags/core/struct/initialize_tags.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
fails:Struct#initialize is private
fails:Struct#initialize does nothing when passed a set of fields equal to self
fails:Struct#initialize explicitly sets instance variables to nil when args not provided to initialize
fails:Struct#initialize can be overriden
1 change: 0 additions & 1 deletion spec/truffle/tags/core/struct/instance_variables_tags.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
fails:Struct#instance_variables returns an empty array if only attributes are defined
fails:Struct#instance_variables returns an array with one name if an instance variable is added
2 changes: 0 additions & 2 deletions spec/truffle/tags/core/struct/length_tags.txt

This file was deleted.

2 changes: 0 additions & 2 deletions spec/truffle/tags/core/struct/members_tags.txt

This file was deleted.

9 changes: 0 additions & 9 deletions spec/truffle/tags/core/struct/new_tags.txt
Original file line number Diff line number Diff line change
@@ -1,15 +1,6 @@
fails:Struct.new creates a constant in Struct namespace with string as first argument
fails:Struct.new overwrites previously defined constants with string as first argument
fails:Struct.new calls to_str on its first argument (constant name)
fails:Struct.new creates a new anonymous class with nil first argument
fails:Struct.new creates a new anonymous class with symbol arguments
fails:Struct.new does not create a constant with symbol as first argument
fails:Struct.new fails with invalid constant name as first argument
fails:Struct.new raises a TypeError if object doesn't respond to to_sym
fails:Struct.new raises a TypeError if object is not a Symbol
fails:Struct.new processes passed block with instance_eval
fails:Struct.new creates a constant in subclass' namespace
fails:Struct.new creates an instance
fails:Struct.new creates reader methods
fails:Struct.new creates writer methods
fails:Struct.new fails with too many arguments

0 comments on commit 8d38b3e

Please sign in to comment.