Skip to content

Commit dfe92af

Browse files
authored
clean up ImportUtils: make getImport return the import (more consistent 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 (#1226)
1 parent 73c0495 commit dfe92af

3 files changed

Lines changed: 50 additions & 31 deletions

File tree

src/ast/import-utils.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,13 @@ namespace wasm {
2525
namespace ImportUtils {
2626
// find an import by the module.base that is being imported.
2727
// return the internal name
28-
inline Name getImport(Module& wasm, Name module, Name base) {
28+
inline Import* getImport(Module& wasm, Name module, Name base) {
2929
for (auto& import : wasm.imports) {
3030
if (import->module == module && import->base == base) {
31-
return import->name;
31+
return import.get();
3232
}
3333
}
34-
return Name();
34+
return nullptr;
3535
}
3636
};
3737

src/passes/SafeHeap.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,9 @@ struct SafeHeap : public Pass {
114114

115115
void addImports(Module* module) {
116116
// imports
117-
dynamicTopPtr = ImportUtils::getImport(*module, ENV, DYNAMICTOP_PTR_IMPORT);
118-
if (!dynamicTopPtr.is()) {
117+
if (auto* existing = ImportUtils::getImport(*module, ENV, DYNAMICTOP_PTR_IMPORT)) {
118+
dynamicTopPtr = existing->name;
119+
} else {
119120
auto* import = new Import;
120121
import->name = dynamicTopPtr = DYNAMICTOP_PTR_IMPORT;
121122
import->module = ENV;
@@ -124,8 +125,9 @@ struct SafeHeap : public Pass {
124125
import->globalType = i32;
125126
module->addImport(import);
126127
}
127-
segfault = ImportUtils::getImport(*module, ENV, SEGFAULT_IMPORT);
128-
if (!segfault.is()) {
128+
if (auto* existing = ImportUtils::getImport(*module, ENV, SEGFAULT_IMPORT)) {
129+
dynamicTopPtr = existing->name;
130+
} else {
129131
auto* import = new Import;
130132
import->name = segfault = SEGFAULT_IMPORT;
131133
import->module = ENV;
@@ -134,8 +136,9 @@ struct SafeHeap : public Pass {
134136
import->functionType = ensureFunctionType("v", module)->name;
135137
module->addImport(import);
136138
}
137-
alignfault = ImportUtils::getImport(*module, ENV, ALIGNFAULT_IMPORT);
138-
if (!alignfault.is()) {
139+
if (auto* existing = ImportUtils::getImport(*module, ENV, ALIGNFAULT_IMPORT)) {
140+
dynamicTopPtr = existing->name;
141+
} else {
139142
auto* import = new Import;
140143
import->name = alignfault = ALIGNFAULT_IMPORT;
141144
import->module = ENV;

src/tools/wasm-ctor-eval.cpp

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
#include "wasm-builder.h"
3434
#include "ast/memory-utils.h"
3535
#include "ast/global-utils.h"
36+
#include "ast/import-utils.h"
37+
#include "ast/literal-utils.h"
3638

3739
using namespace wasm;
3840

@@ -78,11 +80,6 @@ class EvallingGlobalManager {
7880
}
7981
throw FailToEvalException(std::string("tried to access a dangerous (import-initialized) global: ") + name.str + extra);
8082
}
81-
if (sealed) {
82-
if (globals.find(name) == globals.end()) {
83-
throw FailToEvalException(std::string("tried to access missing global: ") + name.str);
84-
}
85-
}
8683
return globals[name];
8784
}
8885

@@ -114,6 +111,13 @@ class EvallingGlobalManager {
114111
}
115112
};
116113

114+
enum {
115+
// put the stack in some ridiculously high location
116+
STACK_START = 0x40000000,
117+
// use a ridiculously large stack size
118+
STACK_SIZE = 32 * 1024 * 1024
119+
};
120+
117121
class EvallingModuleInstance : public ModuleInstanceBase<EvallingGlobalManager, EvallingModuleInstance> {
118122
public:
119123
EvallingModuleInstance(Module& wasm, ExternalInterface* externalInterface) : ModuleInstanceBase(wasm, externalInterface) {
@@ -138,13 +142,6 @@ class EvallingModuleInstance : public ModuleInstanceBase<EvallingGlobalManager,
138142
}
139143
}
140144

141-
enum {
142-
// put the stack in some ridiculously high location
143-
STACK_START = 0x40000000,
144-
// use a ridiculously large stack size
145-
STACK_SIZE = 32 * 1024 * 1024
146-
};
147-
148145
std::vector<char> stack;
149146

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

183173
void importGlobals(EvallingGlobalManager& globals, Module& wasm_) override {
174+
// fill usable values for stack imports, and globals initialized to them
175+
if (auto* stackTop = ImportUtils::getImport(wasm_, "env", "STACKTOP")) {
176+
globals[stackTop->name] = Literal(int32_t(STACK_START));
177+
if (auto* stackTop = GlobalUtils::getGlobalInitializedToImport(wasm_, "env", "STACKTOP")) {
178+
globals[stackTop->name] = Literal(int32_t(STACK_START));
179+
}
180+
}
181+
if (auto* stackMax = ImportUtils::getImport(wasm_, "env", "STACK_MAX")) {
182+
globals[stackMax->name] = Literal(int32_t(STACK_START));
183+
if (auto* stackMax = GlobalUtils::getGlobalInitializedToImport(wasm_, "env", "STACK_MAX")) {
184+
globals[stackMax->name] = Literal(int32_t(STACK_START));
185+
}
186+
}
187+
// fill in fake values for everything else, which is dangerous to use
188+
for (auto& global : wasm_.globals) {
189+
if (globals.find(global->name) == globals.end()) {
190+
globals[global->name] = LiteralUtils::makeLiteralZero(global->type);
191+
}
192+
}
193+
for (auto& import : wasm_.imports) {
194+
if (import->kind == ExternalKind::Global) {
195+
if (globals.find(import->name) == globals.end()) {
196+
globals[import->name] = LiteralUtils::makeLiteralZero(import->globalType);
197+
}
198+
}
199+
}
184200
}
185201

186202
Literal callImport(Import *import, LiteralList& arguments) override {
@@ -248,9 +264,9 @@ struct CtorEvalExternalInterface : EvallingModuleInstance::ExternalInterface {
248264
template <typename T>
249265
T* getMemory(Address address) {
250266
// if memory is on the stack, use the stack
251-
if (address >= instance->STACK_START) {
252-
Address relative = address - instance->STACK_START;
253-
if (relative + sizeof(T) > instance->STACK_SIZE) {
267+
if (address >= STACK_START) {
268+
Address relative = address - STACK_START;
269+
if (relative + sizeof(T) > STACK_SIZE) {
254270
throw FailToEvalException("stack usage too high");
255271
}
256272
// in range, all is good, use the stack

0 commit comments

Comments
 (0)