summaryrefslogtreecommitdiff
path: root/src/tools/spectest-interp.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/spectest-interp.cc')
-rw-r--r--src/tools/spectest-interp.cc220
1 files changed, 42 insertions, 178 deletions
diff --git a/src/tools/spectest-interp.cc b/src/tools/spectest-interp.cc
index 24253c9d..e7a7c1ba 100644
--- a/src/tools/spectest-interp.cc
+++ b/src/tools/spectest-interp.cc
@@ -40,14 +40,9 @@
using namespace wabt;
using namespace wabt::interpreter;
-#define V(name, str) str,
-static const char* s_trap_strings[] = {FOREACH_INTERPRETER_RESULT(V)};
-#undef V
-
static int s_verbose;
static const char* s_infile;
static Thread::Options s_thread_options;
-static bool s_trace;
static Features s_features;
static std::unique_ptr<FileStream> s_log_stream;
@@ -87,7 +82,9 @@ static void ParseOptions(int argc, char** argv) {
// TODO(binji): validate.
s_thread_options.call_stack_size = atoi(argument.c_str());
});
- parser.AddOption('t', "trace", "Trace execution", []() { s_trace = true; });
+ parser.AddOption('t', "trace", "Trace execution", []() {
+ s_thread_options.trace_stream = s_stdout_stream.get();
+ });
parser.AddArgument("filename", OptionParser::ArgumentCount::One,
[](const char* argument) { s_infile = argument; });
@@ -116,134 +113,10 @@ static string_view GetDirname(string_view path) {
return path.substr(0, std::max(last_slash, last_backslash));
}
-/* Not sure, but 100 chars is probably safe */
-#define MAX_TYPED_VALUE_CHARS 100
-
-static void SPrintTypedValue(char* buffer, size_t size, const TypedValue* tv) {
- switch (tv->type) {
- case Type::I32:
- snprintf(buffer, size, "i32:%u", tv->value.i32);
- break;
-
- case Type::I64:
- snprintf(buffer, size, "i64:%" PRIu64, tv->value.i64);
- break;
-
- case Type::F32: {
- float value;
- memcpy(&value, &tv->value.f32_bits, sizeof(float));
- snprintf(buffer, size, "f32:%f", value);
- break;
- }
-
- case Type::F64: {
- double value;
- memcpy(&value, &tv->value.f64_bits, sizeof(double));
- snprintf(buffer, size, "f64:%f", value);
- break;
- }
-
- default:
- WABT_UNREACHABLE;
- }
-}
-
-static void PrintTypedValue(const TypedValue* tv) {
- char buffer[MAX_TYPED_VALUE_CHARS];
- SPrintTypedValue(buffer, sizeof(buffer), tv);
- printf("%s", buffer);
-}
-
-static void PrintTypedValueVector(const std::vector<TypedValue>& values) {
- for (size_t i = 0; i < values.size(); ++i) {
- PrintTypedValue(&values[i]);
- if (i != values.size() - 1)
- printf(", ");
- }
-}
-
-static void PrintInterpreterResult(const char* desc,
- interpreter::Result iresult) {
- printf("%s: %s\n", desc, s_trap_strings[static_cast<size_t>(iresult)]);
-}
-
-static void PrintCall(string_view module_name,
- string_view func_name,
- const std::vector<TypedValue>& args,
- const std::vector<TypedValue>& results,
- interpreter::Result iresult) {
- if (!module_name.empty())
- printf(PRIstringview ".", WABT_PRINTF_STRING_VIEW_ARG(module_name));
- printf(PRIstringview "(", WABT_PRINTF_STRING_VIEW_ARG(func_name));
- PrintTypedValueVector(args);
- printf(") =>");
- if (iresult == interpreter::Result::Ok) {
- if (results.size() > 0) {
- printf(" ");
- PrintTypedValueVector(results);
- }
- printf("\n");
- } else {
- PrintInterpreterResult(" error", iresult);
- }
-}
-
-static interpreter::Result RunFunction(Thread* thread,
- Index func_index,
- const std::vector<TypedValue>& args,
- std::vector<TypedValue>* out_results) {
- return s_trace ? thread->TraceFunction(func_index, s_stdout_stream.get(),
- args, out_results)
- : thread->RunFunction(func_index, args, out_results);
-}
-
-static interpreter::Result RunStartFunction(Thread* thread,
- DefinedModule* module) {
- if (module->start_func_index == kInvalidIndex)
- return interpreter::Result::Ok;
-
- if (s_trace)
- printf(">>> running start function:\n");
- std::vector<TypedValue> args;
- std::vector<TypedValue> results;
- interpreter::Result iresult =
- RunFunction(thread, module->start_func_index, args, &results);
- assert(results.size() == 0);
- return iresult;
-}
-
-static interpreter::Result RunExport(Thread* thread,
- const interpreter::Export* export_,
- const std::vector<TypedValue>& args,
- std::vector<TypedValue>* out_results) {
- if (s_trace) {
- printf(">>> running export \"" PRIstringview "\":\n",
- WABT_PRINTF_STRING_VIEW_ARG(export_->name));
- }
-
- assert(export_->kind == ExternalKind::Func);
- return RunFunction(thread, export_->index, args, out_results);
-}
-
-static interpreter::Result RunExportByName(Thread* thread,
- interpreter::Module* module,
- string_view name,
- const std::vector<TypedValue>& args,
- std::vector<TypedValue>* out_results,
- RunVerbosity verbose) {
- interpreter::Export* export_ = module->GetExport(name);
- if (!export_)
- return interpreter::Result::UnknownExport;
- if (export_->kind != ExternalKind::Func)
- return interpreter::Result::ExportKindMismatch;
- return RunExport(thread, export_, args, out_results);
-}
-
-static interpreter::Result GetGlobalExportByName(
- Thread* thread,
- interpreter::Module* module,
- string_view name,
- std::vector<TypedValue>* out_results) {
+static interpreter::Result GetGlobalExportByName(Thread* thread,
+ interpreter::Module* module,
+ string_view name,
+ TypedValues* out_results) {
interpreter::Export* export_ = module->GetExport(name);
if (!export_)
return interpreter::Result::UnknownExport;
@@ -294,12 +167,12 @@ static interpreter::Result DefaultHostCallback(
for (Index i = 0; i < num_results; ++i)
out_results[i].type = sig->result_types[i];
- std::vector<TypedValue> vec_args(args, args + num_args);
- std::vector<TypedValue> vec_results(out_results, out_results + num_results);
+ TypedValues vec_args(args, args + num_args);
+ TypedValues vec_results(out_results, out_results + num_results);
printf("called host ");
- PrintCall(func->module_name, func->field_name, vec_args, vec_results,
- interpreter::Result::Ok);
+ WriteCall(s_stdout_stream.get(), func->module_name, func->field_name,
+ vec_args, vec_results, interpreter::Result::Ok);
return interpreter::Result::Ok;
}
@@ -415,7 +288,7 @@ struct Action {
::ActionType type = ::ActionType::Invoke;
std::string module_name;
std::string field_name;
- std::vector<TypedValue> args;
+ TypedValues args;
};
// An extremely simple JSON parser that only knows how to parse the expected
@@ -448,7 +321,7 @@ class SpecJSONParser {
wabt::Result ParseTypeObject(Type* out_type);
wabt::Result ParseTypeVector(TypeVector* out_types);
wabt::Result ParseConst(TypedValue* out_value);
- wabt::Result ParseConstVector(std::vector<TypedValue>* out_values);
+ wabt::Result ParseConstVector(TypedValues* out_values);
wabt::Result ParseAction(::Action* out_action);
wabt::Result ParseModuleType(ModuleType* out_type);
@@ -457,7 +330,7 @@ class SpecJSONParser {
wabt::Result OnModuleCommand(string_view filename, string_view name);
wabt::Result RunAction(::Action* action,
interpreter::Result* out_iresult,
- std::vector<TypedValue>* out_results,
+ TypedValues* out_results,
RunVerbosity verbose);
wabt::Result OnActionCommand(::Action* action);
wabt::Result ReadInvalidTextModule(const char* module_filename,
@@ -481,7 +354,7 @@ class SpecJSONParser {
string_view text,
ModuleType module_type);
wabt::Result OnAssertReturnCommand(::Action* action,
- const std::vector<TypedValue>& expected);
+ const TypedValues& expected);
wabt::Result OnAssertReturnNanCommand(::Action* action, bool canonical);
wabt::Result OnAssertTrapCommand(::Action* action, string_view text);
wabt::Result OnAssertExhaustionCommand(::Action* action);
@@ -788,8 +661,7 @@ wabt::Result SpecJSONParser::ParseConst(TypedValue* out_value) {
}
}
-wabt::Result SpecJSONParser::ParseConstVector(
- std::vector<TypedValue>* out_values) {
+wabt::Result SpecJSONParser::ParseConstVector(TypedValues* out_values) {
out_values->clear();
EXPECT("[");
bool first = true;
@@ -878,10 +750,10 @@ wabt::Result SpecJSONParser::OnModuleCommand(string_view filename,
return wabt::Result::Error;
}
- interpreter::Result iresult = RunStartFunction(&thread_, last_module_);
+ interpreter::Result iresult = thread_.RunStartFunction(last_module_);
if (iresult != interpreter::Result::Ok) {
env_.ResetToMarkPoint(mark);
- PrintInterpreterResult("error running start function", iresult);
+ WriteResult(s_stdout_stream.get(), "error running start function", iresult);
return wabt::Result::Error;
}
@@ -895,7 +767,7 @@ wabt::Result SpecJSONParser::OnModuleCommand(string_view filename,
wabt::Result SpecJSONParser::RunAction(::Action* action,
interpreter::Result* out_iresult,
- std::vector<TypedValue>* out_results,
+ TypedValues* out_results,
RunVerbosity verbose) {
out_results->clear();
@@ -909,11 +781,11 @@ wabt::Result SpecJSONParser::RunAction(::Action* action,
switch (action->type) {
case ::ActionType::Invoke:
- *out_iresult = RunExportByName(&thread_, module, action->field_name,
- action->args, out_results, verbose);
+ *out_iresult = thread_.RunExportByName(module, action->field_name,
+ action->args, out_results);
if (verbose == RunVerbosity::Verbose) {
- PrintCall(string_view(), action->field_name, action->args, *out_results,
- *out_iresult);
+ WriteCall(s_stdout_stream.get(), string_view(), action->field_name,
+ action->args, *out_results, *out_iresult);
}
return wabt::Result::Ok;
@@ -931,7 +803,7 @@ wabt::Result SpecJSONParser::RunAction(::Action* action,
}
wabt::Result SpecJSONParser::OnActionCommand(::Action* action) {
- std::vector<TypedValue> results;
+ TypedValues results;
interpreter::Result iresult;
total_++;
@@ -941,8 +813,7 @@ wabt::Result SpecJSONParser::OnActionCommand(::Action* action) {
if (iresult == interpreter::Result::Ok) {
passed_++;
} else {
- PrintCommandError("unexpected trap: %s",
- s_trap_strings[static_cast<size_t>(iresult)]);
+ PrintCommandError("unexpected trap: %s", ResultToString(iresult));
result = wabt::Result::Error;
}
}
@@ -1090,7 +961,7 @@ wabt::Result SpecJSONParser::OnAssertUninstantiableCommand(
ReadModule(path.c_str(), &env_, &error_handler, &module);
if (Succeeded(result)) {
- interpreter::Result iresult = RunStartFunction(&thread_, module);
+ interpreter::Result iresult = thread_.RunStartFunction(module);
if (iresult == interpreter::Result::Ok) {
PrintCommandError("expected error running start function: \"%s\"",
path.c_str());
@@ -1128,8 +999,8 @@ static bool TypedValuesAreEqual(const TypedValue* tv1, const TypedValue* tv2) {
wabt::Result SpecJSONParser::OnAssertReturnCommand(
::Action* action,
- const std::vector<TypedValue>& expected) {
- std::vector<TypedValue> results;
+ const TypedValues& expected) {
+ TypedValues results;
interpreter::Result iresult;
total_++;
@@ -1143,13 +1014,10 @@ wabt::Result SpecJSONParser::OnAssertReturnCommand(
const TypedValue* expected_tv = &expected[i];
const TypedValue* actual_tv = &results[i];
if (!TypedValuesAreEqual(expected_tv, actual_tv)) {
- char expected_str[MAX_TYPED_VALUE_CHARS];
- char actual_str[MAX_TYPED_VALUE_CHARS];
- SPrintTypedValue(expected_str, sizeof(expected_str), expected_tv);
- SPrintTypedValue(actual_str, sizeof(actual_str), actual_tv);
PrintCommandError("mismatch in result %" PRIzd
" of assert_return: expected %s, got %s",
- i, expected_str, actual_str);
+ i, TypedValueToString(*expected_tv).c_str(),
+ TypedValueToString(*actual_tv).c_str());
result = wabt::Result::Error;
}
}
@@ -1161,8 +1029,7 @@ wabt::Result SpecJSONParser::OnAssertReturnCommand(
result = wabt::Result::Error;
}
} else {
- PrintCommandError("unexpected trap: %s",
- s_trap_strings[static_cast<size_t>(iresult)]);
+ PrintCommandError("unexpected trap: %s", ResultToString(iresult));
result = wabt::Result::Error;
}
}
@@ -1175,7 +1042,7 @@ wabt::Result SpecJSONParser::OnAssertReturnCommand(
wabt::Result SpecJSONParser::OnAssertReturnNanCommand(::Action* action,
bool canonical) {
- std::vector<TypedValue> results;
+ TypedValues results;
interpreter::Result iresult;
total_++;
@@ -1194,9 +1061,8 @@ wabt::Result SpecJSONParser::OnAssertReturnNanCommand(::Action* action,
bool is_nan = canonical ? IsCanonicalNan(actual.value.f32_bits)
: IsArithmeticNan(actual.value.f32_bits);
if (!is_nan) {
- char actual_str[MAX_TYPED_VALUE_CHARS];
- SPrintTypedValue(actual_str, sizeof(actual_str), &actual);
- PrintCommandError("expected result to be nan, got %s", actual_str);
+ PrintCommandError("expected result to be nan, got %s",
+ TypedValueToString(actual).c_str());
result = wabt::Result::Error;
}
break;
@@ -1206,9 +1072,8 @@ wabt::Result SpecJSONParser::OnAssertReturnNanCommand(::Action* action,
bool is_nan = canonical ? IsCanonicalNan(actual.value.f64_bits)
: IsArithmeticNan(actual.value.f64_bits);
if (!is_nan) {
- char actual_str[MAX_TYPED_VALUE_CHARS];
- SPrintTypedValue(actual_str, sizeof(actual_str), &actual);
- PrintCommandError("expected result to be nan, got %s", actual_str);
+ PrintCommandError("expected result to be nan, got %s",
+ TypedValueToString(actual).c_str());
result = wabt::Result::Error;
}
break;
@@ -1221,8 +1086,7 @@ wabt::Result SpecJSONParser::OnAssertReturnNanCommand(::Action* action,
break;
}
} else {
- PrintCommandError("unexpected trap: %s",
- s_trap_strings[static_cast<int>(iresult)]);
+ PrintCommandError("unexpected trap: %s", ResultToString(iresult));
result = wabt::Result::Error;
}
}
@@ -1235,7 +1099,7 @@ wabt::Result SpecJSONParser::OnAssertReturnNanCommand(::Action* action,
wabt::Result SpecJSONParser::OnAssertTrapCommand(::Action* action,
string_view text) {
- std::vector<TypedValue> results;
+ TypedValues results;
interpreter::Result iresult;
total_++;
@@ -1255,7 +1119,7 @@ wabt::Result SpecJSONParser::OnAssertTrapCommand(::Action* action,
}
wabt::Result SpecJSONParser::OnAssertExhaustionCommand(::Action* action) {
- std::vector<TypedValue> results;
+ TypedValues results;
interpreter::Result iresult;
total_++;
@@ -1363,7 +1227,7 @@ wabt::Result SpecJSONParser::ParseCommand() {
OnAssertUninstantiableCommand(filename, text, module_type);
} else if (Match("\"assert_return\"")) {
::Action action;
- std::vector<TypedValue> expected;
+ TypedValues expected;
EXPECT(",");
CHECK_RESULT(ParseLine());
@@ -1454,10 +1318,10 @@ static wabt::Result ReadAndRunSpecJSON(const char* spec_json_filename) {
int ProgramMain(int argc, char** argv) {
InitStdio();
- ParseOptions(argc, argv);
-
s_stdout_stream = FileStream::CreateStdout();
+ ParseOptions(argc, argv);
+
wabt::Result result;
result = ReadAndRunSpecJSON(s_infile);
return result != wabt::Result::Ok;