diff options
Diffstat (limited to 'src/wasm/wasm-validator.cpp')
-rw-r--r-- | src/wasm/wasm-validator.cpp | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index cb3841197..c1316f283 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -451,6 +451,7 @@ public: void visitStructGet(StructGet* curr); void visitStructSet(StructSet* curr); void visitArrayNew(ArrayNew* curr); + void visitArrayNewSeg(ArrayNewSeg* curr); void visitArrayInit(ArrayInit* curr); void visitArrayGet(ArrayGet* curr); void visitArraySet(ArraySet* curr); @@ -2683,6 +2684,73 @@ void FunctionValidator::visitArrayNew(ArrayNew* curr) { } } +void FunctionValidator::visitArrayNewSeg(ArrayNewSeg* curr) { + shouldBeTrue(getModule()->features.hasGC(), + curr, + "array.new_{data, elem} requires gc [--enable-gc]"); + shouldBeEqualOrFirstIsUnreachable( + curr->offset->type, + Type(Type::i32), + curr, + "array.new_{data, elem} offset must be an i32"); + shouldBeEqualOrFirstIsUnreachable( + curr->size->type, + Type(Type::i32), + curr, + "array.new_{data, elem} size must be an i32"); + switch (curr->op) { + case NewData: + if (!shouldBeTrue(curr->segment < getModule()->dataSegments.size(), + curr, + "array.new_data segment index out of bounds")) { + return; + } + break; + case NewElem: + if (!shouldBeTrue(curr->segment < getModule()->elementSegments.size(), + curr, + "array.new_elem segment index out of bounds")) { + return; + } + break; + default: + WASM_UNREACHABLE("unexpected op"); + } + if (curr->type == Type::unreachable) { + return; + } + if (!shouldBeTrue( + curr->type.isRef(), + curr, + "array.new_{data, elem} type should be an array reference")) { + return; + } + auto heapType = curr->type.getHeapType(); + if (!shouldBeTrue( + heapType.isArray(), + curr, + "array.new_{data, elem} type shoudl be an array reference")) { + return; + } + auto elemType = heapType.getArray().element.type; + switch (curr->op) { + case NewData: + shouldBeTrue(elemType.isNumber(), + curr, + "array.new_data result element type should be numeric"); + break; + case NewElem: + shouldBeSubType(getModule()->elementSegments[curr->segment]->type, + elemType, + curr, + "array.new_elem segment type should be a subtype of the " + "result element type"); + break; + default: + WASM_UNREACHABLE("unexpected op"); + } +} + void FunctionValidator::visitArrayInit(ArrayInit* curr) { shouldBeTrue(getModule()->features.hasGC(), curr, |