Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 19 additions & 3 deletions src/ir/import-name.h → src/ir/import-names.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
* limitations under the License.
*/

#ifndef wasm_ir_import_name_h
#define wasm_ir_import_name_h
#ifndef wasm_ir_import_names_h
#define wasm_ir_import_names_h

#include <ostream>

Expand All @@ -26,8 +26,24 @@ namespace wasm {
struct ImportNames {
Name module;
Name name;

bool operator==(const ImportNames& other) const {
return module == other.module && name == other.name;
}
};

} // namespace wasm

#endif // wasm_ir_import_name_h
namespace std {

// TODO?
template<> struct hash<wasm::ImportNames> {
size_t operator()(const wasm::ImportNames& importNames) const {
return std::hash<wasm::Name>{}(importNames.module) ^
std::hash<wasm::Name>{}(importNames.name);
}
};

} // namespace std

#endif // wasm_ir_import_names_h
2 changes: 1 addition & 1 deletion src/ir/import-utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#ifndef wasm_ir_import_h
#define wasm_ir_import_h

#include "ir/import-name.h"
#include "ir/import-names.h"
#include "ir/runtime-table.h"
#include "literal.h"
#include "wasm.h"
Expand Down
73 changes: 42 additions & 31 deletions src/tools/wasm-ctor-eval.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,26 +68,6 @@ bool isNullableAndMutable(Expression* ref, Index fieldIndex) {
// the output.
#define RECOMMENDATION "\n recommendation: "

class EvallingImportResolver : public ImportResolver {
public:
EvallingImportResolver() : stubLiteral({Literal(0)}) {};

// Return an unused stub value. We throw FailToEvalException on reading any
// imported globals. We ignore the type and return an i32 literal since some
// types can't be created anyway (e.g. ref none).
Literals* getGlobalOrNull(ImportNames name, Type type) const override {
return &stubLiteral;
}

RuntimeTable* getTableOrNull(ImportNames name,
const Table& type) const override {
throw FailToEvalException{"Imported table access."};
}

private:
mutable Literals stubLiteral;
};

class EvallingRuntimeTable : public RuntimeTable {
public:
// TODO: putting EvallingModuleRunner into its own header would allow us to
Expand Down Expand Up @@ -166,6 +146,39 @@ class EvallingRuntimeTable : public RuntimeTable {
const std::function<Literal(Name, Type)> makeFuncData;
};

class EvallingImportResolver : public ImportResolver {
public:
EvallingImportResolver(const bool& instanceInitialized,
const Module& wasm,
std::function<Literal(Name, Type)> makeFuncData)
: stubLiteral({Literal(0)}), instanceInitialized(instanceInitialized),
wasm(wasm), makeFuncData(makeFuncData) {};

// Return an unused stub value. We throw FailToEvalException on reading any
// imported globals. We ignore the type and return an i32 literal since some
// types can't be created anyway (e.g. ref none).
Literals* getGlobalOrNull(ImportNames name, Type type) const override {
return &stubLiteral;
}

RuntimeTable* getTableOrNull(ImportNames name,
const Table& type) const override {
auto [it, inserted] =
tables.emplace(name,
std::make_unique<EvallingRuntimeTable>(
type, instanceInitialized, wasm, makeFuncData));
return it->second.get();
}

private:
mutable Literals stubLiteral;
mutable std::unordered_map<ImportNames, std::unique_ptr<EvallingRuntimeTable>>
tables;
const bool& instanceInitialized;
const Module& wasm;
const std::function<Literal(Name, Type)> makeFuncData;
};

class EvallingModuleRunner : public ModuleRunnerBase<EvallingModuleRunner> {
public:
EvallingModuleRunner(
Expand All @@ -176,17 +189,11 @@ class EvallingModuleRunner : public ModuleRunnerBase<EvallingModuleRunner> {
: ModuleRunnerBase(
wasm,
externalInterface,
std::make_shared<EvallingImportResolver>(),
linkedInstances_,
// TODO: Only use EvallingRuntimeTable for table imports. We can use
// RealRuntimeTable for non-imported tables.
[this, &instanceInitialized](Literal initial, Table table) {
return std::make_unique<EvallingRuntimeTable>(
table,
instanceInitialized,
this->wasm,
[this](Name name, Type type) { return makeFuncData(name, type); });
}) {}
std::make_shared<EvallingImportResolver>(
instanceInitialized,
wasm,
[this](Name name, Type type) { return makeFuncData(name, type); }),
linkedInstances_) {}

Flow visitGlobalGet(GlobalGet* curr) {
// Error on reads of imported globals.
Expand Down Expand Up @@ -1156,6 +1163,10 @@ EvalCtorOutcome evalCtor(EvallingModuleRunner& instance,
std::cout << " ...stopping due to non-constant func\n";
}
break;
} catch (TrapException& trap) {
if (!quiet) {
std::cout << " ...stopping due to trap\n";
}
}

if (flow.breakTo == NONCONSTANT_FLOW) {
Expand Down
19 changes: 4 additions & 15 deletions src/wasm-interpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -3173,25 +3173,15 @@ class ModuleRunnerBase : public ExpressionRunner<SubType> {
// Like `allGlobals`. Keyed by internal name. All tables including imports.
std::unordered_map<Name, RuntimeTable*> allTables;

using CreateTableFunc = std::unique_ptr<RuntimeTable>(Literal, Table);

ModuleRunnerBase(
Module& wasm,
ExternalInterface* externalInterface,
std::shared_ptr<ImportResolver> importResolver,
std::map<Name, std::shared_ptr<SubType>> linkedInstances_ = {},
std::function<CreateTableFunc> createTable = {})
std::map<Name, std::shared_ptr<SubType>> linkedInstances_ = {})
: ExpressionRunner<SubType>(&wasm), wasm(wasm),
externalInterface(externalInterface),
linkedInstances(std::move(linkedInstances_)),
importResolver(std::move(importResolver)),
createTable(
createTable != nullptr
? std::move(createTable)
: static_cast<std::function<CreateTableFunc>>(
[](Literal initial, Table t) -> std::unique_ptr<RuntimeTable> {
return std::make_unique<RealRuntimeTable>(initial, t);
})) {
importResolver(std::move(importResolver)) {
// Set up a single shared CurrContinuations for all these linked instances,
// reusing one if it exists.
std::shared_ptr<ContinuationStore> shared;
Expand Down Expand Up @@ -3485,8 +3475,8 @@ class ModuleRunnerBase : public ExpressionRunner<SubType> {
"We only support nullable tables today");

auto null = Literal::makeNull(table->type.getHeapType());
auto& runtimeTable =
definedTables.emplace_back(createTable(null, *table));
auto& runtimeTable = definedTables.emplace_back(
std::make_unique<RealRuntimeTable>(null, *table));
auto [_, inserted] =
allTables.try_emplace(table->name, runtimeTable.get());
(void)inserted; // for noassert builds
Expand Down Expand Up @@ -5194,7 +5184,6 @@ class ModuleRunnerBase : public ExpressionRunner<SubType> {
ExternalInterface* externalInterface;
std::map<Name, std::shared_ptr<SubType>> linkedInstances;
std::shared_ptr<ImportResolver> importResolver;
std::function<CreateTableFunc> createTable;
};

class ModuleRunner : public ModuleRunnerBase<ModuleRunner> {
Expand Down
2 changes: 1 addition & 1 deletion src/wasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
#include <unordered_map>
#include <vector>

#include "ir/import-name.h"
#include "ir/import-names.h"
#include "literal.h"
#include "support/index.h"
#include "support/mixed_arena.h"
Expand Down
Loading