@@ -115,79 +115,63 @@ class EvallingModuleRunner : public ModuleRunnerBase<EvallingModuleRunner> {
115115 }
116116};
117117
118- // Build artificial modules based on a module's imports, so that the
118+ // Build an artificial `env` module based on a module's imports, so that the
119119// interpreter can use correct object instances. It initializes usable global
120120// imports, and fills the rest with fake values since those are dangerous to
121- // use. Imported globals can't be read anyway; see
122- // `EvallingModuleRunner::visitGlobalGet`.
123- // Note: wasi_ modules have stubs generated but won't be called due to the
124- // special handling in `CtorEvalExternalInterface::getImportedFunction`. We
125- // still generate the stubs to ensure the link-time validation passes.
126- std::vector<std::unique_ptr<Module>> buildStubModules (Module& wasm) {
127- std::map<Name, std::unique_ptr<Module>> modules;
128-
129- ModuleUtils::iterImports (
130- wasm,
131- [&modules](std::variant<Memory*, Table*, Global*, Function*, Tag*> import ) {
132- Importable* importable =
133- std::visit ([](auto * i) -> Importable* { return i; }, import );
134-
135- auto [it, inserted] = modules.try_emplace (importable->module , nullptr );
136- if (inserted) {
137- it->second = std::make_unique<Module>();
138- it->second ->name = importable->module ;
139- }
140- Module* module = it->second .get ();
141-
142- struct Visitor {
143- Module* module ;
144- void operator ()(Memory* memory) {
145- auto * copied = ModuleUtils::copyMemory (memory, *module );
146- copied->module = Name ();
147- copied->base = Name ();
148- module ->addExport (Builder (*module ).makeExport (
149- memory->base , copied->name , ExternalKind::Memory));
150- }
151- void operator ()(Table* table) {
152- // create tables with similar initial and max values
153- auto * copied = ModuleUtils::copyTable (table, *module );
154- copied->module = Name ();
155- copied->base = Name ();
156- module ->addExport (Builder (*module ).makeExport (
157- table->base , copied->name , ExternalKind::Table));
158- }
159- void operator ()(Global* global) {
160- auto * copied = ModuleUtils::copyGlobal (global, *module );
161- copied->module = Name ();
162- copied->base = Name ();
163-
164- Builder builder (*module );
165- copied->init = builder.makeConst (Literal::makeZero (global->type ));
166- module ->addExport (builder.makeExport (
167- global->base , copied->name , ExternalKind::Global));
168- }
169- void operator ()(Function* func) {
170- Builder builder (*module );
171- auto * copied = ModuleUtils::copyFunction (func, *module );
172- copied->module = Name ();
173- copied->base = Name ();
174- copied->body = builder.makeUnreachable ();
175- module ->addExport (builder.makeExport (
176- func->base , copied->name , ExternalKind::Function));
177- }
178- void operator ()(Tag* tag) {
179- // no-op
180- }
181- };
182- std::visit (Visitor{module }, import );
183- });
121+ // use. we will fail if dangerous globals are used.
122+ std::unique_ptr<Module> buildEnvModule (Module& wasm) {
123+ auto env = std::make_unique<Module>();
124+ env->name = " env" ;
125+
126+ // create empty functions with similar signature
127+ ModuleUtils::iterImportedFunctions (wasm, [&](Function* func) {
128+ if (func->module == env->name ) {
129+ Builder builder (*env);
130+ auto * copied = ModuleUtils::copyFunction (func, *env);
131+ copied->module = Name ();
132+ copied->base = Name ();
133+ copied->body = builder.makeUnreachable ();
134+ env->addExport (
135+ builder.makeExport (func->base , copied->name , ExternalKind::Function));
136+ }
137+ });
138+
139+ // create tables with similar initial and max values
140+ ModuleUtils::iterImportedTables (wasm, [&](Table* table) {
141+ if (table->module == env->name ) {
142+ auto * copied = ModuleUtils::copyTable (table, *env);
143+ copied->module = Name ();
144+ copied->base = Name ();
145+ env->addExport (Builder (*env).makeExport (
146+ table->base , copied->name , ExternalKind::Table));
147+ }
148+ });
149+
150+ ModuleUtils::iterImportedGlobals (wasm, [&](Global* global) {
151+ if (global->module == env->name ) {
152+ auto * copied = ModuleUtils::copyGlobal (global, *env);
153+ copied->module = Name ();
154+ copied->base = Name ();
155+
156+ Builder builder (*env);
157+ copied->init = builder.makeConst (Literal::makeZero (global->type ));
158+ env->addExport (
159+ builder.makeExport (global->base , copied->name , ExternalKind::Global));
160+ }
161+ });
162+
163+ // create an exported memory with the same initial and max size
164+ ModuleUtils::iterImportedMemories (wasm, [&](Memory* memory) {
165+ if (memory->module == env->name ) {
166+ auto * copied = ModuleUtils::copyMemory (memory, *env);
167+ copied->module = Name ();
168+ copied->base = Name ();
169+ env->addExport (Builder (*env).makeExport (
170+ memory->base , copied->name , ExternalKind::Memory));
171+ }
172+ });
184173
185- std::vector<std::unique_ptr<Module>> modulesVector;
186- modulesVector.reserve (modules.size ());
187- for (auto & [_, ptr] : modules) {
188- modulesVector.push_back (std::move (ptr));
189- }
190- return modulesVector;
174+ return env;
191175}
192176
193177// Whether to ignore external input to the program as it runs. If set, we will
@@ -1372,16 +1356,12 @@ void evalCtors(Module& wasm,
13721356
13731357 std::map<Name, std::shared_ptr<EvallingModuleRunner>> linkedInstances;
13741358
1375- // stubModules and interfaces must be kept alive since they are referenced in
1376- // linkedInstances.
1377- std::vector<std::unique_ptr<Module>> stubModules = buildStubModules (wasm);
1378- std::vector<std::unique_ptr<CtorEvalExternalInterface>> interfaces;
1379-
1380- for (auto & module : stubModules) {
1381- interfaces.push_back (std::make_unique<CtorEvalExternalInterface>());
1382- linkedInstances[module ->name ] =
1383- std::make_shared<EvallingModuleRunner>(*module , interfaces.back ().get ());
1384- }
1359+ // build and link the env module
1360+ auto envModule = buildEnvModule (wasm);
1361+ CtorEvalExternalInterface envInterface;
1362+ auto envInstance =
1363+ std::make_shared<EvallingModuleRunner>(*envModule, &envInterface);
1364+ linkedInstances[envModule->name ] = envInstance;
13851365
13861366 CtorEvalExternalInterface interface (linkedInstances);
13871367 try {
0 commit comments