Skip to content

Commit 1b1f73e

Browse files
committed
test: Fix comparing of floating point results in spectest runner
1 parent ce48ea2 commit 1b1f73e

1 file changed

Lines changed: 45 additions & 13 deletions

File tree

test/spectests/spectests.cpp

Lines changed: 45 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,22 @@ fizzy::bytes load_wasm_file(const fs::path& json_file_path, std::string_view fil
5858
std::istreambuf_iterator<char>{wasm_file}, std::istreambuf_iterator<char>{});
5959
}
6060

61+
bool float_values_equal(fizzy::Value value1, fizzy::Value value2) noexcept
62+
{
63+
if (std::isnan(value1.as<float>()))
64+
return value1.as<uint32_t>() == value2.as<uint32_t>(); // compare binary representations
65+
else
66+
return value1.as<float>() == value2.as<float>();
67+
}
68+
69+
bool double_values_equal(fizzy::Value value1, fizzy::Value value2) noexcept
70+
{
71+
if (std::isnan(value1.as<double>()))
72+
return value1.i64 == value2.i64; // compare binary representations
73+
else
74+
return value1.as<double>() == value2.as<double>();
75+
}
76+
6177
struct test_settings
6278
{
6379
bool skip_validation = false;
@@ -402,15 +418,19 @@ class test_runner
402418
return it_instance->second.get();
403419
}
404420

405-
std::optional<fizzy::Value> read_value(const json& v)
421+
std::optional<std::string> read_value_type(const json& v)
406422
{
407-
const auto arg_type = v.at("type").get<std::string>();
408-
if (arg_type != "i32" && arg_type != "i64" && arg_type != "f32" && arg_type != "f64")
423+
const auto type = v.at("type").get<std::string>();
424+
if (type != "i32" && type != "i64" && type != "f32" && type != "f64")
409425
{
410-
skip("Unsupported value type '" + arg_type + "'.");
426+
skip("Unsupported value type '" + type + "'.");
411427
return std::nullopt;
412428
}
429+
return type;
430+
}
413431

432+
static fizzy::Value read_value(const json& v)
433+
{
414434
// Values of all types are serialized to JSON as integers.
415435
// Value type will handle correct conversions.
416436
return std::stoull(v.at("value").get<std::string>());
@@ -433,11 +453,10 @@ class test_runner
433453
std::vector<fizzy::Value> args;
434454
for (const auto& arg : action.at("args"))
435455
{
436-
const auto arg_value = read_value(arg);
437-
if (!arg_value.has_value())
456+
if (!read_value_type(arg))
438457
return std::nullopt;
439458

440-
args.push_back(*arg_value);
459+
args.push_back(read_value(arg));
441460
}
442461

443462
try
@@ -453,16 +472,29 @@ class test_runner
453472

454473
bool check_result(fizzy::Value actual_value, const json& expected)
455474
{
456-
const auto expected_value = read_value(expected);
457-
if (!expected_value.has_value())
475+
const auto value_type = read_value_type(expected);
476+
if (!value_type.has_value())
458477
return false;
459478

460-
if (*expected_value != actual_value)
479+
const auto expected_value = read_value(expected);
480+
481+
bool is_equal = false;
482+
if (value_type == "i32" || value_type == "i64")
483+
is_equal = expected_value.i64 == actual_value.i64;
484+
else if (value_type == "f32")
485+
is_equal = float_values_equal(expected_value, actual_value);
486+
else if (value_type == "f64")
487+
is_equal = double_values_equal(expected_value, actual_value);
488+
else
489+
assert(false);
490+
491+
if (!is_equal)
461492
{
462493
std::stringstream message;
463-
message << "Incorrect returned value. Expected: " << *expected_value << " (0x"
464-
<< std::hex << *expected_value << ") Actual: " << std::dec << actual_value
465-
<< " (0x" << std::hex << actual_value << std::dec << ")";
494+
message << "Incorrect returned value. Expected: " << expected_value.i64 << " (0x"
495+
<< std::hex << expected_value.i64 << ") Actual: " << std::dec
496+
<< actual_value.i64 << " (0x" << std::hex << actual_value.i64 << std::dec
497+
<< ")";
466498
fail(message.str());
467499
return false;
468500
}

0 commit comments

Comments
 (0)