diff options
author | Alon Zakai (kripken) <alonzakai@gmail.com> | 2017-07-31 15:11:11 -0700 |
---|---|---|
committer | Alon Zakai (kripken) <alonzakai@gmail.com> | 2017-07-31 15:11:11 -0700 |
commit | 5f2dd574d6ed53acc96443b9cf3f7a6d806986c3 (patch) | |
tree | db08a3d19472f9f1650c991ad70a5a6093493192 /src/wasm/wasm-binary.cpp | |
parent | bfdbc0c3f6a835231b218a60ddd6b52f7e9affed (diff) | |
parent | 76751bf1f9df4eb2ee6c216744af9ed1e097132e (diff) | |
download | binaryen-5f2dd574d6ed53acc96443b9cf3f7a6d806986c3.tar.gz binaryen-5f2dd574d6ed53acc96443b9cf3f7a6d806986c3.tar.bz2 binaryen-5f2dd574d6ed53acc96443b9cf3f7a6d806986c3.zip |
Merge remote-tracking branch 'origin/master' into fuzz
Diffstat (limited to 'src/wasm/wasm-binary.cpp')
-rw-r--r-- | src/wasm/wasm-binary.cpp | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 1bc5ada94..88b967fdf 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -648,6 +648,16 @@ void WasmBinaryWriter::visitBreak(Break *curr) { if (curr->condition) recurse(curr->condition); o << int8_t(curr->condition ? BinaryConsts::BrIf : BinaryConsts::Br) << U32LEB(getBreakIndex(curr->name)); + if (curr->condition && curr->type == unreachable) { + // a br_if is normally none or emits a value. if it is unreachable, + // then either the condition or the value is unreachable, which is + // extremely rare, and may require us to make the stack polymorphic + // (if the block we branch to has a value, we may lack one as we + // are not a taken branch; the wasm spec on the other hand does + // presume the br_if emits a value of the right type, even if it + // popped unreachable) + o << int8_t(BinaryConsts::Unreachable); + } } void WasmBinaryWriter::visitSwitch(Switch *curr) { @@ -669,6 +679,9 @@ void WasmBinaryWriter::visitCall(Call *curr) { recurse(operand); } o << int8_t(BinaryConsts::CallFunction) << U32LEB(getFunctionIndex(curr->target)); + if (curr->type == unreachable) { + o << int8_t(BinaryConsts::Unreachable); + } } void WasmBinaryWriter::visitCallImport(CallImport *curr) { @@ -689,6 +702,9 @@ void WasmBinaryWriter::visitCallIndirect(CallIndirect *curr) { o << int8_t(BinaryConsts::CallIndirect) << U32LEB(getFunctionTypeIndex(curr->fullType)) << U32LEB(0); // Reserved flags field + if (curr->type == unreachable) { + o << int8_t(BinaryConsts::Unreachable); + } } void WasmBinaryWriter::visitGetLocal(GetLocal *curr) { @@ -700,6 +716,9 @@ void WasmBinaryWriter::visitSetLocal(SetLocal *curr) { if (debug) std::cerr << "zz node: Set|TeeLocal" << std::endl; recurse(curr->value); o << int8_t(curr->isTee() ? BinaryConsts::TeeLocal : BinaryConsts::SetLocal) << U32LEB(mappedLocals[curr->index]); + if (curr->type == unreachable) { + o << int8_t(BinaryConsts::Unreachable); + } } void WasmBinaryWriter::visitGetGlobal(GetGlobal *curr) { @@ -986,6 +1005,9 @@ void WasmBinaryWriter::visitUnary(Unary *curr) { case ReinterpretInt64: o << int8_t(BinaryConsts::F64ReinterpretI64); break; default: abort(); } + if (curr->type == unreachable) { + o << int8_t(BinaryConsts::Unreachable); + } } void WasmBinaryWriter::visitBinary(Binary *curr) { @@ -1075,6 +1097,9 @@ void WasmBinaryWriter::visitBinary(Binary *curr) { case GeFloat64: o << int8_t(BinaryConsts::F64Ge); break; default: abort(); } + if (curr->type == unreachable) { + o << int8_t(BinaryConsts::Unreachable); + } } void WasmBinaryWriter::visitSelect(Select *curr) { @@ -1083,6 +1108,9 @@ void WasmBinaryWriter::visitSelect(Select *curr) { recurse(curr->ifFalse); recurse(curr->condition); o << int8_t(BinaryConsts::Select); + if (curr->type == unreachable) { + o << int8_t(BinaryConsts::Unreachable); + } } void WasmBinaryWriter::visitReturn(Return *curr) { @@ -1771,7 +1799,11 @@ Expression* WasmBinaryBuilder::popExpression() { throw ParseException("attempted pop from empty stack"); } auto ret = expressionStack.back(); - expressionStack.pop_back(); + // to simulate the wasm polymorphic stack mode, leave a final + // unreachable, don't empty the stack in that case + if (!(expressionStack.size() == 1 && ret->type == unreachable)) { + expressionStack.pop_back(); + } return ret; } |