[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:
parent
904c8cedf8
commit
43cef7a627
@ -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 {
|
||||
|
@ -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)
|
||||
written = content.IsOneByte()
|
||||
? EncodeWtf8(memory_start, offset, mem_size,
|
||||
content.ToOneByteVector(), policy, &message)
|
||||
: EncodeWtf8(memory_start, offset, mem_size,
|
||||
content.ToUC16Vector(), policy);
|
||||
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) {
|
||||
|
@ -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,8 +6379,9 @@ 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),
|
||||
CallRuntimeStub(
|
||||
WasmCode::kWasmStringEncodeWtf8,
|
||||
MakeSig::Returns(kI32).Params(kRef, kI32, kSmiKind, kSmiKind),
|
||||
{
|
||||
string_var,
|
||||
offset_var,
|
||||
@ -6390,18 +6391,21 @@ class LiftoffCompiler {
|
||||
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,8 +6618,9 @@ 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),
|
||||
CallRuntimeStub(
|
||||
WasmCode::kWasmStringViewWtf16Encode,
|
||||
MakeSig::Returns(kI32).Params(kI32, kI32, kI32, kRef, kSmiKind),
|
||||
{
|
||||
offset_var,
|
||||
pos_var,
|
||||
@ -6621,6 +6631,9 @@ class LiftoffCompiler {
|
||||
decoder->position());
|
||||
__ DropValues(4);
|
||||
RegisterDebugSideTableEntry(decoder, DebugSideTableBuilder::kDidSpill);
|
||||
|
||||
LiftoffRegister result_reg(kReturnRegister0);
|
||||
__ PushRegister(kI32, result_reg);
|
||||
}
|
||||
|
||||
void StringViewWtf16Slice(FullDecoder* decoder, const Value& view,
|
||||
|
@ -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:
|
||||
|
@ -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) {
|
||||
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());
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 => {
|
||||
|
Loading…
Reference in New Issue
Block a user