summaryrefslogtreecommitdiff
path: root/src/ir/properties.cpp
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2023-03-20 15:14:52 -0700
committerGitHub <noreply@github.com>2023-03-20 15:14:52 -0700
commitef674ecb40d1dcdcb39a33a7d28772edaeff63b8 (patch)
tree51579ccd2a7bc7e6a32cc3bc2fb41b0fd1da4766 /src/ir/properties.cpp
parentf4b0ea75aa56349c970b9ae7c156e2f6fd87de3d (diff)
downloadbinaryen-ef674ecb40d1dcdcb39a33a7d28772edaeff63b8.tar.gz
binaryen-ef674ecb40d1dcdcb39a33a7d28772edaeff63b8.tar.bz2
binaryen-ef674ecb40d1dcdcb39a33a7d28772edaeff63b8.zip
[Wasm GC] Fix detection of externalize/internalize as constant (#5592)
Both isValidInConstantExpression and isSingleConstantExpression must look recursively at the internals of a RefAs that externalizes and internalizes, or else we might do something like externalize a local.get, which is not constant. getLiteral must handle externalize/internalize as well, and return a properly- modified literal. Without these fixes the testcase hits different internal assertions, and we either fail to recognize something is constant or not, or think that it is but fail to produce a literal for it.
Diffstat (limited to 'src/ir/properties.cpp')
-rw-r--r--src/ir/properties.cpp8
1 files changed, 8 insertions, 0 deletions
diff --git a/src/ir/properties.cpp b/src/ir/properties.cpp
index 4ade8aa10..b564b3bf1 100644
--- a/src/ir/properties.cpp
+++ b/src/ir/properties.cpp
@@ -36,6 +36,8 @@ bool isGenerative(Expression* curr, FeatureSet features) {
return scanner.generative;
}
+// Checks an expression in a shallow manner (i.e., does not check children) as
+// to whether it is valid in a wasm constant expression.
static bool isValidInConstantExpression(Module& wasm, Expression* expr) {
if (isSingleConstantExpression(expr) || expr->is<StructNew>() ||
expr->is<ArrayNew>() || expr->is<ArrayNewFixed>() || expr->is<I31New>() ||
@@ -43,6 +45,12 @@ static bool isValidInConstantExpression(Module& wasm, Expression* expr) {
return true;
}
+ if (auto* refAs = expr->dynCast<RefAs>()) {
+ if (refAs->op == ExternExternalize || refAs->op == ExternInternalize) {
+ return true;
+ }
+ }
+
if (auto* get = expr->dynCast<GlobalGet>()) {
auto* g = wasm.getGlobalOrNull(get->name);
// This is called from the validator, so we have to handle non-existent