summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/s2wasm.h30
-rw-r--r--src/wasm-linker.cpp19
2 files changed, 25 insertions, 24 deletions
diff --git a/src/s2wasm.h b/src/s2wasm.h
index 8c04f7891..5b7cd1fa4 100644
--- a/src/s2wasm.h
+++ b/src/s2wasm.h
@@ -745,7 +745,7 @@ class S2WasmBuilder {
};
auto setOutput = [&](Expression* curr, Name assign) {
if (assign.isNull() || assign.str[0] == 'd') { // drop
- addToBlock(curr);
+ addToBlock(builder.makeDrop(curr));
} else if (assign.str[0] == 'p') { // push
push(curr);
} else { // set to a local
@@ -1067,8 +1067,6 @@ class S2WasmBuilder {
return target->cast<Loop>()->name;
}
};
- // fixups
- std::vector<Block*> loopBlocks; // we need to clear their names
// main loop
while (1) {
skipWhitespace();
@@ -1097,21 +1095,27 @@ class S2WasmBuilder {
recordLabel();
} else s = strchr(s, '\n');
} else if (match("loop")) {
+ // Allocate an explicit block. This replaces the exit label that was previously on the loop.
+ // Do this for now to keep LLVM's output compatible with both 0xb and 0xc Binaryen.
+ // TODO: Update LLVM to model the 0xc loop behavior
+ auto* explicitBlock = allocator->alloc<Block>();
+ addToBlock(explicitBlock);
+ bstack.push_back(explicitBlock);
auto curr = allocator->alloc<Loop>();
addToBlock(curr);
curr->name = getNextLabel();
- auto block = allocator->alloc<Block>();
- block->name = getNextLabel();
- curr->body = block;
- loopBlocks.push_back(block);
- bstack.push_back(block);
+ explicitBlock->name = getNextLabel();
+ auto implicitBlock = allocator->alloc<Block>();
+ curr->body = implicitBlock;
bstack.push_back(curr);
} else if (match("end_loop")) {
auto* loop = bstack.back()->cast<Loop>();
bstack.pop_back();
- auto* implicitBlock = bstack.back()->cast<Block>();
+ auto* explicitBlock = bstack.back()->cast<Block>();
bstack.pop_back();
- implicitBlock->finalize();
+
+ explicitBlock->finalize();
+ loop->body->finalize();
loop->finalize();
} else if (match("br_table")) {
auto curr = allocator->alloc<Switch>();
@@ -1147,11 +1151,10 @@ class S2WasmBuilder {
Name assign = getAssign();
skipComma();
auto curr = allocator->alloc<SetLocal>();
- curr->setTee(true);
curr->index = func->getLocalIndex(getAssign());
skipComma();
curr->value = getInput();
- curr->type = curr->value->type;
+ curr->setTee(true);
setOutput(curr, assign);
} else if (match("return")) {
addToBlock(builder.makeReturn(*s == '$' ? getInput() : nullptr));
@@ -1198,9 +1201,6 @@ class S2WasmBuilder {
bstack.pop_back(); // remove the base block for the function body
assert(bstack.empty());
assert(estack.empty());
- for (auto block : loopBlocks) {
- block->name = Name();
- }
func->body->dynCast<Block>()->finalize();
wasm->addFunction(func);
}
diff --git a/src/wasm-linker.cpp b/src/wasm-linker.cpp
index 527ff80ee..80374c1e4 100644
--- a/src/wasm-linker.cpp
+++ b/src/wasm-linker.cpp
@@ -193,23 +193,24 @@ void Linker::layout() {
out.wasm.addFunction(func);
exportFunction(start, true);
out.wasm.addStart(start);
- auto* block = out.wasm.allocator.alloc<Block>();
+ Builder builder(out.wasm);
+ auto* block = builder.makeBlock();
func->body = block;
{
// Create the call, matching its parameters.
// TODO allow calling with non-default values.
- auto* call = out.wasm.allocator.alloc<Call>();
- call->target = startFunction;
- size_t paramNum = 0;
+ std::vector<Expression*> args;
+ Index paramNum = 0;
for (WasmType type : target->params) {
Name name = Name::fromInt(paramNum++);
Builder::addVar(func, name, type);
- auto* param = out.wasm.allocator.alloc<GetLocal>();
- param->index = func->getLocalIndex(name);
- param->type = type;
- call->operands.push_back(param);
+ auto* param = builder.makeGetLocal(func->getLocalIndex(name), type);
+ args.push_back(param);
}
- block->list.push_back(call);
+ auto* call = builder.makeCall(startFunction, args, target->result);
+ Expression* e = call;
+ if (target->result != none) e = builder.makeDrop(call);
+ block->list.push_back(e);
block->finalize();
}
}