diff options
author | Alon Zakai <alonzakai@gmail.com> | 2017-08-10 19:55:28 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-08-10 19:55:28 -0700 |
commit | 5295929fd239ea8a760cd2c3f65510da9972c33c (patch) | |
tree | c045323a48264f4f65fdd1cb01c7793f052814a4 /src | |
parent | 4f0bf336e0e04ec349c7524d86ffd2c4066cb644 (diff) | |
download | binaryen-5295929fd239ea8a760cd2c3f65510da9972c33c.tar.gz binaryen-5295929fd239ea8a760cd2c3f65510da9972c33c.tar.bz2 binaryen-5295929fd239ea8a760cd2c3f65510da9972c33c.zip |
when inlining, we must zero out non-param locals, as their initial zero value may be depended on (#1127)
Diffstat (limited to 'src')
-rw-r--r-- | src/passes/Inlining.cpp | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/src/passes/Inlining.cpp b/src/passes/Inlining.cpp index 377aa5247..20becfe46 100644 --- a/src/passes/Inlining.cpp +++ b/src/passes/Inlining.cpp @@ -28,6 +28,7 @@ #include <pass.h> #include <wasm-builder.h> #include <ast_utils.h> +#include <ast/literal-utils.h> #include <parsing.h> namespace wasm { @@ -121,11 +122,12 @@ private: // Core inlining logic. Modifies the outside function (adding locals as // needed), and returns the inlined code. static Expression* doInlining(Module* module, Function* into, InliningAction& action) { + Function* from = action.contents; auto* call = (*action.callSite)->cast<Call>(); Builder builder(*module); auto* block = Builder(*module).makeBlock(); block->type = call->type; - block->name = Name(std::string("__inlined_func$") + action.contents->name.str); + block->name = Name(std::string("__inlined_func$") + from->name.str); *action.callSite = block; // set up a locals mapping struct Updater : public PostWalker<Updater> { @@ -145,15 +147,19 @@ static Expression* doInlining(Module* module, Function* into, InliningAction& ac } updater; updater.returnName = block->name; updater.builder = &builder; - for (Index i = 0; i < action.contents->getNumLocals(); i++) { - updater.localMapping[i] = builder.addVar(into, action.contents->getLocalType(i)); + for (Index i = 0; i < from->getNumLocals(); i++) { + updater.localMapping[i] = builder.addVar(into, from->getLocalType(i)); } // assign the operands into the params - for (Index i = 0; i < action.contents->params.size(); i++) { + for (Index i = 0; i < from->params.size(); i++) { block->list.push_back(builder.makeSetLocal(updater.localMapping[i], call->operands[i])); } + // zero out the vars (as we may be in a loop, and may depend on their zero-init value + for (Index i = 0; i < from->vars.size(); i++) { + block->list.push_back(builder.makeSetLocal(updater.localMapping[from->getVarIndexBase() + i], LiteralUtils::makeZero(from->vars[i], *module))); + } // generate and update the inlined contents - auto* contents = ExpressionManipulator::copy(action.contents->body, *module); + auto* contents = ExpressionManipulator::copy(from->body, *module); updater.walk(contents); block->list.push_back(contents); return block; |