summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2017-08-10 19:55:28 -0700
committerGitHub <noreply@github.com>2017-08-10 19:55:28 -0700
commit5295929fd239ea8a760cd2c3f65510da9972c33c (patch)
treec045323a48264f4f65fdd1cb01c7793f052814a4 /src
parent4f0bf336e0e04ec349c7524d86ffd2c4066cb644 (diff)
downloadbinaryen-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.cpp16
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;