diff options
author | Alon Zakai <azakai@google.com> | 2021-03-25 11:48:10 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-25 11:48:10 -0700 |
commit | 23ad3cee7d4b3d20ded8627efce3e6f400a35339 (patch) | |
tree | 7d21ba849deec4f76dfc50590a30cb8367ac361f /src | |
parent | ae1a0a633cdffeec5354f8233c1321b832a96488 (diff) | |
download | binaryen-23ad3cee7d4b3d20ded8627efce3e6f400a35339.tar.gz binaryen-23ad3cee7d4b3d20ded8627efce3e6f400a35339.tar.bz2 binaryen-23ad3cee7d4b3d20ded8627efce3e6f400a35339.zip |
Flat IR: Allow ref.as_non_null in nested positions (#3732)
We can't disallow it, as its result is non-null which we can't spill to a local.
This may cause issues eventually in the combination of GC + flatten, but
I don't expect it to. If it does we may need to revisit.
Diffstat (limited to 'src')
-rw-r--r-- | src/ir/flat.h | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/src/ir/flat.h b/src/ir/flat.h index 706ca5a86..273acc42f 100644 --- a/src/ir/flat.h +++ b/src/ir/flat.h @@ -43,8 +43,8 @@ // making the AST have these properties: // // 1. Aside from a local.set, the operands of an instruction must be a -// local.get, a const, or an unreachable. Anything else is written -// to a local earlier. +// local.get, a const, an unreachable, or a ref.as_non_null. Anything else +// is written to a local earlier. // 2. Disallow control flow (block, loop, if, and try) return values, and do // not allow the function body to have a concrete type, i.e., do not use // control flow to pass around values. @@ -54,6 +54,10 @@ // values is prohibited already, but e.g. a block ending in unreachable, // which can normally be nested, is also disallowed). // +// Note: ref.as_non_null must be allowed in a nested position because we cannot +// spill it to a local - the result is non-null, which is not allowable in a +// local. +// #ifndef wasm_ir_flat_h #define wasm_ir_flat_h @@ -82,8 +86,11 @@ inline void verifyFlatness(Function* func) { "set values cannot be control flow"); } else { for (auto* child : ChildIterator(curr)) { + bool isRefAsNonNull = + child->is<RefAs>() && child->cast<RefAs>()->op == RefAsNonNull; verify(Properties::isConstantExpression(child) || - child->is<LocalGet>() || child->is<Unreachable>(), + child->is<LocalGet>() || child->is<Unreachable>() || + isRefAsNonNull, "instructions must only have constant expressions, local.get, " "or unreachable as children"); } |