diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/asm2wasm.h | 8 | ||||
-rw-r--r-- | src/pass.h | 38 | ||||
-rw-r--r-- | src/passes/LowerIfElse.cpp | 4 | ||||
-rw-r--r-- | src/passes/LowerInt64.cpp | 42 | ||||
-rw-r--r-- | src/passes/MergeBlocks.cpp | 4 | ||||
-rw-r--r-- | src/passes/RemoveImports.cpp | 6 | ||||
-rw-r--r-- | src/passes/RemoveUnusedBrs.cpp | 6 | ||||
-rw-r--r-- | src/passes/RemoveUnusedNames.cpp | 8 | ||||
-rw-r--r-- | src/passes/SimplifyLocals.cpp | 4 | ||||
-rw-r--r-- | src/s2wasm.h | 4 | ||||
-rw-r--r-- | src/wasm-binary.h | 2 | ||||
-rw-r--r-- | src/wasm-interpreter.h | 40 | ||||
-rw-r--r-- | src/wasm-validator.h | 24 | ||||
-rw-r--r-- | src/wasm.h | 257 | ||||
-rw-r--r-- | src/wasm2asm.h | 72 |
15 files changed, 264 insertions, 255 deletions
diff --git a/src/asm2wasm.h b/src/asm2wasm.h index 75862abc8..b968b8596 100644 --- a/src/asm2wasm.h +++ b/src/asm2wasm.h @@ -1489,8 +1489,8 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { void Asm2WasmBuilder::optimize() { // Optimization passes. Note: no effort is made to free nodes that are no longer held on to. - struct BlockBreakOptimizer : public WasmWalker { - void visitBlock(Block *curr) override { + struct BlockBreakOptimizer : public WasmWalker<BlockBreakOptimizer, void> { + void visitBlock(Block *curr) { // if the block ends in a break on this very block, then just put the value there Break *last = curr->list[curr->list.size()-1]->dyn_cast<Break>(); if (last && last->value && last->name == curr->name) { @@ -1504,13 +1504,13 @@ void Asm2WasmBuilder::optimize() { } // we might be broken to, but maybe there isn't a break (and we may have removed it, leading to this) - struct BreakSeeker : public WasmWalker { + struct BreakSeeker : public WasmWalker<BreakSeeker, void> { IString target; // look for this one size_t found; BreakSeeker(IString target) : target(target), found(false) {} - void visitBreak(Break *curr) override { + void visitBreak(Break *curr) { if (curr->name == target) found++; } }; diff --git a/src/pass.h b/src/pass.h index 691583f2b..82b3e3c40 100644 --- a/src/pass.h +++ b/src/pass.h @@ -89,20 +89,24 @@ struct PassRunner { // Core pass class // class Pass { - public: - // Override this to perform preparation work before the pass runs +public: + virtual ~Pass() {}; + // Override this to perform preparation work before the pass runs. virtual void prepare(PassRunner* runner, Module* module) {} - virtual void run(PassRunner* runner, Module* module) { abort(); } - virtual ~Pass() {} + virtual void run(PassRunner* runner, Module* module) = 0; +protected: + Pass() {} + Pass(Pass &) {} + Pass &operator=(const Pass&) = delete; }; // // Core pass class that uses AST walking. This class can be parameterized by // different types of AST walkers. // -template <class WalkerType> +template <typename WalkerType> class WalkerPass : public Pass, public WalkerType { - public: +public: void run(PassRunner* runner, Module* module) override { prepare(runner, module); WalkerType::startWalk(module); @@ -114,22 +118,22 @@ class WalkerPass : public Pass, public WalkerType { // e.g. through PassRunner::getLast // Handles names in a module, in particular adding names without duplicates -class NameManager : public WalkerPass<WasmWalker> { +class NameManager : public WalkerPass<WasmWalker<NameManager, void> > { public: Name getUnique(std::string prefix); // TODO: getUniqueInFunction // visitors - void visitBlock(Block* curr) override; - void visitLoop(Loop* curr) override; - void visitBreak(Break* curr) override; - void visitSwitch(Switch* curr) override; - void visitCall(Call* curr) override; - void visitCallImport(CallImport* curr) override; - void visitFunctionType(FunctionType* curr) override; - void visitFunction(Function* curr) override; - void visitImport(Import* curr) override; - void visitExport(Export* curr) override; + void visitBlock(Block* curr); + void visitLoop(Loop* curr); + void visitBreak(Break* curr); + void visitSwitch(Switch* curr); + void visitCall(Call* curr); + void visitCallImport(CallImport* curr); + void visitFunctionType(FunctionType* curr); + void visitFunction(Function* curr); + void visitImport(Import* curr); + void visitExport(Export* curr); private: std::set<Name> names; diff --git a/src/passes/LowerIfElse.cpp b/src/passes/LowerIfElse.cpp index 26ae321e6..dd7fbf998 100644 --- a/src/passes/LowerIfElse.cpp +++ b/src/passes/LowerIfElse.cpp @@ -32,7 +32,7 @@ namespace wasm { -struct LowerIfElse : public WalkerPass<WasmWalker> { +struct LowerIfElse : public WalkerPass<WasmWalker<LowerIfElse, void>> { MixedArena* allocator; std::unique_ptr<NameManager> namer; @@ -42,7 +42,7 @@ struct LowerIfElse : public WalkerPass<WasmWalker> { namer->run(runner, module); } - void visitIf(If *curr) override { + void visitIf(If *curr) { if (curr->ifFalse) { auto block = allocator->alloc<Block>(); auto name = namer->getUnique("L"); // TODO: getUniqueInFunction diff --git a/src/passes/LowerInt64.cpp b/src/passes/LowerInt64.cpp index ae3f773bd..09daa9934 100644 --- a/src/passes/LowerInt64.cpp +++ b/src/passes/LowerInt64.cpp @@ -63,16 +63,16 @@ struct LowerInt64 : public Pass { } } - void visitCall(Call *curr) override { + void visitCall(Call *curr) { fixCall(curr); } - void visitCallImport(CallImport *curr) override { + void visitCallImport(CallImport *curr) { fixCall(curr); } - void visitCallIndirect(CallIndirect *curr) override { + void visitCallIndirect(CallIndirect *curr) { fixCall(curr); } - void visitGetLocal(GetLocal *curr) override { + void visitGetLocal(GetLocal *curr) { if (curr->type == i64) { if (locals.count(curr->name) == 0) { Name highName = namer->getUnique("high"); @@ -85,7 +85,7 @@ struct LowerInt64 : public Pass { fixes[curr] = high; } } - void visitSetLocal(SetLocal *curr) override { + void visitSetLocal(SetLocal *curr) { if (curr->type == i64) { Name highName; if (locals.count(curr->name) == 0) { @@ -142,7 +142,7 @@ struct LowerInt64 : public Pass { return ret; } - void visitLoad(Load *curr) override { + void visitLoad(Load *curr) { if (curr->type == i64) { Name local; auto ret = setToLocalForBlock(curr->ptr, local); @@ -158,7 +158,7 @@ struct LowerInt64 : public Pass { replaceCurrent(ret); } } - void visitStore(Store *curr) override { + void visitStore(Store *curr) { if (curr->type == i64) { Name localPtr, localValue; auto ret = setToLocalForBlock(curr->ptr, localPtr); @@ -178,28 +178,28 @@ struct LowerInt64 : public Pass { replaceCurrent(ret); } } - void visitConst(Const *curr) override { + void visitConst(Const *curr) { } - void visitUnary(Unary *curr) override { + void visitUnary(Unary *curr) { } - void visitBinary(Binary *curr) override { + void visitBinary(Binary *curr) { } - void visitSelect(Select *curr) override { + void visitSelect(Select *curr) { } - void visitHost(Host *curr) override { + void visitHost(Host *curr) { } - void visitNop(Nop *curr) override { + void visitNop(Nop *curr) { } - void visitUnreachable(Unreachable *curr) override { + void visitUnreachable(Unreachable *curr) { } - void visitFunctionType(FunctionType *curr) override { + void visitFunctionType(FunctionType *curr) { } - void visitImport(Import *curr) override { + void visitImport(Import *curr) { } - void visitExport(Export *curr) override { + void visitExport(Export *curr) { } - void visitFunction(Function *curr) override { + void visitFunction(Function *curr) { // TODO: new params for (auto localPair : locals) { // TODO: ignore params curr->locals.emplace_back(localPair.second, i32); @@ -207,11 +207,11 @@ struct LowerInt64 : public Pass { fixes.clear(); locals.clear(); } - void visitTable(Table *curr) override { + void visitTable(Table *curr) { } - void visitMemory(Memory *curr) override { + void visitMemory(Memory *curr) { } - void visitModule(Module *curr) override { + void visitModule(Module *curr) { } }; diff --git a/src/passes/MergeBlocks.cpp b/src/passes/MergeBlocks.cpp index 5543c407b..60b865777 100644 --- a/src/passes/MergeBlocks.cpp +++ b/src/passes/MergeBlocks.cpp @@ -23,8 +23,8 @@ namespace wasm { -struct MergeBlocks : public WalkerPass<WasmWalker> { - void visitBlock(Block *curr) override { +struct MergeBlocks : public WalkerPass<WasmWalker<MergeBlocks, void> > { + void visitBlock(Block *curr) { bool more = true; while (more) { more = false; diff --git a/src/passes/RemoveImports.cpp b/src/passes/RemoveImports.cpp index 0938bbed3..edcd7b580 100644 --- a/src/passes/RemoveImports.cpp +++ b/src/passes/RemoveImports.cpp @@ -27,7 +27,7 @@ namespace wasm { -struct RemoveImports : public WalkerPass<WasmWalker> { +struct RemoveImports : public WalkerPass<WasmWalker<RemoveImports, void> > { MixedArena* allocator; std::map<Name, Import*> importsMap; @@ -36,7 +36,7 @@ struct RemoveImports : public WalkerPass<WasmWalker> { importsMap = module->importsMap; } - void visitCallImport(CallImport *curr) override { + void visitCallImport(CallImport *curr) { WasmType type = importsMap[curr->target]->type->result; if (type == none) { replaceCurrent(allocator->alloc<Nop>()); @@ -47,7 +47,7 @@ struct RemoveImports : public WalkerPass<WasmWalker> { } } - void visitModule(Module *curr) override { + void visitModule(Module *curr) { curr->importsMap.clear(); curr->imports.clear(); } diff --git a/src/passes/RemoveUnusedBrs.cpp b/src/passes/RemoveUnusedBrs.cpp index f01add24c..4bfc368f8 100644 --- a/src/passes/RemoveUnusedBrs.cpp +++ b/src/passes/RemoveUnusedBrs.cpp @@ -23,11 +23,11 @@ namespace wasm { -struct RemoveUnusedBrs : public WalkerPass<WasmWalker> { +struct RemoveUnusedBrs : public WalkerPass<WasmWalker<RemoveUnusedBrs, void> > { // preparation: try to unify branches, as the fewer there are, the higher a chance we can remove them // specifically for if-else, turn an if-else with branches to the same target at the end of each // child, and with a value, to a branch to that target containing the if-else - void visitIf(If* curr) override { + void visitIf(If* curr) { if (!curr->ifFalse) return; if (curr->type != none) return; // already has a returned value // an if_else that indirectly returns a value by breaking to the same target can potentially remove both breaks, and break outside once @@ -63,7 +63,7 @@ struct RemoveUnusedBrs : public WalkerPass<WasmWalker> { } // main portion - void visitBlock(Block *curr) override { + void visitBlock(Block *curr) { if (curr->name.isNull()) return; if (curr->list.size() == 0) return; // preparation - remove all code after a break, since it can't execute, and it might confuse us (we look at the last) diff --git a/src/passes/RemoveUnusedNames.cpp b/src/passes/RemoveUnusedNames.cpp index d3057c78a..8ebcdd1d3 100644 --- a/src/passes/RemoveUnusedNames.cpp +++ b/src/passes/RemoveUnusedNames.cpp @@ -23,22 +23,22 @@ namespace wasm { -struct RemoveUnusedNames : public WalkerPass<WasmWalker> { +struct RemoveUnusedNames : public WalkerPass<WasmWalker<RemoveUnusedNames, void> > { // We maintain a list of branches that we saw in children, then when we reach // a parent block, we know if it was branched to std::set<Name> branchesSeen; - void visitBreak(Break *curr) override { + void visitBreak(Break *curr) { branchesSeen.insert(curr->name); } - void visitBlock(Block *curr) override { + void visitBlock(Block *curr) { if (curr->name.is() && branchesSeen.count(curr->name) == 0) { curr->name = Name(); } } - void visitFunction(Function *curr) override { + void visitFunction(Function *curr) { branchesSeen.clear(); } }; diff --git a/src/passes/SimplifyLocals.cpp b/src/passes/SimplifyLocals.cpp index bf3775445..6d16dfafe 100644 --- a/src/passes/SimplifyLocals.cpp +++ b/src/passes/SimplifyLocals.cpp @@ -23,8 +23,8 @@ namespace wasm { -struct SimplifyLocals : public WalkerPass<WasmWalker> { - void visitBlock(Block *curr) override { +struct SimplifyLocals : public WalkerPass<WasmWalker<SimplifyLocals, void> > { + void visitBlock(Block *curr) { // look for pairs of setlocal-getlocal, which can be just a setlocal (since it returns a value) if (curr->list.size() == 0) return; for (size_t i = 0; i < curr->list.size() - 1; i++) { diff --git a/src/s2wasm.h b/src/s2wasm.h index cc38dd276..e22e76289 100644 --- a/src/s2wasm.h +++ b/src/s2wasm.h @@ -1102,7 +1102,7 @@ public: o << ";; METADATA: { "; // find asmConst calls, and emit their metadata - struct AsmConstWalker : public WasmWalker { + struct AsmConstWalker : public WasmWalker<AsmConstWalker, void> { S2WasmBuilder* parent; std::map<std::string, std::set<std::string>> sigsForCode; @@ -1111,7 +1111,7 @@ public: AsmConstWalker(S2WasmBuilder* parent) : parent(parent) {} - void visitCallImport(CallImport* curr) override { + void visitCallImport(CallImport* curr) { if (curr->target == EMSCRIPTEN_ASM_CONST) { auto arg = curr->operands[0]->cast<Const>(); size_t segmentIndex = parent->addressSegments[arg->value.geti32()]; diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 9accbfbc0..809c559ff 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -323,7 +323,7 @@ char binaryWasmType(WasmType type) { } } -class WasmBinaryWriter : public WasmVisitor<void> { +class WasmBinaryWriter : public WasmVisitor<WasmBinaryWriter, void> { Module* wasm; BufferWithRandomAccess& o; diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 5dbd09ef1..bcd8dee28 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -173,14 +173,14 @@ private: #endif // Execute a statement - class ExpressionRunner : public WasmVisitor<Flow> { + class ExpressionRunner : public WasmVisitor<ExpressionRunner, Flow> { ModuleInstance& instance; FunctionScope& scope; public: ExpressionRunner(ModuleInstance& instance, FunctionScope& scope) : instance(instance), scope(scope) {} - Flow visitBlock(Block *curr) override { + Flow visitBlock(Block *curr) { NOTE_ENTER("Block"); Flow flow; for (auto expression : curr->list) { @@ -192,7 +192,7 @@ private: } return flow; } - Flow visitIf(If *curr) override { + Flow visitIf(If *curr) { NOTE_ENTER("If"); Flow flow = visit(curr->condition); if (flow.breaking()) return flow; @@ -205,7 +205,7 @@ private: if (curr->ifFalse) return visit(curr->ifFalse); return Flow(); } - Flow visitLoop(Loop *curr) override { + Flow visitLoop(Loop *curr) { NOTE_ENTER("Loop"); while (1) { Flow flow = visit(curr->body); @@ -216,7 +216,7 @@ private: return flow; // loop does not loop automatically, only continue achieves that } } - Flow visitBreak(Break *curr) override { + Flow visitBreak(Break *curr) { NOTE_ENTER("Break"); bool condition = true; if (curr->condition) { @@ -232,7 +232,7 @@ private: } return condition ? flow : Flow(); } - Flow visitSwitch(Switch *curr) override { + Flow visitSwitch(Switch *curr) { NOTE_ENTER("Switch"); Flow flow = visit(curr->value); if (flow.breaking()) { @@ -281,7 +281,7 @@ private: return Flow(); } - Flow visitCall(Call *curr) override { + Flow visitCall(Call *curr) { NOTE_ENTER("Call"); NOTE_NAME(curr->target); LiteralList arguments; @@ -293,14 +293,14 @@ private: #endif return ret; } - Flow visitCallImport(CallImport *curr) override { + Flow visitCallImport(CallImport *curr) { NOTE_ENTER("CallImport"); LiteralList arguments; Flow flow = generateArguments(curr->operands, arguments); if (flow.breaking()) return flow; return instance.externalInterface->callImport(instance.wasm.importsMap[curr->target], arguments); } - Flow visitCallIndirect(CallIndirect *curr) override { + Flow visitCallIndirect(CallIndirect *curr) { NOTE_ENTER("CallIndirect"); Flow target = visit(curr->target); if (target.breaking()) return target; @@ -315,14 +315,14 @@ private: return instance.callFunction(name, arguments); } - Flow visitGetLocal(GetLocal *curr) override { + Flow visitGetLocal(GetLocal *curr) { NOTE_ENTER("GetLocal"); IString name = curr->name; NOTE_NAME(name); NOTE_EVAL1(scope.locals[name]); return scope.locals[name]; } - Flow visitSetLocal(SetLocal *curr) override { + Flow visitSetLocal(SetLocal *curr) { NOTE_ENTER("SetLocal"); IString name = curr->name; Flow flow = visit(curr->value); @@ -333,13 +333,13 @@ private: scope.locals[name] = flow.value; return flow; } - Flow visitLoad(Load *curr) override { + Flow visitLoad(Load *curr) { NOTE_ENTER("Load"); Flow flow = visit(curr->ptr); if (flow.breaking()) return flow; return instance.externalInterface->load(curr, instance.getFinalAddress(curr, flow.value)); } - Flow visitStore(Store *curr) override { + Flow visitStore(Store *curr) { NOTE_ENTER("Store"); Flow ptr = visit(curr->ptr); if (ptr.breaking()) return ptr; @@ -348,12 +348,12 @@ private: instance.externalInterface->store(curr, instance.getFinalAddress(curr, ptr.value), value.value); return value; } - Flow visitConst(Const *curr) override { + Flow visitConst(Const *curr) { NOTE_ENTER("Const"); NOTE_EVAL1(curr->value); return Flow(curr->value); // heh } - Flow visitUnary(Unary *curr) override { + Flow visitUnary(Unary *curr) { NOTE_ENTER("Unary"); Flow flow = visit(curr->value); if (flow.breaking()) return flow; @@ -434,7 +434,7 @@ private: } abort(); } - Flow visitBinary(Binary *curr) override { + Flow visitBinary(Binary *curr) { NOTE_ENTER("Binary"); Flow flow = visit(curr->left); if (flow.breaking()) return flow; @@ -612,7 +612,7 @@ private: } abort(); } - Flow visitSelect(Select *curr) override { + Flow visitSelect(Select *curr) { NOTE_ENTER("Select"); Flow condition = visit(curr->condition); if (condition.breaking()) return condition; @@ -623,7 +623,7 @@ private: if (ifFalse.breaking()) return ifFalse; return condition.value.geti32() ? ifTrue : ifFalse; // ;-) } - Flow visitHost(Host *curr) override { + Flow visitHost(Host *curr) { NOTE_ENTER("Host"); switch (curr->op) { case PageSize: return Literal((int32_t)pageSize); @@ -649,11 +649,11 @@ private: default: abort(); } } - Flow visitNop(Nop *curr) override { + Flow visitNop(Nop *curr) { NOTE_ENTER("Nop"); return Flow(); } - Flow visitUnreachable(Unreachable *curr) override { + Flow visitUnreachable(Unreachable *curr) { NOTE_ENTER("Unreachable"); trap("unreachable"); return Flow(); diff --git a/src/wasm-validator.h b/src/wasm-validator.h index f0e73fb85..237942047 100644 --- a/src/wasm-validator.h +++ b/src/wasm-validator.h @@ -25,7 +25,7 @@ namespace wasm { -struct WasmValidator : public WasmWalker { +struct WasmValidator : public WasmWalker<WasmValidator, void> { bool valid; public: @@ -37,23 +37,23 @@ public: // visitors - void visitLoop(Loop *curr) override { + void visitLoop(Loop *curr) { if (curr->in.is()) { LoopChildChecker childChecker(curr->in); childChecker.walk(curr->body); shouldBeTrue(childChecker.valid); } } - void visitSetLocal(SetLocal *curr) override { + void visitSetLocal(SetLocal *curr) { shouldBeTrue(curr->type == curr->value->type); } - void visitLoad(Load *curr) override { + void visitLoad(Load *curr) { validateAlignment(curr->align); } - void visitStore(Store *curr) override { + void visitStore(Store *curr) { validateAlignment(curr->align); } - void visitSwitch(Switch *curr) override { + void visitSwitch(Switch *curr) { std::set<Name> inTable; for (auto target : curr->targets) { if (target.is()) { @@ -65,14 +65,14 @@ public: } shouldBeFalse(curr->default_.is() && inTable.find(curr->default_) == inTable.end()); } - void visitUnary(Unary *curr) override { + void visitUnary(Unary *curr) { shouldBeTrue(curr->value->type == curr->type); } - void visitFunction(Function *curr) override { + void visitFunction(Function *curr) { shouldBeTrue(curr->result == curr->body->type); } - void visitMemory(Memory *curr) override { + void visitMemory(Memory *curr) { shouldBeFalse(curr->initial > curr->max); size_t top = 0; for (auto segment : curr->segments) { @@ -81,7 +81,7 @@ public: } shouldBeFalse(top > curr->initial); } - void visitModule(Module *curr) override { + void visitModule(Module *curr) { for (auto& exp : curr->exports) { Name name = exp->name; bool found = false; @@ -98,13 +98,13 @@ public: private: // the "in" label has a none type, since no one can receive its value. make sure no one breaks to it with a value. - struct LoopChildChecker : public WasmWalker { + struct LoopChildChecker : public WasmWalker<LoopChildChecker, void> { Name in; bool valid = true; LoopChildChecker(Name in) : in(in) {} - void visitBreak(Break *curr) override { + void visitBreak(Break *curr) { if (curr->name == in && curr->value) { valid = false; } diff --git a/src/wasm.h b/src/wasm.h index c6942acfe..a5ad3fe77 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -1137,61 +1137,62 @@ class AllocatingModule : public Module { // etc. // -template<class ReturnType> +template<typename SubType, typename ReturnType> struct WasmVisitor { virtual ~WasmVisitor() {} // should be pure virtual, but https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51048 // Expression visitors - virtual ReturnType visitBlock(Block *curr) { abort(); } - virtual ReturnType visitIf(If *curr) { abort(); } - virtual ReturnType visitLoop(Loop *curr) { abort(); } - virtual ReturnType visitBreak(Break *curr) { abort(); } - virtual ReturnType visitSwitch(Switch *curr) { abort(); } - virtual ReturnType visitCall(Call *curr) { abort(); } - virtual ReturnType visitCallImport(CallImport *curr) { abort(); } - virtual ReturnType visitCallIndirect(CallIndirect *curr) { abort(); } - virtual ReturnType visitGetLocal(GetLocal *curr) { abort(); } - virtual ReturnType visitSetLocal(SetLocal *curr) { abort(); } - virtual ReturnType visitLoad(Load *curr) { abort(); } - virtual ReturnType visitStore(Store *curr) { abort(); } - virtual ReturnType visitConst(Const *curr) { abort(); } - virtual ReturnType visitUnary(Unary *curr) { abort(); } - virtual ReturnType visitBinary(Binary *curr) { abort(); } - virtual ReturnType visitSelect(Select *curr) { abort(); } - virtual ReturnType visitHost(Host *curr) { abort(); } - virtual ReturnType visitNop(Nop *curr) { abort(); } - virtual ReturnType visitUnreachable(Unreachable *curr) { abort(); } + ReturnType visitBlock(Block *curr) { abort(); } + ReturnType visitIf(If *curr) { abort(); } + ReturnType visitLoop(Loop *curr) { abort(); } + ReturnType visitBreak(Break *curr) { abort(); } + ReturnType visitSwitch(Switch *curr) { abort(); } + ReturnType visitCall(Call *curr) { abort(); } + ReturnType visitCallImport(CallImport *curr) { abort(); } + ReturnType visitCallIndirect(CallIndirect *curr) { abort(); } + ReturnType visitGetLocal(GetLocal *curr) { abort(); } + ReturnType visitSetLocal(SetLocal *curr) { abort(); } + ReturnType visitLoad(Load *curr) { abort(); } + ReturnType visitStore(Store *curr) { abort(); } + ReturnType visitConst(Const *curr) { abort(); } + ReturnType visitUnary(Unary *curr) { abort(); } + ReturnType visitBinary(Binary *curr) { abort(); } + ReturnType visitSelect(Select *curr) { abort(); } + ReturnType visitHost(Host *curr) { abort(); } + ReturnType visitNop(Nop *curr) { abort(); } + ReturnType visitUnreachable(Unreachable *curr) { abort(); } // Module-level visitors - virtual ReturnType visitFunctionType(FunctionType *curr) { abort(); } - virtual ReturnType visitImport(Import *curr) { abort(); } - virtual ReturnType visitExport(Export *curr) { abort(); } - virtual ReturnType visitFunction(Function *curr) { abort(); } - virtual ReturnType visitTable(Table *curr) { abort(); } - virtual ReturnType visitMemory(Memory *curr) { abort(); } - virtual ReturnType visitModule(Module *curr) { abort(); } + ReturnType visitFunctionType(FunctionType *curr) { abort(); } + ReturnType visitImport(Import *curr) { abort(); } + ReturnType visitExport(Export *curr) { abort(); } + ReturnType visitFunction(Function *curr) { abort(); } + ReturnType visitTable(Table *curr) { abort(); } + ReturnType visitMemory(Memory *curr) { abort(); } + ReturnType visitModule(Module *curr) { abort(); } ReturnType visit(Expression *curr) { assert(curr); + SubType* self = static_cast<SubType*>(this); switch (curr->_id) { - case Expression::Id::BlockId: return visitBlock((Block*)curr); - case Expression::Id::IfId: return visitIf((If*)curr); - case Expression::Id::LoopId: return visitLoop((Loop*)curr); - case Expression::Id::BreakId: return visitBreak((Break*)curr); - case Expression::Id::SwitchId: return visitSwitch((Switch*)curr); - case Expression::Id::CallId: return visitCall((Call*)curr); - case Expression::Id::CallImportId: return visitCallImport((CallImport*)curr); - case Expression::Id::CallIndirectId: return visitCallIndirect((CallIndirect*)curr); - case Expression::Id::GetLocalId: return visitGetLocal((GetLocal*)curr); - case Expression::Id::SetLocalId: return visitSetLocal((SetLocal*)curr); - case Expression::Id::LoadId: return visitLoad((Load*)curr); - case Expression::Id::StoreId: return visitStore((Store*)curr); - case Expression::Id::ConstId: return visitConst((Const*)curr); - case Expression::Id::UnaryId: return visitUnary((Unary*)curr); - case Expression::Id::BinaryId: return visitBinary((Binary*)curr); - case Expression::Id::SelectId: return visitSelect((Select*)curr); - case Expression::Id::HostId: return visitHost((Host*)curr); - case Expression::Id::NopId: return visitNop((Nop*)curr); - case Expression::Id::UnreachableId: return visitUnreachable((Unreachable*)curr); + case Expression::Id::BlockId: return self->visitBlock((Block*)curr); + case Expression::Id::IfId: return self->visitIf((If*)curr); + case Expression::Id::LoopId: return self->visitLoop((Loop*)curr); + case Expression::Id::BreakId: return self->visitBreak((Break*)curr); + case Expression::Id::SwitchId: return self->visitSwitch((Switch*)curr); + case Expression::Id::CallId: return self->visitCall((Call*)curr); + case Expression::Id::CallImportId: return self->visitCallImport((CallImport*)curr); + case Expression::Id::CallIndirectId: return self->visitCallIndirect((CallIndirect*)curr); + case Expression::Id::GetLocalId: return self->visitGetLocal((GetLocal*)curr); + case Expression::Id::SetLocalId: return self->visitSetLocal((SetLocal*)curr); + case Expression::Id::LoadId: return self->visitLoad((Load*)curr); + case Expression::Id::StoreId: return self->visitStore((Store*)curr); + case Expression::Id::ConstId: return self->visitConst((Const*)curr); + case Expression::Id::UnaryId: return self->visitUnary((Unary*)curr); + case Expression::Id::BinaryId: return self->visitBinary((Binary*)curr); + case Expression::Id::SelectId: return self->visitSelect((Select*)curr); + case Expression::Id::HostId: return self->visitHost((Host*)curr); + case Expression::Id::NopId: return self->visitNop((Nop*)curr); + case Expression::Id::UnreachableId: return self->visitUnreachable((Unreachable*)curr); default: { std::cerr << "visiting unknown expression " << curr->_id << '\n'; abort(); @@ -1201,31 +1202,31 @@ struct WasmVisitor { }; std::ostream& Expression::print(std::ostream &o, unsigned indent) { - struct ExpressionPrinter : public WasmVisitor<void> { + struct ExpressionPrinter : public WasmVisitor<ExpressionPrinter, void> { std::ostream &o; unsigned indent; ExpressionPrinter(std::ostream &o, unsigned indent) : o(o), indent(indent) {} - void visitBlock(Block *curr) override { curr->doPrint(o, indent); } - void visitIf(If *curr) override { curr->doPrint(o, indent); } - void visitLoop(Loop *curr) override { curr->doPrint(o, indent); } - void visitBreak(Break *curr) override { curr->doPrint(o, indent); } - void visitSwitch(Switch *curr) override { curr->doPrint(o, indent); } - void visitCall(Call *curr) override { curr->doPrint(o, indent); } - void visitCallImport(CallImport *curr) override { curr->doPrint(o, indent); } - void visitCallIndirect(CallIndirect *curr) override { curr->doPrint(o, indent); } - void visitGetLocal(GetLocal *curr) override { curr->doPrint(o, indent); } - void visitSetLocal(SetLocal *curr) override { curr->doPrint(o, indent); } - void visitLoad(Load *curr) override { curr->doPrint(o, indent); } - void visitStore(Store *curr) override { curr->doPrint(o, indent); } - void visitConst(Const *curr) override { curr->doPrint(o, indent); } - void visitUnary(Unary *curr) override { curr->doPrint(o, indent); } - void visitBinary(Binary *curr) override { curr->doPrint(o, indent); } - void visitSelect(Select *curr) override { curr->doPrint(o, indent); } - void visitHost(Host *curr) override { curr->doPrint(o, indent); } - void visitNop(Nop *curr) override { curr->doPrint(o, indent); } - void visitUnreachable(Unreachable *curr) override { curr->doPrint(o, indent); } + void visitBlock(Block *curr) { curr->doPrint(o, indent); } + void visitIf(If *curr) { curr->doPrint(o, indent); } + void visitLoop(Loop *curr) { curr->doPrint(o, indent); } + void visitBreak(Break *curr) { curr->doPrint(o, indent); } + void visitSwitch(Switch *curr) { curr->doPrint(o, indent); } + void visitCall(Call *curr) { curr->doPrint(o, indent); } + void visitCallImport(CallImport *curr) { curr->doPrint(o, indent); } + void visitCallIndirect(CallIndirect *curr) { curr->doPrint(o, indent); } + void visitGetLocal(GetLocal *curr) { curr->doPrint(o, indent); } + void visitSetLocal(SetLocal *curr) { curr->doPrint(o, indent); } + void visitLoad(Load *curr) { curr->doPrint(o, indent); } + void visitStore(Store *curr) { curr->doPrint(o, indent); } + void visitConst(Const *curr) { curr->doPrint(o, indent); } + void visitUnary(Unary *curr) { curr->doPrint(o, indent); } + void visitBinary(Binary *curr) { curr->doPrint(o, indent); } + void visitSelect(Select *curr) { curr->doPrint(o, indent); } + void visitHost(Host *curr) { curr->doPrint(o, indent); } + void visitNop(Nop *curr) { curr->doPrint(o, indent); } + void visitUnreachable(Unreachable *curr) { curr->doPrint(o, indent); } }; ExpressionPrinter(o, indent).visit(this); @@ -1233,92 +1234,94 @@ std::ostream& Expression::print(std::ostream &o, unsigned indent) { return o; } -struct WasmWalkerBase : public WasmVisitor<void> { +template<typename SubType, typename ReturnType> +struct WasmWalkerBase : public WasmVisitor<SubType, ReturnType> { virtual void walk(Expression*& curr) { abort(); } virtual void startWalk(Function *func) { abort(); } virtual void startWalk(Module *module) { abort(); } }; -struct ChildWalker : public WasmWalkerBase { - WasmWalkerBase& parent; +template<typename ParentType> +struct ChildWalker : public WasmWalkerBase<ChildWalker<ParentType>, void> { + ParentType& parent; - ChildWalker(WasmWalkerBase& parent) : parent(parent) {} + ChildWalker(ParentType& parent) : parent(parent) {} - void visitBlock(Block *curr) override { + void visitBlock(Block *curr) { ExpressionList& list = curr->list; for (size_t z = 0; z < list.size(); z++) { parent.walk(list[z]); } } - void visitIf(If *curr) override { + void visitIf(If *curr) { parent.walk(curr->condition); parent.walk(curr->ifTrue); parent.walk(curr->ifFalse); } - void visitLoop(Loop *curr) override { + void visitLoop(Loop *curr) { parent.walk(curr->body); } - void visitBreak(Break *curr) override { + void visitBreak(Break *curr) { parent.walk(curr->condition); parent.walk(curr->value); } - void visitSwitch(Switch *curr) override { + void visitSwitch(Switch *curr) { parent.walk(curr->value); for (auto& case_ : curr->cases) { parent.walk(case_.body); } } - void visitCall(Call *curr) override { + void visitCall(Call *curr) { ExpressionList& list = curr->operands; for (size_t z = 0; z < list.size(); z++) { parent.walk(list[z]); } } - void visitCallImport(CallImport *curr) override { + void visitCallImport(CallImport *curr) { ExpressionList& list = curr->operands; for (size_t z = 0; z < list.size(); z++) { parent.walk(list[z]); } } - void visitCallIndirect(CallIndirect *curr) override { + void visitCallIndirect(CallIndirect *curr) { parent.walk(curr->target); ExpressionList& list = curr->operands; for (size_t z = 0; z < list.size(); z++) { parent.walk(list[z]); } } - void visitGetLocal(GetLocal *curr) override {} - void visitSetLocal(SetLocal *curr) override { + void visitGetLocal(GetLocal *curr) {} + void visitSetLocal(SetLocal *curr) { parent.walk(curr->value); } - void visitLoad(Load *curr) override { + void visitLoad(Load *curr) { parent.walk(curr->ptr); } - void visitStore(Store *curr) override { + void visitStore(Store *curr) { parent.walk(curr->ptr); parent.walk(curr->value); } - void visitConst(Const *curr) override {} - void visitUnary(Unary *curr) override { + void visitConst(Const *curr) {} + void visitUnary(Unary *curr) { parent.walk(curr->value); } - void visitBinary(Binary *curr) override { + void visitBinary(Binary *curr) { parent.walk(curr->left); parent.walk(curr->right); } - void visitSelect(Select *curr) override { + void visitSelect(Select *curr) { parent.walk(curr->condition); parent.walk(curr->ifTrue); parent.walk(curr->ifFalse); } - void visitHost(Host *curr) override { + void visitHost(Host *curr) { ExpressionList& list = curr->operands; for (size_t z = 0; z < list.size(); z++) { parent.walk(list[z]); } } - void visitNop(Nop *curr) override {} - void visitUnreachable(Unreachable *curr) override {} + void visitNop(Nop *curr) {} + void visitUnreachable(Unreachable *curr) {} }; // @@ -1327,7 +1330,8 @@ struct ChildWalker : public WasmWalkerBase { // the current expression node. Useful for writing optimization passes. // -struct WasmWalker : public WasmWalkerBase { +template<typename SubType, typename ReturnType> +struct WasmWalker : public WasmWalkerBase<SubType, ReturnType> { Expression* replace; WasmWalker() : replace(nullptr) {} @@ -1338,41 +1342,41 @@ struct WasmWalker : public WasmWalkerBase { } // By default, do nothing - void visitBlock(Block *curr) override {} - void visitIf(If *curr) override {} - void visitLoop(Loop *curr) override {} - void visitBreak(Break *curr) override {} - void visitSwitch(Switch *curr) override {} - void visitCall(Call *curr) override {} - void visitCallImport(CallImport *curr) override {} - void visitCallIndirect(CallIndirect *curr) override {} - void visitGetLocal(GetLocal *curr) override {} - void visitSetLocal(SetLocal *curr) override {} - void visitLoad(Load *curr) override {} - void visitStore(Store *curr) override {} - void visitConst(Const *curr) override {} - void visitUnary(Unary *curr) override {} - void visitBinary(Binary *curr) override {} - void visitSelect(Select *curr) override {} - void visitHost(Host *curr) override {} - void visitNop(Nop *curr) override {} - void visitUnreachable(Unreachable *curr) override {} - - void visitFunctionType(FunctionType *curr) override {} - void visitImport(Import *curr) override {} - void visitExport(Export *curr) override {} - void visitFunction(Function *curr) override {} - void visitTable(Table *curr) override {} - void visitMemory(Memory *curr) override {} - void visitModule(Module *curr) override {} + ReturnType visitBlock(Block *curr) {} + ReturnType visitIf(If *curr) {} + ReturnType visitLoop(Loop *curr) {} + ReturnType visitBreak(Break *curr) {} + ReturnType visitSwitch(Switch *curr) {} + ReturnType visitCall(Call *curr) {} + ReturnType visitCallImport(CallImport *curr) {} + ReturnType visitCallIndirect(CallIndirect *curr) {} + ReturnType visitGetLocal(GetLocal *curr) {} + ReturnType visitSetLocal(SetLocal *curr) {} + ReturnType visitLoad(Load *curr) {} + ReturnType visitStore(Store *curr) {} + ReturnType visitConst(Const *curr) {} + ReturnType visitUnary(Unary *curr) {} + ReturnType visitBinary(Binary *curr) {} + ReturnType visitSelect(Select *curr) {} + ReturnType visitHost(Host *curr) {} + ReturnType visitNop(Nop *curr) {} + ReturnType visitUnreachable(Unreachable *curr) {} + + ReturnType visitFunctionType(FunctionType *curr) {} + ReturnType visitImport(Import *curr) {} + ReturnType visitExport(Export *curr) {} + ReturnType visitFunction(Function *curr) {} + ReturnType visitTable(Table *curr) {} + ReturnType visitMemory(Memory *curr) {} + ReturnType visitModule(Module *curr) {} // children-first void walk(Expression*& curr) override { if (!curr) return; - ChildWalker(*this).visit(curr); + ChildWalker<WasmWalker<SubType, ReturnType> >(*this).visit(curr); - visit(curr); + this->visit(curr); if (replace) { curr = replace; @@ -1385,28 +1389,29 @@ struct WasmWalker : public WasmWalkerBase { } void startWalk(Module *module) override { + SubType* self = static_cast<SubType*>(this); for (auto curr : module->functionTypes) { - visitFunctionType(curr); + self->visitFunctionType(curr); assert(!replace); } for (auto curr : module->imports) { - visitImport(curr); + self->visitImport(curr); assert(!replace); } for (auto curr : module->exports) { - visitExport(curr); + self->visitExport(curr); assert(!replace); } for (auto curr : module->functions) { startWalk(curr); - visitFunction(curr); + self->visitFunction(curr); assert(!replace); } - visitTable(&module->table); + self->visitTable(&module->table); assert(!replace); - visitMemory(&module->memory); + self->visitMemory(&module->memory); assert(!replace); - visitModule(module); + self->visitModule(module); assert(!replace); } }; diff --git a/src/wasm2asm.h b/src/wasm2asm.h index 1a85bc177..4d831f273 100644 --- a/src/wasm2asm.h +++ b/src/wasm2asm.h @@ -387,29 +387,29 @@ Ref Wasm2AsmBuilder::processFunction(Function* func) { } void Wasm2AsmBuilder::scanFunctionBody(Expression* curr) { - struct ExpressionScanner : public WasmWalker { + struct ExpressionScanner : public WasmWalker<ExpressionScanner, void> { Wasm2AsmBuilder* parent; ExpressionScanner(Wasm2AsmBuilder* parent) : parent(parent) {} // Visitors - void visitBlock(Block *curr) override { + void visitBlock(Block *curr) { parent->setStatement(curr); } - void visitIf(If *curr) override { + void visitIf(If *curr) { parent->setStatement(curr); } - void visitLoop(Loop *curr) override { + void visitLoop(Loop *curr) { parent->setStatement(curr); } - void visitBreak(Break *curr) override { + void visitBreak(Break *curr) { parent->setStatement(curr); } - void visitSwitch(Switch *curr) override { + void visitSwitch(Switch *curr) { parent->setStatement(curr); } - void visitCall(Call *curr) override { + void visitCall(Call *curr) { for (auto item : curr->operands) { if (parent->isStatement(item)) { parent->setStatement(curr); @@ -417,10 +417,10 @@ void Wasm2AsmBuilder::scanFunctionBody(Expression* curr) { } } } - void visitCallImport(CallImport *curr) override { + void visitCallImport(CallImport *curr) { visitCall(curr); } - void visitCallIndirect(CallIndirect *curr) override { + void visitCallIndirect(CallIndirect *curr) { if (parent->isStatement(curr->target)) { parent->setStatement(curr); return; @@ -432,37 +432,37 @@ void Wasm2AsmBuilder::scanFunctionBody(Expression* curr) { } } } - void visitSetLocal(SetLocal *curr) override { + void visitSetLocal(SetLocal *curr) { if (parent->isStatement(curr->value)) { parent->setStatement(curr); } } - void visitLoad(Load *curr) override { + void visitLoad(Load *curr) { if (parent->isStatement(curr->ptr)) { parent->setStatement(curr); } } - void visitStore(Store *curr) override { + void visitStore(Store *curr) { if (parent->isStatement(curr->ptr) || parent->isStatement(curr->value)) { parent->setStatement(curr); } } - void visitUnary(Unary *curr) override { + void visitUnary(Unary *curr) { if (parent->isStatement(curr->value)) { parent->setStatement(curr); } } - void visitBinary(Binary *curr) override { + void visitBinary(Binary *curr) { if (parent->isStatement(curr->left) || parent->isStatement(curr->right)) { parent->setStatement(curr); } } - void visitSelect(Select *curr) override { + void visitSelect(Select *curr) { if (parent->isStatement(curr->condition) || parent->isStatement(curr->ifTrue) || parent->isStatement(curr->ifFalse)) { parent->setStatement(curr); } } - void visitHost(Host *curr) override { + void visitHost(Host *curr) { for (auto item : curr->operands) { if (parent->isStatement(item)) { parent->setStatement(curr); @@ -475,7 +475,7 @@ void Wasm2AsmBuilder::scanFunctionBody(Expression* curr) { } Ref Wasm2AsmBuilder::processFunctionBody(Expression* curr, IString result) { - struct ExpressionProcessor : public WasmVisitor<Ref> { + struct ExpressionProcessor : public WasmVisitor<ExpressionProcessor, Ref> { Wasm2AsmBuilder* parent; IString result; ExpressionProcessor(Wasm2AsmBuilder* parent) : parent(parent) {} @@ -579,7 +579,7 @@ Ref Wasm2AsmBuilder::processFunctionBody(Expression* curr, IString result) { // Visitors - Ref visitBlock(Block *curr) override { + Ref visitBlock(Block *curr) { breakResults[curr->name] = result; Ref ret = ValueBuilder::makeBlock(); size_t size = curr->list.size(); @@ -595,7 +595,7 @@ Ref Wasm2AsmBuilder::processFunctionBody(Expression* curr, IString result) { } return ret; } - Ref visitIf(If *curr) override { + Ref visitIf(If *curr) { IString temp; Ref condition = visitForExpression(curr->condition, i32, temp); Ref ifTrue = ValueBuilder::makeStatement(visitAndAssign(curr->ifTrue, result)); @@ -611,7 +611,7 @@ Ref Wasm2AsmBuilder::processFunctionBody(Expression* curr, IString result) { condition[1]->push_back(ValueBuilder::makeIf(ValueBuilder::makeName(temp), ifTrue, ifFalse)); return condition; } - Ref visitLoop(Loop *curr) override { + Ref visitLoop(Loop *curr) { Name asmLabel = curr->out.is() ? curr->out : curr->in; // label using the outside, normal for breaks. if no outside, then inside if (curr->in.is()) continueLabels[curr->in] = asmLabel; Ref body = visit(curr->body, result); @@ -621,7 +621,7 @@ Ref Wasm2AsmBuilder::processFunctionBody(Expression* curr, IString result) { } return ret; } - Ref visitBreak(Break *curr) override { + Ref visitBreak(Break *curr) { if (curr->condition) { // we need an equivalent to an if here, so use that code Break fakeBreak = *curr; @@ -645,7 +645,7 @@ Ref Wasm2AsmBuilder::processFunctionBody(Expression* curr, IString result) { ret[1]->push_back(theBreak); return ret; } - Ref visitSwitch(Switch *curr) override { + Ref visitSwitch(Switch *curr) { Ref ret = ValueBuilder::makeLabel(fromName(curr->name), ValueBuilder::makeBlock()); Ref value; if (isStatement(curr->value)) { @@ -694,7 +694,7 @@ Ref Wasm2AsmBuilder::processFunctionBody(Expression* curr, IString result) { return ret; } - Ref visitCall(Call *curr) override { + Ref visitCall(Call *curr) { Ref theCall = ValueBuilder::makeCall(fromName(curr->target)); if (!isStatement(curr)) { // none of our operands is a statement; go right ahead and create a simple expression @@ -706,10 +706,10 @@ Ref Wasm2AsmBuilder::processFunctionBody(Expression* curr, IString result) { // we must statementize them all return makeStatementizedCall(curr->operands, ValueBuilder::makeBlock(), theCall, result, curr->type); } - Ref visitCallImport(CallImport *curr) override { + Ref visitCallImport(CallImport *curr) { return visitCall(curr); } - Ref visitCallIndirect(CallIndirect *curr) override { + Ref visitCallIndirect(CallIndirect *curr) { std::string stable = std::string("FUNCTION_TABLE_") + getSig(curr->fullType); IString table = IString(stable.c_str(), false); auto makeTableCall = [&](Ref target) { @@ -733,10 +733,10 @@ Ref Wasm2AsmBuilder::processFunctionBody(Expression* curr, IString result) { Ref theCall = makeTableCall(temp.getAstName()); return makeStatementizedCall(curr->operands, ret, theCall, result, curr->type); } - Ref visitGetLocal(GetLocal *curr) override { + Ref visitGetLocal(GetLocal *curr) { return ValueBuilder::makeName(fromName(curr->name)); } - Ref visitSetLocal(SetLocal *curr) override { + Ref visitSetLocal(SetLocal *curr) { if (!isStatement(curr)) { return ValueBuilder::makeAssign(ValueBuilder::makeName(fromName(curr->name)), visit(curr->value, EXPRESSION_RESULT)); } @@ -746,7 +746,7 @@ Ref Wasm2AsmBuilder::processFunctionBody(Expression* curr, IString result) { ret[1]->push_back(ValueBuilder::makeStatement(ValueBuilder::makeAssign(ValueBuilder::makeName(fromName(curr->name)), temp.getAstName()))); return ret; } - Ref visitLoad(Load *curr) override { + Ref visitLoad(Load *curr) { if (isStatement(curr)) { ScopedTemp temp(i32, parent); GetLocal fakeLocal; @@ -808,7 +808,7 @@ Ref Wasm2AsmBuilder::processFunctionBody(Expression* curr, IString result) { } return makeAsmCoercion(ret, wasmToAsmType(curr->type)); } - Ref visitStore(Store *curr) override { + Ref visitStore(Store *curr) { if (isStatement(curr)) { ScopedTemp tempPtr(i32, parent); ScopedTemp tempValue(curr->type, parent); @@ -903,7 +903,7 @@ Ref Wasm2AsmBuilder::processFunctionBody(Expression* curr, IString result) { } return ValueBuilder::makeAssign(ret, value); } - Ref visitConst(Const *curr) override { + Ref visitConst(Const *curr) { switch (curr->type) { case i32: return ValueBuilder::makeInt(curr->value.i32); case f32: { @@ -924,7 +924,7 @@ Ref Wasm2AsmBuilder::processFunctionBody(Expression* curr, IString result) { default: abort(); } } - Ref visitUnary(Unary *curr) override { + Ref visitUnary(Unary *curr) { if (isStatement(curr)) { ScopedTemp temp(curr->value->type, parent); GetLocal fakeLocal; @@ -972,7 +972,7 @@ Ref Wasm2AsmBuilder::processFunctionBody(Expression* curr, IString result) { default: abort(); } } - Ref visitBinary(Binary *curr) override { + Ref visitBinary(Binary *curr) { if (isStatement(curr)) { ScopedTemp tempLeft(curr->left->type, parent); GetLocal fakeLocalLeft; @@ -1045,7 +1045,7 @@ Ref Wasm2AsmBuilder::processFunctionBody(Expression* curr, IString result) { } return makeAsmCoercion(ret, wasmToAsmType(curr->type)); } - Ref visitSelect(Select *curr) override { + Ref visitSelect(Select *curr) { if (isStatement(curr)) { ScopedTemp tempCondition(i32, parent); GetLocal fakeCondition; @@ -1085,13 +1085,13 @@ Ref Wasm2AsmBuilder::processFunctionBody(Expression* curr, IString result) { ) ); } - Ref visitHost(Host *curr) override { + Ref visitHost(Host *curr) { abort(); } - Ref visitNop(Nop *curr) override { + Ref visitNop(Nop *curr) { return ValueBuilder::makeToplevel(); } - Ref visitUnreachable(Unreachable *curr) override { + Ref visitUnreachable(Unreachable *curr) { return ValueBuilder::makeCall(ABORT_FUNC); } }; |