Skip to content

Commit ef6fd86

Browse files
committed
[GR-18163] Ruby 2.7: Better support of Integer#[] with range arguments (#2182)
PullRequest: truffleruby/2274
2 parents 6ff38b6 + 2dfa91f commit ef6fd86

File tree

6 files changed

+53
-25
lines changed

6 files changed

+53
-25
lines changed

spec/ruby/core/integer/element_reference_spec.rb

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -131,16 +131,10 @@
131131
0b000001[-3, 4].should == 0b1000
132132
end
133133

134-
it "ignores negative upper boundary" do
135-
0b101001101[1..-1].should == 0b10100110
136-
0b101001101[1..-2].should == 0b10100110
137-
0b101001101[1..-3].should == 0b10100110
138-
end
139-
140134
it "ignores upper boundary smaller than lower boundary" do
141135
0b101001101[4..1].should == 0b10100
142136
0b101001101[4..2].should == 0b10100
143-
0b101001101[4..3].should == 0b10100
137+
0b101001101[-4..-5].should == 0b1010011010000
144138
end
145139

146140
it "raises FloatDomainError if any boundary is infinity" do

spec/tags/core/integer/element_reference_tags.txt

Lines changed: 0 additions & 13 deletions
This file was deleted.

src/main/java/org/truffleruby/core/CoreLibrary.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,6 +1030,7 @@ public boolean isTruffleBootMainMethod(SharedMethodInfo info) {
10301030
"/core/comparable.rb",
10311031
"/core/numeric.rb",
10321032
"/core/truffle/ctype.rb",
1033+
"/core/truffle/integer_operations.rb",
10331034
"/core/integer.rb",
10341035
"/core/regexp.rb",
10351036
"/core/transcoding.rb",

src/main/ruby/truffleruby/core/integer.rb

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,17 @@ def **(o)
5959
redo_coerced :**, o
6060
end
6161

62-
def [](index)
63-
index = Primitive.rb_to_int(index)
64-
index < 0 ? 0 : (self >> index) & 1
62+
def [](index, len = undefined)
63+
if Primitive.object_kind_of?(index, Range)
64+
Truffle::IntegerOperations.bits_reference_range(self, index)
65+
else
66+
index = Primitive.rb_to_int(index)
67+
if Primitive.undefined?(len)
68+
index < 0 ? 0 : (self >> index) & 1
69+
else
70+
(self >> index) & ((1 << len) - 1)
71+
end
72+
end
6573
end
6674

6775
def allbits?(mask)
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# frozen_string_literal: true
2+
3+
# Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved. This
4+
# code is released under a tri EPL/GPL/LGPL license. You can use it,
5+
# redistribute it and/or modify it under the terms of the:
6+
#
7+
# Eclipse Public License version 2.0, or
8+
# GNU General Public License version 2, or
9+
# GNU Lesser General Public License version 2.1.
10+
11+
module Truffle
12+
module IntegerOperations
13+
def self.bits_reference_range(n, range)
14+
raise FloatDomainError , 'Infinity' if range.begin == Float::INFINITY || range.end == Float::INFINITY
15+
raise FloatDomainError , '-Infinity' if range.begin == -Float::INFINITY || range.end == -Float::INFINITY
16+
17+
if !Primitive.nil?(range.begin) && !Primitive.nil?(range.end)
18+
len = range.end - range.begin
19+
len += 1 unless range.exclude_end?
20+
num = n >> range.begin
21+
mask = (1 << len) - 1
22+
23+
range.end < range.begin ? num : num & mask
24+
elsif Primitive.nil?(range.end)
25+
n >> range.begin
26+
else
27+
len = range.end
28+
len += 1 unless range.exclude_end?
29+
mask = (1 << len) - 1
30+
31+
if n & mask != 0 && range.end >= 0
32+
raise ArgumentError, 'The beginless range for Integer#[] results in infinity'
33+
end
34+
35+
0
36+
end
37+
end
38+
end
39+
end

test/mri/excludes/TestInteger.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,4 @@
1111
exclude :test_floor, "needs investigation"
1212
exclude :test_pow, "needs investigation"
1313
exclude :test_truncate, "needs investigation"
14-
exclude :test_Integer_with_invalid_exception, "needs investigation"
15-
exclude :test_aref, "needs investigation"
14+
exclude :test_Integer_with_invalid_exception, "needs investigation"

0 commit comments

Comments
 (0)