summaryrefslogtreecommitdiff
path: root/src/interpreter.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/interpreter.h')
-rw-r--r--src/interpreter.h263
1 files changed, 189 insertions, 74 deletions
diff --git a/src/interpreter.h b/src/interpreter.h
index d37473d5..3f60bdbb 100644
--- a/src/interpreter.h
+++ b/src/interpreter.h
@@ -22,8 +22,8 @@
#include <memory>
#include <vector>
-#include "common.h"
#include "binding-hash.h"
+#include "common.h"
#include "opcode.h"
#include "writer.h"
@@ -105,6 +105,12 @@ enum class Opcode {
static const int kOpcodeCount = WABT_ENUM_COUNT(Opcode);
struct FuncSignature {
+ FuncSignature() = default;
+ FuncSignature(Index param_count,
+ Type* param_types,
+ Index result_count,
+ Type* result_types);
+
std::vector<Type> param_types;
std::vector<Type> result_types;
};
@@ -255,10 +261,10 @@ struct PrintErrorCallback {
struct HostImportDelegate {
void* user_data;
::wabt::Result (*import_func)(Import*,
- Func*,
- FuncSignature*,
- PrintErrorCallback,
- void* user_data);
+ Func*,
+ FuncSignature*,
+ PrintErrorCallback,
+ void* user_data);
::wabt::Result (*import_table)(Import*,
Table*,
PrintErrorCallback,
@@ -282,6 +288,8 @@ struct Module {
inline struct DefinedModule* as_defined();
inline struct HostModule* as_host();
+ Export* GetExport(StringSlice name);
+
StringSlice name;
std::vector<Export> exports;
BindingHash export_bindings;
@@ -291,12 +299,12 @@ struct Module {
};
struct DefinedModule : Module {
- explicit DefinedModule(size_t istream_start);
+ DefinedModule();
std::vector<Import> imports;
Index start_func_index; /* kInvalidIndex if not defined */
- size_t istream_start;
- size_t istream_end;
+ IstreamOffset istream_start;
+ IstreamOffset istream_end;
};
struct HostModule : Module {
@@ -315,85 +323,192 @@ HostModule* Module::as_host() {
return static_cast<HostModule*>(this);
}
-/* Used to track and reset the state of the environment. */
-struct EnvironmentMark {
- size_t modules_size;
- size_t sigs_size;
- size_t funcs_size;
- size_t memories_size;
- size_t tables_size;
- size_t globals_size;
- size_t istream_size;
-};
+class Environment {
+ public:
+ // Used to track and reset the state of the environment.
+ struct MarkPoint {
+ size_t modules_size = 0;
+ size_t sigs_size = 0;
+ size_t funcs_size = 0;
+ size_t memories_size = 0;
+ size_t tables_size = 0;
+ size_t globals_size = 0;
+ size_t istream_size = 0;
+ };
-struct Environment {
Environment();
- std::vector<std::unique_ptr<Module>> modules;
- std::vector<FuncSignature> sigs;
- std::vector<std::unique_ptr<Func>> funcs;
- std::vector<Memory> memories;
- std::vector<Table> tables;
- std::vector<Global> globals;
- std::unique_ptr<OutputBuffer> istream;
- BindingHash module_bindings;
- BindingHash registered_module_bindings;
-};
+ OutputBuffer& istream() { return *istream_; }
+ void SetIstream(std::unique_ptr<OutputBuffer> istream) {
+ istream_ = std::move(istream);
+ }
+ std::unique_ptr<OutputBuffer> ReleaseIstream() { return std::move(istream_); }
-struct Thread {
- Thread();
-
- Environment* env;
- 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;
-};
+ Index GetFuncSignatureCount() const { return sigs_.size(); }
+ Index GetFuncCount() const { return funcs_.size(); }
+ Index GetGlobalCount() const { return globals_.size(); }
+ Index GetMemoryCount() const { return memories_.size(); }
+ Index GetTableCount() const { return tables_.size(); }
+ Index GetModuleCount() const { return modules_.size(); }
+
+ Index GetLastModuleIndex() const {
+ return modules_.empty() ? kInvalidIndex : modules_.size() - 1;
+ }
+ Index FindModuleIndex(StringSlice name) const;
+
+ FuncSignature* GetFuncSignature(Index index) { return &sigs_[index]; }
+ Func* GetFunc(Index index) {
+ assert(index < funcs_.size());
+ return funcs_[index].get();
+ }
+ Global* GetGlobal(Index index) {
+ assert(index < globals_.size());
+ return &globals_[index];
+ }
+ Memory* GetMemory(Index index) {
+ assert(index < memories_.size());
+ return &memories_[index];
+ }
+ Table* GetTable(Index index) {
+ assert(index < tables_.size());
+ return &tables_[index];
+ }
+ Module* GetModule(Index index) {
+ assert(index < modules_.size());
+ return modules_[index].get();
+ }
+
+ Module* GetLastModule() {
+ return modules_.empty() ? nullptr : modules_.back().get();
+ }
+ Module* FindModule(StringSlice name);
+ Module* FindRegisteredModule(StringSlice name);
+
+ template <typename... Args>
+ FuncSignature* EmplaceBackFuncSignature(Args&&... args) {
+ sigs_.emplace_back(args...);
+ return &sigs_.back();
+ }
+
+ template <typename... Args>
+ Func* EmplaceBackFunc(Args&&... args) {
+ funcs_.emplace_back(args...);
+ return funcs_.back().get();
+ }
+
+ template <typename... Args>
+ Global* EmplaceBackGlobal(Args&&... args) {
+ globals_.emplace_back(args...);
+ return &globals_.back();
+ }
+
+ template <typename... Args>
+ Table* EmplaceBackTable(Args&&... args) {
+ tables_.emplace_back(args...);
+ return &tables_.back();
+ }
+
+ template <typename... Args>
+ Memory* EmplaceBackMemory(Args&&... args) {
+ memories_.emplace_back(args...);
+ return &memories_.back();
+ }
+
+ template <typename... Args>
+ Module* EmplaceBackModule(Args&&... args) {
+ modules_.emplace_back(args...);
+ return modules_.back().get();
+ }
+
+ template <typename... Args>
+ void EmplaceModuleBinding(Args&&... args) {
+ module_bindings_.emplace(args...);
+ }
-// TODO(binji): Remove and use default constructor.
-#define WABT_INTERPRETER_THREAD_OPTIONS_DEFAULT \
- { \
- 512 * 1024 / sizeof(::wabt::interpreter::Value), 64 * 1024, \
- ::wabt::interpreter::kInvalidIstreamOffset \
+ template <typename... Args>
+ void EmplaceRegisteredModuleBinding(Args&&... args) {
+ registered_module_bindings_.emplace(args...);
}
-struct ThreadOptions {
- uint32_t value_stack_size;
- uint32_t call_stack_size;
- IstreamOffset pc;
+ HostModule* AppendHostModule(StringSlice name);
+
+ bool FuncSignaturesAreEqual(Index sig_index_0, Index sig_index_1) const;
+
+ MarkPoint Mark();
+ void ResetToMarkPoint(const MarkPoint&);
+
+ void Disassemble(Stream* stream, IstreamOffset from, IstreamOffset to);
+ void DisassembleModule(Stream* stream, Module*);
+
+ private:
+ friend class Thread;
+
+ std::vector<std::unique_ptr<Module>> modules_;
+ std::vector<FuncSignature> sigs_;
+ std::vector<std::unique_ptr<Func>> funcs_;
+ std::vector<Memory> memories_;
+ std::vector<Table> tables_;
+ std::vector<Global> globals_;
+ std::unique_ptr<OutputBuffer> istream_;
+ BindingHash module_bindings_;
+ BindingHash registered_module_bindings_;
+};
+
+class Thread {
+ public:
+ struct Options {
+ static const uint32_t kDefaultValueStackSize = 512 * 1024 / sizeof(Value);
+ static const uint32_t kDefaultCallStackSize = 64 * 1024;
+
+ explicit Options(uint32_t value_stack_size = kDefaultValueStackSize,
+ uint32_t call_stack_size = kDefaultCallStackSize,
+ IstreamOffset pc = kInvalidIstreamOffset);
+
+ uint32_t value_stack_size;
+ uint32_t call_stack_size;
+ IstreamOffset pc;
+ };
+
+ explicit Thread(Environment*, const Options& = Options());
+
+ Environment* env() { return env_; }
+
+ Result RunFunction(Index func_index,
+ const std::vector<TypedValue>& args,
+ std::vector<TypedValue>* out_results);
+
+ Result TraceFunction(Index func_index,
+ Stream*,
+ const std::vector<TypedValue>& args,
+ std::vector<TypedValue>* out_results);
+
+ private:
+ Result PushValue(Value);
+ Result PushArgs(const FuncSignature*, const std::vector<TypedValue>& args);
+ void CopyResults(const FuncSignature*, std::vector<TypedValue>* out_results);
+
+ Result Run(int num_instructions, IstreamOffset* call_stack_return_top);
+ void Trace(Stream*);
+
+ Result RunDefinedFunction(IstreamOffset);
+ Result TraceDefinedFunction(IstreamOffset, Stream*);
+
+ Result CallHost(HostFunc*);
+
+ Environment* env_;
+ 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_;
};
bool is_canonical_nan_f32(uint32_t f32_bits);
bool is_canonical_nan_f64(uint64_t f64_bits);
bool is_arithmetic_nan_f32(uint32_t f32_bits);
bool is_arithmetic_nan_f64(uint64_t f64_bits);
-bool func_signatures_are_equal(Environment* env,
- Index sig_index_0,
- Index sig_index_1);
-
-// TODO(binji): Use methods on Environment and Thread instead.
-void destroy_environment(Environment* env);
-EnvironmentMark mark_environment(Environment* env);
-void reset_environment_to_mark(Environment* env, EnvironmentMark mark);
-HostModule* append_host_module(Environment* env, StringSlice name);
-void init_thread(Environment* env, Thread* thread, ThreadOptions* options);
-Result push_thread_value(Thread* thread, Value value);
-void destroy_thread(Thread* thread);
-Result call_host(Thread* thread, HostFunc* func);
-Result run_interpreter(Thread* thread,
- int num_instructions,
- IstreamOffset* call_stack_return_top);
-void trace_pc(Thread* thread, Stream* stream);
-void disassemble(Environment* env,
- Stream* stream,
- IstreamOffset from,
- IstreamOffset to);
-void disassemble_module(Environment* env, Stream* stream, Module* module);
-
-Export* get_export_by_name(Module* module, const StringSlice* name);
} // namespace interpreter
} // namespace wabt