[stringref] Add stringref type, section, feature flag definitions
Bug: v8:12868 Change-Id: I69e149aa607ee77dd00267a0bbe4e5828dceb75e Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3647350 Reviewed-by: Jakob Kummerow <jkummerow@chromium.org> Commit-Queue: Andy Wingo <wingo@igalia.com> Cr-Commit-Position: refs/heads/main@{#80526}
This commit is contained in:
parent
8bba185fe5
commit
59518b083a
@ -216,6 +216,18 @@ HeapType read_heap_type(Decoder* decoder, const byte* pc,
|
||||
case kAnyRefCode:
|
||||
case kFuncRefCode:
|
||||
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:
|
||||
DecodeError<validate>(decoder, pc, "Unknown heap type %" PRId64,
|
||||
heap_index);
|
||||
@ -289,6 +301,19 @@ ValueType read_value_type(Decoder* decoder, const byte* pc,
|
||||
: kNullable;
|
||||
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:
|
||||
return kWasmI32;
|
||||
case kI64Code:
|
||||
|
@ -87,6 +87,8 @@ const char* SectionName(SectionCode code) {
|
||||
return "Data";
|
||||
case kTagSectionCode:
|
||||
return "Tag";
|
||||
case kStringRefSectionCode:
|
||||
return "StringRef";
|
||||
case kDataCountSectionCode:
|
||||
return "DataCount";
|
||||
case kNameSectionCode:
|
||||
@ -418,13 +420,25 @@ class ModuleDecoderImpl : public Decoder {
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case kTagSectionCode:
|
||||
case kTagSectionCode: {
|
||||
if (!CheckUnorderedSection(section_code)) return;
|
||||
if (!CheckSectionOrder(section_code, kMemorySectionCode,
|
||||
kGlobalSectionCode)) {
|
||||
SectionCode next = enabled_features_.has_stringref()
|
||||
? kStringRefSectionCode
|
||||
: kGlobalSectionCode;
|
||||
if (!CheckSectionOrder(section_code, kMemorySectionCode, next)) {
|
||||
return;
|
||||
}
|
||||
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:
|
||||
// TODO(titzer): report out of place name section as a warning.
|
||||
// Be lenient with placement of name section. All except first
|
||||
@ -541,6 +555,16 @@ class ModuleDecoderImpl : public Decoder {
|
||||
SectionName(section_code));
|
||||
}
|
||||
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:
|
||||
errorf(pc(), "unexpected section <%s>", SectionName(section_code));
|
||||
return;
|
||||
@ -1451,6 +1475,8 @@ class ModuleDecoderImpl : public Decoder {
|
||||
}
|
||||
}
|
||||
|
||||
void DecodeStringRefSection() { UNIMPLEMENTED(); }
|
||||
|
||||
bool CheckMismatchedCounts() {
|
||||
// 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
|
||||
|
@ -66,6 +66,10 @@ class HeapType {
|
||||
kData, // shorthand: o
|
||||
kArray, // shorthand: g
|
||||
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
|
||||
// does not correspond to a wasm heap type. It has to be last in this list.
|
||||
kBottom
|
||||
@ -86,6 +90,14 @@ class HeapType {
|
||||
return HeapType(kData);
|
||||
case ValueTypeCode::kArrayRefCode:
|
||||
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:
|
||||
return HeapType(kBottom);
|
||||
}
|
||||
@ -140,6 +152,14 @@ class HeapType {
|
||||
return std::string("array");
|
||||
case kAny:
|
||||
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:
|
||||
return std::to_string(representation_);
|
||||
}
|
||||
@ -163,6 +183,14 @@ class HeapType {
|
||||
return mask | kArrayRefCode;
|
||||
case kAny:
|
||||
return mask | kAnyRefCode;
|
||||
case kString:
|
||||
return mask | kStringRefCode;
|
||||
case kStringViewWtf8:
|
||||
return mask | kStringViewWtf8Code;
|
||||
case kStringViewWtf16:
|
||||
return mask | kStringViewWtf16Code;
|
||||
case kStringViewIter:
|
||||
return mask | kStringViewIterCode;
|
||||
default:
|
||||
return static_cast<int32_t>(representation_);
|
||||
}
|
||||
@ -464,6 +492,14 @@ class ValueType {
|
||||
return kEqRefCode;
|
||||
case HeapType::kAny:
|
||||
return kAnyRefCode;
|
||||
case HeapType::kString:
|
||||
return kStringRefCode;
|
||||
case HeapType::kStringViewWtf8:
|
||||
return kStringViewWtf8Code;
|
||||
case HeapType::kStringViewWtf16:
|
||||
return kStringViewWtf16Code;
|
||||
case HeapType::kStringViewIter:
|
||||
return kStringViewIterCode;
|
||||
default:
|
||||
return kOptRefCode;
|
||||
}
|
||||
@ -504,7 +540,11 @@ class ValueType {
|
||||
case kOptRef:
|
||||
return heap_representation() != HeapType::kFunc &&
|
||||
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:
|
||||
return false;
|
||||
}
|
||||
@ -615,6 +655,14 @@ constexpr ValueType kWasmDataRef =
|
||||
ValueType::Ref(HeapType::kData, kNonNullable);
|
||||
constexpr ValueType kWasmArrayRef =
|
||||
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.
|
||||
constexpr int kWasmValueKindBitsMask = (1u << ValueType::kKindBits) - 1;
|
||||
|
@ -49,7 +49,11 @@ enum ValueTypeCode : uint8_t {
|
||||
kRttWithDepthCode = 0x69,
|
||||
kRttCode = 0x68,
|
||||
kDataRefCode = 0x67,
|
||||
kArrayRefCode = 0x66
|
||||
kArrayRefCode = 0x66,
|
||||
kStringRefCode = 0x65,
|
||||
kStringViewWtf8Code = 0x64,
|
||||
kStringViewWtf16Code = 0x63,
|
||||
kStringViewIterCode = 0x62,
|
||||
};
|
||||
|
||||
// Binary encoding of type definitions.
|
||||
@ -103,6 +107,7 @@ enum SectionCode : int8_t {
|
||||
kDataSectionCode = 11, // Data segments
|
||||
kDataCountSectionCode = 12, // Number of data segments
|
||||
kTagSectionCode = 13, // Tag section
|
||||
kStringRefSectionCode = 14, // Stringref literal section
|
||||
|
||||
// The following sections are custom sections, and are identified using a
|
||||
// string rather than an integer. Their enumeration values are not guaranteed
|
||||
@ -116,7 +121,7 @@ enum SectionCode : int8_t {
|
||||
|
||||
// Helper values
|
||||
kFirstSectionInModule = kTypeSectionCode,
|
||||
kLastKnownModuleSection = kTagSectionCode,
|
||||
kLastKnownModuleSection = kStringRefSectionCode,
|
||||
kFirstUnorderedSection = kDataCountSectionCode,
|
||||
};
|
||||
|
||||
|
@ -70,7 +70,12 @@
|
||||
/* Extended Constant Expressions Proposal. */ \
|
||||
/* https://github.com/WebAssembly/extended-const */ \
|
||||
/* 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
|
||||
|
@ -1529,6 +1529,10 @@ void WebAssemblyGlobal(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
case internal::wasm::HeapType::kI31:
|
||||
case internal::wasm::HeapType::kData:
|
||||
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:
|
||||
// TODO(7748): Implement these.
|
||||
UNIMPLEMENTED();
|
||||
@ -1719,6 +1723,10 @@ void EncodeExceptionValues(v8::Isolate* isolate,
|
||||
case i::wasm::HeapType::kI31:
|
||||
case i::wasm::HeapType::kData:
|
||||
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));
|
||||
break;
|
||||
case internal::wasm::HeapType::kBottom:
|
||||
@ -2282,6 +2290,10 @@ void WebAssemblyExceptionGetArg(
|
||||
case i::wasm::HeapType::kI31:
|
||||
case i::wasm::HeapType::kData:
|
||||
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++;
|
||||
break;
|
||||
case i::wasm::HeapType::kBottom:
|
||||
@ -2339,7 +2351,11 @@ void WebAssemblyExceptionGetArg(
|
||||
case i::wasm::HeapType::kEq:
|
||||
case i::wasm::HeapType::kI31:
|
||||
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);
|
||||
result = Utils::ToLocal(i::Handle<i::Object>(obj, i_isolate));
|
||||
break;
|
||||
@ -2436,6 +2452,10 @@ void WebAssemblyGlobalGetValueCommon(
|
||||
case i::wasm::HeapType::kData:
|
||||
case i::wasm::HeapType::kArray:
|
||||
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:
|
||||
// TODO(7748): Implement these.
|
||||
UNIMPLEMENTED();
|
||||
@ -2529,6 +2549,10 @@ void WebAssemblyGlobalSetValue(
|
||||
case i::wasm::HeapType::kData:
|
||||
case i::wasm::HeapType::kArray:
|
||||
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:
|
||||
// TODO(7748): Implement these.
|
||||
UNIMPLEMENTED();
|
||||
|
@ -390,7 +390,11 @@ void WasmTableObject::Set(Isolate* isolate, Handle<WasmTableObject> table,
|
||||
case wasm::HeapType::kData:
|
||||
case wasm::HeapType::kArray:
|
||||
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();
|
||||
case wasm::HeapType::kBottom:
|
||||
UNREACHABLE();
|
||||
|
@ -177,6 +177,13 @@ V8_NOINLINE V8_EXPORT_PRIVATE bool IsSubtypeOfImpl(
|
||||
case HeapType::kArray:
|
||||
return super_heap == HeapType::kArray || super_heap == HeapType::kData ||
|
||||
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:
|
||||
UNREACHABLE();
|
||||
default:
|
||||
@ -199,6 +206,11 @@ V8_NOINLINE V8_EXPORT_PRIVATE bool IsSubtypeOfImpl(
|
||||
return false;
|
||||
case HeapType::kAny:
|
||||
return true;
|
||||
case HeapType::kString:
|
||||
case HeapType::kStringViewWtf8:
|
||||
case HeapType::kStringViewWtf16:
|
||||
case HeapType::kStringViewIter:
|
||||
return false;
|
||||
case HeapType::kBottom:
|
||||
UNREACHABLE();
|
||||
default:
|
||||
|
@ -13,15 +13,15 @@ function assertInvalid(fn, message) {
|
||||
`WebAssembly.Module(): ${message}`);
|
||||
}
|
||||
|
||||
let kStringSectionCodeStr = '0x0' + kStringRefSectionCode.toString(16);
|
||||
let enableMessage = 'enable with --experimental-wasm-stringref'
|
||||
assertInvalid(builder => builder.addLiteralStringRef("foo"),
|
||||
`unknown section code #${kStringSectionCodeStr} @+10`);
|
||||
`unexpected section <StringRef> (${enableMessage}) @+10`);
|
||||
|
||||
for (let [name, code] of [['string', kWasmStringRef],
|
||||
['stringview_wtf8', kWasmStringViewWtf8],
|
||||
['stringview_wtf16', kWasmStringViewWtf16],
|
||||
['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);
|
||||
|
||||
assertInvalid(b => b.addType(makeSig([code], [])),
|
||||
|
Loading…
Reference in New Issue
Block a user