From 01859b6fe896fd3f42852ed2943cd49e3a268cb1 Mon Sep 17 00:00:00 2001 From: Sergey Fedorov Date: Tue, 19 Oct 2021 23:43:13 +0200 Subject: [PATCH] Add support for Array subclass methods to return Array --- spec/truffleruby.mspec | 7 +++++++ .../org/truffleruby/core/array/ArrayIndexNodes.java | 8 +++----- .../java/org/truffleruby/core/array/ArrayNodes.java | 9 +++------ src/main/ruby/truffleruby/core/array.rb | 12 +++--------- src/main/ruby/truffleruby/core/enumerable.rb | 1 + 5 files changed, 17 insertions(+), 20 deletions(-) diff --git a/spec/truffleruby.mspec b/spec/truffleruby.mspec index 481ab90dbf65..0f4bc3f51940 100644 --- a/spec/truffleruby.mspec +++ b/spec/truffleruby.mspec @@ -95,6 +95,13 @@ class MSpecScript # Use spec/ruby/core/nil/nil_spec.rb as a dummy file to avoid being empty set :next, %w[ spec/ruby/core/nil/nil_spec.rb + spec/ruby/core/array/drop_spec.rb + spec/ruby/core/array/drop_while_spec.rb + spec/ruby/core/array/take_spec.rb + spec/ruby/core/array/take_while_spec.rb + spec/ruby/core/array/uniq_spec.rb + spec/ruby/core/array/multiply_spec.rb + spec/ruby/core/array/slice_spec.rb ] set :tags_patterns, [ diff --git a/src/main/java/org/truffleruby/core/array/ArrayIndexNodes.java b/src/main/java/org/truffleruby/core/array/ArrayIndexNodes.java index c187bc98aa81..21222f0cb25d 100644 --- a/src/main/java/org/truffleruby/core/array/ArrayIndexNodes.java +++ b/src/main/java/org/truffleruby/core/array/ArrayIndexNodes.java @@ -13,7 +13,6 @@ import org.truffleruby.builtins.Primitive; import org.truffleruby.builtins.PrimitiveArrayArgumentsNode; import org.truffleruby.core.array.library.ArrayStoreLibrary; -import org.truffleruby.core.klass.RubyClass; import org.truffleruby.language.RubyContextSourceNode; import org.truffleruby.language.RubyNode; @@ -123,17 +122,16 @@ protected RubyArray readInBounds(RubyArray array, int index, int length, ? length : size - index; final Object slice = cowNode.execute(array, index, end); - return createArrayOfSameClass(array, slice, end); + return createArray(array, slice, end); } protected static boolean indexInBounds(RubyArray array, int index) { return index >= 0 && index <= array.size; } - protected RubyArray createArrayOfSameClass(RubyArray array, Object store, int size) { - final RubyClass logicalClass = array.getLogicalClass(); + protected RubyArray createArray(RubyArray array, Object store, int size) { RubyArray newArray = new RubyArray( - logicalClass, + coreLibrary().arrayClass, getLanguage().arrayShape, store, size); diff --git a/src/main/java/org/truffleruby/core/array/ArrayNodes.java b/src/main/java/org/truffleruby/core/array/ArrayNodes.java index cb32d65fcadc..ce785a155228 100644 --- a/src/main/java/org/truffleruby/core/array/ArrayNodes.java +++ b/src/main/java/org/truffleruby/core/array/ArrayNodes.java @@ -163,9 +163,8 @@ public abstract static class MulNode extends PrimitiveArrayArgumentsNode { @Specialization(guards = "count == 0") protected RubyArray mulZero(RubyArray array, int count) { - final RubyClass logicalClass = array.getLogicalClass(); return new RubyArray( - logicalClass, + coreLibrary().arrayClass, getLanguage().arrayShape, ArrayStoreLibrary.INITIAL_STORE, 0); @@ -197,9 +196,8 @@ protected RubyArray mulOther(RubyArray array, int count, profileAndReportLoopCount(loopProfile, n); } - final RubyClass logicalClass = array.getLogicalClass(); return new RubyArray( - logicalClass, + coreLibrary().arrayClass, getLanguage().arrayShape, newStore, newSize); @@ -217,9 +215,8 @@ protected RubyArray mulLong(RubyArray array, long count) { @Specialization(guards = { "isEmptyArray(array)" }) protected RubyArray mulEmpty(RubyArray array, long count) { - final RubyClass logicalClass = array.getLogicalClass(); return new RubyArray( - logicalClass, + coreLibrary().arrayClass, getLanguage().arrayShape, ArrayStoreLibrary.INITIAL_STORE, 0); diff --git a/src/main/ruby/truffleruby/core/array.rb b/src/main/ruby/truffleruby/core/array.rb index eef879cc4e7e..c035ddcd27a2 100644 --- a/src/main/ruby/truffleruby/core/array.rb +++ b/src/main/ruby/truffleruby/core/array.rb @@ -109,6 +109,7 @@ def <=>(other) def *(count) result = Primitive.array_mul(self, count) + if !Primitive.undefined?(result) result elsif str = Truffle::Type.rb_check_convert_type(count, String, :to_str) @@ -443,9 +444,9 @@ def first(n = undefined) def flatten(level=-1) level = Primitive.rb_num2int level - return self.dup if level == 0 + return Array.new(self) if level == 0 - out = self.class.allocate # new_reserved size + out = [] # new_reserved size Primitive.array_flatten_helper(self, out, level) out end @@ -1591,13 +1592,6 @@ def delete_range(index, del_length) end private :delete_range - def uniq(&block) - copy_of_same_class = dup - result = super(&block) - Primitive.steal_array_storage(copy_of_same_class, result) - copy_of_same_class - end - def uniq!(&block) Primitive.check_frozen self result = uniq(&block) diff --git a/src/main/ruby/truffleruby/core/enumerable.rb b/src/main/ruby/truffleruby/core/enumerable.rb index b605b2e21dbe..9c7d712480fb 100644 --- a/src/main/ruby/truffleruby/core/enumerable.rb +++ b/src/main/ruby/truffleruby/core/enumerable.rb @@ -1051,6 +1051,7 @@ class Array alias_method :take, :take alias_method :drop_while, :drop_while alias_method :take_while, :take_while + alias_method :uniq, :uniq alias_method :sum, :sum alias_method :all?, :all? alias_method :none?, :none?