diff --git a/src/shell-interface.h b/src/shell-interface.h index 03b4c819e73..65885e5d85c 100644 --- a/src/shell-interface.h +++ b/src/shell-interface.h @@ -94,15 +94,15 @@ struct ShellExternalInterface : ModuleRunner::ExternalInterface { std::map memories; std::unordered_map> tables; - std::map> linkedInstances; + std::map> linkedInstances; ShellExternalInterface( - std::map> linkedInstances_ = {}) { + std::map> linkedInstances_ = {}) { linkedInstances.swap(linkedInstances_); } virtual ~ShellExternalInterface() = default; - ModuleRunner* getImportInstanceOrNull(Importable* import) { + ModuleRunnerBase* getImportInstanceOrNull(Importable* import) { auto it = linkedInstances.find(import->module); if (it == linkedInstances.end()) { return nullptr; @@ -110,7 +110,7 @@ struct ShellExternalInterface : ModuleRunner::ExternalInterface { return it->second.get(); } - ModuleRunner* getImportInstance(Importable* import) { + ModuleRunnerBase* getImportInstance(Importable* import) { auto* ret = getImportInstanceOrNull(import); if (!ret) { Fatal() << "getImportInstance: unknown import: " << import->module.str @@ -119,7 +119,7 @@ struct ShellExternalInterface : ModuleRunner::ExternalInterface { return ret; } - void init(Module& wasm, ModuleRunner& instance) override { + void init(Module& wasm, ModuleRunnerBase& instance) override { ModuleUtils::iterDefinedMemories(wasm, [&](wasm::Memory* memory) { auto shellMemory = Memory(); shellMemory.resize(memory->initial * wasm::Memory::kPageSize); diff --git a/src/tools/execution-results.h b/src/tools/execution-results.h index 83f861ab7d4..a969520abd7 100644 --- a/src/tools/execution-results.h +++ b/src/tools/execution-results.h @@ -50,13 +50,13 @@ struct LoggingExternalInterface : public ShellExternalInterface { // The ModuleRunner and this ExternalInterface end up needing links both ways, // so we cannot init this in the constructor. - ModuleRunner* instance = nullptr; + ModuleRunnerBase* instance = nullptr; public: LoggingExternalInterface( Loggings& loggings, Module& wasm, - std::map> linkedInstances_ = {}) + std::map> linkedInstances_ = {}) : ShellExternalInterface(linkedInstances_), loggings(loggings), wasm(wasm) { for (auto& exp : wasm.exports) { if (exp->kind == ExternalKind::Table && exp->name == "table") { @@ -294,7 +294,7 @@ struct LoggingExternalInterface : public ShellExternalInterface { return flow.values; } - void setModuleRunner(ModuleRunner* instance_) { instance = instance_; } + void setModuleRunner(ModuleRunnerBase* instance_) { instance = instance_; } }; // gets execution results from a wasm module. this is useful for fuzzing @@ -322,7 +322,7 @@ struct ExecutionResults { // Instantiate the second, if there is one (we instantiate both before // running anything, so that we match the behavior of fuzz_shell.js). - std::map> linkedInstances; + std::map> linkedInstances; std::unique_ptr secondInterface; std::shared_ptr secondInstance; if (second) { @@ -351,16 +351,16 @@ struct ExecutionResults { } } - void instantiate(ModuleRunner& instance, + void instantiate(ModuleRunnerBase& instance, LoggingExternalInterface& interface) { // This is not an optimization: we want to execute anything, even relaxed // SIMD instructions. - instance.setRelaxedBehavior(ModuleRunner::RelaxedBehavior::Execute); + instance.setRelaxedBehavior(ModuleRunnerBase::RelaxedBehavior::Execute); instance.instantiate(); interface.setModuleRunner(&instance); } - void callExports(Module& wasm, ModuleRunner& instance) { + void callExports(Module& wasm, ModuleRunnerBase& instance) { // execute all exported methods (that are therefore preserved through // opts) for (auto& exp : wasm.exports) { @@ -507,11 +507,11 @@ struct ExecutionResults { bool operator!=(ExecutionResults& other) { return !((*this) == other); } - FunctionResult run(Function* func, Module& wasm, ModuleRunner& instance) { + FunctionResult run(Function* func, Module& wasm, ModuleRunnerBase& instance) { // Clear the continuation state after each run of an export. struct CleanUp { - ModuleRunner& instance; - CleanUp(ModuleRunner& instance) : instance(instance) {} + ModuleRunnerBase& instance; + CleanUp(ModuleRunnerBase& instance) : instance(instance) {} ~CleanUp() { instance.clearContinuationStore(); } } cleanUp(instance); diff --git a/src/tools/wasm-ctor-eval.cpp b/src/tools/wasm-ctor-eval.cpp index 455c247ccd7..7f8965170e8 100644 --- a/src/tools/wasm-ctor-eval.cpp +++ b/src/tools/wasm-ctor-eval.cpp @@ -67,12 +67,12 @@ bool isNullableAndMutable(Expression* ref, Index fieldIndex) { // the output. #define RECOMMENDATION "\n recommendation: " -class EvallingModuleRunner : public ModuleRunnerBase { +class EvallingModuleRunner : public ModuleRunnerBase { public: EvallingModuleRunner( Module& wasm, ExternalInterface* externalInterface, - std::map> linkedInstances_ = {}) + std::map> linkedInstances_ = {}) : ModuleRunnerBase(wasm, externalInterface, linkedInstances_) {} Flow visitGlobalGet(GlobalGet* curr) { @@ -84,7 +84,7 @@ class EvallingModuleRunner : public ModuleRunnerBase { global->base.toString()); } - return ModuleRunnerBase::visitGlobalGet(curr); + return ModuleRunnerBase::visitGlobalGet(curr); } Flow visitTableGet(TableGet* curr) { @@ -99,7 +99,7 @@ class EvallingModuleRunner : public ModuleRunnerBase { if (!allowContNew) { throw FailToEvalException("cont.new disallowed"); } - return ModuleRunnerBase::visitContNew(curr); + return ModuleRunnerBase::visitContNew(curr); } // This needs to be duplicated from ModuleRunner, unfortunately. @@ -182,7 +182,7 @@ static bool ignoreExternalInput = false; struct CtorEvalExternalInterface : EvallingModuleRunner::ExternalInterface { Module* wasm; EvallingModuleRunner* instance; - std::map> linkedInstances; + std::map> linkedInstances; // A representation of the contents of wasm memory as we execute. std::unordered_map> memories; @@ -198,8 +198,7 @@ struct CtorEvalExternalInterface : EvallingModuleRunner::ExternalInterface { bool instanceInitialized = false; CtorEvalExternalInterface( - std::map> linkedInstances_ = - {}) { + std::map> linkedInstances_ = {}) { linkedInstances.swap(linkedInstances_); } @@ -216,9 +215,9 @@ struct CtorEvalExternalInterface : EvallingModuleRunner::ExternalInterface { applyGlobalsToModule(); } - void init(Module& wasm_, EvallingModuleRunner& instance_) override { + void init(Module& wasm_, ModuleRunnerBase& instance_) override { wasm = &wasm_; - instance = &instance_; + instance = static_cast(&instance_); for (auto& memory : wasm->memories) { if (!memory->imported()) { std::vector data; @@ -1354,7 +1353,7 @@ void evalCtors(Module& wasm, std::unordered_set keptExportsSet(keptExports.begin(), keptExports.end()); - std::map> linkedInstances; + std::map> linkedInstances; // build and link the env module auto envModule = buildEnvModule(wasm); diff --git a/src/tools/wasm-shell.cpp b/src/tools/wasm-shell.cpp index 154c045f249..b0507079554 100644 --- a/src/tools/wasm-shell.cpp +++ b/src/tools/wasm-shell.cpp @@ -44,9 +44,9 @@ struct Shell { // Keyed by instance name. std::map> interfaces; - std::map> instances; + std::map> instances; // Used for imports, keyed by instance name. - std::map> linkedInstances; + std::map> linkedInstances; Name lastInstance; std::optional lastModuleDefinition; diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index d46dde4d102..8260b5f311b 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -2956,8 +2956,7 @@ using GlobalValueSet = std::map; // To call into the interpreter, use callExport. // -template -class ModuleRunnerBase : public ExpressionRunner { +class ModuleRunnerBase : public ExpressionRunner { public: // // You need to implement one of these to create a concrete interpreter. The @@ -2966,9 +2965,9 @@ class ModuleRunnerBase : public ExpressionRunner { // struct ExternalInterface { ExternalInterface( - std::map> linkedInstances = {}) {} + std::map> linkedInstances = {}) {} virtual ~ExternalInterface() = default; - virtual void init(Module& wasm, SubType& instance) {} + virtual void init(Module& wasm, ModuleRunnerBase& instance) {} virtual void importGlobals(GlobalValueSet& globals, Module& wasm) = 0; virtual Literal getImportedFunction(Function* import) = 0; virtual bool growMemory(Name name, Address oldSize, Address newSize) = 0; @@ -3169,7 +3168,7 @@ class ModuleRunnerBase : public ExpressionRunner { } }; - SubType* self() { return static_cast(this); } + ModuleRunnerBase* self() { return this; } // TODO: this duplicates module in ExpressionRunner, and can be removed Module& wasm; @@ -3183,8 +3182,8 @@ class ModuleRunnerBase : public ExpressionRunner { ModuleRunnerBase( Module& wasm, ExternalInterface* externalInterface, - std::map> linkedInstances_ = {}) - : ExpressionRunner(&wasm), wasm(wasm), + std::map> linkedInstances_ = {}) + : ExpressionRunner(&wasm), wasm(wasm), externalInterface(externalInterface), linkedInstances(linkedInstances_) { // Set up a single shared CurrContinuations for all these linked instances, // reusing one if it exists. @@ -3302,7 +3301,7 @@ class ModuleRunnerBase : public ExpressionRunner { struct TableInstanceInfo { // The ModuleRunner instance in which the memory is defined. - SubType* instance; + ModuleRunnerBase* instance; // The external interface in which the table is defined ExternalInterface* interface() { return instance->externalInterface; } // The name the table has in that interface. @@ -3358,7 +3357,7 @@ class ModuleRunnerBase : public ExpressionRunner { struct MemoryInstanceInfo { // The ModuleRunner instance in which the memory is defined. - SubType* instance; + ModuleRunnerBase* instance; // The external interface in which the memory is defined ExternalInterface* interface() { return instance->externalInterface; } // The name the memory has in that interface. @@ -3445,13 +3444,13 @@ class ModuleRunnerBase : public ExpressionRunner { public: std::vector locals; Function* function; - SubType& parent; + ModuleRunnerBase& parent; FunctionScope* oldScope; FunctionScope(Function* function, const Literals& arguments, - SubType& parent) + ModuleRunnerBase& parent) : function(function), parent(parent) { oldScope = parent.scope; parent.scope = this; @@ -3683,7 +3682,7 @@ class ModuleRunnerBase : public ExpressionRunner { return ret; } - Flow visitTableGet(TableGet* curr) { + virtual Flow visitTableGet(TableGet* curr) { VISIT(index, curr->index) auto info = getTableInstanceInfo(curr->table); auto address = index.getSingleValue().getUnsigned(); @@ -3844,7 +3843,7 @@ class ModuleRunnerBase : public ExpressionRunner { return curr->isTee() ? flow : Flow(); } - Flow visitGlobalGet(GlobalGet* curr) { + virtual Flow visitGlobalGet(GlobalGet* curr) { auto name = curr->name; return getGlobal(name); } @@ -4534,7 +4533,7 @@ class ModuleRunnerBase : public ExpressionRunner { multiValues.pop_back(); return ret; } - Flow visitContNew(ContNew* curr) { + virtual Flow visitContNew(ContNew* curr) { VISIT(funcFlow, curr->func) // Create a new continuation for the target function. auto funcValue = funcFlow.getSingleValue(); @@ -5053,16 +5052,20 @@ class ModuleRunnerBase : public ExpressionRunner { return externalInterface->store(&store, addr, toStore, memoryName); } + virtual Literal makeFuncData(Name name, Type type) { + return ExpressionRunner::makeFuncData(name, type); + } + ExternalInterface* externalInterface; - std::map> linkedInstances; + std::map> linkedInstances; }; -class ModuleRunner : public ModuleRunnerBase { +class ModuleRunner : public ModuleRunnerBase { public: ModuleRunner( Module& wasm, ExternalInterface* externalInterface, - std::map> linkedInstances = {}) + std::map> linkedInstances = {}) : ModuleRunnerBase(wasm, externalInterface, linkedInstances) {} Literal makeFuncData(Name name, Type type) {