Commit 0c2bb397 authored by Andy Wingo's avatar Andy Wingo Committed by V8 LUCI CQ

[stringrefs] Implement string.measure_wtf16

Bug: v8:12868
Change-Id: I717326b27ce783710ffd141370648dde7e0d74a1
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3695561
Commit-Queue: Andy Wingo <wingo@igalia.com>
Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/main@{#81035}
parent 16458924
......@@ -5775,6 +5775,17 @@ Node* WasmGraphBuilder::StringMeasureWtf8(Node* string, CheckForNull null_check,
string);
}
Node* WasmGraphBuilder::StringMeasureWtf16(Node* string,
CheckForNull null_check,
wasm::WasmCodePosition position) {
if (null_check == kWithNullCheck) {
string = AssertNotNull(string, position);
}
return gasm_->LoadImmutableFromObject(
MachineType::Int32(), string,
wasm::ObjectAccess::ToTagged(String::kLengthOffset));
}
// 1 bit V8 Smi tag, 31 bits V8 Smi shift, 1 bit i31ref high-bit truncation.
constexpr int kI31To32BitSmiShift = 33;
......
......@@ -545,6 +545,8 @@ class WasmGraphBuilder {
wasm::WasmCodePosition position);
Node* StringMeasureWtf8(Node* string, CheckForNull null_check,
wasm::WasmCodePosition position);
Node* StringMeasureWtf16(Node* string, CheckForNull null_check,
wasm::WasmCodePosition position);
Node* IsNull(Node* object);
Node* TypeGuard(Node* value, wasm::ValueType type);
......
......@@ -212,6 +212,10 @@ Reduction WasmTyper::Reduce(Node* node) {
m.Is(wasm::ObjectAccess::ToTagged(WasmArray::kLengthOffset))) {
return NoChange();
}
// Do not modify if we are retrieving anything from a string.
if (object_type.type.is_reference_to(wasm::HeapType::kString)) {
return NoChange();
}
uint32_t ref_index = object_type.type.ref_index();
DCHECK(object_type.module->has_type(ref_index));
wasm::TypeDefinition type_def = object_type.module->types[ref_index];
......
......@@ -6120,7 +6120,14 @@ class LiftoffCompiler {
void StringMeasureWtf16(FullDecoder* decoder, const Value& str,
Value* result) {
UNIMPLEMENTED();
LiftoffRegList pinned;
LiftoffRegister string_reg = pinned.set(__ PopToRegister(pinned));
MaybeEmitNullCheck(decoder, string_reg.gp(), pinned, str.type);
LiftoffRegister value = __ GetUnusedRegister(kGpReg, pinned);
LoadObjectField(value, string_reg.gp(), no_reg,
wasm::ObjectAccess::ToTagged(String::kLengthOffset),
ValueKind::kI32, false /* is_signed */, pinned);
__ PushRegister(kI32, value);
}
void StringEncodeWtf8(FullDecoder* decoder,
......
......@@ -1425,7 +1425,8 @@ class WasmGraphBuildingInterface {
void StringMeasureWtf16(FullDecoder* decoder, const Value& str,
Value* result) {
UNIMPLEMENTED();
result->node = builder_->StringMeasureWtf16(
str.node, NullCheckFor(str.type), decoder->position());
}
void StringEncodeWtf8(FullDecoder* decoder,
......
......@@ -215,3 +215,29 @@ function makeWtf16TestDataSegment() {
assertThrows(() => instance.exports.string_measure_wtf8_null(),
WebAssembly.RuntimeError, "dereferencing a null pointer");
})();
(function TestStringMeasureWtf16() {
let builder = new WasmModuleBuilder();
builder.addFunction("string_measure_wtf16", kSig_i_w)
.exportFunc()
.addBody([
kExprLocalGet, 0,
kGCPrefix, kExprStringMeasureWtf16
]);
builder.addFunction("string_measure_wtf16_null", kSig_i_v)
.exportFunc()
.addBody([
kExprRefNull, kStringRefCode,
kGCPrefix, kExprStringMeasureWtf16
]);
let instance = builder.instantiate();
for (let str of interestingStrings) {
assertEquals(str.length, instance.exports.string_measure_wtf16(str));
}
assertThrows(() => instance.exports.string_measure_wtf16_null(),
WebAssembly.RuntimeError, "dereferencing a null pointer");
})();
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