diff options
Diffstat (limited to 'src/tools/spectest-interp.cc')
-rw-r--r-- | src/tools/spectest-interp.cc | 81 |
1 files changed, 80 insertions, 1 deletions
diff --git a/src/tools/spectest-interp.cc b/src/tools/spectest-interp.cc index 618bd018..d5b11b76 100644 --- a/src/tools/spectest-interp.cc +++ b/src/tools/spectest-interp.cc @@ -167,6 +167,12 @@ class AssertReturnCommand : public CommandMixin<CommandType::AssertReturn> { TypedValues expected; }; +class AssertReturnFuncCommand + : public CommandMixin<CommandType::AssertReturnFunc> { + public: + Action action; +}; + template <CommandType TypeEnum> class AssertTrapCommandBase : public CommandMixin<TypeEnum> { public: @@ -447,6 +453,12 @@ wabt::Result JSONParser::ParseTypeObject(Type* out_type) { } else if (type_str == "v128") { *out_type = Type::V128; return wabt::Result::Ok; + } else if (type_str == "funcref") { + *out_type = Type::Funcref; + return wabt::Result::Ok; + } else if (type_str == "anyref") { + *out_type = Type::Anyref; + return wabt::Result::Ok; } else { PrintError("unknown type: \"%s\"", type_str.c_str()); return wabt::Result::Error; @@ -515,8 +527,26 @@ wabt::Result JSONParser::ParseConst(TypedValue* out_value) { out_value->type = Type::V128; out_value->value.vec128 = value_bits; return wabt::Result::Ok; + } else if (type_str == "nullref") { + out_value->type = Type::Nullref; + out_value->value.ref = {RefType::Null, 0}; + return wabt::Result::Ok; + } else if (type_str == "hostref") { + uint32_t value; + CHECK_RESULT( + ParseInt32(value_start, value_end, &value, ParseIntType::UnsignedOnly)); + out_value->type = Type::Hostref; + out_value->value.ref = {RefType::Host, value}; + return wabt::Result::Ok; + } else if (type_str == "funcref") { + uint32_t value; + CHECK_RESULT( + ParseInt32(value_start, value_end, &value, ParseIntType::UnsignedOnly)); + out_value->type = Type::Funcref; + out_value->value.ref = {RefType::Func, value}; + return wabt::Result::Ok; } else { - PrintError("unknown type: \"%s\"", type_str.c_str()); + PrintError("unknown concrete type: \"%s\"", type_str.c_str()); return wabt::Result::Error; } } @@ -711,6 +741,13 @@ wabt::Result JSONParser::ParseCommand(CommandPtr* out_command) { EXPECT_KEY("expected"); CHECK_RESULT(ParseConstVector(&command->expected)); *out_command = std::move(command); + } else if (Match("\"assert_return_func\"")) { + auto command = MakeUnique<AssertReturnFuncCommand>(); + EXPECT(","); + CHECK_RESULT(ParseLine(&command->line)); + EXPECT(","); + CHECK_RESULT(ParseAction(&command->action)); + *out_command = std::move(command); } else if (Match("\"assert_return_canonical_nan\"")) { auto command = MakeUnique<AssertReturnCanonicalNanCommand>(); EXPECT(","); @@ -804,6 +841,7 @@ class CommandRunner { wabt::Result OnAssertUninstantiableCommand( const AssertUninstantiableCommand*); wabt::Result OnAssertReturnCommand(const AssertReturnCommand*); + wabt::Result OnAssertReturnFuncCommand(const AssertReturnFuncCommand*); template <typename NanCommand> wabt::Result OnAssertReturnNanCommand(const NanCommand*); wabt::Result OnAssertTrapCommand(const AssertTrapCommand*); @@ -906,6 +944,11 @@ wabt::Result CommandRunner::Run(const Script& script) { OnAssertReturnCommand(cast<AssertReturnCommand>(command.get()))); break; + case CommandType::AssertReturnFunc: + TallyCommand( + OnAssertReturnFuncCommand(cast<AssertReturnFuncCommand>(command.get()))); + break; + case CommandType::AssertReturnCanonicalNan: TallyCommand(OnAssertReturnNanCommand( cast<AssertReturnCanonicalNanCommand>(command.get()))); @@ -941,6 +984,7 @@ static ExecResult GetGlobalExportByName(Environment* env, string_view name) { interp::Export* export_ = module->GetExport(name); if (!export_) { + printf("xxx\n"); return ExecResult(interp::Result::UnknownExport); } if (export_->kind != ExternalKind::Global) { @@ -1221,11 +1265,46 @@ static bool TypedValuesAreEqual(const TypedValue& tv1, const TypedValue& tv2) { return tv1.value.f64_bits == tv2.value.f64_bits; case Type::V128: return tv1.value.vec128 == tv2.value.vec128; + case Type::Nullref: + return true; + case Type::Funcref: + return tv1.value.ref.index == tv2.value.ref.index; + case Type::Hostref: + return tv1.value.ref.index == tv2.value.ref.index; default: WABT_UNREACHABLE; } } +wabt::Result CommandRunner::OnAssertReturnFuncCommand( + const AssertReturnFuncCommand* command) { + ExecResult exec_result = + RunAction(command->line, &command->action, RunVerbosity::Quiet); + + if (exec_result.result != interp::Result::Ok) { + PrintError(command->line, "unexpected trap: %s", + ResultToString(exec_result.result)); + return wabt::Result::Error; + } + + if (exec_result.values.size() != 1) { + PrintError(command->line, + "expected 1 result in assert_return_func, got %" PRIzd, + exec_result.values.size()); + return wabt::Result::Error; + } + + const TypedValue& result = exec_result.values[0]; + if (result.type != Type::Funcref) { + PrintError(command->line, + "mismatch in result of assert_return_func: expected %s, got %s", + GetTypeName(Type::Funcref), TypedValueToString(result).c_str()); + return wabt::Result::Error; + } + + return wabt::Result::Ok; +} + wabt::Result CommandRunner::OnAssertReturnCommand( const AssertReturnCommand* command) { ExecResult exec_result = |