зеркало из https://github.com/github/ruby.git
Add "c_long_size" guard, supplanting "wordsize" and stop using Integer#size
What a "word" is when talking about sizes is confusing because it's a highly overloaded term. Intel, Microsoft, and GDB are just a few vendors that have their own definition of what a "word" is. Specs that used the "wordsize" guard actually were mostly testing for the size of the C `long` fundamental type, so rename the guard for clarity. Also, get the size of `long` directly from RbConfig instead of guessing using Integer#size. Integer#size is not guaranteed to have anything to do with the `long` type.
This commit is contained in:
Родитель
1a18b03ee7
Коммит
12e6cf77ef
|
@ -53,23 +53,27 @@ class PlatformGuard < SpecGuard
|
|||
end
|
||||
end
|
||||
|
||||
WORD_SIZE = 1.size * 8
|
||||
|
||||
POINTER_SIZE = begin
|
||||
require 'rbconfig/sizeof'
|
||||
RbConfig::SIZEOF["void*"] * 8
|
||||
rescue LoadError
|
||||
WORD_SIZE
|
||||
[0].pack('j').size
|
||||
end
|
||||
|
||||
def self.wordsize?(size)
|
||||
size == WORD_SIZE
|
||||
C_LONG_SIZE = if defined?(RbConfig::SIZEOF[])
|
||||
RbConfig::SIZEOF["long"] * 8
|
||||
else
|
||||
[0].pack('l!').size
|
||||
end
|
||||
|
||||
def self.pointer_size?(size)
|
||||
size == POINTER_SIZE
|
||||
end
|
||||
|
||||
def self.c_long_size?(size)
|
||||
size == C_LONG_SIZE
|
||||
end
|
||||
|
||||
def initialize(*args)
|
||||
if args.last.is_a?(Hash)
|
||||
@options, @platforms = args.last, args[0..-2]
|
||||
|
@ -85,10 +89,10 @@ class PlatformGuard < SpecGuard
|
|||
case key
|
||||
when :os
|
||||
match &&= PlatformGuard.os?(*value)
|
||||
when :wordsize
|
||||
match &&= PlatformGuard.wordsize? value
|
||||
when :pointer_size
|
||||
match &&= PlatformGuard.pointer_size? value
|
||||
when :c_long_size
|
||||
match &&= PlatformGuard::c_long_size? value
|
||||
end
|
||||
end
|
||||
match
|
||||
|
|
|
@ -28,7 +28,7 @@ end
|
|||
# specs based on the relationship between values rather than specific
|
||||
# values.
|
||||
if PlatformGuard.standard? or PlatformGuard.implementation? :topaz
|
||||
if PlatformGuard.wordsize? 32
|
||||
if PlatformGuard.c_long_size? 32
|
||||
def fixnum_max
|
||||
(2**30) - 1
|
||||
end
|
||||
|
@ -36,7 +36,7 @@ if PlatformGuard.standard? or PlatformGuard.implementation? :topaz
|
|||
def fixnum_min
|
||||
-(2**30)
|
||||
end
|
||||
elsif PlatformGuard.wordsize? 64
|
||||
elsif PlatformGuard.c_long_size? 64
|
||||
def fixnum_max
|
||||
(2**62) - 1
|
||||
end
|
||||
|
|
|
@ -81,44 +81,44 @@ RSpec.describe Object, "#platform_is_not" do
|
|||
end
|
||||
end
|
||||
|
||||
RSpec.describe Object, "#platform_is :wordsize => SIZE_SPEC" do
|
||||
RSpec.describe Object, "#platform_is :c_long_size => SIZE_SPEC" do
|
||||
before :each do
|
||||
@guard = PlatformGuard.new :darwin, :wordsize => 32
|
||||
@guard = PlatformGuard.new :darwin, :c_long_size => 32
|
||||
allow(PlatformGuard).to receive(:os?).and_return(true)
|
||||
allow(PlatformGuard).to receive(:new).and_return(@guard)
|
||||
ScratchPad.clear
|
||||
end
|
||||
|
||||
it "yields when #wordsize? returns true" do
|
||||
allow(PlatformGuard).to receive(:wordsize?).and_return(true)
|
||||
platform_is(:wordsize => 32) { ScratchPad.record :yield }
|
||||
it "yields when #c_long_size? returns true" do
|
||||
allow(PlatformGuard).to receive(:c_long_size?).and_return(true)
|
||||
platform_is(:c_long_size => 32) { ScratchPad.record :yield }
|
||||
expect(ScratchPad.recorded).to eq(:yield)
|
||||
end
|
||||
|
||||
it "doesn not yield when #wordsize? returns false" do
|
||||
allow(PlatformGuard).to receive(:wordsize?).and_return(false)
|
||||
platform_is(:wordsize => 32) { ScratchPad.record :yield }
|
||||
it "doesn not yield when #c_long_size? returns false" do
|
||||
allow(PlatformGuard).to receive(:c_long_size?).and_return(false)
|
||||
platform_is(:c_long_size => 32) { ScratchPad.record :yield }
|
||||
expect(ScratchPad.recorded).not_to eq(:yield)
|
||||
end
|
||||
end
|
||||
|
||||
RSpec.describe Object, "#platform_is_not :wordsize => SIZE_SPEC" do
|
||||
RSpec.describe Object, "#platform_is_not :c_long_size => SIZE_SPEC" do
|
||||
before :each do
|
||||
@guard = PlatformGuard.new :darwin, :wordsize => 32
|
||||
@guard = PlatformGuard.new :darwin, :c_long_size => 32
|
||||
allow(PlatformGuard).to receive(:os?).and_return(true)
|
||||
allow(PlatformGuard).to receive(:new).and_return(@guard)
|
||||
ScratchPad.clear
|
||||
end
|
||||
|
||||
it "yields when #wordsize? returns false" do
|
||||
allow(PlatformGuard).to receive(:wordsize?).and_return(false)
|
||||
platform_is_not(:wordsize => 32) { ScratchPad.record :yield }
|
||||
it "yields when #c_long_size? returns false" do
|
||||
allow(PlatformGuard).to receive(:c_long_size?).and_return(false)
|
||||
platform_is_not(:c_long_size => 32) { ScratchPad.record :yield }
|
||||
expect(ScratchPad.recorded).to eq(:yield)
|
||||
end
|
||||
|
||||
it "doesn not yield when #wordsize? returns true" do
|
||||
allow(PlatformGuard).to receive(:wordsize?).and_return(true)
|
||||
platform_is_not(:wordsize => 32) { ScratchPad.record :yield }
|
||||
it "doesn not yield when #c_long_size? returns true" do
|
||||
allow(PlatformGuard).to receive(:c_long_size?).and_return(true)
|
||||
platform_is_not(:c_long_size => 32) { ScratchPad.record :yield }
|
||||
expect(ScratchPad.recorded).not_to eq(:yield)
|
||||
end
|
||||
end
|
||||
|
@ -184,13 +184,13 @@ RSpec.describe PlatformGuard, ".standard?" do
|
|||
end
|
||||
end
|
||||
|
||||
RSpec.describe PlatformGuard, ".wordsize?" do
|
||||
RSpec.describe PlatformGuard, ".c_long_size?" do
|
||||
it "returns true when arg is 32 and 1.size is 4" do
|
||||
expect(PlatformGuard.wordsize?(32)).to eq(1.size == 4)
|
||||
expect(PlatformGuard.c_long_size?(32)).to eq(1.size == 4)
|
||||
end
|
||||
|
||||
it "returns true when arg is 64 and 1.size is 8" do
|
||||
expect(PlatformGuard.wordsize?(64)).to eq(1.size == 8)
|
||||
expect(PlatformGuard.c_long_size?(64)).to eq(1.size == 8)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -164,7 +164,7 @@ end
|
|||
platform_is_not :linux, :darwin do # Not Linux and not Darwin
|
||||
end
|
||||
|
||||
platform_is wordsize: 64 do
|
||||
platform_is pointer_size: 64 do
|
||||
# 64-bit platform
|
||||
end
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ describe "Array#pack with format 'L'" do
|
|||
it_behaves_like :array_pack_32bit_be, 'L>'
|
||||
end
|
||||
|
||||
platform_is wordsize: 32 do
|
||||
platform_is c_long_size: 32 do
|
||||
describe "with modifier '<' and '_'" do
|
||||
it_behaves_like :array_pack_32bit_le, 'L<_'
|
||||
it_behaves_like :array_pack_32bit_le, 'L_<'
|
||||
|
@ -51,7 +51,7 @@ describe "Array#pack with format 'L'" do
|
|||
end
|
||||
end
|
||||
|
||||
platform_is wordsize: 64 do
|
||||
platform_is c_long_size: 64 do
|
||||
describe "with modifier '<' and '_'" do
|
||||
it_behaves_like :array_pack_64bit_le, 'L<_'
|
||||
it_behaves_like :array_pack_64bit_le, 'L_<'
|
||||
|
@ -83,7 +83,7 @@ describe "Array#pack with format 'l'" do
|
|||
it_behaves_like :array_pack_32bit_be, 'l>'
|
||||
end
|
||||
|
||||
platform_is wordsize: 32 do
|
||||
platform_is c_long_size: 32 do
|
||||
describe "with modifier '<' and '_'" do
|
||||
it_behaves_like :array_pack_32bit_le, 'l<_'
|
||||
it_behaves_like :array_pack_32bit_le, 'l_<'
|
||||
|
@ -105,7 +105,7 @@ describe "Array#pack with format 'l'" do
|
|||
end
|
||||
end
|
||||
|
||||
platform_is wordsize: 64 do
|
||||
platform_is c_long_size: 64 do
|
||||
describe "with modifier '<' and '_'" do
|
||||
it_behaves_like :array_pack_64bit_le, 'l<_'
|
||||
it_behaves_like :array_pack_64bit_le, 'l_<'
|
||||
|
@ -137,7 +137,7 @@ little_endian do
|
|||
it_behaves_like :array_pack_32bit_le, 'l'
|
||||
end
|
||||
|
||||
platform_is wordsize: 32 do
|
||||
platform_is c_long_size: 32 do
|
||||
describe "Array#pack with format 'L' with modifier '_'" do
|
||||
it_behaves_like :array_pack_32bit_le, 'L_'
|
||||
end
|
||||
|
@ -155,7 +155,7 @@ little_endian do
|
|||
end
|
||||
end
|
||||
|
||||
platform_is wordsize: 64 do
|
||||
platform_is c_long_size: 64 do
|
||||
describe "Array#pack with format 'L' with modifier '_'" do
|
||||
it_behaves_like :array_pack_64bit_le, 'L_'
|
||||
end
|
||||
|
@ -183,7 +183,7 @@ big_endian do
|
|||
it_behaves_like :array_pack_32bit_be, 'l'
|
||||
end
|
||||
|
||||
platform_is wordsize: 32 do
|
||||
platform_is c_long_size: 32 do
|
||||
describe "Array#pack with format 'L' with modifier '_'" do
|
||||
it_behaves_like :array_pack_32bit_be, 'L_'
|
||||
end
|
||||
|
@ -201,7 +201,7 @@ big_endian do
|
|||
end
|
||||
end
|
||||
|
||||
platform_is wordsize: 64 do
|
||||
platform_is c_long_size: 64 do
|
||||
describe "Array#pack with format 'L' with modifier '_'" do
|
||||
it_behaves_like :array_pack_64bit_be, 'L_'
|
||||
end
|
||||
|
|
|
@ -273,7 +273,7 @@ describe :array_pack_32bit_le_platform, shared: true do
|
|||
str.should == "\x78\x65\x43\x12\xcd\xab\xf0\xde\x21\x43\x65\x78"
|
||||
end
|
||||
|
||||
platform_is wordsize: 64 do
|
||||
platform_is c_long_size: 64 do
|
||||
it "encodes the least significant 32 bits of a number that is greater than 32 bits" do
|
||||
[ [[0xff_7865_4321], "\x21\x43\x65\x78"],
|
||||
[[-0xff_7865_4321], "\xdf\xbc\x9a\x87"]
|
||||
|
@ -299,7 +299,7 @@ describe :array_pack_32bit_be_platform, shared: true do
|
|||
str.should == "\x12\x43\x65\x78\xde\xf0\xab\xcd\x78\x65\x43\x21"
|
||||
end
|
||||
|
||||
platform_is wordsize: 64 do
|
||||
platform_is c_long_size: 64 do
|
||||
it "encodes the least significant 32 bits of a number that is greater than 32 bits" do
|
||||
[ [[0xff_7865_4321], "\x78\x65\x43\x21"],
|
||||
[[-0xff_7865_4321], "\x87\x9a\xbc\xdf"]
|
||||
|
|
|
@ -84,7 +84,7 @@ describe :update_time, shared: true do
|
|||
end
|
||||
|
||||
platform_is :linux do
|
||||
platform_is wordsize: 64 do
|
||||
platform_is pointer_size: 64 do
|
||||
it "allows Time instances in the far future to set mtime and atime (but some filesystems limit it up to 2446-05-10 or 2038-01-19 or 2486-07-02)" do
|
||||
# https://ext4.wiki.kernel.org/index.php/Ext4_Disk_Layout#Inode_Timestamps
|
||||
# "Therefore, timestamps should not overflow until May 2446."
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
require_relative '../../spec_helper'
|
||||
|
||||
describe "Integer#size" do
|
||||
platform_is wordsize: 32 do
|
||||
platform_is c_long_size: 32 do
|
||||
it "returns the number of bytes in the machine representation of self" do
|
||||
-1.size.should == 4
|
||||
0.size.should == 4
|
||||
|
@ -9,7 +9,7 @@ describe "Integer#size" do
|
|||
end
|
||||
end
|
||||
|
||||
platform_is wordsize: 64 do
|
||||
platform_is c_long_size: 64 do
|
||||
it "returns the number of bytes in the machine representation of self" do
|
||||
-1.size.should == 8
|
||||
0.size.should == 8
|
||||
|
|
|
@ -38,7 +38,7 @@ describe "Marshal.dump" do
|
|||
].should be_computed_by(:dump)
|
||||
end
|
||||
|
||||
platform_is wordsize: 64 do
|
||||
platform_is c_long_size: 64 do
|
||||
it "dumps a positive Fixnum > 31 bits as a Bignum" do
|
||||
Marshal.dump(2**31 + 1).should == "\x04\bl+\a\x01\x00\x00\x80"
|
||||
end
|
||||
|
|
|
@ -1049,7 +1049,7 @@ describe :marshal_load, shared: true do
|
|||
end
|
||||
|
||||
describe "for a Bignum" do
|
||||
platform_is wordsize: 64 do
|
||||
platform_is c_long_size: 64 do
|
||||
context "that is Bignum on 32-bit platforms but Fixnum on 64-bit" do
|
||||
it "dumps a Fixnum" do
|
||||
val = Marshal.send(@method, "\004\bl+\ab:wU")
|
||||
|
|
|
@ -14,7 +14,7 @@ describe "String#unpack with format 'L'" do
|
|||
it_behaves_like :string_unpack_32bit_be_unsigned, 'L>'
|
||||
end
|
||||
|
||||
platform_is wordsize: 32 do
|
||||
platform_is c_long_size: 32 do
|
||||
describe "with modifier '<' and '_'" do
|
||||
it_behaves_like :string_unpack_32bit_le, 'L<_'
|
||||
it_behaves_like :string_unpack_32bit_le, 'L_<'
|
||||
|
@ -44,7 +44,7 @@ describe "String#unpack with format 'L'" do
|
|||
end
|
||||
end
|
||||
|
||||
platform_is wordsize: 64 do
|
||||
platform_is c_long_size: 64 do
|
||||
describe "with modifier '<' and '_'" do
|
||||
it_behaves_like :string_unpack_64bit_le, 'L<_'
|
||||
it_behaves_like :string_unpack_64bit_le, 'L_<'
|
||||
|
@ -86,7 +86,7 @@ describe "String#unpack with format 'l'" do
|
|||
it_behaves_like :string_unpack_32bit_be_signed, 'l>'
|
||||
end
|
||||
|
||||
platform_is wordsize: 32 do
|
||||
platform_is c_long_size: 32 do
|
||||
describe "with modifier '<' and '_'" do
|
||||
it_behaves_like :string_unpack_32bit_le, 'l<_'
|
||||
it_behaves_like :string_unpack_32bit_le, 'l_<'
|
||||
|
@ -116,7 +116,7 @@ describe "String#unpack with format 'l'" do
|
|||
end
|
||||
end
|
||||
|
||||
platform_is wordsize: 64 do
|
||||
platform_is c_long_size: 64 do
|
||||
describe "with modifier '<' and '_'" do
|
||||
it_behaves_like :string_unpack_64bit_le, 'l<_'
|
||||
it_behaves_like :string_unpack_64bit_le, 'l_<'
|
||||
|
@ -160,7 +160,7 @@ little_endian do
|
|||
it_behaves_like :string_unpack_32bit_le_signed, 'l'
|
||||
end
|
||||
|
||||
platform_is wordsize: 32 do
|
||||
platform_is c_long_size: 32 do
|
||||
describe "String#unpack with format 'L' with modifier '_'" do
|
||||
it_behaves_like :string_unpack_32bit_le, 'L_'
|
||||
it_behaves_like :string_unpack_32bit_le_unsigned, 'L_'
|
||||
|
@ -182,7 +182,7 @@ little_endian do
|
|||
end
|
||||
end
|
||||
|
||||
platform_is wordsize: 64 do
|
||||
platform_is c_long_size: 64 do
|
||||
describe "String#unpack with format 'L' with modifier '_'" do
|
||||
it_behaves_like :string_unpack_64bit_le, 'L_'
|
||||
it_behaves_like :string_unpack_64bit_le_unsigned, 'L_'
|
||||
|
@ -218,7 +218,7 @@ big_endian do
|
|||
it_behaves_like :string_unpack_32bit_be_signed, 'l'
|
||||
end
|
||||
|
||||
platform_is wordsize: 32 do
|
||||
platform_is c_long_size: 32 do
|
||||
describe "String#unpack with format 'L' with modifier '_'" do
|
||||
it_behaves_like :string_unpack_32bit_be, 'L_'
|
||||
it_behaves_like :string_unpack_32bit_be_unsigned, 'L_'
|
||||
|
@ -240,7 +240,7 @@ big_endian do
|
|||
end
|
||||
end
|
||||
|
||||
platform_is wordsize: 64 do
|
||||
platform_is c_long_size: 64 do
|
||||
describe "String#unpack with format 'L' with modifier '_'" do
|
||||
it_behaves_like :string_unpack_64bit_be, 'L_'
|
||||
it_behaves_like :string_unpack_64bit_be_unsigned, 'L_'
|
||||
|
|
|
@ -36,7 +36,7 @@ describe "BigDecimal#sqrt" do
|
|||
BigDecimal('121').sqrt(5).should be_close(11, 0.00001)
|
||||
end
|
||||
|
||||
platform_is_not wordsize: 32 do # fails on i686
|
||||
platform_is_not c_long_size: 32 do # fails on i686
|
||||
it "returns square root of 0.9E-99999 with desired precision" do
|
||||
@frac_2.sqrt(1).to_s.should =~ /\A0\.3E-49999\z/i
|
||||
end
|
||||
|
|
|
@ -123,7 +123,7 @@ describe "CApiBignumSpecs" do
|
|||
val.should == @max_ulong
|
||||
end
|
||||
|
||||
platform_is wordsize: 64 do
|
||||
platform_is c_long_size: 64 do
|
||||
it "packs max_ulong into 2 ulongs to allow sign bit" do
|
||||
val = @s.rb_big_pack_length(@max_ulong)
|
||||
val.should == 2
|
||||
|
|
|
@ -25,7 +25,7 @@ describe "CApiFixnumSpecs" do
|
|||
end
|
||||
end
|
||||
|
||||
platform_is wordsize: 64 do # sizeof(long) > sizeof(int)
|
||||
platform_is c_long_size: 64 do # sizeof(long) > sizeof(int)
|
||||
it "raises a TypeError if passed nil" do
|
||||
-> { @s.FIX2INT(nil) }.should raise_error(TypeError)
|
||||
end
|
||||
|
@ -74,7 +74,7 @@ describe "CApiFixnumSpecs" do
|
|||
end
|
||||
end
|
||||
|
||||
platform_is wordsize: 64 do # sizeof(long) > sizeof(int)
|
||||
platform_is c_long_size: 64 do # sizeof(long) > sizeof(int)
|
||||
it "raises a TypeError if passed nil" do
|
||||
-> { @s.FIX2UINT(nil) }.should raise_error(TypeError)
|
||||
end
|
||||
|
|
|
@ -106,7 +106,7 @@ describe "CApiNumericSpecs" do
|
|||
@s.NUM2LONG(5).should == 5
|
||||
end
|
||||
|
||||
platform_is wordsize: 32 do
|
||||
platform_is c_long_size: 32 do
|
||||
it "converts -1 to an signed number" do
|
||||
@s.NUM2LONG(-1).should == -1
|
||||
end
|
||||
|
@ -120,7 +120,7 @@ describe "CApiNumericSpecs" do
|
|||
end
|
||||
end
|
||||
|
||||
platform_is wordsize: 64 do
|
||||
platform_is c_long_size: 64 do
|
||||
it "converts -1 to an signed number" do
|
||||
@s.NUM2LONG(-1).should == -1
|
||||
end
|
||||
|
@ -210,7 +210,7 @@ describe "CApiNumericSpecs" do
|
|||
@s.NUM2ULONG(5).should == 5
|
||||
end
|
||||
|
||||
platform_is wordsize: 32 do
|
||||
platform_is c_long_size: 32 do
|
||||
it "converts -1 to an unsigned number" do
|
||||
@s.NUM2ULONG(-1).should == 4294967295
|
||||
end
|
||||
|
@ -231,7 +231,7 @@ describe "CApiNumericSpecs" do
|
|||
end
|
||||
end
|
||||
|
||||
platform_is wordsize: 64 do
|
||||
platform_is c_long_size: 64 do
|
||||
it "converts -1 to an unsigned number" do
|
||||
@s.NUM2ULONG(-1).should == 18446744073709551615
|
||||
end
|
||||
|
|
|
@ -209,7 +209,7 @@ describe "C-API Util function" do
|
|||
end
|
||||
end
|
||||
|
||||
platform_is wordsize: 64 do
|
||||
platform_is c_long_size: 64 do
|
||||
describe "rb_long2int" do
|
||||
it "raises a RangeError if the value is outside the range of a C int" do
|
||||
-> { @o.rb_long2int(0xffff_ffff_ffff) }.should raise_error(RangeError)
|
||||
|
|
|
@ -44,13 +44,13 @@ describe :string_times, shared: true do
|
|||
result.encoding.should equal(Encoding::UTF_8)
|
||||
end
|
||||
|
||||
platform_is wordsize: 32 do
|
||||
platform_is c_long_size: 32 do
|
||||
it "raises an ArgumentError if the length of the resulting string doesn't fit into a long" do
|
||||
-> { @object.call("abc", (2 ** 31) - 1) }.should raise_error(ArgumentError)
|
||||
end
|
||||
end
|
||||
|
||||
platform_is wordsize: 64 do
|
||||
platform_is c_long_size: 64 do
|
||||
it "raises an ArgumentError if the length of the resulting string doesn't fit into a long" do
|
||||
-> { @object.call("abc", (2 ** 63) - 1) }.should raise_error(ArgumentError)
|
||||
end
|
||||
|
|
Загрузка…
Ссылка в новой задаче