summaryrefslogtreecommitdiff
path: root/src/wasm
diff options
context:
space:
mode:
Diffstat (limited to 'src/wasm')
-rw-r--r--src/wasm/wasm-binary.cpp111
-rw-r--r--src/wasm/wasm-ir-builder.cpp73
-rw-r--r--src/wasm/wasm-s-parser.cpp33
-rw-r--r--src/wasm/wasm-stack.cpp65
-rw-r--r--src/wasm/wasm-validator.cpp42
-rw-r--r--src/wasm/wasm.cpp9
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;