summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/interp.cc273
-rw-r--r--src/interp.h87
-rw-r--r--src/tools/spectest-interp.cc128
-rw-r--r--src/tools/wasm-interp.cc22
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;