[stringrefs] Encoding instructions return code units written

See https://github.com/WebAssembly/stringref/issues/24.

Bug: v8:12868
Change-Id: Ib3854625aa18ae0e59f8d62d04e7132ca7381f60
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3749179
Commit-Queue: Andy Wingo <wingo@igalia.com>
Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/main@{#81582}
This commit is contained in:
Andy Wingo 2022-07-07 09:49:49 +02:00 committed by V8 LUCI CQ
parent 904c8cedf8
commit 43cef7a627
7 changed files with 142 additions and 105 deletions

View File

@ -49,7 +49,7 @@ extern runtime WasmStringConst(Context, WasmInstanceObject, Smi): String;
extern runtime WasmStringMeasureUtf8(Context, String): Number;
extern runtime WasmStringMeasureWtf8(Context, String): Number;
extern runtime WasmStringEncodeWtf8(
Context, WasmInstanceObject, Smi, Smi, String, Number): JSAny;
Context, WasmInstanceObject, Smi, Smi, String, Number): Number;
extern runtime WasmStringEncodeWtf16(
Context, WasmInstanceObject, Smi, String, Number, Smi, Smi): JSAny;
}
@ -856,18 +856,20 @@ builtin WasmStringMeasureWtf8(string: String): int32 {
return Signed(ChangeNumberToUint32(result));
}
builtin WasmStringEncodeWtf8(
string: String, offset: uint32, memory: Smi, policy: Smi): JSAny {
string: String, offset: uint32, memory: Smi, policy: Smi): uint32 {
const instance = LoadInstanceFromFrame();
tail runtime::WasmStringEncodeWtf8(
const result = runtime::WasmStringEncodeWtf8(
LoadContextFromInstance(instance), instance, memory, policy, string,
WasmUint32ToNumber(offset));
return ChangeNumberToUint32(result);
}
builtin WasmStringEncodeWtf16(
string: String, offset: uint32, memory: Smi): JSAny {
string: String, offset: uint32, memory: Smi): uint32 {
const instance = LoadInstanceFromFrame();
tail runtime::WasmStringEncodeWtf16(
runtime::WasmStringEncodeWtf16(
LoadContextFromInstance(instance), instance, memory, string,
WasmUint32ToNumber(offset), SmiConstant(0), SmiFromInt32(string.length));
return Unsigned(string.length);
}
builtin WasmStringConcat(a: String, b: String): String {
const context = LoadContextFromFrame();
@ -900,16 +902,17 @@ transitioning builtin WasmStringViewWtf16GetCodeUnit(
}
builtin WasmStringViewWtf16Encode(
offset: uint32, start: uint32, length: uint32, string: String,
memory: Smi): JSAny {
memory: Smi): uint32 {
const instance = LoadInstanceFromFrame();
const clampedStart =
start < Unsigned(string.length) ? start : Unsigned(string.length);
const maxLength = Unsigned(string.length) - clampedStart;
const clampedLength = length < maxLength ? length : maxLength;
tail runtime::WasmStringEncodeWtf16(
runtime::WasmStringEncodeWtf16(
LoadContextFromInstance(instance), instance, memory, string,
WasmUint32ToNumber(offset), SmiFromUint32(clampedStart),
SmiFromUint32(clampedLength));
return clampedLength;
}
transitioning builtin WasmStringViewWtf16Slice(
string: String, start: uint32, end: uint32): String {

View File

@ -1020,14 +1020,15 @@ bool HasUnpairedSurrogate(base::Vector<const base::uc16> wtf16) {
}
// TODO(12868): Consider unifying with api.cc:String::WriteUtf8.
template <typename T>
MessageTemplate EncodeWtf8(char* memory_start, uint32_t offset, size_t mem_size,
base::Vector<const T> wtf16,
wasm::StringRefWtf8Policy policy) {
int EncodeWtf8(char* memory_start, uint32_t offset, size_t mem_size,
base::Vector<const T> wtf16, wasm::StringRefWtf8Policy policy,
MessageTemplate* message) {
// The first check is a quick estimate to decide whether the second check
// is worth the computation.
if (!base::IsInBounds<size_t>(offset, MaxEncodedSize(wtf16), mem_size) &&
!base::IsInBounds<size_t>(offset, MeasureWtf8(wtf16), mem_size)) {
return MessageTemplate::kWasmTrapMemOutOfBounds;
*message = MessageTemplate::kWasmTrapMemOutOfBounds;
return -1;
}
bool replace_invalid = false;
@ -1036,7 +1037,8 @@ MessageTemplate EncodeWtf8(char* memory_start, uint32_t offset, size_t mem_size,
break;
case wasm::kWtf8PolicyReject:
if (HasUnpairedSurrogate(wtf16)) {
return MessageTemplate::kWasmTrapStringIsolatedSurrogate;
*message = MessageTemplate::kWasmTrapStringIsolatedSurrogate;
return -1;
}
break;
case wasm::kWtf8PolicyReplace:
@ -1046,13 +1048,15 @@ MessageTemplate EncodeWtf8(char* memory_start, uint32_t offset, size_t mem_size,
UNREACHABLE();
}
char* dst = memory_start + offset;
char* dst_start = memory_start + offset;
char* dst = dst_start;
int previous = unibrow::Utf16::kNoPreviousCharacter;
for (auto code_unit : wtf16) {
dst += unibrow::Utf8::Encode(dst, code_unit, previous, replace_invalid);
previous = code_unit;
}
return MessageTemplate::kNone;
DCHECK_LE(dst - dst_start, static_cast<ptrdiff_t>(kMaxInt));
return static_cast<int>(dst - dst_start);
}
} // namespace
@ -1123,19 +1127,22 @@ RUNTIME_FUNCTION(Runtime_WasmStringEncodeWtf8) {
auto policy = static_cast<wasm::StringRefWtf8Policy>(policy_value);
string = String::Flatten(isolate, string);
MessageTemplate error;
MessageTemplate message;
int written;
{
DisallowGarbageCollection no_gc;
String::FlatContent content = string->GetFlatContent(no_gc);
error = content.IsOneByte() ? EncodeWtf8(memory_start, offset, mem_size,
content.ToOneByteVector(), policy)
: EncodeWtf8(memory_start, offset, mem_size,
content.ToUC16Vector(), policy);
written = content.IsOneByte()
? EncodeWtf8(memory_start, offset, mem_size,
content.ToOneByteVector(), policy, &message)
: EncodeWtf8(memory_start, offset, mem_size,
content.ToUC16Vector(), policy, &message);
}
if (error != MessageTemplate::kNone) {
return ThrowWasmError(isolate, error);
if (written < 0) {
DCHECK_NE(message, MessageTemplate::kNone);
return ThrowWasmError(isolate, message);
}
return Smi::zero(); // Unused.
return *isolate->factory()->NewNumberFromInt(written);
}
RUNTIME_FUNCTION(Runtime_WasmStringEncodeWtf16) {

View File

@ -6358,7 +6358,7 @@ class LiftoffCompiler {
void StringEncodeWtf8(FullDecoder* decoder,
const EncodeWtf8Immediate<validate>& imm,
const Value& str, const Value& offset) {
const Value& str, const Value& offset, Value* result) {
LiftoffRegList pinned;
LiftoffAssembler::VarState& offset_var =
@ -6379,29 +6379,33 @@ class LiftoffCompiler {
LoadSmi(policy_reg, static_cast<int32_t>(imm.policy.value));
LiftoffAssembler::VarState policy_var(kSmiKind, policy_reg, 0);
CallRuntimeStub(WasmCode::kWasmStringEncodeWtf8,
MakeSig::Params(kRef, kI32, kSmiKind, kSmiKind),
{
string_var,
offset_var,
memory_var,
policy_var,
},
decoder->position());
CallRuntimeStub(
WasmCode::kWasmStringEncodeWtf8,
MakeSig::Returns(kI32).Params(kRef, kI32, kSmiKind, kSmiKind),
{
string_var,
offset_var,
memory_var,
policy_var,
},
decoder->position());
__ DropValues(2);
RegisterDebugSideTableEntry(decoder, DebugSideTableBuilder::kDidSpill);
LiftoffRegister result_reg(kReturnRegister0);
__ PushRegister(kI32, result_reg);
}
void StringEncodeWtf8Array(FullDecoder* decoder,
const Wtf8PolicyImmediate<validate>& imm,
const Value& str, const Value& array,
const Value& start) {
const Value& start, Value* result) {
UNIMPLEMENTED();
}
void StringEncodeWtf16(FullDecoder* decoder,
const MemoryIndexImmediate<validate>& imm,
const Value& str, const Value& offset) {
const Value& str, const Value& offset, Value* result) {
LiftoffRegList pinned;
LiftoffAssembler::VarState& offset_var =
@ -6418,7 +6422,7 @@ class LiftoffCompiler {
LiftoffAssembler::VarState memory_var(kSmiKind, memory_reg, 0);
CallRuntimeStub(WasmCode::kWasmStringEncodeWtf16,
MakeSig::Params(kRef, kI32, kSmiKind),
MakeSig::Returns(kI32).Params(kRef, kI32, kSmiKind),
{
string_var,
offset_var,
@ -6427,10 +6431,14 @@ class LiftoffCompiler {
decoder->position());
__ DropValues(2);
RegisterDebugSideTableEntry(decoder, DebugSideTableBuilder::kDidSpill);
LiftoffRegister result_reg(kReturnRegister0);
__ PushRegister(kI32, result_reg);
}
void StringEncodeWtf16Array(FullDecoder* decoder, const Value& str,
const Value& array, const Value& start) {
const Value& array, const Value& start,
Value* result) {
UNIMPLEMENTED();
}
@ -6589,7 +6597,8 @@ class LiftoffCompiler {
void StringViewWtf16Encode(FullDecoder* decoder,
const MemoryIndexImmediate<validate>& imm,
const Value& view, const Value& offset,
const Value& pos, const Value& codeunits) {
const Value& pos, const Value& codeunits,
Value* result) {
LiftoffRegList pinned;
LiftoffAssembler::VarState& codeunits_var =
@ -6609,18 +6618,22 @@ class LiftoffCompiler {
LoadSmi(memory_reg, imm.index);
LiftoffAssembler::VarState memory_var(kSmiKind, memory_reg, 0);
CallRuntimeStub(WasmCode::kWasmStringViewWtf16Encode,
MakeSig::Params(kI32, kI32, kI32, kRef, kSmiKind),
{
offset_var,
pos_var,
codeunits_var,
view_var,
memory_var,
},
decoder->position());
CallRuntimeStub(
WasmCode::kWasmStringViewWtf16Encode,
MakeSig::Returns(kI32).Params(kI32, kI32, kI32, kRef, kSmiKind),
{
offset_var,
pos_var,
codeunits_var,
view_var,
memory_var,
},
decoder->position());
__ DropValues(4);
RegisterDebugSideTableEntry(decoder, DebugSideTableBuilder::kDidSpill);
LiftoffRegister result_reg(kReturnRegister0);
__ PushRegister(kI32, result_reg);
}
void StringViewWtf16Slice(FullDecoder* decoder, const Value& view,

View File

@ -1172,13 +1172,13 @@ struct ControlBase : public PcForErrors<validate> {
const Value& str, Value* result) \
F(StringMeasureWtf16, const Value& str, Value* result) \
F(StringEncodeWtf8, const EncodeWtf8Immediate<validate>& memory, \
const Value& str, const Value& address) \
const Value& str, const Value& address, Value* result) \
F(StringEncodeWtf8Array, const Wtf8PolicyImmediate<validate>& imm, \
const Value& str, const Value& array, const Value& start) \
const Value& str, const Value& array, const Value& start, Value* result) \
F(StringEncodeWtf16, const MemoryIndexImmediate<validate>& memory, \
const Value& str, const Value& address) \
const Value& str, const Value& address, Value* result) \
F(StringEncodeWtf16Array, const Value& str, const Value& array, \
const Value& start) \
const Value& start, Value* result) \
F(StringConcat, const Value& head, const Value& tail, Value* result) \
F(StringEq, const Value& a, const Value& b, Value* result) \
F(StringIsUSVSequence, const Value& str, Value* result) \
@ -1194,7 +1194,7 @@ struct ControlBase : public PcForErrors<validate> {
Value* result) \
F(StringViewWtf16Encode, const MemoryIndexImmediate<validate>& memory, \
const Value& view, const Value& addr, const Value& pos, \
const Value& codeunits) \
const Value& codeunits, Value* result) \
F(StringViewWtf16Slice, const Value& view, const Value& start, \
const Value& end, Value* result) \
F(StringAsIter, const Value& str, Value* result) \
@ -2403,19 +2403,18 @@ class WasmDecoder : public Decoder {
case kExprStringViewIterRewind:
case kExprStringViewIterSlice:
return { 2, 1 };
case kExprStringNewWtf8Array:
case kExprStringNewWtf16Array:
case kExprStringEncodeWtf8:
case kExprStringEncodeWtf8Array:
case kExprStringEncodeWtf16:
case kExprStringEncodeWtf16Array:
return { 3, 0 };
case kExprStringNewWtf8Array:
case kExprStringNewWtf16Array:
case kExprStringViewWtf8Advance:
case kExprStringViewWtf8Slice:
case kExprStringViewWtf16Slice:
return { 3, 1 };
case kExprStringViewWtf16Encode:
return { 4, 0 };
return { 4, 1 };
case kExprStringViewWtf8Encode:
return { 4, 2 };
default:
@ -5299,8 +5298,11 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
ValueType addr_type = this->module_->is_memory64 ? kWasmI64 : kWasmI32;
Value str = Peek(1, 0, kWasmStringRef);
Value addr = Peek(0, 1, addr_type);
CALL_INTERFACE_IF_OK_AND_REACHABLE(StringEncodeWtf8, imm, str, addr);
Value result = CreateValue(kWasmI32);
CALL_INTERFACE_IF_OK_AND_REACHABLE(StringEncodeWtf8, imm, str, addr,
&result);
Drop(2);
Push(result);
return opcode_length + imm.length;
}
case kExprStringEncodeWtf16: {
@ -5310,8 +5312,11 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
ValueType addr_type = this->module_->is_memory64 ? kWasmI64 : kWasmI32;
Value str = Peek(1, 0, kWasmStringRef);
Value addr = Peek(0, 1, addr_type);
CALL_INTERFACE_IF_OK_AND_REACHABLE(StringEncodeWtf16, imm, str, addr);
Value result = CreateValue(kWasmI32);
CALL_INTERFACE_IF_OK_AND_REACHABLE(StringEncodeWtf16, imm, str, addr,
&result);
Drop(2);
Push(result);
return opcode_length + imm.length;
}
case kExprStringConcat: {
@ -5433,9 +5438,11 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
Value addr = Peek(2, 1, addr_type);
Value pos = Peek(1, 2, kWasmI32);
Value codeunits = Peek(0, 3, kWasmI32);
Value result = CreateValue(kWasmI32);
CALL_INTERFACE_IF_OK_AND_REACHABLE(StringViewWtf16Encode, imm, view,
addr, pos, codeunits);
addr, pos, codeunits, &result);
Drop(4);
Push(result);
return opcode_length + imm.length;
}
case kExprStringViewWtf16Slice: {
@ -5536,9 +5543,11 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
Value str = Peek(2, 0, kWasmStringRef);
Value array = PeekPackedArray(1, 1, kWasmI8);
Value start = Peek(0, 2, kWasmI32);
Value result = CreateValue(kWasmI32);
CALL_INTERFACE_IF_OK_AND_REACHABLE(StringEncodeWtf8Array, imm, str,
array, start);
array, start, &result);
Drop(3);
Push(result);
return opcode_length + imm.length;
}
case kExprStringEncodeWtf16Array: {
@ -5547,9 +5556,11 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
Value str = Peek(2, 0, kWasmStringRef);
Value array = PeekPackedArray(1, 1, kWasmI16);
Value start = Peek(0, 2, kWasmI32);
Value result = CreateValue(kWasmI32);
CALL_INTERFACE_IF_OK_AND_REACHABLE(StringEncodeWtf16Array, str, array,
start);
start, &result);
Drop(3);
Push(result);
return opcode_length;
}
default:

View File

@ -1437,28 +1437,30 @@ class WasmGraphBuildingInterface {
void StringEncodeWtf8(FullDecoder* decoder,
const EncodeWtf8Immediate<validate>& imm,
const Value& str, const Value& offset) {
builder_->StringEncodeWtf8(imm.memory.index, imm.policy.value, str.node,
NullCheckFor(str.type), offset.node,
decoder->position());
const Value& str, const Value& offset, Value* result) {
result->node = builder_->StringEncodeWtf8(
imm.memory.index, imm.policy.value, str.node, NullCheckFor(str.type),
offset.node, decoder->position());
}
void StringEncodeWtf8Array(FullDecoder* decoder,
const Wtf8PolicyImmediate<validate>& imm,
const Value& str, const Value& array,
const Value& start) {
const Value& start, Value* result) {
UNIMPLEMENTED();
}
void StringEncodeWtf16(FullDecoder* decoder,
const MemoryIndexImmediate<validate>& imm,
const Value& str, const Value& offset) {
builder_->StringEncodeWtf16(imm.index, str.node, NullCheckFor(str.type),
offset.node, decoder->position());
const Value& str, const Value& offset, Value* result) {
result->node =
builder_->StringEncodeWtf16(imm.index, str.node, NullCheckFor(str.type),
offset.node, decoder->position());
}
void StringEncodeWtf16Array(FullDecoder* decoder, const Value& str,
const Value& array, const Value& start) {
const Value& array, const Value& start,
Value* result) {
UNIMPLEMENTED();
}
@ -1515,8 +1517,9 @@ class WasmGraphBuildingInterface {
void StringViewWtf16Encode(FullDecoder* decoder,
const MemoryIndexImmediate<validate>& imm,
const Value& view, const Value& offset,
const Value& pos, const Value& codeunits) {
builder_->StringViewWtf16Encode(
const Value& pos, const Value& codeunits,
Value* result) {
result->node = builder_->StringViewWtf16Encode(
imm.index, view.node, NullCheckFor(view.type), offset.node, pos.node,
codeunits.node, decoder->position());
}

View File

@ -11,11 +11,10 @@ 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_i_wiii = makeSig([kWasmStringRef, kWasmI32, kWasmI32, kWasmI32],
[kWasmI32]);
let kSig_w_wii = makeSig([kWasmStringRef, kWasmI32, kWasmI32],
[kWasmStringRef]);
let kSig_v_wi = makeSig([kWasmStringRef, kWasmI32], []);
let kSig_v_wiii = makeSig([kWasmStringRef, kWasmI32, kWasmI32, kWasmI32],
[]);
let kSig_w_ww = makeSig([kWasmStringRef, kWasmStringRef], [kWasmStringRef]);
let kSig_w_w = makeSig([kWasmStringRef], [kWasmStringRef]);
@ -325,7 +324,7 @@ function makeWtf16TestDataSegment() {
builder.addMemory(1, undefined, true /* exported */, false);
for (let [policy, name] of ["utf8", "wtf8", "replace"].entries()) {
builder.addFunction("encode_" + name, kSig_v_wi)
builder.addFunction("encode_" + name, kSig_i_wi)
.exportFunc()
.addBody([
kExprLocalGet, 0,
@ -334,7 +333,7 @@ function makeWtf16TestDataSegment() {
]);
}
builder.addFunction("encode_null", kSig_v_v)
builder.addFunction("encode_null", kSig_i_v)
.exportFunc()
.addBody([
kExprRefNull, kStringRefCode,
@ -368,7 +367,7 @@ function makeWtf16TestDataSegment() {
for (let str of interestingStrings) {
let wtf8 = encodeWtf8(str);
let offset = memory.length - wtf8.length;
instance.exports.encode_wtf8(str, offset);
assertEquals(wtf8.length, instance.exports.encode_wtf8(str, offset));
checkMemory(offset, wtf8);
clearMemory(offset, offset + wtf8.length);
}
@ -381,7 +380,7 @@ function makeWtf16TestDataSegment() {
"Failed to encode string as UTF-8: contains unpaired surrogate");
} else {
let wtf8 = encodeWtf8(str);
instance.exports.encode_utf8(str, offset);
assertEquals(wtf8.length, instance.exports.encode_utf8(str, offset));
checkMemory(offset, wtf8);
clearMemory(offset, offset + wtf8.length);
}
@ -389,10 +388,10 @@ function makeWtf16TestDataSegment() {
for (let str of interestingStrings) {
let offset = 42;
instance.exports.encode_replace(str, offset);
let replaced = ReplaceIsolatedSurrogates(str);
if (!HasIsolatedSurrogate(str)) assertEquals(str, replaced);
let wtf8 = encodeWtf8(replaced);
assertEquals(wtf8.length, instance.exports.encode_replace(str, offset));
checkMemory(offset, wtf8);
clearMemory(offset, offset + wtf8.length);
}
@ -420,7 +419,7 @@ function makeWtf16TestDataSegment() {
builder.addMemory(1, undefined, true /* exported */, false);
builder.addFunction("encode_wtf16", kSig_v_wi)
builder.addFunction("encode_wtf16", kSig_i_wi)
.exportFunc()
.addBody([
kExprLocalGet, 0,
@ -428,7 +427,7 @@ function makeWtf16TestDataSegment() {
kGCPrefix, kExprStringEncodeWtf16, 0,
]);
builder.addFunction("encode_null", kSig_v_v)
builder.addFunction("encode_null", kSig_i_v)
.exportFunc()
.addBody([
kExprRefNull, kStringRefCode,
@ -462,7 +461,7 @@ function makeWtf16TestDataSegment() {
for (let str of interestingStrings) {
let wtf16 = encodeWtf16LE(str);
let offset = memory.length - wtf16.length;
instance.exports.encode_wtf16(str, offset);
assertEquals(str.length, instance.exports.encode_wtf16(str, offset));
checkMemory(offset, wtf16);
clearMemory(offset, offset + wtf16.length);
}
@ -470,7 +469,7 @@ function makeWtf16TestDataSegment() {
for (let str of interestingStrings) {
let wtf16 = encodeWtf16LE(str);
let offset = 0;
instance.exports.encode_wtf16(str, offset);
assertEquals(str.length, instance.exports.encode_wtf16(str, offset));
checkMemory(offset, wtf16);
clearMemory(offset, offset + wtf16.length);
}
@ -649,7 +648,7 @@ function makeWtf16TestDataSegment() {
kGCPrefix, kExprStringViewWtf16GetCodeunit
]);
builder.addFunction("encode", kSig_v_wiii)
builder.addFunction("encode", kSig_i_wiii)
.exportFunc()
.addBody([
kExprLocalGet, 0,
@ -660,7 +659,7 @@ function makeWtf16TestDataSegment() {
kGCPrefix, kExprStringViewWtf16Encode, 0
]);
builder.addFunction("encode_null", kSig_v_v)
builder.addFunction("encode_null", kSig_i_v)
.exportFunc()
.addBody([
kExprRefNull, kStringViewWtf16Code,
@ -724,7 +723,8 @@ function makeWtf16TestDataSegment() {
}
for (let offset of [0, 42, memory.length - bytes.length]) {
instance.exports.encode(str, offset, start, length);
assertEquals(slice.length,
instance.exports.encode(str, offset, start, length));
checkMemory(offset, bytes);
clearMemory(offset, offset + bytes.length);
}

View File

@ -44,7 +44,7 @@ for (let [name, code] of [['string', kStringRefCode],
let kSig_w_ii = makeSig([kWasmI32, kWasmI32], [kWasmStringRef]);
let kSig_w_v = makeSig([], [kWasmStringRef]);
let kSig_i_w = makeSig([kWasmStringRef], [kWasmI32]);
let kSig_v_wi = makeSig([kWasmStringRef, kWasmI32], []);
let kSig_i_wi = makeSig([kWasmStringRef, kWasmI32], [kWasmI32]);
let kSig_w_ww = makeSig([kWasmStringRef, kWasmStringRef], [kWasmStringRef]);
let kSig_i_ww = makeSig([kWasmStringRef, kWasmStringRef], [kWasmI32]);
let kSig_x_w = makeSig([kWasmStringRef], [kWasmStringViewWtf8]);
@ -58,8 +58,8 @@ let kSig_w_xii = makeSig([kWasmStringViewWtf8, kWasmI32, kWasmI32],
let kSig_y_w = makeSig([kWasmStringRef], [kWasmStringViewWtf16]);
let kSig_i_y = makeSig([kWasmStringViewWtf16], [kWasmI32]);
let kSig_i_yi = makeSig([kWasmStringViewWtf16, kWasmI32], [kWasmI32]);
let kSig_v_yiii = makeSig([kWasmStringViewWtf16, kWasmI32, kWasmI32,
kWasmI32], []);
let kSig_i_yiii = makeSig([kWasmStringViewWtf16, kWasmI32, kWasmI32,
kWasmI32], [kWasmI32]);
let kSig_w_yii = makeSig([kWasmStringViewWtf16, kWasmI32, kWasmI32],
[kWasmStringRef]);
let kSig_z_w = makeSig([kWasmStringRef], [kWasmStringViewIter]);
@ -127,23 +127,23 @@ let kSig_w_zi = makeSig([kWasmStringViewIter, kWasmI32],
kGCPrefix, kExprStringMeasureWtf16
]);
builder.addFunction("string.encode_wtf8/utf-8", kSig_v_wi)
builder.addFunction("string.encode_wtf8/utf-8", kSig_i_wi)
.addBody([
kExprLocalGet, 0, kExprLocalGet, 1,
kGCPrefix, kExprStringEncodeWtf8, 0, kWtf8PolicyAccept
]);
builder.addFunction("string.encode_wtf8/wtf-8", kSig_v_wi)
builder.addFunction("string.encode_wtf8/wtf-8", kSig_i_wi)
.addBody([
kExprLocalGet, 0, kExprLocalGet, 1,
kGCPrefix, kExprStringEncodeWtf8, 0, kWtf8PolicyReject
]);
builder.addFunction("string.encode_wtf8/replace", kSig_v_wi)
builder.addFunction("string.encode_wtf8/replace", kSig_i_wi)
.addBody([
kExprLocalGet, 0, kExprLocalGet, 1,
kGCPrefix, kExprStringEncodeWtf8, 0, kWtf8PolicyReplace
]);
builder.addFunction("string.encode_wtf16", kSig_v_wi)
builder.addFunction("string.encode_wtf16", kSig_i_wi)
.addBody([
kExprLocalGet, 0, kExprLocalGet, 1,
kGCPrefix, kExprStringEncodeWtf16, 0
@ -215,7 +215,7 @@ let kSig_w_zi = makeSig([kWasmStringViewIter, kWasmI32],
kGCPrefix, kExprStringViewWtf16GetCodeunit
]);
builder.addFunction("stringview_wtf16.encode", kSig_v_yiii)
builder.addFunction("stringview_wtf16.encode", kSig_i_yiii)
.addBody([
kExprLocalGet, 0, kExprLocalGet, 1, kExprLocalGet, 2, kExprLocalGet, 3,
kGCPrefix, kExprStringViewWtf16Encode, 0
@ -292,7 +292,7 @@ let kSig_w_zi = makeSig([kWasmStringViewIter, kWasmI32],
kGCPrefix, kExprStringNewWtf16Array
]);
builder.addFunction("string.encode_wtf8_array/accept", kSig_v_v)
builder.addFunction("string.encode_wtf8_array/accept", kSig_i_v)
.addBody([
kExprRefNull, kStringRefCode,
kExprRefNull, i8_array,
@ -300,7 +300,7 @@ let kSig_w_zi = makeSig([kWasmStringViewIter, kWasmI32],
kGCPrefix, kExprStringEncodeWtf8Array, kWtf8PolicyAccept
]);
builder.addFunction("string.encode_wtf8_array/reject", kSig_v_v)
builder.addFunction("string.encode_wtf8_array/reject", kSig_i_v)
.addBody([
kExprRefNull, kStringRefCode,
kExprRefNull, i8_array,
@ -308,7 +308,7 @@ let kSig_w_zi = makeSig([kWasmStringViewIter, kWasmI32],
kGCPrefix, kExprStringEncodeWtf8Array, kWtf8PolicyReject
]);
builder.addFunction("string.encode_wtf8_array/replace", kSig_v_v)
builder.addFunction("string.encode_wtf8_array/replace", kSig_i_v)
.addBody([
kExprRefNull, kStringRefCode,
kExprRefNull, i8_array,
@ -316,7 +316,7 @@ let kSig_w_zi = makeSig([kWasmStringViewIter, kWasmI32],
kGCPrefix, kExprStringEncodeWtf8Array, kWtf8PolicyReplace
]);
builder.addFunction("string.encode_wtf16_array", kSig_v_v)
builder.addFunction("string.encode_wtf16_array", kSig_i_v)
.addBody([
kExprRefNull, kStringRefCode,
kExprRefNull, i16_array,
@ -362,38 +362,38 @@ assertInvalid(
assertInvalid(
builder => {
builder.addFunction("string.encode_wtf8/no-mem", kSig_v_wi)
builder.addFunction("string.encode_wtf8/no-mem", kSig_i_wi)
.addBody([
kExprLocalGet, 0, kExprLocalGet, 1,
kGCPrefix, kExprStringEncodeWtf8, 0, kWtf8PolicyAccept
]);
},
"Compiling function #0:\"string.encode_wtf8/no-mem\" failed: " +
"memory instruction with no memory @+31");
"memory instruction with no memory @+32");
assertInvalid(
builder => {
builder.addMemory(0, undefined, false, false);
builder.addFunction("string.encode_wtf8/bad-mem", kSig_v_wi)
builder.addFunction("string.encode_wtf8/bad-mem", kSig_i_wi)
.addBody([
kExprLocalGet, 0, kExprLocalGet, 1,
kGCPrefix, kExprStringEncodeWtf8, 1, kWtf8PolicyAccept
]);
},
"Compiling function #0:\"string.encode_wtf8/bad-mem\" failed: " +
"expected memory index 0, found 1 @+36");
"expected memory index 0, found 1 @+37");
assertInvalid(
builder => {
builder.addMemory(0, undefined, false, false);
builder.addFunction("string.encode_wtf8/bad-policy", kSig_v_wi)
builder.addFunction("string.encode_wtf8/bad-policy", kSig_i_wi)
.addBody([
kExprLocalGet, 0, kExprLocalGet, 1,
kGCPrefix, kExprStringEncodeWtf8, 0, 3
]);
},
"Compiling function #0:\"string.encode_wtf8/bad-policy\" failed: " +
"expected wtf8 policy 0, 1, or 2, but found 3 @+37");
"expected wtf8 policy 0, 1, or 2, but found 3 @+38");
assertInvalid(
builder => {