diff options
Diffstat (limited to 'src/tools/wasm-ctor-eval.cpp')
-rw-r--r-- | src/tools/wasm-ctor-eval.cpp | 80 |
1 files changed, 73 insertions, 7 deletions
diff --git a/src/tools/wasm-ctor-eval.cpp b/src/tools/wasm-ctor-eval.cpp index b0a1c0551..009a91c0b 100644 --- a/src/tools/wasm-ctor-eval.cpp +++ b/src/tools/wasm-ctor-eval.cpp @@ -142,7 +142,7 @@ std::unique_ptr<Module> buildEnvModule(Module& wasm) { // create empty functions with similar signature ModuleUtils::iterImportedFunctions(wasm, [&](Function* func) { - if (func->module == "env") { + if (func->module == env->name) { Builder builder(*env); auto* copied = ModuleUtils::copyFunction(func, *env); copied->module = Name(); @@ -155,7 +155,7 @@ std::unique_ptr<Module> buildEnvModule(Module& wasm) { // create tables with similar initial and max values ModuleUtils::iterImportedTables(wasm, [&](Table* table) { - if (table->module == "env") { + if (table->module == env->name) { auto* copied = ModuleUtils::copyTable(table, *env); copied->module = Name(); copied->base = Name(); @@ -165,7 +165,7 @@ std::unique_ptr<Module> buildEnvModule(Module& wasm) { }); ModuleUtils::iterImportedGlobals(wasm, [&](Global* global) { - if (global->module == "env") { + if (global->module == env->name) { auto* copied = ModuleUtils::copyGlobal(global, *env); copied->module = Name(); copied->base = Name(); @@ -179,7 +179,7 @@ std::unique_ptr<Module> buildEnvModule(Module& wasm) { // create an exported memory with the same initial and max size ModuleUtils::iterImportedMemories(wasm, [&](Memory* memory) { - if (memory->module == "env") { + if (memory->module == env->name) { env->memory.name = wasm.memory.name; env->memory.exists = true; env->memory.initial = memory->initial; @@ -194,6 +194,11 @@ std::unique_ptr<Module> buildEnvModule(Module& wasm) { return env; } +// Whether to ignore external input to the program as it runs. If set, we will +// assume that stdin is empty, that any env vars we try to read are not set, +// that there are not arguments passed to main, etc. +static bool ignoreExternalInput = false; + struct CtorEvalExternalInterface : EvallingModuleInstance::ExternalInterface { Module* wasm; EvallingModuleInstance* instance; @@ -242,10 +247,63 @@ struct CtorEvalExternalInterface : EvallingModuleInstance::ExternalInterface { } Literals callImport(Function* import, LiteralList& arguments) override { + Name WASI("wasi_snapshot_preview1"); + + if (ignoreExternalInput) { + if (import->module == WASI) { + if (import->base == "environ_sizes_get") { + if (arguments.size() != 2 || arguments[0].type != Type::i32 || + import->getResults() != Type::i32) { + throw FailToEvalException("wasi environ_sizes_get has wrong sig"); + } + + // Write out a count of i32(0) and return __WASI_ERRNO_SUCCESS (0). + store32(arguments[0].geti32(), 0); + return {Literal(int32_t(0))}; + } + + if (import->base == "environ_get") { + if (arguments.size() != 2 || arguments[0].type != Type::i32 || + import->getResults() != Type::i32) { + throw FailToEvalException("wasi environ_get has wrong sig"); + } + + // Just return __WASI_ERRNO_SUCCESS (0). + return {Literal(int32_t(0))}; + } + + if (import->base == "args_sizes_get") { + if (arguments.size() != 2 || arguments[0].type != Type::i32 || + import->getResults() != Type::i32) { + throw FailToEvalException("wasi args_sizes_get has wrong sig"); + } + + // Write out an argc of i32(0) and return a __WASI_ERRNO_SUCCESS (0). + store32(arguments[0].geti32(), 0); + return {Literal(int32_t(0))}; + } + + if (import->base == "args_get") { + if (arguments.size() != 2 || arguments[0].type != Type::i32 || + import->getResults() != Type::i32) { + throw FailToEvalException("wasi args_get has wrong sig"); + } + + // Just return __WASI_ERRNO_SUCCESS (0). + return {Literal(int32_t(0))}; + } + + // Otherwise, we don't recognize this import; continue normally to + // error. + } + } + std::string extra; if (import->module == ENV && import->base == "___cxa_atexit") { extra = "\nrecommendation: build with -s NO_EXIT_RUNTIME=1 so that calls " "to atexit are not emitted"; + } else if (import->module == WASI && !ignoreExternalInput) { + extra = "\nrecommendation: consider --ignore-external-input"; } throw FailToEvalException(std::string("call import: ") + import->module.str + "." + import->base.str + @@ -416,14 +474,14 @@ private: }; void evalCtors(Module& wasm, std::vector<std::string> ctors) { + std::map<Name, std::shared_ptr<EvallingModuleInstance>> linkedInstances; + // build and link the env module auto envModule = buildEnvModule(wasm); CtorEvalExternalInterface envInterface; auto envInstance = std::make_shared<EvallingModuleInstance>(*envModule, &envInterface); - - std::map<Name, std::shared_ptr<EvallingModuleInstance>> linkedInstances; - linkedInstances["env"] = envInstance; + linkedInstances[envModule->name] = envInstance; CtorEvalExternalInterface interface(linkedInstances); try { @@ -525,6 +583,14 @@ int main(int argc, const char* argv[]) { WasmCtorEvalOption, Options::Arguments::One, [&](Options* o, const std::string& argument) { ctorsString = argument; }) + .add("--ignore-external-input", + "-ipi", + "Assumes no env vars are to be read, stdin is empty, etc.", + WasmCtorEvalOption, + Options::Arguments::Zero, + [&](Options* o, const std::string& argument) { + ignoreExternalInput = true; + }) .add_positional("INFILE", Options::Arguments::One, [](Options* o, const std::string& argument) { |