diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/s2wasm.h | 30 | ||||
-rw-r--r-- | src/wasm-linker.cpp | 19 |
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(); } } |