diff options
author | Alon Zakai <azakai@google.com> | 2020-12-09 11:17:28 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-09 11:17:28 -0800 |
commit | 823222ff566b38495327bc28b4726871b0a86b26 (patch) | |
tree | d0425f0c40d61e9085bc3a9880faa08eafd70276 /src/wasm/wasm-validator.cpp | |
parent | 63a042e3a94df7ba3a5c9dde03990a9813fdc366 (diff) | |
download | binaryen-823222ff566b38495327bc28b4726871b0a86b26.tar.gz binaryen-823222ff566b38495327bc28b4726871b0a86b26.tar.bz2 binaryen-823222ff566b38495327bc28b4726871b0a86b26.zip |
[GC] Add struct.new and start to test interesting execution (#3433)
With struct.new read/write support, we can start to do interesting
things! This adds a test of creating a struct and seeing that references
behave like references, that is, if we write to the value X refers to, and
if Y refers to the same thing, when reading from Y's value we see the
change as well.
The test is run through all of -O1, which uncovered a minor issue in
Precompute: We can't try to precompute a reference type, as we can't
replace a reference with a value.
Note btw that the test shows the optimizer properly running
CoalesceLocals on reference types, merging two locals.
Diffstat (limited to 'src/wasm/wasm-validator.cpp')
-rw-r--r-- | src/wasm/wasm-validator.cpp | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index c6e22899c..e97541444 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -2238,7 +2238,39 @@ void FunctionValidator::visitStructNew(StructNew* curr) { shouldBeTrue(getModule()->features.hasGC(), curr, "struct.new requires gc to be enabled"); - WASM_UNREACHABLE("TODO (gc): struct.new"); + if (curr->type == Type::unreachable) { + return; + } + if (!shouldBeTrue( + curr->rtt->type.isRtt(), curr, "struct.new rtt must be rtt")) { + return; + } + auto heapType = curr->rtt->type.getHeapType(); + if (!shouldBeTrue( + heapType.isStruct(), curr, "struct.new heap type must be struct")) { + return; + } + const auto& fields = heapType.getStruct().fields; + if (curr->isWithDefault()) { + shouldBeTrue(curr->operands.empty(), + curr, + "struct.new_with_default should have no operands"); + // All the fields must be defaultable. + for (const auto& field : fields) { + // TODO: add type.isDefaultable()? + shouldBeTrue(!field.type.isRef() || field.type.isNullable(), + field, + "struct.new_with_default value type must be defaultable"); + } + } else { + // All the fields must have the proper type. + for (Index i = 0; i < fields.size(); i++) { + shouldBeSubType(curr->operands[i]->type, + fields[i].type, + curr, + "struct.new operand must have proper type"); + } + } } void FunctionValidator::visitStructGet(StructGet* curr) { |