summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2021-03-25 11:48:10 -0700
committerGitHub <noreply@github.com>2021-03-25 11:48:10 -0700
commit23ad3cee7d4b3d20ded8627efce3e6f400a35339 (patch)
tree7d21ba849deec4f76dfc50590a30cb8367ac361f /src
parentae1a0a633cdffeec5354f8233c1321b832a96488 (diff)
downloadbinaryen-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.h13
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");
}