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

[stringref] Add support for parsing stringref instructions

Bug: v8:12868

This wires up the parser and the decoder interface for stringref.  All
of the interfaces throw UNIMPLEMENTED, however.

Change-Id: If8cb131032e425a5672f793c6e4c24ddd188aebc
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3645115Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Andy Wingo <wingo@igalia.com>
Cr-Commit-Position: refs/heads/main@{#80545}
parent b15aa56c
......@@ -5964,6 +5964,136 @@ class LiftoffCompiler {
br_depth);
}
void StringNewWtf8(FullDecoder* decoder,
const MemoryIndexImmediate<validate>& imm,
const Value& index, const Value& bytes, Value* result) {
UNIMPLEMENTED();
}
void StringNewWtf16(FullDecoder* decoder,
const MemoryIndexImmediate<validate>& imm,
const Value& index, const Value& codeunits,
Value* result) {
UNIMPLEMENTED();
}
void StringConst(FullDecoder* decoder,
const StringConstImmediate<validate>& imm, Value* result) {
UNIMPLEMENTED();
}
void StringMeasureUtf8(FullDecoder* decoder, const Value& str,
Value* result) {
UNIMPLEMENTED();
}
void StringMeasureWtf8(FullDecoder* decoder, const Value& str,
Value* result) {
UNIMPLEMENTED();
}
void StringMeasureWtf16(FullDecoder* decoder, const Value& str,
Value* result) {
UNIMPLEMENTED();
}
void StringEncodeWtf8(FullDecoder* decoder,
const EncodeWtf8Immediate<validate>& imm,
const Value& str, const Value& address) {
UNIMPLEMENTED();
}
void StringEncodeWtf16(FullDecoder* decoder,
const MemoryIndexImmediate<validate>& imm,
const Value& str, const Value& address) {
UNIMPLEMENTED();
}
void StringConcat(FullDecoder* decoder, const Value& head, const Value& tail,
Value* result) {
UNIMPLEMENTED();
}
void StringEq(FullDecoder* decoder, const Value& a, const Value& b,
Value* result) {
UNIMPLEMENTED();
}
void StringAsWtf8(FullDecoder* decoder, const Value& str, Value* result) {
UNIMPLEMENTED();
}
void StringViewWtf8Advance(FullDecoder* decoder, const Value& view,
const Value& pos, const Value& bytes,
Value* result) {
UNIMPLEMENTED();
}
void StringViewWtf8Encode(FullDecoder* decoder,
const EncodeWtf8Immediate<validate>& imm,
const Value& view, const Value& addr,
const Value& pos, const Value& bytes,
Value* next_pos, Value* bytes_written) {
UNIMPLEMENTED();
}
void StringViewWtf8Slice(FullDecoder* decoder, const Value& view,
const Value& start, const Value& end,
Value* result) {
UNIMPLEMENTED();
}
void StringAsWtf16(FullDecoder* decoder, const Value& str, Value* result) {
UNIMPLEMENTED();
}
void StringViewWtf16Length(FullDecoder* decoder, const Value& view,
Value* result) {
UNIMPLEMENTED();
}
void StringViewWtf16GetCodeUnit(FullDecoder* decoder, const Value& view,
const Value& pos, Value* result) {
UNIMPLEMENTED();
}
void StringViewWtf16Encode(FullDecoder* decoder,
const MemoryIndexImmediate<validate>& imm,
const Value& view, const Value& addr,
const Value& pos, const Value& codeunits) {
UNIMPLEMENTED();
}
void StringViewWtf16Slice(FullDecoder* decoder, const Value& view,
const Value& start, const Value& end,
Value* result) {
UNIMPLEMENTED();
}
void StringAsIter(FullDecoder* decoder, const Value& str, Value* result) {
UNIMPLEMENTED();
}
void StringViewIterCur(FullDecoder* decoder, const Value& view,
Value* result) {
UNIMPLEMENTED();
}
void StringViewIterAdvance(FullDecoder* decoder, const Value& view,
const Value& codepoints, Value* result) {
UNIMPLEMENTED();
}
void StringViewIterRewind(FullDecoder* decoder, const Value& view,
const Value& codepoints, Value* result) {
UNIMPLEMENTED();
}
void StringViewIterSlice(FullDecoder* decoder, const Value& view,
const Value& codepoints, Value* result) {
UNIMPLEMENTED();
}
void Forward(FullDecoder* decoder, const Value& from, Value* to) {
// Nothing to do here.
}
......
......@@ -136,6 +136,16 @@ class Decoder {
return read_leb<int64_t, validate, kNoTrace, 33>(pc, length, name);
}
template <ValidateFlag validate>
WasmOpcode read_two_byte_opcode(const byte* pc, uint32_t* length,
const char* name = "prefixed opcode") {
DCHECK(*pc == kGCPrefix);
uint32_t index = read_u8<validate>(pc + 1, name);
index |= kGCPrefix << 8;
*length = 2;
return static_cast<WasmOpcode>(index);
}
// Convenient overload for callers who don't care about length.
template <ValidateFlag validate>
WasmOpcode read_prefixed_opcode(const byte* pc) {
......@@ -149,6 +159,10 @@ class Decoder {
template <ValidateFlag validate>
WasmOpcode read_prefixed_opcode(const byte* pc, uint32_t* length,
const char* name = "prefixed opcode") {
if (*pc == kGCPrefix) {
return read_two_byte_opcode<validate>(pc, length, name);
}
uint32_t index;
// Prefixed opcodes all use LEB128 encoding.
......
This diff is collapsed.
......@@ -1311,6 +1311,136 @@ class WasmGraphBuildingInterface {
br_depth, false);
}
void StringNewWtf8(FullDecoder* decoder,
const MemoryIndexImmediate<validate>& imm,
const Value& index, const Value& bytes, Value* result) {
UNIMPLEMENTED();
}
void StringNewWtf16(FullDecoder* decoder,
const MemoryIndexImmediate<validate>& imm,
const Value& index, const Value& codeunits,
Value* result) {
UNIMPLEMENTED();
}
void StringConst(FullDecoder* decoder,
const StringConstImmediate<validate>& imm, Value* result) {
UNIMPLEMENTED();
}
void StringMeasureUtf8(FullDecoder* decoder, const Value& str,
Value* result) {
UNIMPLEMENTED();
}
void StringMeasureWtf8(FullDecoder* decoder, const Value& str,
Value* result) {
UNIMPLEMENTED();
}
void StringMeasureWtf16(FullDecoder* decoder, const Value& str,
Value* result) {
UNIMPLEMENTED();
}
void StringEncodeWtf8(FullDecoder* decoder,
const EncodeWtf8Immediate<validate>& imm,
const Value& str, const Value& address) {
UNIMPLEMENTED();
}
void StringEncodeWtf16(FullDecoder* decoder,
const MemoryIndexImmediate<validate>& imm,
const Value& str, const Value& address) {
UNIMPLEMENTED();
}
void StringConcat(FullDecoder* decoder, const Value& head, const Value& tail,
Value* result) {
UNIMPLEMENTED();
}
void StringEq(FullDecoder* decoder, const Value& a, const Value& b,
Value* result) {
UNIMPLEMENTED();
}
void StringAsWtf8(FullDecoder* decoder, const Value& str, Value* result) {
UNIMPLEMENTED();
}
void StringViewWtf8Advance(FullDecoder* decoder, const Value& view,
const Value& pos, const Value& bytes,
Value* result) {
UNIMPLEMENTED();
}
void StringViewWtf8Encode(FullDecoder* decoder,
const EncodeWtf8Immediate<validate>& imm,
const Value& view, const Value& addr,
const Value& pos, const Value& bytes,
Value* next_pos, Value* bytes_written) {
UNIMPLEMENTED();
}
void StringViewWtf8Slice(FullDecoder* decoder, const Value& view,
const Value& start, const Value& end,
Value* result) {
UNIMPLEMENTED();
}
void StringAsWtf16(FullDecoder* decoder, const Value& str, Value* result) {
UNIMPLEMENTED();
}
void StringViewWtf16Length(FullDecoder* decoder, const Value& view,
Value* result) {
UNIMPLEMENTED();
}
void StringViewWtf16GetCodeUnit(FullDecoder* decoder, const Value& view,
const Value& pos, Value* result) {
UNIMPLEMENTED();
}
void StringViewWtf16Encode(FullDecoder* decoder,
const MemoryIndexImmediate<validate>& imm,
const Value& view, const Value& addr,
const Value& pos, const Value& codeunits) {
UNIMPLEMENTED();
}
void StringViewWtf16Slice(FullDecoder* decoder, const Value& view,
const Value& start, const Value& end,
Value* result) {
UNIMPLEMENTED();
}
void StringAsIter(FullDecoder* decoder, const Value& str, Value* result) {
UNIMPLEMENTED();
}
void StringViewIterCur(FullDecoder* decoder, const Value& view,
Value* result) {
UNIMPLEMENTED();
}
void StringViewIterAdvance(FullDecoder* decoder, const Value& view,
const Value& codepoints, Value* result) {
UNIMPLEMENTED();
}
void StringViewIterRewind(FullDecoder* decoder, const Value& view,
const Value& codepoints, Value* result) {
UNIMPLEMENTED();
}
void StringViewIterSlice(FullDecoder* decoder, const Value& view,
const Value& codepoints, Value* result) {
UNIMPLEMENTED();
}
void Forward(FullDecoder* decoder, const Value& from, Value* to) {
to->node = from.node;
}
......
......@@ -66,7 +66,7 @@ class HeapType {
kData, // shorthand: o
kArray, // shorthand: g
kAny, // shorthand: a. Aka kExtern.
kString, // shorthand: s.
kString, // shorthand: w.
kStringViewWtf8, // shorthand: x.
kStringViewWtf16, // shorthand: y.
kStringViewIter, // shorthand: z.
......
......@@ -146,6 +146,15 @@ enum NameSectionKindCode : uint8_t {
kFieldCode = 10
};
// What to do when treating a stringref as WTF-8 and we see an isolated
// surrogate.
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.
kLastWtf8Policy = kWtf8PolicyReplace
};
constexpr size_t kWasmPageSize = 0x10000;
constexpr uint32_t kWasmPageSizeLog2 = 16;
static_assert(kWasmPageSize == size_t{1} << kWasmPageSizeLog2, "consistency");
......
......@@ -194,6 +194,12 @@ struct WasmTag {
const WasmTagSig* sig; // type signature of the tag.
};
// Static representation of a wasm literal stringref.
struct WasmStringRefLiteral {
explicit WasmStringRefLiteral(uint32_t offset) : offset(offset) {}
uint32_t offset; // Offset into string literals table.
};
// Static representation of a wasm data segment.
struct WasmDataSegment {
// Construct an active segment.
......@@ -510,6 +516,7 @@ struct V8_EXPORT_PRIVATE WasmModule {
std::vector<WasmImport> import_table;
std::vector<WasmExport> export_table;
std::vector<WasmTag> tags;
std::vector<WasmStringRefLiteral> stringref_literals;
std::vector<WasmElemSegment> elem_segments;
std::vector<WasmCompilationHint> compilation_hints;
BranchHintInfo branch_hints;
......
......@@ -444,6 +444,31 @@ constexpr const char* WasmOpcodes::OpcodeName(WasmOpcode opcode) {
CASE_OP(BrOnNonData, "br_on_non_data")
CASE_OP(BrOnNonI31, "br_on_non_i31")
CASE_OP(BrOnNonArray, "br_on_non_array")
CASE_OP(StringNewWtf8, "string.new_wtf8")
CASE_OP(StringNewWtf16, "string.new_wtf16")
CASE_OP(StringConst, "string.const")
CASE_OP(StringMeasureUtf8, "string.measure_utf8")
CASE_OP(StringMeasureWtf8, "string.measure_wtf8")
CASE_OP(StringMeasureWtf16, "string.measure_wtf16")
CASE_OP(StringEncodeWtf8, "string.encode_wtf8")
CASE_OP(StringEncodeWtf16, "string.encode_wtf16")
CASE_OP(StringConcat, "string.concat")
CASE_OP(StringEq, "string.eq")
CASE_OP(StringIsUSVSequence, "string.is_usv_sequence")
CASE_OP(StringAsWtf8, "string.as_wtf8")
CASE_OP(StringViewWtf8Advance, "stringview_wtf8.advance")
CASE_OP(StringViewWtf8Encode, "stringview_wtf8.encode")
CASE_OP(StringViewWtf8Slice, "stringview_wtf8.slice")
CASE_OP(StringAsWtf16, "string.as_wtf16")
CASE_OP(StringViewWtf16Length, "stringview_wtf16.length")
CASE_OP(StringViewWtf16GetCodeUnit, "stringview_wtf16.get_codeunit")
CASE_OP(StringViewWtf16Encode, "stringview_wtf16.encode")
CASE_OP(StringViewWtf16Slice, "stringview_wtf16.slice")
CASE_OP(StringAsIter, "string.as_iter")
CASE_OP(StringViewIterCur, "stringview_iter.cur")
CASE_OP(StringViewIterAdvance, "stringview_iter.advance")
CASE_OP(StringViewIterRewind, "stringview_iter.rewind")
CASE_OP(StringViewIterSlice, "stringview_iter.slice")
case kNumericPrefix:
case kSimdPrefix:
......
......@@ -724,7 +724,32 @@ bool V8_EXPORT_PRIVATE IsJSCompatibleSignature(const FunctionSig* sig,
V(BrOnNonFunc, 0xfb63, _) \
V(BrOnNonData, 0xfb64, _) \
V(BrOnNonI31, 0xfb65, _) \
V(BrOnNonArray, 0xfb67, _)
V(BrOnNonArray, 0xfb67, _) \
V(StringNewWtf8, 0xfb80, _) \
V(StringNewWtf16, 0xfb81, _) \
V(StringConst, 0xfb82, _) \
V(StringMeasureUtf8, 0xfb83, _) \
V(StringMeasureWtf8, 0xfb84, _) \
V(StringMeasureWtf16, 0xfb85, _) \
V(StringEncodeWtf8, 0xfb86, _) \
V(StringEncodeWtf16, 0xfb87, _) \
V(StringConcat, 0xfb88, _) \
V(StringEq, 0xfb89, _) \
V(StringIsUSVSequence, 0xfb8a, _) \
V(StringAsWtf8, 0xfb90, _) \
V(StringViewWtf8Advance, 0xfb91, _) \
V(StringViewWtf8Encode, 0xfb92, _) \
V(StringViewWtf8Slice, 0xfb93, _) \
V(StringAsWtf16, 0xfb98, _) \
V(StringViewWtf16Length, 0xfb99, _) \
V(StringViewWtf16GetCodeUnit, 0xfb9a, _) \
V(StringViewWtf16Encode, 0xfb9b, _) \
V(StringViewWtf16Slice, 0xfb9c, _) \
V(StringAsIter, 0xfba0, _) \
V(StringViewIterCur, 0xfba1, _) \
V(StringViewIterAdvance, 0xfba2, _) \
V(StringViewIterRewind, 0xfba3, _) \
V(StringViewIterSlice, 0xfba4, _)
// All opcodes.
#define FOREACH_OPCODE(V) \
......
......@@ -40,6 +40,7 @@ for (let [name, code] of [['string', kWasmStringRef],
`${message} @+12`);
assertInvalid(b => b.addTag(makeSig([code], [])),
`${message} @+13`);
assertInvalid(b => b.addFunction(undefined, kSig_v_v).addLocals(code, 1),
`Compiling function #0 failed: ${message} @+24`);
assertInvalid(
b => b.addFunction(undefined, kSig_v_v).addLocals(code, 1).addBody([]),
`Compiling function #0 failed: ${message} @+24`);
}
This diff is collapsed.
......@@ -532,31 +532,31 @@ let kExprBrOnNonFunc = 0x63;
let kExprBrOnNonData = 0x64;
let kExprBrOnNonI31 = 0x65;
let kExprBrOnNonArray = 0x67;
let kStringNewWtf8 = 0x80;
let kStringNewWtf16 = 0x81;
let kStringConst = 0x82;
let kStringMeasureUtf8 = 0x83;
let kStringMeasureWtf8 = 0x84;
let kStringMeasureWtf16 = 0x85;
let kStringEncodeWtf8 = 0x86;
let kStringEncodeWtf16 = 0x87;
let kStringConcat = 0x88;
let kStringEq = 0x89;
let kStringIsUsvSequence = 0x8a;
let kStringAsWtf8 = 0x90;
let kStringViewWtf8Advance = 0x91;
let kStringViewWtf8Encode = 0x92;
let kStringViewWtf8Slice = 0x93;
let kStringAsWtf16 = 0x98;
let kStringViewWtf16Length = 0x99;
let kStringViewWtf16GetCodeunit = 0x9a;
let kStringViewWtf16Encode = 0x9b;
let kStringViewWtf16Slice = 0x9c;
let kStringAsIter = 0xa0;
let kStringViewIterCur = 0xa1
let kStringViewIterAdvance = 0xa2;
let kStringViewIterRewind = 0xa3
let kStringViewIterSlice = 0xa4;
let kExprStringNewWtf8 = 0x80;
let kExprStringNewWtf16 = 0x81;
let kExprStringConst = 0x82;
let kExprStringMeasureUtf8 = 0x83;
let kExprStringMeasureWtf8 = 0x84;
let kExprStringMeasureWtf16 = 0x85;
let kExprStringEncodeWtf8 = 0x86;
let kExprStringEncodeWtf16 = 0x87;
let kExprStringConcat = 0x88;
let kExprStringEq = 0x89;
let kExprStringIsUsvSequence = 0x8a;
let kExprStringAsWtf8 = 0x90;
let kExprStringViewWtf8Advance = 0x91;
let kExprStringViewWtf8Encode = 0x92;
let kExprStringViewWtf8Slice = 0x93;
let kExprStringAsWtf16 = 0x98;
let kExprStringViewWtf16Length = 0x99;
let kExprStringViewWtf16GetCodeunit = 0x9a;
let kExprStringViewWtf16Encode = 0x9b;
let kExprStringViewWtf16Slice = 0x9c;
let kExprStringAsIter = 0xa0;
let kExprStringViewIterCur = 0xa1
let kExprStringViewIterAdvance = 0xa2;
let kExprStringViewIterRewind = 0xa3
let kExprStringViewIterSlice = 0xa4;
// Numeric opcodes.
let kExprI32SConvertSatF32 = 0x00;
......
......@@ -4831,10 +4831,21 @@ TEST_F(WasmOpcodeLengthTest, IllegalRefIndices) {
ExpectFailure(kExprBlock, kOptRefCode, U32V_4(0x01000000));
}
TEST_F(WasmOpcodeLengthTest, PrefixedOpcodesLEB) {
// kExprI32New with a 4-byte LEB-encoded opcode.
ExpectLength(5, 0xfb, 0xa0, 0x80, 0x80, 0x00);
TEST_F(WasmOpcodeLengthTest, GCOpcodes) {
// GC opcodes aren't parsed as LEBs.
// struct.new_with_rtt, with leb immediate operand.
ExpectLength(3, 0xfb, 0x01, 0x42);
ExpectLength(4, 0xfb, 0x01, 0x80, 0x00);
// string.new_wtf8 with $mem=0.
ExpectLength(3, 0xfb, 0x80, 0x00);
// string.as_wtf8.
ExpectLength(2, 0xfb, 0x90);
}
TEST_F(WasmOpcodeLengthTest, PrefixedOpcodesLEB) {
// kExprI8x16Splat with a 3-byte LEB-encoded opcode.
ExpectLength(4, 0xfd, 0x8f, 0x80, 0x00);
......
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