diff --git a/js/src/wasm/WasmModuleTypes.h b/js/src/wasm/WasmModuleTypes.h index a9259c5c5dd1..e1839122ac2e 100644 --- a/js/src/wasm/WasmModuleTypes.h +++ b/js/src/wasm/WasmModuleTypes.h @@ -614,9 +614,6 @@ struct TableDesc { uint32_t initialLength; Maybe maximumLength; - WASM_CHECK_CACHEABLE_POD(elemType, isImportedOrExported, isAsmJS, - globalDataOffset, initialLength, maximumLength); - TableDesc() = default; TableDesc(RefType elemType, uint32_t initialLength, Maybe maximumLength, bool isAsmJS, @@ -629,8 +626,6 @@ struct TableDesc { maximumLength(maximumLength) {} }; -WASM_DECLARE_CACHEABLE_POD(TableDesc); - using TableDescVector = Vector; } // namespace wasm diff --git a/js/src/wasm/WasmSerialize.cpp b/js/src/wasm/WasmSerialize.cpp index c31e9c8ed23e..20b3a2a43a45 100644 --- a/js/src/wasm/WasmSerialize.cpp +++ b/js/src/wasm/WasmSerialize.cpp @@ -412,16 +412,56 @@ CoderResult CodeShareableBytes(Coder& coder, return CodePodVector(coder, &item->bytes); } +// WasmValType.h + +template +CoderResult CodeValType(Coder& coder, CoderArg item) { + if constexpr (mode == MODE_DECODE) { + return coder.readBytes((void*)item, sizeof(ValType)); + } else { + return coder.writeBytes((const void*)item, sizeof(ValType)); + } +} + +CoderResult CodeFieldType(Coder& coder, FieldType* item) { + return coder.readBytes((void*)item, sizeof(FieldType)); +} + +template +CoderResult CodeFieldType(Coder& coder, const FieldType* item) { + STATIC_ASSERT_ENCODING_OR_SIZING; + return coder.writeBytes((const void*)item, sizeof(FieldType)); +} + +CoderResult CodeRefType(Coder& coder, RefType* item) { + return coder.readBytes((void*)item, sizeof(RefType)); +} + +template +CoderResult CodeRefType(Coder& coder, const RefType* item) { + STATIC_ASSERT_ENCODING_OR_SIZING; + return coder.writeBytes((const void*)item, sizeof(RefType)); +} + +// WasmValue.h + +template +CoderResult CodeLitVal(Coder& coder, CoderArg item) { + MOZ_TRY(CodeValType(coder, &item->type_)); + MOZ_TRY(CodePod(coder, &item->cell_)); + return Ok(); +} + // WasmInitExpr.h template CoderResult CodeInitExpr(Coder& coder, CoderArg item) { WASM_VERIFY_SERIALIZATION_FOR_SIZE(wasm::InitExpr, 80); MOZ_TRY(CodePod(coder, &item->kind_)); - MOZ_TRY(CodePod(coder, &item->type_)); + MOZ_TRY(CodeValType(coder, &item->type_)); switch (item->kind_) { case InitExprKind::Literal: - MOZ_TRY(CodePod(coder, &item->literal_)); + MOZ_TRY(CodeLitVal(coder, &item->literal_)); break; case InitExprKind::Variable: MOZ_TRY(CodePodVector(coder, &item->bytecode_)); @@ -437,21 +477,40 @@ CoderResult CodeInitExpr(Coder& coder, CoderArg item) { template CoderResult CodeFuncType(Coder& coder, CoderArg item) { WASM_VERIFY_SERIALIZATION_FOR_SIZE(wasm::FuncType, 208); - MOZ_TRY(CodePodVector(coder, &item->results_)); - MOZ_TRY(CodePodVector(coder, &item->args_)); + MOZ_TRY((CodeVector>(coder, &item->args_))); + MOZ_TRY( + (CodeVector>(coder, &item->results_))); MOZ_TRY(CodePod(coder, &item->immediateTypeId_)); return Ok(); } +template +CoderResult CodeStructField(Coder& coder, + CoderArg item) { + MOZ_TRY(CodeFieldType(coder, &item->type)); + MOZ_TRY(CodePod(coder, &item->offset)); + MOZ_TRY(CodePod(coder, &item->isMutable)); + return Ok(); +} + template CoderResult CodeStructType(Coder& coder, CoderArg item) { WASM_VERIFY_SERIALIZATION_FOR_SIZE(wasm::StructType, 48); - MOZ_TRY(CodePodVector(coder, &item->fields_)); + MOZ_TRY((CodeVector>( + coder, &item->fields_))); MOZ_TRY(CodePod(coder, &item->size_)); return Ok(); } +template +CoderResult CodeArrayType(Coder& coder, CoderArg item) { + WASM_VERIFY_SERIALIZATION_FOR_SIZE(wasm::ArrayType, 48); + MOZ_TRY(CodeFieldType(coder, &item->elementType_)); + MOZ_TRY(CodePod(coder, &item->isMutable_)); + return Ok(); +} + template CoderResult CodeTypeDef(Coder& coder, CoderArg item) { WASM_VERIFY_SERIALIZATION_FOR_SIZE(wasm::TypeDef, 216); @@ -477,7 +536,10 @@ CoderResult CodeTypeDef(Coder& coder, CoderArg item) { break; } case TypeDefKind::Array: { - MOZ_TRY(CodePod(coder, &item->arrayType_)); + if constexpr (mode == MODE_DECODE) { + new (&item->arrayType_) ArrayType(); + } + MOZ_TRY(CodeArrayType(coder, &item->arrayType_)); break; } case TypeDefKind::None: { @@ -525,7 +587,8 @@ CoderResult CodeGlobalDesc(Coder& coder, template CoderResult CodeTagType(Coder& coder, CoderArg item) { WASM_VERIFY_SERIALIZATION_FOR_SIZE(wasm::TagType, 168); - MOZ_TRY(CodePodVector(coder, &item->argTypes_)); + MOZ_TRY( + (CodeVector>(coder, &item->argTypes_))); MOZ_TRY(CodePodVector(coder, &item->argOffsets_)); MOZ_TRY(CodePod(coder, &item->size_)); return Ok(); @@ -548,7 +611,7 @@ CoderResult CodeElemSegment(Coder& coder, WASM_VERIFY_SERIALIZATION_FOR_SIZE(wasm::ElemSegment, 184); MOZ_TRY(CodePod(coder, &item->kind)); MOZ_TRY(CodePod(coder, &item->tableIndex)); - MOZ_TRY(CodePod(coder, &item->elemType)); + MOZ_TRY(CodeRefType(coder, &item->elemType)); MOZ_TRY((CodeMaybe>( coder, &item->offsetIfActive))); MOZ_TRY(CodePodVector(coder, &item->elemFuncIndices)); @@ -575,6 +638,18 @@ CoderResult CodeCustomSection(Coder& coder, return Ok(); } +template +CoderResult CodeTableDesc(Coder& coder, CoderArg item) { + WASM_VERIFY_SERIALIZATION_FOR_SIZE(wasm::TableDesc, 48); + MOZ_TRY(CodeRefType(coder, &item->elemType)); + MOZ_TRY(CodePod(coder, &item->isImportedOrExported)); + MOZ_TRY(CodePod(coder, &item->isAsmJS)); + MOZ_TRY(CodePod(coder, &item->globalDataOffset)); + MOZ_TRY(CodePod(coder, &item->initialLength)); + MOZ_TRY(CodePod(coder, &item->maximumLength)); + return Ok(); +} + // WasmCodegenTypes.h template @@ -805,7 +880,8 @@ CoderResult CodeMetadata(Coder& coder, MOZ_TRY((CodePod(coder, &item->typeIdsOffsetStart))); MOZ_TRY((CodeVector>( coder, &item->globals))); - MOZ_TRY(CodePodVector(coder, &item->tables)); + MOZ_TRY(( + CodeVector>(coder, &item->tables))); MOZ_TRY((CodeVector>(coder, &item->tags))); MOZ_TRY(CodePod(coder, &item->moduleName)); MOZ_TRY(CodePodVector(coder, &item->funcNames)); diff --git a/js/src/wasm/WasmTypeDef.h b/js/src/wasm/WasmTypeDef.h index 6ba0e0e84bf0..92aa6e6ec1b0 100644 --- a/js/src/wasm/WasmTypeDef.h +++ b/js/src/wasm/WasmTypeDef.h @@ -217,12 +217,8 @@ struct StructField { FieldType type; uint32_t offset; bool isMutable; - - WASM_CHECK_CACHEABLE_POD(type, offset, isMutable); }; -WASM_DECLARE_CACHEABLE_POD(StructField); - using StructFieldVector = Vector; class StructType { @@ -300,9 +296,8 @@ class ArrayType { FieldType elementType_; // field type bool isMutable_; // mutability - WASM_CHECK_CACHEABLE_POD(elementType_, isMutable_); - public: + ArrayType() : isMutable_(false) {} ArrayType(FieldType elementType, bool isMutable) : elementType_(elementType), isMutable_(isMutable) {} diff --git a/js/src/wasm/WasmValType.h b/js/src/wasm/WasmValType.h index 458916e6a1a0..62c2c8ec685c 100644 --- a/js/src/wasm/WasmValType.h +++ b/js/src/wasm/WasmValType.h @@ -57,8 +57,6 @@ union PackedTypeCode { PackedRepr pointerTag_ : PointerTagBits; }; - WASM_CHECK_CACHEABLE_POD(bits_); - public: static constexpr uint32_t NoTypeCode = (1 << TypeCodeBits) - 1; static constexpr uint32_t NoTypeIndex = (1 << TypeIndexBits) - 1; @@ -162,11 +160,7 @@ union PackedTypeCode { } }; -WASM_DECLARE_CACHEABLE_POD(PackedTypeCode); - static_assert(sizeof(PackedTypeCode) == sizeof(uint32_t), "packed"); -static_assert(std::is_pod_v, - "must be POD to be simply serialized/deserialized"); // An enum that describes the representation classes for tables; The table // element type is mapped into this by Table::repr(). @@ -188,8 +182,6 @@ class RefType { private: PackedTypeCode ptc_; - WASM_CHECK_CACHEABLE_POD(ptc_); - #ifdef DEBUG bool isValid() const { switch (ptc_.typeCode()) { @@ -265,8 +257,6 @@ class RefType { bool operator!=(const RefType& that) const { return ptc_ != that.ptc_; } }; -WASM_DECLARE_CACHEABLE_POD(RefType); - class FieldTypeTraits { public: enum Kind { @@ -415,8 +405,6 @@ class PackedType : public T { protected: PackedTypeCode tc_; - WASM_CHECK_CACHEABLE_POD(tc_); - explicit PackedType(TypeCode c) : tc_(PackedTypeCode::pack(c)) { MOZ_ASSERT(c != AbstractReferenceTypeIndexCode); MOZ_ASSERT(isValid()); @@ -692,9 +680,6 @@ class PackedType : public T { using ValType = PackedType; using FieldType = PackedType; -WASM_DECLARE_CACHEABLE_POD(ValType); -WASM_DECLARE_CACHEABLE_POD(FieldType); - // The dominant use of this data type is for locals and args, and profiling // with ZenGarden and Tanks suggests an initial size of 16 minimises heap // allocation, both in terms of blocks and bytes. diff --git a/js/src/wasm/WasmValue.h b/js/src/wasm/WasmValue.h index f699af5277ee..130f04e3b45f 100644 --- a/js/src/wasm/WasmValue.h +++ b/js/src/wasm/WasmValue.h @@ -276,21 +276,18 @@ class LitVal { Cell() : v128_() {} ~Cell() = default; + + WASM_CHECK_CACHEABLE_POD(i32_, i64_, f32_, f64_, v128_); + WASM_ALLOW_NON_CACHEABLE_POD_FIELD( + ref_, + "The pointer value in ref_ is guaranteed to always be null in a " + "LitVal."); }; protected: ValType type_; Cell cell_; - // We check the fields of cell_ here instead of in the union to avoid a - // template issue. In addition, Cell is only cacheable POD when used in - // LitVal and not Val, so checking here makes sense. - WASM_CHECK_CACHEABLE_POD(type_, cell_.i32_, cell_.i64_, cell_.f32_, - cell_.f64_, cell_.v128_); - WASM_ALLOW_NON_CACHEABLE_POD_FIELD( - cell_.ref_, - "The pointer value in ref_ is guaranteed to always be null in a LitVal."); - public: LitVal() : type_(ValType()), cell_{} {} @@ -369,9 +366,11 @@ class LitVal { MOZ_ASSERT(type_ == ValType::V128); return cell_.v128_; } + + WASM_DECLARE_FRIEND_SERIALIZE(LitVal); }; -WASM_DECLARE_CACHEABLE_POD(LitVal); +WASM_DECLARE_CACHEABLE_POD(LitVal::Cell); // A Val is a LitVal that can contain (non-null) pointers to GC things. All Vals // must be used with the rooting APIs as they may contain JS objects.