Commit 70289dd7 authored by Andy Wingo's avatar Andy Wingo Committed by V8 LUCI CQ

[stringrefs] Implement string.is_usv_sequence

Bug: v8:12868
Change-Id: I2f12858db1956a3b14b95341f1459df8abc03db0
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3702797
Commit-Queue: Andy Wingo <wingo@igalia.com>
Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/main@{#81188}
parent 69b900dd
...@@ -840,6 +840,12 @@ builtin WasmStringEqual(a: String, b: String): int32 { ...@@ -840,6 +840,12 @@ builtin WasmStringEqual(a: String, b: String): int32 {
if (StringEqual(context, a, b) == True) return 1; if (StringEqual(context, a, b) == True) return 1;
return 0; return 0;
} }
builtin WasmStringIsUSVSequence(str: String): int32 {
if (IsOneByteStringInstanceType(str.instanceType)) return 1;
const length = runtime::WasmStringMeasureUtf8(LoadContextFromFrame(), str);
if (Signed(ChangeNumberToUint32(length)) < 0) return 0;
return 1;
}
transitioning builtin WasmStringViewWtf16GetCodeUnit( transitioning builtin WasmStringViewWtf16GetCodeUnit(
string: String, offset: uint32): uint32 { string: String, offset: uint32): uint32 {
try { try {
......
...@@ -5832,6 +5832,14 @@ Node* WasmGraphBuilder::StringEqual(Node* a, CheckForNull a_null_check, Node* b, ...@@ -5832,6 +5832,14 @@ Node* WasmGraphBuilder::StringEqual(Node* a, CheckForNull a_null_check, Node* b,
return done.PhiAt(0); return done.PhiAt(0);
} }
Node* WasmGraphBuilder::StringIsUSVSequence(Node* str, CheckForNull null_check,
wasm::WasmCodePosition position) {
if (null_check == kWithNullCheck) str = AssertNotNull(str, position);
return gasm_->CallBuiltin(Builtin::kWasmStringIsUSVSequence,
Operator::kNoDeopt, str);
}
Node* WasmGraphBuilder::StringViewWtf16GetCodeUnit( Node* WasmGraphBuilder::StringViewWtf16GetCodeUnit(
Node* string, CheckForNull null_check, Node* offset, Node* string, CheckForNull null_check, Node* offset,
wasm::WasmCodePosition position) { wasm::WasmCodePosition position) {
......
...@@ -558,6 +558,8 @@ class WasmGraphBuilder { ...@@ -558,6 +558,8 @@ class WasmGraphBuilder {
wasm::WasmCodePosition position); wasm::WasmCodePosition position);
Node* StringEqual(Node* a, CheckForNull a_null_check, Node* b, Node* StringEqual(Node* a, CheckForNull a_null_check, Node* b,
CheckForNull b_null_check, wasm::WasmCodePosition position); CheckForNull b_null_check, wasm::WasmCodePosition position);
Node* StringIsUSVSequence(Node* str, CheckForNull null_check,
wasm::WasmCodePosition position);
Node* StringViewWtf16GetCodeUnit(Node* string, CheckForNull null_check, Node* StringViewWtf16GetCodeUnit(Node* string, CheckForNull null_check,
Node* offset, Node* offset,
wasm::WasmCodePosition position); wasm::WasmCodePosition position);
......
...@@ -6246,6 +6246,26 @@ class LiftoffCompiler { ...@@ -6246,6 +6246,26 @@ class LiftoffCompiler {
__ PushRegister(kI32, result_reg); __ PushRegister(kI32, result_reg);
} }
void StringIsUSVSequence(FullDecoder* decoder, const Value& str,
Value* result) {
LiftoffRegList pinned;
LiftoffRegister str_reg = pinned.set(__ PopToRegister(pinned));
MaybeEmitNullCheck(decoder, str_reg.gp(), pinned, str.type);
LiftoffAssembler::VarState str_var(kRef, str_reg, 0);
CallRuntimeStub(WasmCode::kWasmStringIsUSVSequence,
MakeSig::Returns(kI32).Params(kRef),
{
str_var,
},
decoder->position());
RegisterDebugSideTableEntry(decoder, DebugSideTableBuilder::kDidSpill);
LiftoffRegister result_reg(kReturnRegister0);
__ PushRegister(kI32, result_reg);
}
void StringAsWtf8(FullDecoder* decoder, const Value& str, Value* result) { void StringAsWtf8(FullDecoder* decoder, const Value& str, Value* result) {
UNIMPLEMENTED(); UNIMPLEMENTED();
} }
......
...@@ -1146,6 +1146,7 @@ struct ControlBase : public PcForErrors<validate> { ...@@ -1146,6 +1146,7 @@ struct ControlBase : public PcForErrors<validate> {
const Value& str, const Value& address) \ const Value& str, const Value& address) \
F(StringConcat, const Value& head, const Value& tail, Value* result) \ F(StringConcat, const Value& head, const Value& tail, Value* result) \
F(StringEq, const Value& a, const Value& b, Value* result) \ F(StringEq, const Value& a, const Value& b, Value* result) \
F(StringIsUSVSequence, const Value& str, Value* result) \
F(StringAsWtf8, const Value& str, Value* result) \ F(StringAsWtf8, const Value& str, Value* result) \
F(StringViewWtf8Advance, const Value& view, const Value& pos, \ F(StringViewWtf8Advance, const Value& view, const Value& pos, \
const Value& bytes, Value* result) \ const Value& bytes, Value* result) \
...@@ -5243,6 +5244,15 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> { ...@@ -5243,6 +5244,15 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
Push(result); Push(result);
return opcode_length; return opcode_length;
} }
case kExprStringIsUSVSequence: {
NON_CONST_ONLY
Value str = Peek(0, 0, kWasmStringRef);
Value result = CreateValue(kWasmI32);
CALL_INTERFACE_IF_OK_AND_REACHABLE(StringIsUSVSequence, str, &result);
Drop(1);
Push(result);
return opcode_length;
}
case kExprStringAsWtf8: { case kExprStringAsWtf8: {
NON_CONST_ONLY NON_CONST_ONLY
Value str = Peek(0, 0, kWasmStringRef); Value str = Peek(0, 0, kWasmStringRef);
......
...@@ -1460,6 +1460,12 @@ class WasmGraphBuildingInterface { ...@@ -1460,6 +1460,12 @@ class WasmGraphBuildingInterface {
NullCheckFor(b.type), decoder->position()); NullCheckFor(b.type), decoder->position());
} }
void StringIsUSVSequence(FullDecoder* decoder, const Value& str,
Value* result) {
result->node = builder_->StringIsUSVSequence(
str.node, NullCheckFor(str.type), decoder->position());
}
void StringAsWtf8(FullDecoder* decoder, const Value& str, Value* result) { void StringAsWtf8(FullDecoder* decoder, const Value& str, Value* result) {
UNIMPLEMENTED(); UNIMPLEMENTED();
} }
......
...@@ -132,6 +132,7 @@ struct WasmModule; ...@@ -132,6 +132,7 @@ struct WasmModule;
V(WasmStringEncodeWtf16) \ V(WasmStringEncodeWtf16) \
V(WasmStringConcat) \ V(WasmStringConcat) \
V(WasmStringEqual) \ V(WasmStringEqual) \
V(WasmStringIsUSVSequence) \
V(WasmStringViewWtf16GetCodeUnit) \ V(WasmStringViewWtf16GetCodeUnit) \
V(WasmStringViewWtf16Encode) \ V(WasmStringViewWtf16Encode) \
V(WasmStringViewWtf16Slice) V(WasmStringViewWtf16Slice)
......
...@@ -518,6 +518,34 @@ function HasIsolatedSurrogate(str) { ...@@ -518,6 +518,34 @@ function HasIsolatedSurrogate(str) {
WebAssembly.RuntimeError, "dereferencing a null pointer"); WebAssembly.RuntimeError, "dereferencing a null pointer");
})(); })();
(function TestStringIsUSVSequence() {
let builder = new WasmModuleBuilder();
builder.addFunction("is_usv_sequence", kSig_i_w)
.exportFunc()
.addBody([
kExprLocalGet, 0,
kGCPrefix, kExprStringIsUsvSequence
]);
builder.addFunction("is_usv_sequence_null", kSig_i_v)
.exportFunc()
.addBody([
kExprRefNull, kStringRefCode,
kGCPrefix, kExprStringIsUsvSequence
]);
let instance = builder.instantiate();
for (let str of interestingStrings) {
assertEquals(HasIsolatedSurrogate(str) ? 0 : 1,
instance.exports.is_usv_sequence(str));
}
assertThrows(() => instance.exports.is_usv_sequence_null(),
WebAssembly.RuntimeError, "dereferencing a null pointer");
})();
(function TestStringViewWtf16() { (function TestStringViewWtf16() {
let builder = new WasmModuleBuilder(); let builder = new WasmModuleBuilder();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment