@@ -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+
6177struct 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