summaryrefslogtreecommitdiff
path: root/src/wasm/wasm-validator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/wasm/wasm-validator.cpp')
-rw-r--r--src/wasm/wasm-validator.cpp34
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) {