diff options
author | Alon Zakai <alonzakai@gmail.com> | 2017-05-09 09:36:45 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-05-09 09:36:45 -0700 |
commit | 64aa81e0e9655cf16e3af65e1bbe98e7fc6cf974 (patch) | |
tree | 26f3608bb1944b63712a8d1a161e61b41956276d /src/wasm/wasm.cpp | |
parent | b856925f6c25df22a0901d8f9e24e4247b4acc18 (diff) | |
download | binaryen-64aa81e0e9655cf16e3af65e1bbe98e7fc6cf974.tar.gz binaryen-64aa81e0e9655cf16e3af65e1bbe98e7fc6cf974.tar.bz2 binaryen-64aa81e0e9655cf16e3af65e1bbe98e7fc6cf974.zip |
Unreachable typing fixes (#1004)
* fix type of drop, set_local, set_global, load, etc: when operand is unreachable, so is the node itself
* support binary tests properly in test/passes
* fix unreachable typing of blocks with no name and an unreachable child
* fix continue emitting in asm2wasm
* properly handle emitting of unreachable load
Diffstat (limited to 'src/wasm/wasm.cpp')
-rw-r--r-- | src/wasm/wasm.cpp | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index 96ca8fbc8..834d9e28f 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -198,6 +198,16 @@ void Block::finalize() { if (!name.is()) { // nothing branches here, so this is easy if (list.size() > 0) { + // if we have an unreachable child, we are unreachable + // (we don't need to recurse into children, they can't + // break to us) + for (auto* child : list) { + if (child->type == unreachable) { + type = unreachable; + return; + } + } + // children are reachable, so last element determines type type = list.back()->type; } else { type = none; @@ -264,6 +274,31 @@ void Switch::finalize() { type = unreachable; } +template<typename T> +void handleUnreachableOperands(T* curr) { + for (auto* child : curr->operands) { + if (child->type == unreachable) { + curr->type = unreachable; + break; + } + } +} + +void Call::finalize() { + handleUnreachableOperands(this); +} + +void CallImport::finalize() { + handleUnreachableOperands(this); +} + +void CallIndirect::finalize() { + handleUnreachableOperands(this); + if (target->type == unreachable) { + type = unreachable; + } +} + bool FunctionType::structuralComparison(FunctionType& b) { if (result != b.result) return false; if (params.size() != b.params.size()) return false; @@ -290,6 +325,24 @@ void SetLocal::setTee(bool is) { else type = none; } +void SetLocal::finalize() { + if (value->type == unreachable) { + type = unreachable; + } +} + +void SetGlobal::finalize() { + if (value->type == unreachable) { + type = unreachable; + } +} + +void Load::finalize() { + if (ptr->type == unreachable) { + type = unreachable; + } +} + void Store::finalize() { assert(valueType != none); // must be set if (ptr->type == unreachable || value->type == unreachable) { @@ -423,6 +476,14 @@ void Select::finalize() { } } +void Drop::finalize() { + if (value->type == unreachable) { + type = unreachable; + } else { + type = none; + } +} + void Host::finalize() { switch (op) { case PageSize: case CurrentMemory: case HasFeature: { |