diff options
Diffstat (limited to 'src/wasm')
-rw-r--r-- | src/wasm/wasm-binary.cpp | 111 | ||||
-rw-r--r-- | src/wasm/wasm-ir-builder.cpp | 73 | ||||
-rw-r--r-- | src/wasm/wasm-s-parser.cpp | 33 | ||||
-rw-r--r-- | src/wasm/wasm-stack.cpp | 65 | ||||
-rw-r--r-- | src/wasm/wasm-validator.cpp | 42 | ||||
-rw-r--r-- | src/wasm/wasm.cpp | 9 |
6 files changed, 67 insertions, 266 deletions
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index c8dd7bace..befafde59 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -7501,77 +7501,21 @@ bool WasmBinaryReader::maybeVisitArrayInit(Expression*& out, uint32_t code) { bool WasmBinaryReader::maybeVisitStringNew(Expression*& out, uint32_t code) { StringNewOp op; - Expression* length = nullptr; - Expression* start = nullptr; - Expression* end = nullptr; - bool try_ = false; - if (code == BinaryConsts::StringNewUTF8) { - // FIXME: the memory index should be an LEB like all other places - if (getInt8() != 0) { - throwError("Unexpected nonzero memory index"); - } - op = StringNewUTF8; - length = popNonVoidExpression(); - } else if (code == BinaryConsts::StringNewLossyUTF8) { - // FIXME: the memory index should be an LEB like all other places - if (getInt8() != 0) { - throwError("Unexpected nonzero memory index"); - } - op = StringNewLossyUTF8; - length = popNonVoidExpression(); - } else if (code == BinaryConsts::StringNewWTF8) { - // FIXME: the memory index should be an LEB like all other places - if (getInt8() != 0) { - throwError("Unexpected nonzero memory index"); - } - op = StringNewWTF8; - length = popNonVoidExpression(); - } else if (code == BinaryConsts::StringNewUTF8Try) { - // FIXME: the memory index should be an LEB like all other places - if (getInt8() != 0) { - throwError("Unexpected nonzero memory index"); - } - op = StringNewUTF8; - try_ = true; - length = popNonVoidExpression(); - } else if (code == BinaryConsts::StringNewWTF16) { - if (getInt8() != 0) { - throwError("Unexpected nonzero memory index"); - } - op = StringNewWTF16; - length = popNonVoidExpression(); - } else if (code == BinaryConsts::StringNewUTF8Array) { - op = StringNewUTF8Array; - end = popNonVoidExpression(); - start = popNonVoidExpression(); - } else if (code == BinaryConsts::StringNewLossyUTF8Array) { + if (code == BinaryConsts::StringNewLossyUTF8Array) { op = StringNewLossyUTF8Array; - end = popNonVoidExpression(); - start = popNonVoidExpression(); - } else if (code == BinaryConsts::StringNewWTF8Array) { - op = StringNewWTF8Array; - end = popNonVoidExpression(); - start = popNonVoidExpression(); - } else if (code == BinaryConsts::StringNewUTF8ArrayTry) { - op = StringNewUTF8Array; - try_ = true; - end = popNonVoidExpression(); - start = popNonVoidExpression(); } else if (code == BinaryConsts::StringNewWTF16Array) { op = StringNewWTF16Array; - end = popNonVoidExpression(); - start = popNonVoidExpression(); } else if (code == BinaryConsts::StringFromCodePoint) { - op = StringNewFromCodePoint; + out = Builder(wasm).makeStringNew(StringNewFromCodePoint, + popNonVoidExpression()); + return true; } else { return false; } - auto* ptr = popNonVoidExpression(); - if (length) { - out = Builder(wasm).makeStringNew(op, ptr, length, try_); - } else { - out = Builder(wasm).makeStringNew(op, ptr, start, end, try_); - } + Expression* end = popNonVoidExpression(); + Expression* start = popNonVoidExpression(); + auto* ref = popNonVoidExpression(); + out = Builder(wasm).makeStringNew(op, ref, start, end); return true; } @@ -7605,14 +7549,8 @@ bool WasmBinaryReader::maybeVisitStringMeasure(Expression*& out, StringMeasureOp op; if (code == BinaryConsts::StringMeasureUTF8) { op = StringMeasureUTF8; - } else if (code == BinaryConsts::StringMeasureWTF8) { - op = StringMeasureWTF8; } else if (code == BinaryConsts::StringMeasureWTF16) { op = StringMeasureWTF16; - } else if (code == BinaryConsts::StringIsUSV) { - op = StringMeasureIsUSV; - } else if (code == BinaryConsts::StringHash) { - op = StringMeasureHash; } else { return false; } @@ -7623,43 +7561,14 @@ bool WasmBinaryReader::maybeVisitStringMeasure(Expression*& out, bool WasmBinaryReader::maybeVisitStringEncode(Expression*& out, uint32_t code) { StringEncodeOp op; - Expression* start = nullptr; - // TODO: share this code with string.measure? - if (code == BinaryConsts::StringEncodeUTF8) { - if (getInt8() != 0) { - throwError("Unexpected nonzero memory index"); - } - op = StringEncodeUTF8; - } else if (code == BinaryConsts::StringEncodeLossyUTF8) { - if (getInt8() != 0) { - throwError("Unexpected nonzero memory index"); - } - op = StringEncodeLossyUTF8; - } else if (code == BinaryConsts::StringEncodeWTF8) { - if (getInt8() != 0) { - throwError("Unexpected nonzero memory index"); - } - op = StringEncodeWTF8; - } else if (code == BinaryConsts::StringEncodeWTF16) { - if (getInt8() != 0) { - throwError("Unexpected nonzero memory index"); - } - op = StringEncodeWTF16; - } else if (code == BinaryConsts::StringEncodeUTF8Array) { - op = StringEncodeUTF8Array; - start = popNonVoidExpression(); - } else if (code == BinaryConsts::StringEncodeLossyUTF8Array) { + if (code == BinaryConsts::StringEncodeLossyUTF8Array) { op = StringEncodeLossyUTF8Array; - start = popNonVoidExpression(); - } else if (code == BinaryConsts::StringEncodeWTF8Array) { - op = StringEncodeWTF8Array; - start = popNonVoidExpression(); } else if (code == BinaryConsts::StringEncodeWTF16Array) { op = StringEncodeWTF16Array; - start = popNonVoidExpression(); } else { return false; } + auto* start = popNonVoidExpression(); auto* ptr = popNonVoidExpression(); auto* ref = popNonVoidExpression(); out = Builder(wasm).makeStringEncode(op, ref, ptr, start); diff --git a/src/wasm/wasm-ir-builder.cpp b/src/wasm/wasm-ir-builder.cpp index a4b7becf8..bf737bbd6 100644 --- a/src/wasm/wasm-ir-builder.cpp +++ b/src/wasm/wasm-ir-builder.cpp @@ -1804,35 +1804,21 @@ Result<> IRBuilder::makeRefAs(RefAsOp op) { return Ok{}; } -Result<> IRBuilder::makeStringNew(StringNewOp op, bool try_, Name mem) { +Result<> IRBuilder::makeStringNew(StringNewOp op) { StringNew curr; curr.op = op; - // TODO: Store the memory in the IR. - switch (op) { - case StringNewUTF8: - case StringNewWTF8: - case StringNewLossyUTF8: - case StringNewWTF16: - CHECK_ERR(visitStringNew(&curr)); - push(builder.makeStringNew(op, curr.ptr, curr.length, try_)); - return Ok{}; - case StringNewUTF8Array: - case StringNewWTF8Array: - case StringNewLossyUTF8Array: - case StringNewWTF16Array: - // There's no type annotation on these instructions due to a bug in the - // stringref proposal, so we just fudge it and pass `array` instead of a - // defined heap type. This will allow us to pop a child with an invalid - // array type, but that's just too bad. - CHECK_ERR(ChildPopper{*this}.visitStringNew(&curr, HeapType::array)); - push(builder.makeStringNew(op, curr.ptr, curr.start, curr.end, try_)); - return Ok{}; - case StringNewFromCodePoint: - CHECK_ERR(visitStringNew(&curr)); - push(builder.makeStringNew(op, curr.ptr, nullptr, try_)); - return Ok{}; - } - WASM_UNREACHABLE("unexpected op"); + if (op == StringNewFromCodePoint) { + CHECK_ERR(visitStringNew(&curr)); + push(builder.makeStringNew(op, curr.ref)); + return Ok{}; + } + // There's no type annotation on these instructions due to a bug in the + // stringref proposal, so we just fudge it and pass `array` instead of a + // defined heap type. This will allow us to pop a child with an invalid + // array type, but that's just too bad. + CHECK_ERR(ChildPopper{*this}.visitStringNew(&curr, HeapType::array)); + push(builder.makeStringNew(op, curr.ref, curr.start, curr.end)); + return Ok{}; } Result<> IRBuilder::makeStringConst(Name string) { @@ -1848,33 +1834,16 @@ Result<> IRBuilder::makeStringMeasure(StringMeasureOp op) { return Ok{}; } -Result<> IRBuilder::makeStringEncode(StringEncodeOp op, Name mem) { +Result<> IRBuilder::makeStringEncode(StringEncodeOp op) { StringEncode curr; curr.op = op; - // TODO: Store the memory in the IR. - switch (op) { - case StringEncodeUTF8: - case StringEncodeLossyUTF8: - case StringEncodeWTF8: - case StringEncodeWTF16: { - CHECK_ERR(visitStringEncode(&curr)); - push(builder.makeStringEncode(op, curr.ref, curr.ptr, curr.start)); - return Ok{}; - } - case StringEncodeUTF8Array: - case StringEncodeLossyUTF8Array: - case StringEncodeWTF8Array: - case StringEncodeWTF16Array: { - // There's no type annotation on these instructions due to a bug in the - // stringref proposal, so we just fudge it and pass `array` instead of a - // defined heap type. This will allow us to pop a child with an invalid - // array type, but that's just too bad. - CHECK_ERR(ChildPopper{*this}.visitStringEncode(&curr, HeapType::array)); - push(builder.makeStringEncode(op, curr.ref, curr.ptr, curr.start)); - return Ok{}; - } - } - WASM_UNREACHABLE("unexpected op"); + // There's no type annotation on these instructions due to a bug in the + // stringref proposal, so we just fudge it and pass `array` instead of a + // defined heap type. This will allow us to pop a child with an invalid + // array type, but that's just too bad. + CHECK_ERR(ChildPopper{*this}.visitStringEncode(&curr, HeapType::array)); + push(builder.makeStringEncode(op, curr.str, curr.array, curr.start)); + return Ok{}; } Result<> IRBuilder::makeStringConcat() { diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index 978ea6a9b..f9eae14b8 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -3301,30 +3301,13 @@ Expression* SExpressionWasmBuilder::makeRefAs(Element& s, RefAsOp op) { return Builder(wasm).makeRefAs(op, value); } -Expression* -SExpressionWasmBuilder::makeStringNew(Element& s, StringNewOp op, bool try_) { - Expression* length = nullptr; - if (op == StringNewWTF8) { - length = parseExpression(s[2]); - return Builder(wasm).makeStringNew(op, parseExpression(s[1]), length, try_); - } else if (op == StringNewUTF8 || op == StringNewLossyUTF8 || - op == StringNewWTF16) { - length = parseExpression(s[2]); - return Builder(wasm).makeStringNew(op, parseExpression(s[1]), length, try_); - } else if (op == StringNewWTF8Array) { - auto* start = parseExpression(s[2]); - auto* end = parseExpression(s[3]); - return Builder(wasm).makeStringNew( - op, parseExpression(s[1]), start, end, try_); - } else if (op == StringNewUTF8Array || op == StringNewLossyUTF8Array || - op == StringNewWTF16Array) { +Expression* SExpressionWasmBuilder::makeStringNew(Element& s, StringNewOp op) { + if (op == StringNewLossyUTF8Array || op == StringNewWTF16Array) { auto* start = parseExpression(s[2]); auto* end = parseExpression(s[3]); - return Builder(wasm).makeStringNew( - op, parseExpression(s[1]), start, end, try_); + return Builder(wasm).makeStringNew(op, parseExpression(s[1]), start, end); } else if (op == StringNewFromCodePoint) { - return Builder(wasm).makeStringNew( - op, parseExpression(s[1]), nullptr, try_); + return Builder(wasm).makeStringNew(op, parseExpression(s[1])); } else { throw SParseException("bad string.new op", s); } @@ -3350,13 +3333,9 @@ Expression* SExpressionWasmBuilder::makeStringMeasure(Element& s, Expression* SExpressionWasmBuilder::makeStringEncode(Element& s, StringEncodeOp op) { - Expression* start = nullptr; - if (op == StringEncodeWTF8Array || op == StringEncodeUTF8Array || - op == StringEncodeLossyUTF8Array || op == StringEncodeWTF16Array) { - start = parseExpression(s[3]); - } + return Builder(wasm).makeStringEncode( - op, parseExpression(s[1]), parseExpression(s[2]), start); + op, parseExpression(s[1]), parseExpression(s[2]), parseExpression(s[3])); } Expression* SExpressionWasmBuilder::makeStringConcat(Element& s) { diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp index a817e5294..1d7fe5255 100644 --- a/src/wasm/wasm-stack.cpp +++ b/src/wasm/wasm-stack.cpp @@ -2298,7 +2298,7 @@ void BinaryInstWriter::visitRefAs(RefAs* curr) { } void BinaryInstWriter::visitStringNew(StringNew* curr) { - if (curr->ptr->type.isNull()) { + if (curr->ref->type.isNull()) { // This is a bottom type, so this is an array-receiving operation that does // not receive an array. The spec allows this, but V8 does not, see // https://github.com/WebAssembly/stringref/issues/66 @@ -2308,36 +2308,6 @@ void BinaryInstWriter::visitStringNew(StringNew* curr) { } o << int8_t(BinaryConsts::GCPrefix); switch (curr->op) { - case StringNewUTF8: - if (!curr->try_) { - o << U32LEB(BinaryConsts::StringNewUTF8); - } else { - o << U32LEB(BinaryConsts::StringNewUTF8Try); - } - o << int8_t(0); // Memory index. - break; - case StringNewWTF8: - o << U32LEB(BinaryConsts::StringNewWTF8); - o << int8_t(0); // Memory index. - break; - case StringNewLossyUTF8: - o << U32LEB(BinaryConsts::StringNewLossyUTF8); - o << int8_t(0); // Memory index. - break; - case StringNewWTF16: - o << U32LEB(BinaryConsts::StringNewWTF16); - o << int8_t(0); // Memory index. - break; - case StringNewUTF8Array: - if (!curr->try_) { - o << U32LEB(BinaryConsts::StringNewUTF8Array); - } else { - o << U32LEB(BinaryConsts::StringNewUTF8ArrayTry); - } - break; - case StringNewWTF8Array: - o << U32LEB(BinaryConsts::StringNewWTF8Array); - break; case StringNewLossyUTF8Array: o << U32LEB(BinaryConsts::StringNewLossyUTF8Array); break; @@ -2363,56 +2333,25 @@ void BinaryInstWriter::visitStringMeasure(StringMeasure* curr) { case StringMeasureUTF8: o << U32LEB(BinaryConsts::StringMeasureUTF8); break; - case StringMeasureWTF8: - o << U32LEB(BinaryConsts::StringMeasureWTF8); - break; case StringMeasureWTF16: o << U32LEB(BinaryConsts::StringMeasureWTF16); break; - case StringMeasureIsUSV: - o << U32LEB(BinaryConsts::StringIsUSV); - break; - case StringMeasureHash: - o << U32LEB(BinaryConsts::StringHash); - break; default: WASM_UNREACHABLE("invalid string.new*"); } } void BinaryInstWriter::visitStringEncode(StringEncode* curr) { - if (curr->ptr->type.isNull()) { + if (curr->str->type.isNull()) { // See visitStringNew. emitUnreachable(); return; } o << int8_t(BinaryConsts::GCPrefix); switch (curr->op) { - case StringEncodeUTF8: - o << U32LEB(BinaryConsts::StringEncodeUTF8); - o << int8_t(0); // Memory index. - break; - case StringEncodeLossyUTF8: - o << U32LEB(BinaryConsts::StringEncodeLossyUTF8); - o << int8_t(0); // Memory index. - break; - case StringEncodeWTF8: - o << U32LEB(BinaryConsts::StringEncodeWTF8); - o << int8_t(0); // Memory index. - break; - case StringEncodeWTF16: - o << U32LEB(BinaryConsts::StringEncodeWTF16); - o << int8_t(0); // Memory index. - break; - case StringEncodeUTF8Array: - o << U32LEB(BinaryConsts::StringEncodeUTF8Array); - break; case StringEncodeLossyUTF8Array: o << U32LEB(BinaryConsts::StringEncodeLossyUTF8Array); break; - case StringEncodeWTF8Array: - o << U32LEB(BinaryConsts::StringEncodeWTF8Array); - break; case StringEncodeWTF16Array: o << U32LEB(BinaryConsts::StringEncodeWTF16Array); break; diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index e9bee8e08..bf7ebc620 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -3248,37 +3248,43 @@ void FunctionValidator::visitStringNew(StringNew* curr) { "string operations require reference-types [--enable-strings]"); switch (curr->op) { + case StringNewLossyUTF8Array: case StringNewWTF16Array: { - auto ptrType = curr->ptr->type; - if (ptrType == Type::unreachable) { + auto refType = curr->ref->type; + if (refType == Type::unreachable) { return; } - if (!shouldBeTrue(ptrType.isRef(), - curr, - "string.new_wtf16_array input must have string type")) { + if (!shouldBeTrue( + refType.isRef(), curr, "string.new input must have array type")) { return; } - auto ptrHeapType = ptrType.getHeapType(); - if (!shouldBeTrue(ptrHeapType.isBottom() || ptrHeapType.isArray(), + auto heapType = refType.getHeapType(); + if (!shouldBeTrue(heapType.isBottom() || heapType.isArray(), curr, - "string.new_wtf16_array input must be array")) { + "string.new input must have array type")) { return; } + shouldBeEqualOrFirstIsUnreachable(curr->start->type, + Type(Type::i32), + curr, + "string.new start must be i32"); shouldBeEqualOrFirstIsUnreachable( - curr->start->type, - Type(Type::i32), - curr, - "string.new_wtf16_array start must be i32"); + curr->end->type, Type(Type::i32), curr, "string.new end must be i32"); + return; + } + case StringNewFromCodePoint: shouldBeEqualOrFirstIsUnreachable( - curr->end->type, + curr->ref->type, Type(Type::i32), curr, - "string.new_wtf16_array end must be i32"); - break; - } - default: { - } + "string.from_code_point code point must be i32"); + shouldBeTrue( + !curr->start, curr, "string.from_code_point should not have start"); + shouldBeTrue( + !curr->end, curr, "string.from_code_point should not have end"); + return; } + WASM_UNREACHABLE("unexpected op"); } void FunctionValidator::visitStringConst(StringConst* curr) { diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index 22ea4d86f..a4b9da21b 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -1244,13 +1244,12 @@ void RefAs::finalize() { } void StringNew::finalize() { - if (ptr->type == Type::unreachable || - (length && length->type == Type::unreachable) || + if (ref->type == Type::unreachable || (start && start->type == Type::unreachable) || (end && end->type == Type::unreachable)) { type = Type::unreachable; } else { - type = Type(HeapType::string, try_ ? Nullable : NonNullable); + type = Type(HeapType::string, NonNullable); } } @@ -1265,8 +1264,8 @@ void StringMeasure::finalize() { } void StringEncode::finalize() { - if (ref->type == Type::unreachable || ptr->type == Type::unreachable || - (start && start->type == Type::unreachable)) { + if (str->type == Type::unreachable || array->type == Type::unreachable || + start->type == Type::unreachable) { type = Type::unreachable; } else { type = Type::i32; |