Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 15 additions & 30 deletions ext/digest/blake3/extconf.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def blake3_disable(macro)
# Probe used to confirm the compiler both accepts +flag+ and can compile the
# intrinsics the backend relies on.
def blake3_have_isa?(name, flag, snippet)
checking_for("#{name} intrinsics (#{flag})") do
checking_for("#{name} intrinsics" + (flag ? " (#{flag})" : "")) do
try_compile(snippet, flag)
end
end
Expand All @@ -40,27 +40,29 @@ def blake3_have_isa?(name, flag, snippet)
when /\A(x86_64|amd64|x64)\z/i
# Try to detect which SIMD features this x86 machine and compiler has
x86_backends = [
["blake3_sse2", "SSE2", "-msse2",
["blake3_sse2", "SSE2", ["-msse2", "-arch:SSE2"],
"#include <immintrin.h>\nint main(void){ volatile __m128i x = _mm_setzero_si128(); (void)x; return 0; }\n",
"BLAKE3_NO_SSE2"],
["blake3_sse41", "SSE4.1", "-msse4.1",
["blake3_sse41", "SSE4.1", ["-msse4.1", "-arch:AVX"],
"#include <immintrin.h>\nint main(void){ volatile __m128i x = _mm_setzero_si128(); return _mm_testz_si128(x, x); }\n",
"BLAKE3_NO_SSE41"],
["blake3_avx2", "AVX2", "-mavx2",
["blake3_avx2", "AVX2", ["-mavx2", "-arch:AVX2"],
"#include <immintrin.h>\nint main(void){ volatile __m256i x = _mm256_setzero_si256(); (void)x; return 0; }\n",
"BLAKE3_NO_AVX2"],
["blake3_avx512", "AVX-512", "-mavx512f -mavx512vl",
["blake3_avx512", "AVX-512", ["-mavx512f -mavx512vl", "-arch:AVX512"],
"#include <immintrin.h>\nint main(void){ volatile __m512i x = _mm512_setzero_si512(); (void)x; return 0; }\n",
"BLAKE3_NO_AVX512"],
]

x86_backends.each do |obj, name, flag, snippet, no_macro|
if blake3_have_isa?(name, flag, snippet)
objs << obj
simd_cflags[obj] = flag
else
x86_backends.each do |obj, name, flags, snippet, no_macro|
[nil, *flags].any? do |flag|
if blake3_have_isa?(name, flag, snippet)
objs << obj
simd_cflags[obj] = flag
true
end
end or
blake3_disable(no_macro)
end
end
when /\A(aarch64|arm64)\z/i
# NEON is part of the AArch64 baseline, so no runtime detection or special
Expand All @@ -82,26 +84,9 @@ def blake3_have_isa?(name, flag, snippet)

have_header("sys/cdefs.h")

checking_for("C11 atomics") do
ok = try_compile(<<~C)
static _Atomic int atomic_int = 0;
static int t(void) {return atomic_int;}
#{MAIN_DOES_NOTHING 't'}
C
unless ok
$defs << "-DBLAKE3_ATOMICS=0"
end
ok
end

$preload = %w[digest]

create_makefile("digest/blake3") do |mk|
mk.grep(/^CPPFLAGS *=/) {|m|
m.sub!(/(?=-DRUBY_EXTCONF_H)/) {[$defs, ''].join(' ')}
}
mk
end
create_makefile("digest/blake3")

# Emit one explicit compile rule per SIMD backend so each gets its own
# instruction-set flag. mkmf's implicit .c.o rule compiles every object with
Expand All @@ -116,7 +101,7 @@ def blake3_have_isa?(name, flag, snippet)
simd_cflags.each do |obj, flag|
target = "#{obj}.#{$OBJEXT}"
mf.puts "#{target}: $(srcdir)/#{obj}.c"
mf.puts "\t$(ECHO) compiling $(<)"
mf.puts "\t$(ECHO) compiling #{obj}.c"
mf.puts "\t$(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) #{flag} $(COUTFLAG)$@ -c $(CSRCFLAG)$(srcdir)/#{obj}.c"
end
end
Expand Down
26 changes: 13 additions & 13 deletions test/json/json_common_interface_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -158,16 +158,16 @@ def test_load_with_proc

def test_load_with_options
json = '{ "foo": NaN }'
assert JSON.load(json, nil, :allow_nan => true)['foo'].nan?
assert JSON.load(json, :allow_nan => true)['foo'].nan?
assert JSON.load(json, nil, allow_nan: true)['foo'].nan?
assert JSON.load(json, allow_nan: true)['foo'].nan?
end

def test_load_null
assert_equal nil, JSON.load(nil, nil, :allow_blank => true)
assert_raise(TypeError) { JSON.load(nil, nil, :allow_blank => false) }
assert_raise(JSON::ParserError) { JSON.load('', nil, :allow_blank => false) }
assert_raise(TypeError) { JSON.load([], nil, :allow_blank => true) }
assert_raise(TypeError) { JSON.load({}, nil, :allow_blank => true) }
assert_equal nil, JSON.load(nil, nil, allow_blank: true)
assert_raise(TypeError) { JSON.load(nil, nil, allow_blank: false) }
assert_raise(JSON::ParserError) { JSON.load('', nil, allow_blank: false) }
assert_raise(TypeError) { JSON.load([], nil, allow_blank: true) }
assert_raise(TypeError) { JSON.load({}, nil, allow_blank: true) }
end

def test_unsafe_load
Expand Down Expand Up @@ -240,16 +240,16 @@ def test_unsafe_load_default_options

def test_unsafe_load_with_options
nan_json = '{ "foo": NaN }'
assert_raise(JSON::ParserError) { JSON.unsafe_load(nan_json, nil, :allow_nan => false)['foo'].nan? }
assert_raise(JSON::ParserError) { JSON.unsafe_load(nan_json, nil, allow_nan: false)['foo'].nan? }
# make sure it still uses the defaults when something is provided
assert JSON.unsafe_load(nan_json, nil, :allow_blank => true)['foo'].nan?
assert JSON.unsafe_load(nan_json, :allow_nan => true)['foo'].nan?
assert JSON.unsafe_load(nan_json, nil, allow_blank: true)['foo'].nan?
assert JSON.unsafe_load(nan_json, allow_nan: true)['foo'].nan?
end

def test_unsafe_load_null
assert_equal nil, JSON.unsafe_load(nil, nil, :allow_blank => true)
assert_raise(TypeError) { JSON.unsafe_load(nil, nil, :allow_blank => false) }
assert_raise(JSON::ParserError) { JSON.unsafe_load('', nil, :allow_blank => false) }
assert_equal nil, JSON.unsafe_load(nil, nil, allow_blank: true)
assert_raise(TypeError) { JSON.unsafe_load(nil, nil, allow_blank: false) }
assert_raise(JSON::ParserError) { JSON.unsafe_load('', nil, allow_blank: false) }
end

def test_dump
Expand Down
110 changes: 55 additions & 55 deletions test/json/json_generator_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ def test_generate_pretty
end

def test_generate_pretty_custom
state = State.new(:space_before => "<psb>", :space => "<ps>", :indent => "<pi>", :object_nl => "\n<po_nl>\n", :array_nl => "<pa_nl>")
state = State.new(space_before: "<psb>", space: "<ps>", indent: "<pi>", object_nl: "\n<po_nl>\n", array_nl: "<pa_nl>")
json = pretty_generate({1=>{}, 2=>['a','b'], 3=>4}, state)
assert_equal(<<~'JSON'.chomp, json)
{
Expand Down Expand Up @@ -244,7 +244,7 @@ def test_generate_sort_keys_with_proc
end

def test_generate_custom
state = State.new(:space_before => " ", :space => " ", :indent => "<i>", :object_nl => "\n", :array_nl => "<a_nl>")
state = State.new(space_before: " ", space: " ", indent: "<i>", object_nl: "\n", array_nl: "<a_nl>")
json = generate({1=>{2=>3,4=>[5,6]}}, state)
assert_equal(<<~'JSON'.chomp, json)
{
Expand Down Expand Up @@ -307,62 +307,62 @@ def test_falsy_state
def test_state_defaults
state = JSON::State.new
assert_equal({
:allow_duplicate_key => false,
:allow_nan => false,
:array_nl => "",
:as_json => false,
:ascii_only => false,
:buffer_initial_length => 1024,
:depth => 0,
:script_safe => false,
:strict => false,
:indent => "",
:max_nesting => 100,
:object_nl => "",
:space => "",
:space_before => "",
:sort_keys => false,
allow_duplicate_key: false,
allow_nan: false,
array_nl: "",
as_json: false,
ascii_only: false,
buffer_initial_length: 1024,
depth: 0,
script_safe: false,
strict: false,
indent: "",
max_nesting: 100,
object_nl: "",
space: "",
space_before: "",
sort_keys: false,
}.sort_by { |n,| n.to_s }.to_h, state.to_h.sort_by { |n,| n.to_s }.to_h)

state = JSON::State.new(allow_duplicate_key: true)
assert_equal({
:allow_duplicate_key => true,
:allow_nan => false,
:array_nl => "",
:as_json => false,
:ascii_only => false,
:buffer_initial_length => 1024,
:depth => 0,
:script_safe => false,
:strict => false,
:indent => "",
:max_nesting => 100,
:object_nl => "",
:space => "",
:space_before => "",
:sort_keys => false,
allow_duplicate_key: true,
allow_nan: false,
array_nl: "",
as_json: false,
ascii_only: false,
buffer_initial_length: 1024,
depth: 0,
script_safe: false,
strict: false,
indent: "",
max_nesting: 100,
object_nl: "",
space: "",
space_before: "",
sort_keys: false,
}.sort_by { |n,| n.to_s }, state.to_h.sort_by { |n,| n.to_s })
end

def test_allow_nan
error = assert_raise(GeneratorError) { generate([JSON::NaN]) }
assert_same JSON::NaN, error.invalid_object
assert_equal '[NaN]', generate([JSON::NaN], :allow_nan => true)
assert_equal '[NaN]', generate([JSON::NaN], allow_nan: true)
assert_raise(GeneratorError) { generate([JSON::NaN]) }
assert_raise(GeneratorError) { pretty_generate([JSON::NaN]) }
assert_equal "[\n NaN\n]", pretty_generate([JSON::NaN], :allow_nan => true)
assert_equal "[\n NaN\n]", pretty_generate([JSON::NaN], allow_nan: true)
error = assert_raise(GeneratorError) { generate([JSON::Infinity]) }
assert_same JSON::Infinity, error.invalid_object
assert_equal '[Infinity]', generate([JSON::Infinity], :allow_nan => true)
assert_equal '[Infinity]', generate([JSON::Infinity], allow_nan: true)
assert_raise(GeneratorError) { generate([JSON::Infinity]) }
assert_raise(GeneratorError) { pretty_generate([JSON::Infinity]) }
assert_equal "[\n Infinity\n]", pretty_generate([JSON::Infinity], :allow_nan => true)
assert_equal "[\n Infinity\n]", pretty_generate([JSON::Infinity], allow_nan: true)
error = assert_raise(GeneratorError) { generate([JSON::MinusInfinity]) }
assert_same JSON::MinusInfinity, error.invalid_object
assert_equal '[-Infinity]', generate([JSON::MinusInfinity], :allow_nan => true)
assert_equal '[-Infinity]', generate([JSON::MinusInfinity], allow_nan: true)
assert_raise(GeneratorError) { generate([JSON::MinusInfinity]) }
assert_raise(GeneratorError) { pretty_generate([JSON::MinusInfinity]) }
assert_equal "[\n -Infinity\n]", pretty_generate([JSON::MinusInfinity], :allow_nan => true)
assert_equal "[\n -Infinity\n]", pretty_generate([JSON::MinusInfinity], allow_nan: true)
end

# An object that changes state.depth when it receives to_json(state)
Expand Down Expand Up @@ -489,11 +489,11 @@ def test_gc

def test_configure_using_configure_and_merge
numbered_state = {
:indent => "1",
:space => '2',
:space_before => '3',
:object_nl => '4',
:array_nl => '5'
indent: "1",
space: '2',
space_before: '3',
object_nl: '4',
array_nl: '5'
}
state1 = JSON.state.new
state1.merge(numbered_state)
Expand All @@ -513,7 +513,7 @@ def test_configure_using_configure_and_merge

def test_configure_hash_conversion
state = JSON.state.new
state.configure(:indent => '1')
state.configure(indent: '1')
assert_equal '1', state.indent
state = JSON.state.new
foo = 'foo'.dup
Expand Down Expand Up @@ -595,14 +595,14 @@ def test_nesting
too_deep = '[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]'
too_deep_ary = eval too_deep
assert_raise(JSON::NestingError) { generate too_deep_ary }
assert_raise(JSON::NestingError) { generate too_deep_ary, :max_nesting => 100 }
ok = generate too_deep_ary, :max_nesting => 101
assert_raise(JSON::NestingError) { generate too_deep_ary, max_nesting: 100 }
ok = generate too_deep_ary, max_nesting: 101
assert_equal too_deep, ok
ok = generate too_deep_ary, :max_nesting => nil
ok = generate too_deep_ary, max_nesting: nil
assert_equal too_deep, ok
ok = generate too_deep_ary, :max_nesting => false
ok = generate too_deep_ary, max_nesting: false
assert_equal too_deep, ok
ok = generate too_deep_ary, :max_nesting => 0
ok = generate too_deep_ary, max_nesting: 0
assert_equal too_deep, ok

assert_raise(TypeError) { generate too_deep_ary, max_nesting: "garbage" }
Expand Down Expand Up @@ -631,27 +631,27 @@ def test_backslash
#
data = [ '/' ]
json = '["\/"]'
assert_equal json, generate(data, :script_safe => true)
assert_equal json, generate(data, script_safe: true)
#
data = [ '///////////' ]
json = '["\/\/\/\/\/\/\/\/\/\/\/"]'
assert_equal json, generate(data, :script_safe => true)
assert_equal json, generate(data, script_safe: true)
#
data = [ '///////////////////////////////////////////////////////' ]
json = '["\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/"]'
assert_equal json, generate(data, :script_safe => true)
assert_equal json, generate(data, script_safe: true)
#
data = [ "\u2028\u2029" ]
json = '["\u2028\u2029"]'
assert_equal json, generate(data, :script_safe => true)
assert_equal json, generate(data, script_safe: true)
#
data = [ "ABC \u2028 DEF \u2029 GHI" ]
json = '["ABC \u2028 DEF \u2029 GHI"]'
assert_equal json, generate(data, :script_safe => true)
assert_equal json, generate(data, script_safe: true)
#
data = [ "/\u2028\u2029" ]
json = '["\/\u2028\u2029"]'
assert_equal json, generate(data, :script_safe => true)
assert_equal json, generate(data, script_safe: true)
#
data = ['"']
json = '["\""]'
Expand Down
Loading