[stringrefs] Implement string.eq
Bug: v8:12868 Change-Id: I56ccab1a0cfacfae236c4f87c31a84d3afecafc8 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3702437 Commit-Queue: Andy Wingo <wingo@igalia.com> Reviewed-by: Jakob Kummerow <jkummerow@chromium.org> Cr-Commit-Position: refs/heads/main@{#81153}
This commit is contained in:
parent
4ac5b2f6e0
commit
310fe8e61c
@ -833,6 +833,13 @@ builtin WasmStringConcat(a: String, b: String): String {
|
||||
const context = LoadContextFromFrame();
|
||||
return a + b;
|
||||
}
|
||||
builtin WasmStringEqual(a: String, b: String): int32 {
|
||||
if (TaggedEqual(a, b)) return 1;
|
||||
if (a.length != b.length) return 0;
|
||||
const context = LoadContextFromFrame();
|
||||
if (StringEqual(context, a, b) == True) return 1;
|
||||
return 0;
|
||||
}
|
||||
transitioning builtin WasmStringViewWtf16GetCodeUnit(
|
||||
string: String, offset: uint32): uint32 {
|
||||
try {
|
||||
|
@ -5818,6 +5818,20 @@ Node* WasmGraphBuilder::StringConcat(Node* head, CheckForNull head_null_check,
|
||||
head, tail);
|
||||
}
|
||||
|
||||
Node* WasmGraphBuilder::StringEqual(Node* a, CheckForNull a_null_check, Node* b,
|
||||
CheckForNull b_null_check,
|
||||
wasm::WasmCodePosition position) {
|
||||
if (a_null_check == kWithNullCheck) a = AssertNotNull(a, position);
|
||||
if (b_null_check == kWithNullCheck) b = AssertNotNull(b, position);
|
||||
|
||||
auto done = gasm_->MakeLabel(MachineRepresentation::kWord32);
|
||||
gasm_->GotoIf(gasm_->TaggedEqual(a, b), &done, Int32Constant(1));
|
||||
gasm_->Goto(&done, gasm_->CallBuiltin(Builtin::kWasmStringEqual,
|
||||
Operator::kNoDeopt, a, b));
|
||||
gasm_->Bind(&done);
|
||||
return done.PhiAt(0);
|
||||
}
|
||||
|
||||
Node* WasmGraphBuilder::StringViewWtf16GetCodeUnit(
|
||||
Node* string, CheckForNull null_check, Node* offset,
|
||||
wasm::WasmCodePosition position) {
|
||||
|
@ -556,6 +556,8 @@ class WasmGraphBuilder {
|
||||
Node* StringConcat(Node* head, CheckForNull head_null_check, Node* tail,
|
||||
CheckForNull tail_null_check,
|
||||
wasm::WasmCodePosition position);
|
||||
Node* StringEqual(Node* a, CheckForNull a_null_check, Node* b,
|
||||
CheckForNull b_null_check, wasm::WasmCodePosition position);
|
||||
Node* StringViewWtf16GetCodeUnit(Node* string, CheckForNull null_check,
|
||||
Node* offset,
|
||||
wasm::WasmCodePosition position);
|
||||
|
@ -6223,7 +6223,27 @@ class LiftoffCompiler {
|
||||
|
||||
void StringEq(FullDecoder* decoder, const Value& a, const Value& b,
|
||||
Value* result) {
|
||||
UNIMPLEMENTED();
|
||||
LiftoffRegList pinned;
|
||||
|
||||
LiftoffRegister b_reg = pinned.set(__ PopToRegister(pinned));
|
||||
MaybeEmitNullCheck(decoder, b_reg.gp(), pinned, b.type);
|
||||
LiftoffAssembler::VarState b_var(kRef, b_reg, 0);
|
||||
|
||||
LiftoffRegister a_reg = pinned.set(__ PopToRegister(pinned));
|
||||
MaybeEmitNullCheck(decoder, a_reg.gp(), pinned, a.type);
|
||||
LiftoffAssembler::VarState a_var(kRef, a_reg, 0);
|
||||
|
||||
CallRuntimeStub(WasmCode::kWasmStringEqual,
|
||||
MakeSig::Returns(kI32).Params(kRef, kRef),
|
||||
{
|
||||
a_var,
|
||||
b_var,
|
||||
},
|
||||
decoder->position());
|
||||
RegisterDebugSideTableEntry(decoder, DebugSideTableBuilder::kDidSpill);
|
||||
|
||||
LiftoffRegister result_reg(kReturnRegister0);
|
||||
__ PushRegister(kI32, result_reg);
|
||||
}
|
||||
|
||||
void StringAsWtf8(FullDecoder* decoder, const Value& str, Value* result) {
|
||||
|
@ -1455,7 +1455,9 @@ class WasmGraphBuildingInterface {
|
||||
|
||||
void StringEq(FullDecoder* decoder, const Value& a, const Value& b,
|
||||
Value* result) {
|
||||
UNIMPLEMENTED();
|
||||
result->node =
|
||||
builder_->StringEqual(a.node, NullCheckFor(a.type), b.node,
|
||||
NullCheckFor(b.type), decoder->position());
|
||||
}
|
||||
|
||||
void StringAsWtf8(FullDecoder* decoder, const Value& str, Value* result) {
|
||||
|
@ -131,6 +131,7 @@ struct WasmModule;
|
||||
V(WasmStringEncodeWtf8) \
|
||||
V(WasmStringEncodeWtf16) \
|
||||
V(WasmStringConcat) \
|
||||
V(WasmStringEqual) \
|
||||
V(WasmStringViewWtf16GetCodeUnit) \
|
||||
V(WasmStringViewWtf16Encode) \
|
||||
V(WasmStringViewWtf16Slice)
|
||||
|
@ -10,6 +10,7 @@ let kSig_w_ii = makeSig([kWasmI32, kWasmI32], [kWasmStringRef]);
|
||||
let kSig_w_v = makeSig([], [kWasmStringRef]);
|
||||
let kSig_i_w = makeSig([kWasmStringRef], [kWasmI32]);
|
||||
let kSig_i_wi = makeSig([kWasmStringRef, kWasmI32], [kWasmI32]);
|
||||
let kSig_i_ww = makeSig([kWasmStringRef, kWasmStringRef], [kWasmI32]);
|
||||
let kSig_w_wii = makeSig([kWasmStringRef, kWasmI32, kWasmI32],
|
||||
[kWasmStringRef]);
|
||||
let kSig_v_wi = makeSig([kWasmStringRef, kWasmI32], []);
|
||||
@ -475,6 +476,48 @@ function HasIsolatedSurrogate(str) {
|
||||
WebAssembly.RuntimeError, "dereferencing a null pointer");
|
||||
})();
|
||||
|
||||
(function TestStringEq() {
|
||||
let builder = new WasmModuleBuilder();
|
||||
|
||||
builder.addFunction("eq", kSig_i_ww)
|
||||
.exportFunc()
|
||||
.addBody([
|
||||
kExprLocalGet, 0,
|
||||
kExprLocalGet, 1,
|
||||
kGCPrefix, kExprStringEq
|
||||
]);
|
||||
|
||||
builder.addFunction("eq_null_a", kSig_i_w)
|
||||
.exportFunc()
|
||||
.addBody([
|
||||
kExprRefNull, kStringRefCode,
|
||||
kExprLocalGet, 0,
|
||||
kGCPrefix, kExprStringEq
|
||||
]);
|
||||
builder.addFunction("eq_null_b", kSig_i_w)
|
||||
.exportFunc()
|
||||
.addBody([
|
||||
kExprLocalGet, 0,
|
||||
kExprRefNull, kStringRefCode,
|
||||
kGCPrefix, kExprStringEq
|
||||
]);
|
||||
|
||||
let instance = builder.instantiate();
|
||||
|
||||
for (let head of interestingStrings) {
|
||||
for (let tail of interestingStrings) {
|
||||
let result = (head == tail)|0;
|
||||
assertEquals(result, instance.exports.eq(head, tail));
|
||||
assertEquals(result, instance.exports.eq(head + head, tail + tail));
|
||||
}
|
||||
}
|
||||
|
||||
assertThrows(() => instance.exports.eq_null_a("hey"),
|
||||
WebAssembly.RuntimeError, "dereferencing a null pointer");
|
||||
assertThrows(() => instance.exports.eq_null_b("hey"),
|
||||
WebAssembly.RuntimeError, "dereferencing a null pointer");
|
||||
})();
|
||||
|
||||
(function TestStringViewWtf16() {
|
||||
let builder = new WasmModuleBuilder();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user