Skip to content

Commit

Permalink
clean up ImportUtils: make getImport return the import (more consiste…
Browse files Browse the repository at this point in the history
…nt with other similar APIs) and fix some ctor-evalling handling of imports, which was incorrect - we need to create fake globals when importing globals, not later, which is too late for initialized globals from imports (WebAssembly#1226)
  • Loading branch information
kripken authored Oct 17, 2017
1 parent 73c0495 commit dfe92af
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 31 deletions.
6 changes: 3 additions & 3 deletions src/ast/import-utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ namespace wasm {
namespace ImportUtils {
// find an import by the module.base that is being imported.
// return the internal name
inline Name getImport(Module& wasm, Name module, Name base) {
inline Import* getImport(Module& wasm, Name module, Name base) {
for (auto& import : wasm.imports) {
if (import->module == module && import->base == base) {
return import->name;
return import.get();
}
}
return Name();
return nullptr;
}
};

Expand Down
15 changes: 9 additions & 6 deletions src/passes/SafeHeap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,9 @@ struct SafeHeap : public Pass {

void addImports(Module* module) {
// imports
dynamicTopPtr = ImportUtils::getImport(*module, ENV, DYNAMICTOP_PTR_IMPORT);
if (!dynamicTopPtr.is()) {
if (auto* existing = ImportUtils::getImport(*module, ENV, DYNAMICTOP_PTR_IMPORT)) {
dynamicTopPtr = existing->name;
} else {
auto* import = new Import;
import->name = dynamicTopPtr = DYNAMICTOP_PTR_IMPORT;
import->module = ENV;
Expand All @@ -124,8 +125,9 @@ struct SafeHeap : public Pass {
import->globalType = i32;
module->addImport(import);
}
segfault = ImportUtils::getImport(*module, ENV, SEGFAULT_IMPORT);
if (!segfault.is()) {
if (auto* existing = ImportUtils::getImport(*module, ENV, SEGFAULT_IMPORT)) {
dynamicTopPtr = existing->name;
} else {
auto* import = new Import;
import->name = segfault = SEGFAULT_IMPORT;
import->module = ENV;
Expand All @@ -134,8 +136,9 @@ struct SafeHeap : public Pass {
import->functionType = ensureFunctionType("v", module)->name;
module->addImport(import);
}
alignfault = ImportUtils::getImport(*module, ENV, ALIGNFAULT_IMPORT);
if (!alignfault.is()) {
if (auto* existing = ImportUtils::getImport(*module, ENV, ALIGNFAULT_IMPORT)) {
dynamicTopPtr = existing->name;
} else {
auto* import = new Import;
import->name = alignfault = ALIGNFAULT_IMPORT;
import->module = ENV;
Expand Down
60 changes: 38 additions & 22 deletions src/tools/wasm-ctor-eval.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
#include "wasm-builder.h"
#include "ast/memory-utils.h"
#include "ast/global-utils.h"
#include "ast/import-utils.h"
#include "ast/literal-utils.h"

using namespace wasm;

Expand Down Expand Up @@ -78,11 +80,6 @@ class EvallingGlobalManager {
}
throw FailToEvalException(std::string("tried to access a dangerous (import-initialized) global: ") + name.str + extra);
}
if (sealed) {
if (globals.find(name) == globals.end()) {
throw FailToEvalException(std::string("tried to access missing global: ") + name.str);
}
}
return globals[name];
}

Expand Down Expand Up @@ -114,6 +111,13 @@ class EvallingGlobalManager {
}
};

enum {
// put the stack in some ridiculously high location
STACK_START = 0x40000000,
// use a ridiculously large stack size
STACK_SIZE = 32 * 1024 * 1024
};

class EvallingModuleInstance : public ModuleInstanceBase<EvallingGlobalManager, EvallingModuleInstance> {
public:
EvallingModuleInstance(Module& wasm, ExternalInterface* externalInterface) : ModuleInstanceBase(wasm, externalInterface) {
Expand All @@ -138,13 +142,6 @@ class EvallingModuleInstance : public ModuleInstanceBase<EvallingGlobalManager,
}
}

enum {
// put the stack in some ridiculously high location
STACK_START = 0x40000000,
// use a ridiculously large stack size
STACK_SIZE = 32 * 1024 * 1024
};

std::vector<char> stack;

// create C stack space for us to use. We do *NOT* care about their contents,
Expand All @@ -153,13 +150,6 @@ class EvallingModuleInstance : public ModuleInstanceBase<EvallingGlobalManager,
void setupEnvironment() {
// prepare scratch memory
stack.resize(STACK_SIZE);
// fill usable values for stack imports
if (auto* stackTop = GlobalUtils::getGlobalInitializedToImport(wasm, "env", "STACKTOP")) {
globals[stackTop->name] = Literal(int32_t(STACK_START));
}
if (auto* stackMax = GlobalUtils::getGlobalInitializedToImport(wasm, "env", "STACK_MAX")) {
globals[stackMax->name] = Literal(int32_t(STACK_START));
}
// tell the module to accept writes up to the stack end
auto total = STACK_START + STACK_SIZE;
memorySize = total / Memory::kPageSize;
Expand All @@ -181,6 +171,32 @@ struct CtorEvalExternalInterface : EvallingModuleInstance::ExternalInterface {
}

void importGlobals(EvallingGlobalManager& globals, Module& wasm_) override {
// fill usable values for stack imports, and globals initialized to them
if (auto* stackTop = ImportUtils::getImport(wasm_, "env", "STACKTOP")) {
globals[stackTop->name] = Literal(int32_t(STACK_START));
if (auto* stackTop = GlobalUtils::getGlobalInitializedToImport(wasm_, "env", "STACKTOP")) {
globals[stackTop->name] = Literal(int32_t(STACK_START));
}
}
if (auto* stackMax = ImportUtils::getImport(wasm_, "env", "STACK_MAX")) {
globals[stackMax->name] = Literal(int32_t(STACK_START));
if (auto* stackMax = GlobalUtils::getGlobalInitializedToImport(wasm_, "env", "STACK_MAX")) {
globals[stackMax->name] = Literal(int32_t(STACK_START));
}
}
// fill in fake values for everything else, which is dangerous to use
for (auto& global : wasm_.globals) {
if (globals.find(global->name) == globals.end()) {
globals[global->name] = LiteralUtils::makeLiteralZero(global->type);
}
}
for (auto& import : wasm_.imports) {
if (import->kind == ExternalKind::Global) {
if (globals.find(import->name) == globals.end()) {
globals[import->name] = LiteralUtils::makeLiteralZero(import->globalType);
}
}
}
}

Literal callImport(Import *import, LiteralList& arguments) override {
Expand Down Expand Up @@ -248,9 +264,9 @@ struct CtorEvalExternalInterface : EvallingModuleInstance::ExternalInterface {
template <typename T>
T* getMemory(Address address) {
// if memory is on the stack, use the stack
if (address >= instance->STACK_START) {
Address relative = address - instance->STACK_START;
if (relative + sizeof(T) > instance->STACK_SIZE) {
if (address >= STACK_START) {
Address relative = address - STACK_START;
if (relative + sizeof(T) > STACK_SIZE) {
throw FailToEvalException("stack usage too high");
}
// in range, all is good, use the stack
Expand Down

0 comments on commit dfe92af

Please sign in to comment.