diff options
author | Derek Schuff <dschuff@chromium.org> | 2017-01-31 16:27:50 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-01-31 16:27:50 -0800 |
commit | 7bc8f14d8699f56777a763f99ad8098fcf7c0583 (patch) | |
tree | c838d496b731f846362328076f87a4da364c4065 /src/ast/ExpressionManipulator.cpp | |
parent | 64284970344ce5463adada38e348230256b31226 (diff) | |
download | binaryen-7bc8f14d8699f56777a763f99ad8098fcf7c0583.tar.gz binaryen-7bc8f14d8699f56777a763f99ad8098fcf7c0583.tar.bz2 binaryen-7bc8f14d8699f56777a763f99ad8098fcf7c0583.zip |
Make ast_utils into a library (#892)
Split ExpressionAnalyzer and ExpressionManipulator into cpp files, and turn their giant template functions into simple functions which take a callback.
More organization, fewer mammoth headers, makes the build a few seconds faster, and the binaries a couple MB smaller.
Diffstat (limited to 'src/ast/ExpressionManipulator.cpp')
-rw-r--r-- | src/ast/ExpressionManipulator.cpp | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/src/ast/ExpressionManipulator.cpp b/src/ast/ExpressionManipulator.cpp new file mode 100644 index 000000000..fb861f0d8 --- /dev/null +++ b/src/ast/ExpressionManipulator.cpp @@ -0,0 +1,152 @@ +/* + * Copyright 2017 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ast_utils.h" +#include "support/hash.h" + +namespace wasm { + +Expression* ExpressionManipulator::flexibleCopy(Expression* original, Module& wasm, CustomCopier custom) { + struct Copier : public Visitor<Copier, Expression*> { + Module& wasm; + CustomCopier custom; + + Builder builder; + + Copier(Module& wasm, CustomCopier custom) : wasm(wasm), custom(custom), builder(wasm) {} + + Expression* copy(Expression* curr) { + if (!curr) return nullptr; + auto* ret = custom(curr); + if (ret) return ret; + return Visitor<Copier, Expression*>::visit(curr); + } + + Expression* visitBlock(Block *curr) { + auto* ret = builder.makeBlock(); + for (Index i = 0; i < curr->list.size(); i++) { + ret->list.push_back(copy(curr->list[i])); + } + ret->name = curr->name; + ret->finalize(curr->type); + return ret; + } + Expression* visitIf(If *curr) { + return builder.makeIf(copy(curr->condition), copy(curr->ifTrue), copy(curr->ifFalse)); + } + Expression* visitLoop(Loop *curr) { + return builder.makeLoop(curr->name, copy(curr->body)); + } + Expression* visitBreak(Break *curr) { + return builder.makeBreak(curr->name, copy(curr->value), copy(curr->condition)); + } + Expression* visitSwitch(Switch *curr) { + return builder.makeSwitch(curr->targets, curr->default_, copy(curr->condition), copy(curr->value)); + } + Expression* visitCall(Call *curr) { + auto* ret = builder.makeCall(curr->target, {}, curr->type); + for (Index i = 0; i < curr->operands.size(); i++) { + ret->operands.push_back(copy(curr->operands[i])); + } + return ret; + } + Expression* visitCallImport(CallImport *curr) { + auto* ret = builder.makeCallImport(curr->target, {}, curr->type); + for (Index i = 0; i < curr->operands.size(); i++) { + ret->operands.push_back(copy(curr->operands[i])); + } + return ret; + } + Expression* visitCallIndirect(CallIndirect *curr) { + auto* ret = builder.makeCallIndirect(curr->fullType, copy(curr->target), {}, curr->type); + for (Index i = 0; i < curr->operands.size(); i++) { + ret->operands.push_back(copy(curr->operands[i])); + } + return ret; + } + Expression* visitGetLocal(GetLocal *curr) { + return builder.makeGetLocal(curr->index, curr->type); + } + Expression* visitSetLocal(SetLocal *curr) { + if (curr->isTee()) { + return builder.makeTeeLocal(curr->index, copy(curr->value)); + } else { + return builder.makeSetLocal(curr->index, copy(curr->value)); + } + } + Expression* visitGetGlobal(GetGlobal *curr) { + return builder.makeGetGlobal(curr->name, curr->type); + } + Expression* visitSetGlobal(SetGlobal *curr) { + return builder.makeSetGlobal(curr->name, copy(curr->value)); + } + Expression* visitLoad(Load *curr) { + return builder.makeLoad(curr->bytes, curr->signed_, curr->offset, curr->align, copy(curr->ptr), curr->type); + } + Expression* visitStore(Store *curr) { + return builder.makeStore(curr->bytes, curr->offset, curr->align, copy(curr->ptr), copy(curr->value), curr->valueType); + } + Expression* visitConst(Const *curr) { + return builder.makeConst(curr->value); + } + Expression* visitUnary(Unary *curr) { + return builder.makeUnary(curr->op, copy(curr->value)); + } + Expression* visitBinary(Binary *curr) { + return builder.makeBinary(curr->op, copy(curr->left), copy(curr->right)); + } + Expression* visitSelect(Select *curr) { + return builder.makeSelect(copy(curr->condition), copy(curr->ifTrue), copy(curr->ifFalse)); + } + Expression* visitDrop(Drop *curr) { + return builder.makeDrop(copy(curr->value)); + } + Expression* visitReturn(Return *curr) { + return builder.makeReturn(copy(curr->value)); + } + Expression* visitHost(Host *curr) { + assert(curr->operands.size() == 0); + return builder.makeHost(curr->op, curr->nameOperand, {}); + } + Expression* visitNop(Nop *curr) { + return builder.makeNop(); + } + Expression* visitUnreachable(Unreachable *curr) { + return builder.makeUnreachable(); + } + }; + + Copier copier(wasm, custom); + return copier.copy(original); +} + + +// Splice an item into the middle of a block's list +void ExpressionManipulator::spliceIntoBlock(Block* block, Index index, Expression* add) { + auto& list = block->list; + if (index == list.size()) { + list.push_back(add); // simple append + } else { + // we need to make room + list.push_back(nullptr); + for (Index i = list.size() - 1; i > index; i--) { + list[i] = list[i - 1]; + } + list[index] = add; + } +} + +} // namespace wasm |