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

[stringref] Add stringref type, section, feature flag definitions

Bug: v8:12868
Change-Id: I69e149aa607ee77dd00267a0bbe4e5828dceb75e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3647350Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Andy Wingo <wingo@igalia.com>
Cr-Commit-Position: refs/heads/main@{#80526}
parent 8bba185f
...@@ -216,6 +216,18 @@ HeapType read_heap_type(Decoder* decoder, const byte* pc, ...@@ -216,6 +216,18 @@ HeapType read_heap_type(Decoder* decoder, const byte* pc,
case kAnyRefCode: case kAnyRefCode:
case kFuncRefCode: case kFuncRefCode:
return HeapType::from_code(code); return HeapType::from_code(code);
case kStringRefCode:
case kStringViewWtf8Code:
case kStringViewWtf16Code:
case kStringViewIterCode:
if (!VALIDATE(enabled.has_stringref())) {
DecodeError<validate>(decoder, pc,
"invalid heap type '%s', enable with "
"--experimental-wasm-stringref",
HeapType::from_code(code).name().c_str());
return HeapType(HeapType::kBottom);
}
return HeapType::from_code(code);
default: default:
DecodeError<validate>(decoder, pc, "Unknown heap type %" PRId64, DecodeError<validate>(decoder, pc, "Unknown heap type %" PRId64,
heap_index); heap_index);
...@@ -289,6 +301,19 @@ ValueType read_value_type(Decoder* decoder, const byte* pc, ...@@ -289,6 +301,19 @@ ValueType read_value_type(Decoder* decoder, const byte* pc,
: kNullable; : kNullable;
return ValueType::Ref(heap_type, nullability); return ValueType::Ref(heap_type, nullability);
} }
case kStringRefCode:
case kStringViewWtf8Code:
case kStringViewWtf16Code:
case kStringViewIterCode: {
if (!VALIDATE(enabled.has_stringref())) {
DecodeError<validate>(decoder, pc,
"invalid value type '%sref', enable with "
"--experimental-wasm-stringref",
HeapType::from_code(code).name().c_str());
return kWasmBottom;
}
return ValueType::Ref(HeapType::from_code(code), kNullable);
}
case kI32Code: case kI32Code:
return kWasmI32; return kWasmI32;
case kI64Code: case kI64Code:
......
...@@ -87,6 +87,8 @@ const char* SectionName(SectionCode code) { ...@@ -87,6 +87,8 @@ const char* SectionName(SectionCode code) {
return "Data"; return "Data";
case kTagSectionCode: case kTagSectionCode:
return "Tag"; return "Tag";
case kStringRefSectionCode:
return "StringRef";
case kDataCountSectionCode: case kDataCountSectionCode:
return "DataCount"; return "DataCount";
case kNameSectionCode: case kNameSectionCode:
...@@ -418,13 +420,25 @@ class ModuleDecoderImpl : public Decoder { ...@@ -418,13 +420,25 @@ class ModuleDecoderImpl : public Decoder {
return; return;
} }
break; break;
case kTagSectionCode: case kTagSectionCode: {
if (!CheckUnorderedSection(section_code)) return; if (!CheckUnorderedSection(section_code)) return;
if (!CheckSectionOrder(section_code, kMemorySectionCode, SectionCode next = enabled_features_.has_stringref()
kGlobalSectionCode)) { ? kStringRefSectionCode
: kGlobalSectionCode;
if (!CheckSectionOrder(section_code, kMemorySectionCode, next)) {
return; return;
} }
break; break;
}
case kStringRefSectionCode: {
if (!CheckUnorderedSection(section_code)) return;
SectionCode prev =
enabled_features_.has_eh() ? kTagSectionCode : kMemorySectionCode;
if (!CheckSectionOrder(section_code, prev, kGlobalSectionCode)) {
return;
}
break;
}
case kNameSectionCode: case kNameSectionCode:
// TODO(titzer): report out of place name section as a warning. // TODO(titzer): report out of place name section as a warning.
// Be lenient with placement of name section. All except first // Be lenient with placement of name section. All except first
...@@ -541,6 +555,16 @@ class ModuleDecoderImpl : public Decoder { ...@@ -541,6 +555,16 @@ class ModuleDecoderImpl : public Decoder {
SectionName(section_code)); SectionName(section_code));
} }
break; break;
case kStringRefSectionCode:
if (enabled_features_.has_stringref()) {
DecodeStringRefSection();
} else {
errorf(pc(),
"unexpected section <%s> (enable with "
"--experimental-wasm-stringref)",
SectionName(section_code));
}
break;
default: default:
errorf(pc(), "unexpected section <%s>", SectionName(section_code)); errorf(pc(), "unexpected section <%s>", SectionName(section_code));
return; return;
...@@ -1451,6 +1475,8 @@ class ModuleDecoderImpl : public Decoder { ...@@ -1451,6 +1475,8 @@ class ModuleDecoderImpl : public Decoder {
} }
} }
void DecodeStringRefSection() { UNIMPLEMENTED(); }
bool CheckMismatchedCounts() { bool CheckMismatchedCounts() {
// The declared vs. defined function count is normally checked when // The declared vs. defined function count is normally checked when
// decoding the code section, but we have to check it here too in case the // decoding the code section, but we have to check it here too in case the
......
...@@ -66,6 +66,10 @@ class HeapType { ...@@ -66,6 +66,10 @@ class HeapType {
kData, // shorthand: o kData, // shorthand: o
kArray, // shorthand: g kArray, // shorthand: g
kAny, // shorthand: a. Aka kExtern. kAny, // shorthand: a. Aka kExtern.
kString, // shorthand: s.
kStringViewWtf8, // shorthand: x.
kStringViewWtf16, // shorthand: y.
kStringViewIter, // shorthand: z.
// This value is used to represent failures in the parsing of heap types and // This value is used to represent failures in the parsing of heap types and
// does not correspond to a wasm heap type. It has to be last in this list. // does not correspond to a wasm heap type. It has to be last in this list.
kBottom kBottom
...@@ -86,6 +90,14 @@ class HeapType { ...@@ -86,6 +90,14 @@ class HeapType {
return HeapType(kData); return HeapType(kData);
case ValueTypeCode::kArrayRefCode: case ValueTypeCode::kArrayRefCode:
return HeapType(kArray); return HeapType(kArray);
case ValueTypeCode::kStringRefCode:
return HeapType(kString);
case ValueTypeCode::kStringViewWtf8Code:
return HeapType(kStringViewWtf8);
case ValueTypeCode::kStringViewWtf16Code:
return HeapType(kStringViewWtf16);
case ValueTypeCode::kStringViewIterCode:
return HeapType(kStringViewIter);
default: default:
return HeapType(kBottom); return HeapType(kBottom);
} }
...@@ -140,6 +152,14 @@ class HeapType { ...@@ -140,6 +152,14 @@ class HeapType {
return std::string("array"); return std::string("array");
case kAny: case kAny:
return std::string(FLAG_experimental_wasm_gc ? "any" : "extern"); return std::string(FLAG_experimental_wasm_gc ? "any" : "extern");
case kString:
return std::string("string");
case kStringViewWtf8:
return std::string("stringview_wtf8");
case kStringViewWtf16:
return std::string("stringview_wtf16");
case kStringViewIter:
return std::string("stringview_iter");
default: default:
return std::to_string(representation_); return std::to_string(representation_);
} }
...@@ -163,6 +183,14 @@ class HeapType { ...@@ -163,6 +183,14 @@ class HeapType {
return mask | kArrayRefCode; return mask | kArrayRefCode;
case kAny: case kAny:
return mask | kAnyRefCode; return mask | kAnyRefCode;
case kString:
return mask | kStringRefCode;
case kStringViewWtf8:
return mask | kStringViewWtf8Code;
case kStringViewWtf16:
return mask | kStringViewWtf16Code;
case kStringViewIter:
return mask | kStringViewIterCode;
default: default:
return static_cast<int32_t>(representation_); return static_cast<int32_t>(representation_);
} }
...@@ -464,6 +492,14 @@ class ValueType { ...@@ -464,6 +492,14 @@ class ValueType {
return kEqRefCode; return kEqRefCode;
case HeapType::kAny: case HeapType::kAny:
return kAnyRefCode; return kAnyRefCode;
case HeapType::kString:
return kStringRefCode;
case HeapType::kStringViewWtf8:
return kStringViewWtf8Code;
case HeapType::kStringViewWtf16:
return kStringViewWtf16Code;
case HeapType::kStringViewIter:
return kStringViewIterCode;
default: default:
return kOptRefCode; return kOptRefCode;
} }
...@@ -504,7 +540,11 @@ class ValueType { ...@@ -504,7 +540,11 @@ class ValueType {
case kOptRef: case kOptRef:
return heap_representation() != HeapType::kFunc && return heap_representation() != HeapType::kFunc &&
heap_representation() != HeapType::kEq && heap_representation() != HeapType::kEq &&
heap_representation() != HeapType::kAny; heap_representation() != HeapType::kAny &&
heap_representation() != HeapType::kString &&
heap_representation() != HeapType::kStringViewWtf8 &&
heap_representation() != HeapType::kStringViewWtf16 &&
heap_representation() != HeapType::kStringViewIter;
default: default:
return false; return false;
} }
...@@ -615,6 +655,14 @@ constexpr ValueType kWasmDataRef = ...@@ -615,6 +655,14 @@ constexpr ValueType kWasmDataRef =
ValueType::Ref(HeapType::kData, kNonNullable); ValueType::Ref(HeapType::kData, kNonNullable);
constexpr ValueType kWasmArrayRef = constexpr ValueType kWasmArrayRef =
ValueType::Ref(HeapType::kArray, kNonNullable); ValueType::Ref(HeapType::kArray, kNonNullable);
constexpr ValueType kWasmStringRef =
ValueType::Ref(HeapType::kString, kNullable);
constexpr ValueType kWasmStringViewWtf8 =
ValueType::Ref(HeapType::kStringViewWtf8, kNullable);
constexpr ValueType kWasmStringViewWtf16 =
ValueType::Ref(HeapType::kStringViewWtf16, kNullable);
constexpr ValueType kWasmStringViewIter =
ValueType::Ref(HeapType::kStringViewIter, kNullable);
// Constants used by the generic js-to-wasm wrapper. // Constants used by the generic js-to-wasm wrapper.
constexpr int kWasmValueKindBitsMask = (1u << ValueType::kKindBits) - 1; constexpr int kWasmValueKindBitsMask = (1u << ValueType::kKindBits) - 1;
......
...@@ -49,7 +49,11 @@ enum ValueTypeCode : uint8_t { ...@@ -49,7 +49,11 @@ enum ValueTypeCode : uint8_t {
kRttWithDepthCode = 0x69, kRttWithDepthCode = 0x69,
kRttCode = 0x68, kRttCode = 0x68,
kDataRefCode = 0x67, kDataRefCode = 0x67,
kArrayRefCode = 0x66 kArrayRefCode = 0x66,
kStringRefCode = 0x65,
kStringViewWtf8Code = 0x64,
kStringViewWtf16Code = 0x63,
kStringViewIterCode = 0x62,
}; };
// Binary encoding of type definitions. // Binary encoding of type definitions.
...@@ -103,6 +107,7 @@ enum SectionCode : int8_t { ...@@ -103,6 +107,7 @@ enum SectionCode : int8_t {
kDataSectionCode = 11, // Data segments kDataSectionCode = 11, // Data segments
kDataCountSectionCode = 12, // Number of data segments kDataCountSectionCode = 12, // Number of data segments
kTagSectionCode = 13, // Tag section kTagSectionCode = 13, // Tag section
kStringRefSectionCode = 14, // Stringref literal section
// The following sections are custom sections, and are identified using a // The following sections are custom sections, and are identified using a
// string rather than an integer. Their enumeration values are not guaranteed // string rather than an integer. Their enumeration values are not guaranteed
...@@ -116,7 +121,7 @@ enum SectionCode : int8_t { ...@@ -116,7 +121,7 @@ enum SectionCode : int8_t {
// Helper values // Helper values
kFirstSectionInModule = kTypeSectionCode, kFirstSectionInModule = kTypeSectionCode,
kLastKnownModuleSection = kTagSectionCode, kLastKnownModuleSection = kStringRefSectionCode,
kFirstUnorderedSection = kDataCountSectionCode, kFirstUnorderedSection = kDataCountSectionCode,
}; };
......
...@@ -70,7 +70,12 @@ ...@@ -70,7 +70,12 @@
/* Extended Constant Expressions Proposal. */ \ /* Extended Constant Expressions Proposal. */ \
/* https://github.com/WebAssembly/extended-const */ \ /* https://github.com/WebAssembly/extended-const */ \
/* V8 side owner: manoskouk */ \ /* V8 side owner: manoskouk */ \
V(extended_const, "extended constant expressions", false) V(extended_const, "extended constant expressions", false) \
\
/* Reference-Typed Strings Proposal. */ \
/* https://github.com/WebAssembly/stringref */ \
/* V8 side owner: jkummerow */ \
V(stringref, "reference-typed strings", false)
// ############################################################################# // #############################################################################
// Staged features (disabled by default, but enabled via --wasm-staging (also // Staged features (disabled by default, but enabled via --wasm-staging (also
......
...@@ -1529,6 +1529,10 @@ void WebAssemblyGlobal(const v8::FunctionCallbackInfo<v8::Value>& args) { ...@@ -1529,6 +1529,10 @@ void WebAssemblyGlobal(const v8::FunctionCallbackInfo<v8::Value>& args) {
case internal::wasm::HeapType::kI31: case internal::wasm::HeapType::kI31:
case internal::wasm::HeapType::kData: case internal::wasm::HeapType::kData:
case internal::wasm::HeapType::kArray: case internal::wasm::HeapType::kArray:
case internal::wasm::HeapType::kString:
case internal::wasm::HeapType::kStringViewWtf8:
case internal::wasm::HeapType::kStringViewWtf16:
case internal::wasm::HeapType::kStringViewIter:
default: default:
// TODO(7748): Implement these. // TODO(7748): Implement these.
UNIMPLEMENTED(); UNIMPLEMENTED();
...@@ -1719,6 +1723,10 @@ void EncodeExceptionValues(v8::Isolate* isolate, ...@@ -1719,6 +1723,10 @@ void EncodeExceptionValues(v8::Isolate* isolate,
case i::wasm::HeapType::kI31: case i::wasm::HeapType::kI31:
case i::wasm::HeapType::kData: case i::wasm::HeapType::kData:
case i::wasm::HeapType::kArray: case i::wasm::HeapType::kArray:
case i::wasm::HeapType::kString:
case i::wasm::HeapType::kStringViewWtf8:
case i::wasm::HeapType::kStringViewWtf16:
case i::wasm::HeapType::kStringViewIter:
values_out->set(index++, *Utils::OpenHandle(*value)); values_out->set(index++, *Utils::OpenHandle(*value));
break; break;
case internal::wasm::HeapType::kBottom: case internal::wasm::HeapType::kBottom:
...@@ -2282,6 +2290,10 @@ void WebAssemblyExceptionGetArg( ...@@ -2282,6 +2290,10 @@ void WebAssemblyExceptionGetArg(
case i::wasm::HeapType::kI31: case i::wasm::HeapType::kI31:
case i::wasm::HeapType::kData: case i::wasm::HeapType::kData:
case i::wasm::HeapType::kArray: case i::wasm::HeapType::kArray:
case i::wasm::HeapType::kString:
case i::wasm::HeapType::kStringViewWtf8:
case i::wasm::HeapType::kStringViewWtf16:
case i::wasm::HeapType::kStringViewIter:
decode_index++; decode_index++;
break; break;
case i::wasm::HeapType::kBottom: case i::wasm::HeapType::kBottom:
...@@ -2339,7 +2351,11 @@ void WebAssemblyExceptionGetArg( ...@@ -2339,7 +2351,11 @@ void WebAssemblyExceptionGetArg(
case i::wasm::HeapType::kEq: case i::wasm::HeapType::kEq:
case i::wasm::HeapType::kI31: case i::wasm::HeapType::kI31:
case i::wasm::HeapType::kArray: case i::wasm::HeapType::kArray:
case i::wasm::HeapType::kData: { case i::wasm::HeapType::kData:
case i::wasm::HeapType::kString:
case i::wasm::HeapType::kStringViewWtf8:
case i::wasm::HeapType::kStringViewWtf16:
case i::wasm::HeapType::kStringViewIter: {
auto obj = values->get(decode_index); auto obj = values->get(decode_index);
result = Utils::ToLocal(i::Handle<i::Object>(obj, i_isolate)); result = Utils::ToLocal(i::Handle<i::Object>(obj, i_isolate));
break; break;
...@@ -2436,6 +2452,10 @@ void WebAssemblyGlobalGetValueCommon( ...@@ -2436,6 +2452,10 @@ void WebAssemblyGlobalGetValueCommon(
case i::wasm::HeapType::kData: case i::wasm::HeapType::kData:
case i::wasm::HeapType::kArray: case i::wasm::HeapType::kArray:
case i::wasm::HeapType::kEq: case i::wasm::HeapType::kEq:
case i::wasm::HeapType::kString:
case i::wasm::HeapType::kStringViewWtf8:
case i::wasm::HeapType::kStringViewWtf16:
case i::wasm::HeapType::kStringViewIter:
default: default:
// TODO(7748): Implement these. // TODO(7748): Implement these.
UNIMPLEMENTED(); UNIMPLEMENTED();
...@@ -2529,6 +2549,10 @@ void WebAssemblyGlobalSetValue( ...@@ -2529,6 +2549,10 @@ void WebAssemblyGlobalSetValue(
case i::wasm::HeapType::kData: case i::wasm::HeapType::kData:
case i::wasm::HeapType::kArray: case i::wasm::HeapType::kArray:
case i::wasm::HeapType::kEq: case i::wasm::HeapType::kEq:
case i::wasm::HeapType::kString:
case i::wasm::HeapType::kStringViewWtf8:
case i::wasm::HeapType::kStringViewWtf16:
case i::wasm::HeapType::kStringViewIter:
default: default:
// TODO(7748): Implement these. // TODO(7748): Implement these.
UNIMPLEMENTED(); UNIMPLEMENTED();
......
...@@ -390,7 +390,11 @@ void WasmTableObject::Set(Isolate* isolate, Handle<WasmTableObject> table, ...@@ -390,7 +390,11 @@ void WasmTableObject::Set(Isolate* isolate, Handle<WasmTableObject> table,
case wasm::HeapType::kData: case wasm::HeapType::kData:
case wasm::HeapType::kArray: case wasm::HeapType::kArray:
case wasm::HeapType::kI31: case wasm::HeapType::kI31:
// TODO(7748): Implement once we have struct/arrays/i31ref tables. case wasm::HeapType::kString:
case wasm::HeapType::kStringViewWtf8:
case wasm::HeapType::kStringViewWtf16:
case wasm::HeapType::kStringViewIter:
// TODO(7748): Implement once we have struct/arrays/i31ref/string tables.
UNREACHABLE(); UNREACHABLE();
case wasm::HeapType::kBottom: case wasm::HeapType::kBottom:
UNREACHABLE(); UNREACHABLE();
......
...@@ -177,6 +177,13 @@ V8_NOINLINE V8_EXPORT_PRIVATE bool IsSubtypeOfImpl( ...@@ -177,6 +177,13 @@ V8_NOINLINE V8_EXPORT_PRIVATE bool IsSubtypeOfImpl(
case HeapType::kArray: case HeapType::kArray:
return super_heap == HeapType::kArray || super_heap == HeapType::kData || return super_heap == HeapType::kArray || super_heap == HeapType::kData ||
super_heap == HeapType::kEq || super_heap == HeapType::kAny; super_heap == HeapType::kEq || super_heap == HeapType::kAny;
case HeapType::kString:
case HeapType::kStringViewWtf8:
case HeapType::kStringViewWtf16:
case HeapType::kStringViewIter:
// stringref is a subtype of anyref (aka externref) under wasm-gc.
return sub_heap == super_heap ||
(FLAG_experimental_wasm_gc && super_heap == HeapType::kAny);
case HeapType::kBottom: case HeapType::kBottom:
UNREACHABLE(); UNREACHABLE();
default: default:
...@@ -199,6 +206,11 @@ V8_NOINLINE V8_EXPORT_PRIVATE bool IsSubtypeOfImpl( ...@@ -199,6 +206,11 @@ V8_NOINLINE V8_EXPORT_PRIVATE bool IsSubtypeOfImpl(
return false; return false;
case HeapType::kAny: case HeapType::kAny:
return true; return true;
case HeapType::kString:
case HeapType::kStringViewWtf8:
case HeapType::kStringViewWtf16:
case HeapType::kStringViewIter:
return false;
case HeapType::kBottom: case HeapType::kBottom:
UNREACHABLE(); UNREACHABLE();
default: default:
......
...@@ -13,15 +13,15 @@ function assertInvalid(fn, message) { ...@@ -13,15 +13,15 @@ function assertInvalid(fn, message) {
`WebAssembly.Module(): ${message}`); `WebAssembly.Module(): ${message}`);
} }
let kStringSectionCodeStr = '0x0' + kStringRefSectionCode.toString(16); let enableMessage = 'enable with --experimental-wasm-stringref'
assertInvalid(builder => builder.addLiteralStringRef("foo"), assertInvalid(builder => builder.addLiteralStringRef("foo"),
`unknown section code #${kStringSectionCodeStr} @+10`); `unexpected section <StringRef> (${enableMessage}) @+10`);
for (let [name, code] of [['string', kWasmStringRef], for (let [name, code] of [['string', kWasmStringRef],
['stringview_wtf8', kWasmStringViewWtf8], ['stringview_wtf8', kWasmStringViewWtf8],
['stringview_wtf16', kWasmStringViewWtf16], ['stringview_wtf16', kWasmStringViewWtf16],
['stringview_iter', kWasmStringViewIter]]) { ['stringview_iter', kWasmStringViewIter]]) {
let message = `invalid value type 0x${(code & kLeb128Mask).toString(16)}`; let message = `invalid value type '${name}ref', ${enableMessage}`;
let default_init = WasmInitExpr.RefNull(code); let default_init = WasmInitExpr.RefNull(code);
assertInvalid(b => b.addType(makeSig([code], [])), assertInvalid(b => b.addType(makeSig([code], [])),
......
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