diff options
author | Joyee Cheung <joyeec9h3@gmail.com> | 2023-04-07 02:17:47 +0200 |
---|---|---|
committer | Joyee Cheung <joyeec9h3@gmail.com> | 2023-04-26 00:34:49 +0200 |
commit | 2e44a14cfb84a0665fb4bac06b2fca76e8da06a7 (patch) | |
tree | 613dddb805deec2e3b5a50977c22dceb1388980a /src | |
parent | ab3a54f2eed465f730f55fc9efa972ab465e374d (diff) | |
download | node-new-2e44a14cfb84a0665fb4bac06b2fca76e8da06a7.tar.gz |
src: split BlobSerializer/BlobDeserializer
This patch splits BlobSerializer and BlobDeserializer out of
SnapshotSerializer and SnapshotDeserializer. The child classes
can implement serialization methods for custom types on top
of BlobSerializer/BlobDeserializer for conversions between
native types and binary blobs. This allows us to reuse the
classes for other cases (e.g. SEA blobs).
PR-URL: https://github.com/nodejs/node/pull/47458
Reviewed-By: Darshan Sen <raisinten@gmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/env.h | 1 | ||||
-rw-r--r-- | src/node_snapshotable.cc | 268 |
2 files changed, 169 insertions, 100 deletions
@@ -534,6 +534,7 @@ struct SnapshotData { bool Check() const; static bool FromFile(SnapshotData* out, FILE* in); static bool FromBlob(SnapshotData* out, const std::vector<char>& in); + static bool FromBlob(SnapshotData* out, std::string_view in); static const SnapshotData* FromEmbedderWrapper( const EmbedderSnapshotData* data); EmbedderSnapshotData::Pointer AsEmbedderWrapper() const; diff --git a/src/node_snapshotable.cc b/src/node_snapshotable.cc index 0c842a8631..6302fa04c4 100644 --- a/src/node_snapshotable.cc +++ b/src/node_snapshotable.cc @@ -140,16 +140,15 @@ std::ostream& operator<<(std::ostream& output, const EnvSerializeInfo& i) { return output; } -class SnapshotSerializerDeserializer { +class BlobSerializerDeserializer { public: - SnapshotSerializerDeserializer() - : is_debug(per_process::enabled_debug_list.enabled( - DebugCategory::MKSNAPSHOT)) {} + explicit BlobSerializerDeserializer(bool is_debug_v) : is_debug(is_debug_v) {} template <typename... Args> void Debug(const char* format, Args&&... args) const { - per_process::Debug( - DebugCategory::MKSNAPSHOT, format, std::forward<Args>(args)...); + if (is_debug) { + FPrintF(stderr, format, std::forward<Args>(args)...); + } } template <typename T> @@ -185,18 +184,28 @@ class SnapshotSerializerDeserializer { bool is_debug = false; }; -class SnapshotDeserializer : public SnapshotSerializerDeserializer { +// TODO(joyeecheung): move it to the separate header file. +// Child classes are expected to implement T Read<T>() where +// !std::is_arithmetic_v<T> && !std::is_same_v<T, std::string> +template <typename Impl> +class BlobDeserializer : public BlobSerializerDeserializer { public: - explicit SnapshotDeserializer(const std::vector<char>& s) - : SnapshotSerializerDeserializer(), sink(s) {} - ~SnapshotDeserializer() {} + explicit BlobDeserializer(bool is_debug_v, std::string_view s) + : BlobSerializerDeserializer(is_debug_v), sink(s) {} + ~BlobDeserializer() {} + + size_t read_total = 0; + std::string_view sink; + + Impl* impl() { return static_cast<Impl*>(this); } + const Impl* impl() const { return static_cast<const Impl*>(this); } // Helper for reading numeric types. template <typename T> - T Read() { + T ReadArithmetic() { static_assert(std::is_arithmetic_v<T>, "Not an arithmetic type"); T result; - Read(&result, 1); + ReadArithmetic(&result, 1); return result; } @@ -209,14 +218,19 @@ class SnapshotDeserializer : public SnapshotSerializerDeserializer { std::string name = GetName<T>(); Debug("\nReadVector<%s>()(%d-byte)\n", name.c_str(), sizeof(T)); } - size_t count = static_cast<size_t>(Read<size_t>()); + size_t count = static_cast<size_t>(ReadArithmetic<size_t>()); if (count == 0) { return std::vector<T>(); } if (is_debug) { Debug("Reading %d vector elements...\n", count); } - std::vector<T> result = ReadVector<T>(count, std::is_arithmetic<T>{}); + std::vector<T> result; + if constexpr (std::is_arithmetic_v<T>) { + result = ReadArithmeticVector<T>(count); + } else { + result = ReadNonArithmeticVector<T>(count); + } if (is_debug) { std::string str = std::is_arithmetic_v<T> ? "" : ToStr(result); std::string name = GetName<T>(); @@ -226,7 +240,7 @@ class SnapshotDeserializer : public SnapshotSerializerDeserializer { } std::string ReadString() { - size_t length = Read<size_t>(); + size_t length = ReadArithmetic<size_t>(); if (is_debug) { Debug("ReadString(), length=%d: ", length); @@ -245,13 +259,9 @@ class SnapshotDeserializer : public SnapshotSerializerDeserializer { return result; } - size_t read_total = 0; - const std::vector<char>& sink; - - private: // Helper for reading an array of numeric types. template <typename T> - void Read(T* out, size_t count) { + void ReadArithmetic(T* out, size_t count) { static_assert(std::is_arithmetic_v<T>, "Not an arithmetic type"); DCHECK_GT(count, 0); // Should not read contents for vectors of size 0. if (is_debug) { @@ -272,17 +282,18 @@ class SnapshotDeserializer : public SnapshotSerializerDeserializer { // Helper for reading numeric vectors. template <typename Number> - std::vector<Number> ReadVector(size_t count, std::true_type) { + std::vector<Number> ReadArithmeticVector(size_t count) { static_assert(std::is_arithmetic_v<Number>, "Not an arithmetic type"); DCHECK_GT(count, 0); // Should not read contents for vectors of size 0. std::vector<Number> result(count); - Read(result.data(), count); + ReadArithmetic(result.data(), count); return result; } + private: // Helper for reading non-numeric vectors. template <typename T> - std::vector<T> ReadVector(size_t count, std::false_type) { + std::vector<T> ReadNonArithmeticVector(size_t count) { static_assert(!std::is_arithmetic_v<T>, "Arithmetic type"); DCHECK_GT(count, 0); // Should not read contents for vectors of size 0. std::vector<T> result; @@ -293,29 +304,49 @@ class SnapshotDeserializer : public SnapshotSerializerDeserializer { if (is_debug) { Debug("\n[%d] ", i); } - result.push_back(Read<T>()); + result.push_back(ReadElement<T>()); } is_debug = original_is_debug; return result; } + + template <typename T> + T ReadElement() { + if constexpr (std::is_arithmetic_v<T>) { + return ReadArithmetic<T>(); + } else if constexpr (std::is_same_v<T, std::string>) { + return ReadString(); + } else { + return impl()->template Read<T>(); + } + } }; -class SnapshotSerializer : public SnapshotSerializerDeserializer { +// TODO(joyeecheung): move it to the separate header file. +// Child classes are expected to implement size_t Write<T>(const T&) where +// !std::is_arithmetic_v<T> && !std::is_same_v<T, std::string> +template <typename Impl> +class BlobSerializer : public BlobSerializerDeserializer { public: - SnapshotSerializer() : SnapshotSerializerDeserializer() { + explicit BlobSerializer(bool is_debug_v) + : BlobSerializerDeserializer(is_debug_v) { // Currently the snapshot blob built with an empty script is around 4MB. // So use that as the default sink size. sink.reserve(4 * 1024 * 1024); } - ~SnapshotSerializer() {} + ~BlobSerializer() {} + + Impl* impl() { return static_cast<Impl*>(this); } + const Impl* impl() const { return static_cast<const Impl*>(this); } + std::vector<char> sink; // Helper for writing numeric types. template <typename T> - size_t Write(const T& data) { + size_t WriteArithmetic(const T& data) { static_assert(std::is_arithmetic_v<T>, "Not an arithmetic type"); - return Write(&data, 1); + return WriteArithmetic(&data, 1); } // Layout of vectors: @@ -333,11 +364,16 @@ class SnapshotSerializer : public SnapshotSerializerDeserializer { str.c_str()); } - size_t written_total = Write<size_t>(data.size()); + size_t written_total = WriteArithmetic<size_t>(data.size()); if (data.size() == 0) { return written_total; } - written_total += WriteVector<T>(data, std::is_arithmetic<T>{}); + + if constexpr (std::is_arithmetic_v<T>) { + written_total += WriteArithmeticVector<T>(data); + } else { + written_total += WriteNonArithmeticVector<T>(data); + } if (is_debug) { std::string name = GetName<T>(); @@ -352,7 +388,7 @@ class SnapshotSerializer : public SnapshotSerializerDeserializer { // [ |length| bytes ] contents size_t WriteString(const std::string& data) { CHECK_GT(data.size(), 0); // No empty strings should be written. - size_t written_total = Write<size_t>(data.size()); + size_t written_total = WriteArithmetic<size_t>(data.size()); if (is_debug) { std::string str = ToStr(data); Debug("WriteString(), length=%zu: \"%s\"\n", data.size(), data.c_str()); @@ -370,10 +406,10 @@ class SnapshotSerializer : public SnapshotSerializerDeserializer { return written_total; } - private: // Helper for writing an array of numeric types. template <typename T> - size_t Write(const T* data, size_t count) { + size_t WriteArithmetic(const T* data, size_t count) { + static_assert(std::is_arithmetic_v<T>, "Arithmetic type"); DCHECK_GT(count, 0); // Should not write contents for vectors of size 0. if (is_debug) { std::string str = @@ -398,13 +434,16 @@ class SnapshotSerializer : public SnapshotSerializerDeserializer { // Helper for writing numeric vectors. template <typename Number> - size_t WriteVector(const std::vector<Number>& data, std::true_type) { - return Write(data.data(), data.size()); + size_t WriteArithmeticVector(const std::vector<Number>& data) { + static_assert(std::is_arithmetic_v<Number>, "Arithmetic type"); + return WriteArithmetic(data.data(), data.size()); } + private: // Helper for writing non-numeric vectors. template <typename T> - size_t WriteVector(const std::vector<T>& data, std::false_type) { + size_t WriteNonArithmeticVector(const std::vector<T>& data) { + static_assert(!std::is_arithmetic_v<T>, "Arithmetic type"); DCHECK_GT(data.size(), 0); // Should not write contents for vectors of size 0. size_t written_total = 0; @@ -414,25 +453,50 @@ class SnapshotSerializer : public SnapshotSerializerDeserializer { if (is_debug) { Debug("\n[%d] ", i); } - written_total += Write<T>(data[i]); + written_total += WriteElement<T>(data[i]); } is_debug = original_is_debug; return written_total; } + + template <typename T> + size_t WriteElement(const T& data) { + if constexpr (std::is_arithmetic_v<T>) { + return WriteArithmetic<T>(data); + } else if constexpr (std::is_same_v<T, std::string>) { + return WriteString(data); + } else { + return impl()->template Write<T>(data); + } + } }; -// Layout of serialized std::string: -// [ 4/8 bytes ] length -// [ |length| bytes ] contents -template <> -std::string SnapshotDeserializer::Read() { - return ReadString(); -} -template <> -size_t SnapshotSerializer::Write(const std::string& data) { - return WriteString(data); -} +class SnapshotDeserializer : public BlobDeserializer<SnapshotDeserializer> { + public: + explicit SnapshotDeserializer(std::string_view v) + : BlobDeserializer<SnapshotDeserializer>( + per_process::enabled_debug_list.enabled(DebugCategory::MKSNAPSHOT), + v) {} + + template <typename T, + std::enable_if_t<!std::is_same<T, std::string>::value>* = nullptr, + std::enable_if_t<!std::is_arithmetic<T>::value>* = nullptr> + T Read(); +}; + +class SnapshotSerializer : public BlobSerializer<SnapshotSerializer> { + public: + SnapshotSerializer() + : BlobSerializer<SnapshotSerializer>( + per_process::enabled_debug_list.enabled( + DebugCategory::MKSNAPSHOT)) {} + + template <typename T, + std::enable_if_t<!std::is_same<T, std::string>::value>* = nullptr, + std::enable_if_t<!std::is_arithmetic<T>::value>* = nullptr> + size_t Write(const T& data); +}; // Layout of v8::StartupData // [ 4/8 bytes ] raw_size @@ -441,13 +505,13 @@ template <> v8::StartupData SnapshotDeserializer::Read() { Debug("Read<v8::StartupData>()\n"); - int raw_size = Read<int>(); + int raw_size = ReadArithmetic<int>(); Debug("size=%d\n", raw_size); CHECK_GT(raw_size, 0); // There should be no startup data of size 0. // The data pointer of v8::StartupData would be deleted so it must be new'ed. std::unique_ptr<char> buf = std::unique_ptr<char>(new char[raw_size]); - Read<char>(buf.get(), raw_size); + ReadArithmetic<char>(buf.get(), raw_size); return v8::StartupData{buf.release(), raw_size}; } @@ -457,8 +521,9 @@ size_t SnapshotSerializer::Write(const v8::StartupData& data) { Debug("\nWrite<v8::StartupData>() size=%d\n", data.raw_size); CHECK_GT(data.raw_size, 0); // There should be no startup data of size 0. - size_t written_total = Write<int>(data.raw_size); - written_total += Write<char>(data.data, static_cast<size_t>(data.raw_size)); + size_t written_total = WriteArithmetic<int>(data.raw_size); + written_total += + WriteArithmetic<char>(data.data, static_cast<size_t>(data.raw_size)); Debug("Write<v8::StartupData>() wrote %d bytes\n\n", written_total); return written_total; @@ -508,8 +573,8 @@ PropInfo SnapshotDeserializer::Read() { PropInfo result; result.name = ReadString(); - result.id = Read<uint32_t>(); - result.index = Read<SnapshotIndex>(); + result.id = ReadArithmetic<uint32_t>(); + result.index = ReadArithmetic<SnapshotIndex>(); if (is_debug) { std::string str = ToStr(result); @@ -527,8 +592,8 @@ size_t SnapshotSerializer::Write(const PropInfo& data) { } size_t written_total = WriteString(data.name); - written_total += Write<uint32_t>(data.id); - written_total += Write<SnapshotIndex>(data.index); + written_total += WriteArithmetic<uint32_t>(data.id); + written_total += WriteArithmetic<SnapshotIndex>(data.index); Debug("Write<PropInfo>() wrote %d bytes\n", written_total); return written_total; @@ -547,10 +612,10 @@ AsyncHooks::SerializeInfo SnapshotDeserializer::Read() { Debug("Read<AsyncHooks::SerializeInfo>()\n"); AsyncHooks::SerializeInfo result; - result.async_ids_stack = Read<AliasedBufferIndex>(); - result.fields = Read<AliasedBufferIndex>(); - result.async_id_fields = Read<AliasedBufferIndex>(); - result.js_execution_async_resources = Read<SnapshotIndex>(); + result.async_ids_stack = ReadArithmetic<AliasedBufferIndex>(); + result.fields = ReadArithmetic<AliasedBufferIndex>(); + result.async_id_fields = ReadArithmetic<AliasedBufferIndex>(); + result.js_execution_async_resources = ReadArithmetic<SnapshotIndex>(); result.native_execution_async_resources = ReadVector<SnapshotIndex>(); if (is_debug) { @@ -567,10 +632,12 @@ size_t SnapshotSerializer::Write(const AsyncHooks::SerializeInfo& data) { Debug("Write<AsyncHooks::SerializeInfo>() %s\n", str.c_str()); } - size_t written_total = Write<AliasedBufferIndex>(data.async_ids_stack); - written_total += Write<AliasedBufferIndex>(data.fields); - written_total += Write<AliasedBufferIndex>(data.async_id_fields); - written_total += Write<SnapshotIndex>(data.js_execution_async_resources); + size_t written_total = + WriteArithmetic<AliasedBufferIndex>(data.async_ids_stack); + written_total += WriteArithmetic<AliasedBufferIndex>(data.fields); + written_total += WriteArithmetic<AliasedBufferIndex>(data.async_id_fields); + written_total += + WriteArithmetic<SnapshotIndex>(data.js_execution_async_resources); written_total += WriteVector<SnapshotIndex>(data.native_execution_async_resources); @@ -585,7 +652,7 @@ TickInfo::SerializeInfo SnapshotDeserializer::Read() { Debug("Read<TickInfo::SerializeInfo>()\n"); TickInfo::SerializeInfo result; - result.fields = Read<AliasedBufferIndex>(); + result.fields = ReadArithmetic<AliasedBufferIndex>(); if (is_debug) { std::string str = ToStr(result); @@ -602,7 +669,7 @@ size_t SnapshotSerializer::Write(const TickInfo::SerializeInfo& data) { Debug("Write<TickInfo::SerializeInfo>() %s\n", str.c_str()); } - size_t written_total = Write<AliasedBufferIndex>(data.fields); + size_t written_total = WriteArithmetic<AliasedBufferIndex>(data.fields); Debug("Write<TickInfo::SerializeInfo>() wrote %d bytes\n", written_total); return written_total; @@ -612,11 +679,10 @@ size_t SnapshotSerializer::Write(const TickInfo::SerializeInfo& data) { // [ 4/8 bytes ] snapshot index of fields template <> ImmediateInfo::SerializeInfo SnapshotDeserializer::Read() { - per_process::Debug(DebugCategory::MKSNAPSHOT, - "Read<ImmediateInfo::SerializeInfo>()\n"); + Debug("Read<ImmediateInfo::SerializeInfo>()\n"); ImmediateInfo::SerializeInfo result; - result.fields = Read<AliasedBufferIndex>(); + result.fields = ReadArithmetic<AliasedBufferIndex>(); if (is_debug) { std::string str = ToStr(result); Debug("Read<ImmediateInfo::SerializeInfo>() %s\n", str.c_str()); @@ -631,7 +697,7 @@ size_t SnapshotSerializer::Write(const ImmediateInfo::SerializeInfo& data) { Debug("Write<ImmediateInfo::SerializeInfo>() %s\n", str.c_str()); } - size_t written_total = Write<AliasedBufferIndex>(data.fields); + size_t written_total = WriteArithmetic<AliasedBufferIndex>(data.fields); Debug("Write<ImmediateInfo::SerializeInfo>() wrote %d bytes\n", written_total); @@ -644,13 +710,12 @@ size_t SnapshotSerializer::Write(const ImmediateInfo::SerializeInfo& data) { // [ 4/8 bytes ] snapshot index of observers template <> performance::PerformanceState::SerializeInfo SnapshotDeserializer::Read() { - per_process::Debug(DebugCategory::MKSNAPSHOT, - "Read<PerformanceState::SerializeInfo>()\n"); + Debug("Read<PerformanceState::SerializeInfo>()\n"); performance::PerformanceState::SerializeInfo result; - result.root = Read<AliasedBufferIndex>(); - result.milestones = Read<AliasedBufferIndex>(); - result.observers = Read<AliasedBufferIndex>(); + result.root = ReadArithmetic<AliasedBufferIndex>(); + result.milestones = ReadArithmetic<AliasedBufferIndex>(); + result.observers = ReadArithmetic<AliasedBufferIndex>(); if (is_debug) { std::string str = ToStr(result); Debug("Read<PerformanceState::SerializeInfo>() %s\n", str.c_str()); @@ -666,9 +731,9 @@ size_t SnapshotSerializer::Write( Debug("Write<PerformanceState::SerializeInfo>() %s\n", str.c_str()); } - size_t written_total = Write<AliasedBufferIndex>(data.root); - written_total += Write<AliasedBufferIndex>(data.milestones); - written_total += Write<AliasedBufferIndex>(data.observers); + size_t written_total = WriteArithmetic<AliasedBufferIndex>(data.root); + written_total += WriteArithmetic<AliasedBufferIndex>(data.milestones); + written_total += WriteArithmetic<AliasedBufferIndex>(data.observers); Debug("Write<PerformanceState::SerializeInfo>() wrote %d bytes\n", written_total); @@ -682,8 +747,7 @@ size_t SnapshotSerializer::Write( // [ ... ] |length| of PropInfo data template <> IsolateDataSerializeInfo SnapshotDeserializer::Read() { - per_process::Debug(DebugCategory::MKSNAPSHOT, - "Read<IsolateDataSerializeInfo>()\n"); + Debug("Read<IsolateDataSerializeInfo>()\n"); IsolateDataSerializeInfo result; result.primitive_values = ReadVector<SnapshotIndex>(); @@ -711,12 +775,12 @@ size_t SnapshotSerializer::Write(const IsolateDataSerializeInfo& data) { template <> RealmSerializeInfo SnapshotDeserializer::Read() { - per_process::Debug(DebugCategory::MKSNAPSHOT, "Read<RealmSerializeInfo>()\n"); + Debug("Read<RealmSerializeInfo>()\n"); RealmSerializeInfo result; result.builtins = ReadVector<std::string>(); result.persistent_values = ReadVector<PropInfo>(); result.native_objects = ReadVector<PropInfo>(); - result.context = Read<SnapshotIndex>(); + result.context = ReadArithmetic<SnapshotIndex>(); return result; } @@ -731,7 +795,7 @@ size_t SnapshotSerializer::Write(const RealmSerializeInfo& data) { size_t written_total = WriteVector<std::string>(data.builtins); written_total += WriteVector<PropInfo>(data.persistent_values); written_total += WriteVector<PropInfo>(data.native_objects); - written_total += Write<SnapshotIndex>(data.context); + written_total += WriteArithmetic<SnapshotIndex>(data.context); Debug("Write<RealmSerializeInfo>() wrote %d bytes\n", written_total); return written_total; @@ -739,17 +803,17 @@ size_t SnapshotSerializer::Write(const RealmSerializeInfo& data) { template <> EnvSerializeInfo SnapshotDeserializer::Read() { - per_process::Debug(DebugCategory::MKSNAPSHOT, "Read<EnvSerializeInfo>()\n"); + Debug("Read<EnvSerializeInfo>()\n"); EnvSerializeInfo result; result.async_hooks = Read<AsyncHooks::SerializeInfo>(); result.tick_info = Read<TickInfo::SerializeInfo>(); result.immediate_info = Read<ImmediateInfo::SerializeInfo>(); - result.timeout_info = Read<AliasedBufferIndex>(); + result.timeout_info = ReadArithmetic<AliasedBufferIndex>(); result.performance_state = Read<performance::PerformanceState::SerializeInfo>(); - result.exit_info = Read<AliasedBufferIndex>(); - result.stream_base_state = Read<AliasedBufferIndex>(); - result.should_abort_on_uncaught_toggle = Read<AliasedBufferIndex>(); + result.exit_info = ReadArithmetic<AliasedBufferIndex>(); + result.stream_base_state = ReadArithmetic<AliasedBufferIndex>(); + result.should_abort_on_uncaught_toggle = ReadArithmetic<AliasedBufferIndex>(); result.principal_realm = Read<RealmSerializeInfo>(); return result; } @@ -765,13 +829,13 @@ size_t SnapshotSerializer::Write(const EnvSerializeInfo& data) { size_t written_total = Write<AsyncHooks::SerializeInfo>(data.async_hooks); written_total += Write<TickInfo::SerializeInfo>(data.tick_info); written_total += Write<ImmediateInfo::SerializeInfo>(data.immediate_info); - written_total += Write<AliasedBufferIndex>(data.timeout_info); + written_total += WriteArithmetic<AliasedBufferIndex>(data.timeout_info); written_total += Write<performance::PerformanceState::SerializeInfo>( data.performance_state); - written_total += Write<AliasedBufferIndex>(data.exit_info); - written_total += Write<AliasedBufferIndex>(data.stream_base_state); + written_total += WriteArithmetic<AliasedBufferIndex>(data.exit_info); + written_total += WriteArithmetic<AliasedBufferIndex>(data.stream_base_state); written_total += - Write<AliasedBufferIndex>(data.should_abort_on_uncaught_toggle); + WriteArithmetic<AliasedBufferIndex>(data.should_abort_on_uncaught_toggle); written_total += Write<RealmSerializeInfo>(data.principal_realm); Debug("Write<EnvSerializeInfo>() wrote %d bytes\n", written_total); @@ -789,14 +853,14 @@ size_t SnapshotSerializer::Write(const EnvSerializeInfo& data) { // [ 4 bytes ] v8 cache version tag template <> SnapshotMetadata SnapshotDeserializer::Read() { - per_process::Debug(DebugCategory::MKSNAPSHOT, "Read<SnapshotMetadata>()\n"); + Debug("Read<SnapshotMetadata>()\n"); SnapshotMetadata result; - result.type = static_cast<SnapshotMetadata::Type>(Read<uint8_t>()); + result.type = static_cast<SnapshotMetadata::Type>(ReadArithmetic<uint8_t>()); result.node_version = ReadString(); result.node_arch = ReadString(); result.node_platform = ReadString(); - result.v8_cache_version_tag = Read<uint32_t>(); + result.v8_cache_version_tag = ReadArithmetic<uint32_t>(); if (is_debug) { std::string str = ToStr(result); @@ -816,7 +880,7 @@ size_t SnapshotSerializer::Write(const SnapshotMetadata& data) { // Node.js may perform synchronizations that are platform-specific and they // can be changed in semver-patches. Debug("Write snapshot type %" PRIu8 "\n", static_cast<uint8_t>(data.type)); - written_total += Write<uint8_t>(static_cast<uint8_t>(data.type)); + written_total += WriteArithmetic<uint8_t>(static_cast<uint8_t>(data.type)); Debug("Write Node.js version %s\n", data.node_version.c_str()); written_total += WriteString(data.node_version); Debug("Write Node.js arch %s\n", data.node_arch); @@ -825,7 +889,7 @@ size_t SnapshotSerializer::Write(const SnapshotMetadata& data) { written_total += WriteString(data.node_platform); Debug("Write V8 cached data version tag %" PRIx32 "\n", data.v8_cache_version_tag); - written_total += Write<uint32_t>(data.v8_cache_version_tag); + written_total += WriteArithmetic<uint32_t>(data.v8_cache_version_tag); return written_total; } @@ -848,7 +912,7 @@ std::vector<char> SnapshotData::ToBlob() const { // Metadata w.Debug("Write magic %" PRIx32 "\n", kMagic); - written_total += w.Write<uint32_t>(kMagic); + written_total += w.WriteArithmetic<uint32_t>(kMagic); w.Debug("Write metadata\n"); written_total += w.Write<SnapshotMetadata>(metadata); @@ -883,13 +947,17 @@ bool SnapshotData::FromFile(SnapshotData* out, FILE* in) { } bool SnapshotData::FromBlob(SnapshotData* out, const std::vector<char>& in) { + return FromBlob(out, std::string_view(in.data(), in.size())); +} + +bool SnapshotData::FromBlob(SnapshotData* out, std::string_view in) { SnapshotDeserializer r(in); r.Debug("SnapshotData::FromBlob()\n"); DCHECK_EQ(out->data_ownership, SnapshotData::DataOwnership::kOwned); // Metadata - uint32_t magic = r.Read<uint32_t>(); + uint32_t magic = r.ReadArithmetic<uint32_t>(); r.Debug("Read magic %" PRIx32 "\n", magic); CHECK_EQ(magic, kMagic); out->metadata = r.Read<SnapshotMetadata>(); |