diff options
-rw-r--r-- | src/interp.cc | 273 | ||||
-rw-r--r-- | src/interp.h | 87 | ||||
-rw-r--r-- | src/tools/spectest-interp.cc | 128 | ||||
-rw-r--r-- | src/tools/wasm-interp.cc | 22 |
4 files changed, 257 insertions, 253 deletions
diff --git a/src/interp.cc b/src/interp.cc index 2c9ccdc6..c835b770 100644 --- a/src/interp.cc +++ b/src/interp.cc @@ -144,24 +144,14 @@ Module* Environment::FindRegisteredModule(string_view name) { } Thread::Options::Options(uint32_t value_stack_size, - uint32_t call_stack_size, - IstreamOffset pc, - Stream* trace_stream) + uint32_t call_stack_size) : value_stack_size(value_stack_size), - call_stack_size(call_stack_size), - pc(pc), - trace_stream(trace_stream) {} + call_stack_size(call_stack_size) {} Thread::Thread(Environment* env, const Options& options) : env_(env), value_stack_(options.value_stack_size), - call_stack_(options.call_stack_size), - value_stack_top_(value_stack_.data()), - value_stack_end_(value_stack_.data() + value_stack_.size()), - call_stack_top_(call_stack_.data()), - call_stack_end_(call_stack_.data() + call_stack_.size()), - pc_(options.pc), - trace_stream_(options.trace_stream) {} + call_stack_(options.call_stack_size) {} FuncSignature::FuncSignature(Index param_count, Type* param_types, @@ -243,34 +233,6 @@ HostModule* Environment::AppendHostModule(string_view name) { return module; } -Result Thread::PushArgs(const FuncSignature* sig, const TypedValues& args) { - if (sig->param_types.size() != args.size()) - return interp::Result::ArgumentTypeMismatch; - - for (size_t i = 0; i < sig->param_types.size(); ++i) { - if (sig->param_types[i] != args[i].type) - return interp::Result::ArgumentTypeMismatch; - - interp::Result iresult = Push(args[i].value); - if (iresult != interp::Result::Ok) { - value_stack_top_ = value_stack_.data(); - return iresult; - } - } - return interp::Result::Ok; -} - -void Thread::CopyResults(const FuncSignature* sig, TypedValues* out_results) { - size_t expected_results = sig->result_types.size(); - size_t value_stack_depth = value_stack_top_ - value_stack_.data(); - WABT_USE(value_stack_depth); - assert(expected_results == value_stack_depth); - - out_results->clear(); - for (size_t i = 0; i < expected_results; ++i) - out_results->emplace_back(sig->result_types[i], value_stack_[i]); -} - uint32_t ToRep(bool x) { return x ? 1 : 0; } uint32_t ToRep(uint32_t x) { return x; } uint64_t ToRep(uint64_t x) { return x; } @@ -587,7 +549,7 @@ template<> uint64_t GetValue<double>(Value v) { return v.f64_bits; } } while (0) #define CHECK_STACK() \ - TRAP_IF(value_stack_top_ >= value_stack_end_, ValueStackExhausted) + TRAP_IF(value_stack_top_ >= value_stack_.size(), ValueStackExhausted) #define PUSH_NEG_1_AND_BREAK_IF(cond) \ if (WABT_UNLIKELY(cond)) { \ @@ -690,17 +652,28 @@ Value& Thread::Top() { } Value& Thread::Pick(Index depth) { - return *(value_stack_top_ - depth); + return value_stack_[value_stack_top_ - depth]; +} + +void Thread::Reset() { + pc_ = 0; + value_stack_top_ = 0; + call_stack_top_ = 0; } Result Thread::Push(Value value) { CHECK_STACK(); - *value_stack_top_++ = value; + value_stack_[value_stack_top_++] = value; return Result::Ok; } Value Thread::Pop() { - return *--value_stack_top_; + return value_stack_[--value_stack_top_]; +} + +Value Thread::ValueAt(Index at) const { + assert(at < value_stack_top_); + return value_stack_[at]; } template <typename T> @@ -731,13 +704,13 @@ void Thread::DropKeep(uint32_t drop_count, uint8_t keep_count) { } Result Thread::PushCall(const uint8_t* pc) { - TRAP_IF(call_stack_top_ >= call_stack_end_, CallStackExhausted); - *call_stack_top_++ = pc - GetIstream(); + TRAP_IF(call_stack_top_ >= call_stack_.size(), CallStackExhausted); + call_stack_[call_stack_top_++] = pc - GetIstream(); return Result::Ok; } IstreamOffset Thread::PopCall() { - return *--call_stack_top_; + return call_stack_[--call_stack_top_]; } template <typename T> @@ -1221,87 +1194,6 @@ bool Environment::FuncSignaturesAreEqual(Index sig_index_0, sig_0->result_types == sig_1->result_types; } -Result Thread::RunFunction(Index func_index, - const TypedValues& args, - TypedValues* out_results) { - Func* func = env_->GetFunc(func_index); - FuncSignature* sig = env_->GetFuncSignature(func->sig_index); - - Result result = PushArgs(sig, args); - if (result == Result::Ok) { - result = func->is_host - ? CallHost(cast<HostFunc>(func)) - : RunDefinedFunction(cast<DefinedFunc>(func)->offset); - if (result == Result::Ok) - CopyResults(sig, out_results); - } - - // Always reset the value and call stacks. - value_stack_top_ = value_stack_.data(); - call_stack_top_ = call_stack_.data(); - return result; -} - -Result Thread::RunStartFunction(DefinedModule* module) { - if (module->start_func_index == kInvalidIndex) - return Result::Ok; - - if (trace_stream_) { - trace_stream_->Writef(">>> running start function:\n"); - } - TypedValues args; - TypedValues results; - Result result = RunFunction(module->start_func_index, args, &results); - assert(results.size() == 0); - return result; -} - -Result Thread::RunExport(const Export* export_, - const TypedValues& args, - TypedValues* out_results) { - if (trace_stream_) { - trace_stream_->Writef(">>> running export \"" PRIstringview "\":\n", - WABT_PRINTF_STRING_VIEW_ARG(export_->name)); - } - - assert(export_->kind == ExternalKind::Func); - return RunFunction(export_->index, args, out_results); -} - -Result Thread::RunExportByName(interp::Module* module, - string_view name, - const TypedValues& args, - TypedValues* out_results) { - interp::Export* export_ = module->GetExport(name); - if (!export_) - return interp::Result::UnknownExport; - if (export_->kind != ExternalKind::Func) - return interp::Result::ExportKindMismatch; - return RunExport(export_, args, out_results); -} - -Result Thread::RunDefinedFunction(IstreamOffset function_offset) { - Result result = Result::Ok; - pc_ = function_offset; - IstreamOffset* call_stack_return_top = call_stack_top_; - if (trace_stream_) { - const int kNumInstructions = 1; - while (result == Result::Ok) { - Trace(trace_stream_); - result = Run(kNumInstructions, call_stack_return_top); - } - } else { - const int kNumInstructions = 1000; - while (result == Result::Ok) { - result = Run(kNumInstructions, call_stack_return_top); - } - } - if (result != Result::Returned) - return result; - // Use OK instead of RETURNED for consistency. - return Result::Ok; -} - Result Thread::CallHost(HostFunc* func) { FuncSignature* sig = &env_->sigs_[func->sig_index]; @@ -1330,9 +1222,8 @@ Result Thread::CallHost(HostFunc* func) { return Result::Ok; } -Result Thread::Run(int num_instructions, IstreamOffset* call_stack_return_top) { +Result Thread::Run(int num_instructions) { Result result = Result::Ok; - assert(call_stack_return_top < call_stack_end_); const uint8_t* istream = GetIstream(); const uint8_t* pc = &istream[pc_]; @@ -1376,7 +1267,7 @@ Result Thread::Run(int num_instructions, IstreamOffset* call_stack_return_top) { } case Opcode::Return: - if (call_stack_top_ == call_stack_return_top) { + if (call_stack_top_ == 0) { result = Result::Returned; goto exit_loop; } @@ -2271,11 +2162,11 @@ Result Thread::Run(int num_instructions, IstreamOffset* call_stack_return_top) { break; case Opcode::InterpAlloca: { - Value* old_value_stack_top = value_stack_top_; - value_stack_top_ += ReadU32(&pc); + uint32_t old_value_stack_top = value_stack_top_; + size_t count = ReadU32(&pc); + value_stack_top_ += count; CHECK_STACK(); - memset(old_value_stack_top, 0, - (value_stack_top_ - old_value_stack_top) * sizeof(Value)); + memset(&value_stack_[old_value_stack_top], 0, count * sizeof(Value)); break; } @@ -2334,11 +2225,9 @@ exit_loop: void Thread::Trace(Stream* stream) { const uint8_t* istream = GetIstream(); const uint8_t* pc = &istream[pc_]; - size_t value_stack_depth = value_stack_top_ - value_stack_.data(); - size_t call_stack_depth = call_stack_top_ - call_stack_.data(); - stream->Writef("#%" PRIzd ". %4" PRIzd ": V:%-3" PRIzd "| ", call_stack_depth, - pc - istream, value_stack_depth); + stream->Writef("#%u. %4" PRIzd ": V:%-3u| ", call_stack_top_, pc - istream, + value_stack_top_); Opcode opcode = ReadOpcode(&pc); assert(!opcode.IsInvalid()); @@ -3200,5 +3089,109 @@ void Environment::DisassembleModule(Stream* stream, Module* module) { defined_module->istream_end); } +Executor::Executor(Environment* env, + Stream* trace_stream, + const Thread::Options& options) + : env_(env), trace_stream_(trace_stream), thread_(env, options) {} + +ExecResult Executor::RunFunction(Index func_index, const TypedValues& args) { + ExecResult exec_result; + Func* func = env_->GetFunc(func_index); + FuncSignature* sig = env_->GetFuncSignature(func->sig_index); + + exec_result.result = PushArgs(sig, args); + if (exec_result.result == Result::Ok) { + exec_result.result = func->is_host + ? thread_.CallHost(cast<HostFunc>(func)) + : RunDefinedFunction(cast<DefinedFunc>(func)->offset); + if (exec_result.result == Result::Ok) + CopyResults(sig, &exec_result.values); + } + + thread_.Reset(); + return exec_result; +} + +ExecResult Executor::RunStartFunction(DefinedModule* module) { + if (module->start_func_index == kInvalidIndex) + return ExecResult(Result::Ok); + + if (trace_stream_) { + trace_stream_->Writef(">>> running start function:\n"); + } + + TypedValues args; + ExecResult exec_result = RunFunction(module->start_func_index, args); + assert(exec_result.values.size() == 0); + return exec_result; +} + +ExecResult Executor::RunExport(const Export* export_, const TypedValues& args) { + if (trace_stream_) { + trace_stream_->Writef(">>> running export \"" PRIstringview "\":\n", + WABT_PRINTF_STRING_VIEW_ARG(export_->name)); + } + + assert(export_->kind == ExternalKind::Func); + return RunFunction(export_->index, args); +} + +ExecResult Executor::RunExportByName(Module* module, + string_view name, + const TypedValues& args) { + Export* export_ = module->GetExport(name); + if (!export_) + return ExecResult(Result::UnknownExport); + if (export_->kind != ExternalKind::Func) + return ExecResult(Result::ExportKindMismatch); + return RunExport(export_, args); +} + +Result Executor::RunDefinedFunction(IstreamOffset function_offset) { + Result result = Result::Ok; + thread_.set_pc(function_offset); + if (trace_stream_) { + const int kNumInstructions = 1; + while (result == Result::Ok) { + thread_.Trace(trace_stream_); + result = thread_.Run(kNumInstructions); + } + } else { + const int kNumInstructions = 1000; + while (result == Result::Ok) { + result = thread_.Run(kNumInstructions); + } + } + if (result != Result::Returned) + return result; + // Use OK instead of RETURNED for consistency. + return Result::Ok; +} + +Result Executor::PushArgs(const FuncSignature* sig, const TypedValues& args) { + if (sig->param_types.size() != args.size()) + return Result::ArgumentTypeMismatch; + + for (size_t i = 0; i < sig->param_types.size(); ++i) { + if (sig->param_types[i] != args[i].type) + return Result::ArgumentTypeMismatch; + + Result result = thread_.Push(args[i].value); + if (result != Result::Ok) { + return result; + } + } + return Result::Ok; +} + +void Executor::CopyResults(const FuncSignature* sig, TypedValues* out_results) { + size_t expected_results = sig->result_types.size(); + assert(expected_results == thread_.NumValues()); + + out_results->clear(); + for (size_t i = 0; i < expected_results; ++i) + out_results->emplace_back(sig->result_types[i], thread_.ValueAt(i)); +} + } // namespace interp } // namespace wabt diff --git a/src/interp.h b/src/interp.h index 888609c1..771a6f56 100644 --- a/src/interp.h +++ b/src/interp.h @@ -468,40 +468,32 @@ class Thread { static const uint32_t kDefaultCallStackSize = 64 * 1024; explicit Options(uint32_t value_stack_size = kDefaultValueStackSize, - uint32_t call_stack_size = kDefaultCallStackSize, - IstreamOffset pc = kInvalidIstreamOffset, - Stream* trace_stream = nullptr); + uint32_t call_stack_size = kDefaultCallStackSize); uint32_t value_stack_size; uint32_t call_stack_size; - IstreamOffset pc; - Stream* trace_stream; }; explicit Thread(Environment*, const Options& = Options()); Environment* env() { return env_; } - Result RunFunction(Index func_index, - const TypedValues& args, - TypedValues* out_results); - Result RunStartFunction(DefinedModule* module); - Result RunExport(const Export*, - const TypedValues& args, - TypedValues* out_results); - Result RunExportByName(Module* module, - string_view name, - const TypedValues& args, - TypedValues* out_results); + void set_pc(IstreamOffset offset) { pc_ = offset; } + IstreamOffset pc() const { return pc_; } - private: - const uint8_t* GetIstream() const { return env_->istream_->data.data(); } - - Result PushArgs(const FuncSignature*, const TypedValues& args); - void CopyResults(const FuncSignature*, TypedValues* out_results); + void Reset(); + Index NumValues() const { return value_stack_top_; } + Result Push(Value) WABT_WARN_UNUSED; + Value Pop(); + Value ValueAt(Index at) const; - Result Run(int num_instructions, IstreamOffset* call_stack_return_top); void Trace(Stream*); + Result Run(int num_instructions = 1); + + Result CallHost(HostFunc*); + + private: + const uint8_t* GetIstream() const { return env_->istream_->data.data(); } Memory* ReadMemory(const uint8_t** pc); template <typename MemType> @@ -512,9 +504,6 @@ class Thread { Value& Top(); Value& Pick(Index depth); - Result Push(Value) WABT_WARN_UNUSED; - Value Pop(); - // Push/Pop values with conversions, e.g. Push<float> will convert to the // ValueTypeRep (uint32_t) and push that. Similarly, Pop<float> will pop the // value and convert to float. @@ -565,19 +554,45 @@ class Thread { template <typename R, typename T = R> Result BinopTrap(BinopTrapFunc<R, T> func) WABT_WARN_UNUSED; - Result RunDefinedFunction(IstreamOffset); - - Result CallHost(HostFunc*); - - Environment* env_; + Environment* env_ = nullptr; std::vector<Value> value_stack_; std::vector<IstreamOffset> call_stack_; - Value* value_stack_top_; - Value* value_stack_end_; - IstreamOffset* call_stack_top_; - IstreamOffset* call_stack_end_; - IstreamOffset pc_; - Stream* trace_stream_; + uint32_t value_stack_top_ = 0; + uint32_t call_stack_top_ = 0; + IstreamOffset pc_ = 0; +}; + +struct ExecResult { + ExecResult() = default; + explicit ExecResult(Result result) : result(result) {} + ExecResult(Result result, const TypedValues& values) + : result(result), values(values) {} + + Result result = Result::Ok; + TypedValues values; +}; + +class Executor { + public: + explicit Executor(Environment*, + Stream* trace_stream = nullptr, + const Thread::Options& options = Thread::Options()); + + ExecResult RunFunction(Index func_index, const TypedValues& args); + ExecResult RunStartFunction(DefinedModule* module); + ExecResult RunExport(const Export*, const TypedValues& args); + ExecResult RunExportByName(Module* module, + string_view name, + const TypedValues& args); + + private: + Result RunDefinedFunction(IstreamOffset function_offset); + Result PushArgs(const FuncSignature*, const TypedValues& args); + void CopyResults(const FuncSignature*, TypedValues* out_results); + + Environment* env_ = nullptr; + Stream* trace_stream_ = nullptr; + Thread thread_; }; bool IsCanonicalNan(uint32_t f32_bits); diff --git a/src/tools/spectest-interp.cc b/src/tools/spectest-interp.cc index 3602940a..1cda45a3 100644 --- a/src/tools/spectest-interp.cc +++ b/src/tools/spectest-interp.cc @@ -43,6 +43,7 @@ using namespace wabt::interp; static int s_verbose; static const char* s_infile; static Thread::Options s_thread_options; +static Stream* s_trace_stream; static Features s_features; static std::unique_ptr<FileStream> s_log_stream; @@ -82,9 +83,8 @@ 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_thread_options.trace_stream = s_stdout_stream.get(); - }); + parser.AddOption('t', "trace", "Trace execution", + []() { s_trace_stream = s_stdout_stream.get(); }); parser.AddArgument("filename", OptionParser::ArgumentCount::One, [](const char* argument) { s_infile = argument; }); @@ -767,8 +767,7 @@ class CommandRunner { PrintError(uint32_t line_number, const char* format, ...); wabt::Result RunAction(int line_number, const Action* action, - interp::Result* out_iresult, - TypedValues* out_results, + ExecResult* out_result, RunVerbosity verbose); wabt::Result OnModuleCommand(const ModuleCommand*); @@ -795,7 +794,7 @@ class CommandRunner { const char* desc); Environment env_; - Thread thread_; + Executor executor_; DefinedModule* last_module_ = nullptr; int passed_ = 0; int total_ = 0; @@ -924,7 +923,8 @@ static void InitEnvironment(Environment* env) { host_module->import_delegate.reset(new SpectestHostImportDelegate()); } -CommandRunner::CommandRunner() : thread_(&env_, s_thread_options) { +CommandRunner::CommandRunner() + : executor_(&env_, s_trace_stream, s_thread_options) { InitEnvironment(&env_); } @@ -994,28 +994,24 @@ void CommandRunner::PrintError(uint32_t line_number, const char* format, ...) { printf("%s:%u: %s\n", source_filename_.c_str(), line_number, buffer); } -static interp::Result GetGlobalExportByName(Thread* thread, - interp::Module* module, - string_view name, - TypedValues* out_results) { +static ExecResult GetGlobalExportByName(Environment* env, + interp::Module* module, + string_view name) { interp::Export* export_ = module->GetExport(name); if (!export_) - return interp::Result::UnknownExport; + return ExecResult(interp::Result::UnknownExport); if (export_->kind != ExternalKind::Global) - return interp::Result::ExportKindMismatch; + return ExecResult(interp::Result::ExportKindMismatch); - interp::Global* global = thread->env()->GetGlobal(export_->index); - out_results->clear(); - out_results->push_back(global->typed_value); - return interp::Result::Ok; + interp::Global* global = env->GetGlobal(export_->index); + return ExecResult(interp::Result::Ok, {global->typed_value}); } wabt::Result CommandRunner::RunAction(int line_number, const Action* action, - interp::Result* out_iresult, - TypedValues* out_results, + ExecResult* out_exec_result, RunVerbosity verbose) { - out_results->clear(); + out_exec_result->values.clear(); interp::Module* module; if (!action->module_name.empty()) { @@ -1027,17 +1023,18 @@ wabt::Result CommandRunner::RunAction(int line_number, switch (action->type) { case ActionType::Invoke: - *out_iresult = thread_.RunExportByName(module, action->field_name, - action->args, out_results); + *out_exec_result = + executor_.RunExportByName(module, action->field_name, action->args); if (verbose == RunVerbosity::Verbose) { WriteCall(s_stdout_stream.get(), string_view(), action->field_name, - action->args, *out_results, *out_iresult); + action->args, out_exec_result->values, + out_exec_result->result); } return wabt::Result::Ok; case ActionType::Get: { - *out_iresult = GetGlobalExportByName(&thread_, module, action->field_name, - out_results); + *out_exec_result = + GetGlobalExportByName(&env_, module, action->field_name); return wabt::Result::Ok; } @@ -1131,10 +1128,11 @@ wabt::Result CommandRunner::OnModuleCommand(const ModuleCommand* command) { return wabt::Result::Error; } - interp::Result iresult = thread_.RunStartFunction(last_module_); - if (iresult != interp::Result::Ok) { + ExecResult exec_result = executor_.RunStartFunction(last_module_); + if (exec_result.result != interp::Result::Ok) { env_.ResetToMarkPoint(mark); - WriteResult(s_stdout_stream.get(), "error running start function", iresult); + WriteResult(s_stdout_stream.get(), "error running start function", + exec_result.result); return wabt::Result::Error; } @@ -1147,17 +1145,17 @@ wabt::Result CommandRunner::OnModuleCommand(const ModuleCommand* command) { } wabt::Result CommandRunner::OnActionCommand(const ActionCommand* command) { - TypedValues results; - interp::Result iresult; + ExecResult exec_result; total_++; - wabt::Result result = RunAction(command->line, &command->action, &iresult, - &results, RunVerbosity::Verbose); + wabt::Result result = RunAction(command->line, &command->action, &exec_result, + RunVerbosity::Verbose); if (Succeeded(result)) { - if (iresult == interp::Result::Ok) { + if (exec_result.result == interp::Result::Ok) { passed_++; } else { - PrintError(command->line, "unexpected trap: %s", ResultToString(iresult)); + PrintError(command->line, "unexpected trap: %s", + ResultToString(exec_result.result)); result = wabt::Result::Error; } } @@ -1255,8 +1253,8 @@ wabt::Result CommandRunner::OnAssertUninstantiableCommand( ReadModule(command->filename.c_str(), &env_, &error_handler, &module); if (Succeeded(result)) { - interp::Result iresult = thread_.RunStartFunction(module); - if (iresult == interp::Result::Ok) { + ExecResult exec_result = executor_.RunStartFunction(module); + if (exec_result.result == interp::Result::Ok) { PrintError(command->line, "expected error running start function: \"%s\"", command->filename.c_str()); result = wabt::Result::Error; @@ -1294,19 +1292,18 @@ static bool TypedValuesAreEqual(const TypedValue* tv1, const TypedValue* tv2) { wabt::Result CommandRunner::OnAssertReturnCommand( const AssertReturnCommand* command) { - TypedValues results; - interp::Result iresult; + ExecResult exec_result; total_++; - wabt::Result result = RunAction(command->line, &command->action, &iresult, - &results, RunVerbosity::Quiet); + wabt::Result result = RunAction(command->line, &command->action, &exec_result, + RunVerbosity::Quiet); if (Succeeded(result)) { - if (iresult == interp::Result::Ok) { - if (results.size() == command->expected.size()) { - for (size_t i = 0; i < results.size(); ++i) { + if (exec_result.result == interp::Result::Ok) { + if (exec_result.values.size() == command->expected.size()) { + for (size_t i = 0; i < exec_result.values.size(); ++i) { const TypedValue* expected_tv = &command->expected[i]; - const TypedValue* actual_tv = &results[i]; + const TypedValue* actual_tv = &exec_result.values[i]; if (!TypedValuesAreEqual(expected_tv, actual_tv)) { PrintError(command->line, "mismatch in result %" PRIzd @@ -1320,11 +1317,12 @@ wabt::Result CommandRunner::OnAssertReturnCommand( PrintError(command->line, "result length mismatch in assert_return: expected %" PRIzd ", got %" PRIzd, - command->expected.size(), results.size()); + command->expected.size(), exec_result.values.size()); result = wabt::Result::Error; } } else { - PrintError(command->line, "unexpected trap: %s", ResultToString(iresult)); + PrintError(command->line, "unexpected trap: %s", + ResultToString(exec_result.result)); result = wabt::Result::Error; } } @@ -1340,21 +1338,20 @@ wabt::Result CommandRunner::OnAssertReturnNanCommand( const NanCommand* command) { const bool is_canonical = command->type == CommandType::AssertReturnCanonicalNan; - TypedValues results; - interp::Result iresult; + ExecResult exec_result; total_++; - wabt::Result result = RunAction(command->line, &command->action, &iresult, - &results, RunVerbosity::Quiet); + wabt::Result result = RunAction(command->line, &command->action, &exec_result, + RunVerbosity::Quiet); if (Succeeded(result)) { - if (iresult == interp::Result::Ok) { - if (results.size() != 1) { + if (exec_result.result == interp::Result::Ok) { + if (exec_result.values.size() != 1) { PrintError(command->line, "expected one result, got %" PRIzd, - results.size()); + exec_result.values.size()); result = wabt::Result::Error; } - const TypedValue& actual = results[0]; + const TypedValue& actual = exec_result.values[0]; switch (actual.type) { case Type::F32: { bool is_nan = is_canonical ? IsCanonicalNan(actual.value.f32_bits) @@ -1386,7 +1383,8 @@ wabt::Result CommandRunner::OnAssertReturnNanCommand( break; } } else { - PrintError(command->line, "unexpected trap: %s", ResultToString(iresult)); + PrintError(command->line, "unexpected trap: %s", + ResultToString(exec_result.result)); result = wabt::Result::Error; } } @@ -1399,14 +1397,13 @@ wabt::Result CommandRunner::OnAssertReturnNanCommand( wabt::Result CommandRunner::OnAssertTrapCommand( const AssertTrapCommand* command) { - TypedValues results; - interp::Result iresult; + ExecResult exec_result; total_++; - wabt::Result result = RunAction(command->line, &command->action, &iresult, - &results, RunVerbosity::Quiet); + wabt::Result result = RunAction(command->line, &command->action, &exec_result, + RunVerbosity::Quiet); if (Succeeded(result)) { - if (iresult != interp::Result::Ok) { + if (exec_result.result != interp::Result::Ok) { passed_++; } else { PrintError(command->line, "expected trap: \"%s\"", command->text.c_str()); @@ -1419,15 +1416,14 @@ wabt::Result CommandRunner::OnAssertTrapCommand( wabt::Result CommandRunner::OnAssertExhaustionCommand( const AssertExhaustionCommand* command) { - TypedValues results; - interp::Result iresult; + ExecResult exec_result; total_++; - wabt::Result result = RunAction(command->line, &command->action, &iresult, - &results, RunVerbosity::Quiet); + wabt::Result result = RunAction(command->line, &command->action, &exec_result, + RunVerbosity::Quiet); if (Succeeded(result)) { - if (iresult == interp::Result::TrapCallStackExhausted || - iresult == interp::Result::TrapValueStackExhausted) { + if (exec_result.result == interp::Result::TrapCallStackExhausted || + exec_result.result == interp::Result::TrapValueStackExhausted) { passed_++; } else { PrintError(command->line, "expected call stack exhaustion"); diff --git a/src/tools/wasm-interp.cc b/src/tools/wasm-interp.cc index af842853..82b455e0 100644 --- a/src/tools/wasm-interp.cc +++ b/src/tools/wasm-interp.cc @@ -43,6 +43,7 @@ using namespace wabt::interp; static int s_verbose; static const char* s_infile; static Thread::Options s_thread_options; +static Stream* s_trace_stream; static bool s_run_all_exports; static bool s_host_print; static Features s_features; @@ -95,9 +96,8 @@ 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_thread_options.trace_stream = s_stdout_stream.get(); - }); + parser.AddOption('t', "trace", "Trace execution", + []() { s_trace_stream = s_stdout_stream.get(); }); parser.AddOption( "run-all-exports", "Run all the exported functions, in order. Useful for testing", @@ -113,15 +113,15 @@ static void ParseOptions(int argc, char** argv) { } static void RunAllExports(interp::Module* module, - Thread* thread, + Executor* executor, RunVerbosity verbose) { TypedValues args; TypedValues results; for (const interp::Export& export_ : module->exports) { - interp::Result iresult = thread->RunExport(&export_, args, &results); + ExecResult exec_result = executor->RunExport(&export_, args); if (verbose == RunVerbosity::Verbose) { WriteCall(s_stdout_stream.get(), string_view(), export_.name, args, - results, iresult); + exec_result.values, exec_result.result); } } } @@ -234,14 +234,14 @@ static wabt::Result ReadAndRunModule(const char* module_filename) { DefinedModule* module = nullptr; result = ReadModule(module_filename, &env, &error_handler, &module); if (Succeeded(result)) { - Thread thread(&env, s_thread_options); - interp::Result iresult = thread.RunStartFunction(module); - if (iresult == interp::Result::Ok) { + Executor executor(&env, s_trace_stream, s_thread_options); + ExecResult exec_result = executor.RunStartFunction(module); + if (exec_result.result == interp::Result::Ok) { if (s_run_all_exports) - RunAllExports(module, &thread, RunVerbosity::Verbose); + RunAllExports(module, &executor, RunVerbosity::Verbose); } else { WriteResult(s_stdout_stream.get(), "error running start function", - iresult); + exec_result.result); } } return result; |