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

[stringrefs] Add wtf8_policy immediate to string.measure_wtf8

Following change in https://github.com/WebAssembly/stringref/pull/22.

Bug: v8:12868
Change-Id: Ic7728bff5d03ab547cb26ff41d6966f95bfb6b62
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3717986
Commit-Queue: Andy Wingo <wingo@igalia.com>
Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/main@{#81308}
parent 22698d26
......@@ -6078,34 +6078,25 @@ class LiftoffCompiler {
__ PushRegister(kRef, result_reg);
}
void StringMeasureUtf8(FullDecoder* decoder, const Value& str,
Value* result) {
LiftoffRegList pinned;
LiftoffRegister string_reg = pinned.set(__ PopToRegister(pinned));
MaybeEmitNullCheck(decoder, string_reg.gp(), pinned, str.type);
LiftoffAssembler::VarState string_var(kRef, string_reg, 0);
CallRuntimeStub(WasmCode::kWasmStringMeasureUtf8,
MakeSig::Returns(kI32).Params(kRef),
{
string_var,
},
decoder->position());
RegisterDebugSideTableEntry(decoder, DebugSideTableBuilder::kDidSpill);
LiftoffRegister result_reg(kReturnRegister0);
__ PushRegister(kI32, result_reg);
}
void StringMeasureWtf8(FullDecoder* decoder, const Value& str,
Value* result) {
void StringMeasureWtf8(FullDecoder* decoder,
const Wtf8PolicyImmediate<validate>& imm,
const Value& str, Value* result) {
LiftoffRegList pinned;
LiftoffRegister string_reg = pinned.set(__ PopToRegister(pinned));
MaybeEmitNullCheck(decoder, string_reg.gp(), pinned, str.type);
LiftoffAssembler::VarState string_var(kRef, string_reg, 0);
CallRuntimeStub(WasmCode::kWasmStringMeasureWtf8,
MakeSig::Returns(kI32).Params(kRef),
WasmCode::RuntimeStubId stub_id;
switch (imm.value) {
case kWtf8PolicyReject:
stub_id = WasmCode::kWasmStringMeasureUtf8;
break;
case kWtf8PolicyAccept:
case kWtf8PolicyReplace:
stub_id = WasmCode::kWasmStringMeasureWtf8;
break;
}
CallRuntimeStub(stub_id, MakeSig::Returns(kI32).Params(kRef),
{
string_var,
},
......
......@@ -1137,8 +1137,8 @@ struct ControlBase : public PcForErrors<validate> {
const Value& offset, const Value& size, Value* result) \
F(StringNewWtf16, const MemoryIndexImmediate<validate>& imm, \
const Value& offset, const Value& size, Value* result) \
F(StringMeasureUtf8, const Value& str, Value* result) \
F(StringMeasureWtf8, const Value& str, Value* result) \
F(StringMeasureWtf8, const Wtf8PolicyImmediate<validate>& imm, \
const Value& str, Value* result) \
F(StringMeasureWtf16, const Value& str, Value* result) \
F(StringEncodeWtf8, const EncodeWtf8Immediate<validate>& memory, \
const Value& str, const Value& address) \
......@@ -2028,8 +2028,10 @@ class WasmDecoder : public Decoder {
StringConstImmediate<validate> imm(decoder, pc + length);
return length + imm.length;
}
case kExprStringMeasureUtf8:
case kExprStringMeasureWtf8:
case kExprStringMeasureWtf8: {
Wtf8PolicyImmediate<validate> imm(decoder, pc + length);
return length + imm.length;
}
case kExprStringMeasureWtf16:
case kExprStringConcat:
case kExprStringEq:
......@@ -2250,7 +2252,6 @@ class WasmDecoder : public Decoder {
}
case kExprStringConst:
return { 0, 1 };
case kExprStringMeasureUtf8:
case kExprStringMeasureWtf8:
case kExprStringMeasureWtf16:
case kExprStringIsUSVSequence:
......@@ -5223,23 +5224,16 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
Push(result);
return opcode_length + imm.length;
}
case kExprStringMeasureUtf8: {
NON_CONST_ONLY
Value str = Peek(0, 0, kWasmStringRef);
Value result = CreateValue(kWasmI32);
CALL_INTERFACE_IF_OK_AND_REACHABLE(StringMeasureUtf8, str, &result);
Drop(str);
Push(result);
return opcode_length;
}
case kExprStringMeasureWtf8: {
NON_CONST_ONLY
Wtf8PolicyImmediate<validate> imm(this, this->pc_ + opcode_length);
Value str = Peek(0, 0, kWasmStringRef);
Value result = CreateValue(kWasmI32);
CALL_INTERFACE_IF_OK_AND_REACHABLE(StringMeasureWtf8, str, &result);
CALL_INTERFACE_IF_OK_AND_REACHABLE(StringMeasureWtf8, imm, str,
&result);
Drop(str);
Push(result);
return opcode_length;
return opcode_length + imm.length;
}
case kExprStringMeasureWtf16: {
NON_CONST_ONLY
......
......@@ -1413,16 +1413,20 @@ class WasmGraphBuildingInterface {
result->node = builder_->StringConst(imm.index);
}
void StringMeasureUtf8(FullDecoder* decoder, const Value& str,
Value* result) {
result->node = builder_->StringMeasureUtf8(str.node, NullCheckFor(str.type),
decoder->position());
}
void StringMeasureWtf8(FullDecoder* decoder, const Value& str,
Value* result) {
result->node = builder_->StringMeasureWtf8(str.node, NullCheckFor(str.type),
decoder->position());
void StringMeasureWtf8(FullDecoder* decoder,
const Wtf8PolicyImmediate<validate>& imm,
const Value& str, Value* result) {
switch (imm.value) {
case kWtf8PolicyReject:
result->node = builder_->StringMeasureUtf8(
str.node, NullCheckFor(str.type), decoder->position());
break;
case kWtf8PolicyAccept:
case kWtf8PolicyReplace:
result->node = builder_->StringMeasureWtf8(
str.node, NullCheckFor(str.type), decoder->position());
break;
}
}
void StringMeasureWtf16(FullDecoder* decoder, const Value& str,
......
......@@ -151,7 +151,8 @@ enum NameSectionKindCode : uint8_t {
enum StringRefWtf8Policy : uint8_t {
kWtf8PolicyReject = 0, // Strict UTF-8; no isolated surrogates allowed.
kWtf8PolicyAccept = 1, // Follow WTF-8 encoding of isolates surrogates.
kWtf8PolicyReplace = 2, // Replace isolated surrogates with U+FFFD.
kWtf8PolicyReplace = 2, // Replace isolated surrogates and decoding errors
// with U+FFFD.
kLastWtf8Policy = kWtf8PolicyReplace
};
......
......@@ -742,7 +742,6 @@ bool V8_EXPORT_PRIVATE IsJSCompatibleSignature(const FunctionSig* sig,
V(StringNewWtf8, 0xfb80, _, "string.new_wtf8") \
V(StringNewWtf16, 0xfb81, _, "string.new_wtf16") \
V(StringConst, 0xfb82, _, "string.const") \
V(StringMeasureUtf8, 0xfb83, _, "string.measure_utf8") \
V(StringMeasureWtf8, 0xfb84, _, "string.measure_wtf8") \
V(StringMeasureWtf16, 0xfb85, _, "string.measure_wtf16") \
V(StringEncodeWtf8, 0xfb86, _, "string.encode_wtf8") \
......
......@@ -186,34 +186,50 @@ function HasIsolatedSurrogate(str) {
.exportFunc()
.addBody([
kExprLocalGet, 0,
kGCPrefix, kExprStringMeasureUtf8
kGCPrefix, kExprStringMeasureWtf8, 0
]);
builder.addFunction("string_measure_wtf8", kSig_i_w)
.exportFunc()
.addBody([
kExprLocalGet, 0,
kGCPrefix, kExprStringMeasureWtf8
kGCPrefix, kExprStringMeasureWtf8, 1
]);
builder.addFunction("string_measure_wtf8_replace", kSig_i_w)
.exportFunc()
.addBody([
kExprLocalGet, 0,
kGCPrefix, kExprStringMeasureWtf8, 2
]);
builder.addFunction("string_measure_utf8_null", kSig_i_v)
.exportFunc()
.addBody([
kExprRefNull, kStringRefCode,
kGCPrefix, kExprStringMeasureUtf8
kGCPrefix, kExprStringMeasureWtf8, 0
]);
builder.addFunction("string_measure_wtf8_null", kSig_i_v)
.exportFunc()
.addBody([
kExprRefNull, kStringRefCode,
kGCPrefix, kExprStringMeasureWtf8
kGCPrefix, kExprStringMeasureWtf8, 1
]);
builder.addFunction("string_measure_wtf8_replace_null", kSig_i_v)
.exportFunc()
.addBody([
kExprRefNull, kStringRefCode,
kGCPrefix, kExprStringMeasureWtf8, 2
]);
let instance = builder.instantiate();
for (let str of interestingStrings) {
let wtf8 = encodeWtf8(str);
assertEquals(wtf8.length, instance.exports.string_measure_wtf8(str));
assertEquals(wtf8.length,
instance.exports.string_measure_wtf8_replace(str));
if (HasIsolatedSurrogate(str)) {
assertEquals(-1, instance.exports.string_measure_utf8(str));
} else {
......@@ -225,6 +241,8 @@ function HasIsolatedSurrogate(str) {
WebAssembly.RuntimeError, "dereferencing a null pointer");
assertThrows(() => instance.exports.string_measure_wtf8_null(),
WebAssembly.RuntimeError, "dereferencing a null pointer");
assertThrows(() => instance.exports.string_measure_wtf8_replace_null(),
WebAssembly.RuntimeError, "dereferencing a null pointer");
})();
(function TestStringMeasureWtf16() {
......
......@@ -91,16 +91,22 @@ let kSig_w_zi = makeSig([kWasmStringViewIter, kWasmI32],
kGCPrefix, kExprStringConst, 0
]);
builder.addFunction("string.measure_utf8", kSig_i_w)
builder.addFunction("string.measure_wtf8/utf-8", kSig_i_w)
.addBody([
kExprLocalGet, 0,
kGCPrefix, kExprStringMeasureUtf8
kGCPrefix, kExprStringMeasureWtf8, 0
]);
builder.addFunction("string.measure_wtf8", kSig_i_w)
builder.addFunction("string.measure_wtf8/wtf-8", kSig_i_w)
.addBody([
kExprLocalGet, 0,
kGCPrefix, kExprStringMeasureWtf8
kGCPrefix, kExprStringMeasureWtf8, 1
]);
builder.addFunction("string.measure_wtf8/replace", kSig_i_w)
.addBody([
kExprLocalGet, 0,
kGCPrefix, kExprStringMeasureWtf8, 2
]);
builder.addFunction("string.measure_wtf16", kSig_i_w)
......@@ -309,3 +315,14 @@ assertInvalid(
},
"Compiling function #0:\"string.encode_wtf8/bad-policy\" failed: " +
"expected wtf8 policy 0, 1, or 2, but found 3 @+37");
assertInvalid(
builder => {
builder.addFunction("string.measure_wtf8/bad-policy", kSig_i_w)
.addBody([
kExprLocalGet, 0,
kGCPrefix, kExprStringMeasureWtf8, 3
]);
},
"Compiling function #0:\"string.measure_wtf8/bad-policy\" failed: " +
"expected wtf8 policy 0, 1, or 2, but found 3 @+29");
......@@ -536,7 +536,6 @@ let kExprBrOnNonArray = 0x67;
let kExprStringNewWtf8 = 0x80;
let kExprStringNewWtf16 = 0x81;
let kExprStringConst = 0x82;
let kExprStringMeasureUtf8 = 0x83;
let kExprStringMeasureWtf8 = 0x84;
let kExprStringMeasureWtf16 = 0x85;
let kExprStringEncodeWtf8 = 0x86;
......
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