Index: src/api.cc |
diff --git a/src/api.cc b/src/api.cc |
index 6858a325c40a86dea6b2fa130591d36c4ac09ff5..312faebdc716ff9d243ac663ee5770c1037edfa1 100644 |
--- a/src/api.cc |
+++ b/src/api.cc |
@@ -24,6 +24,7 @@ |
#include "src/base/functional.h" |
#include "src/base/platform/platform.h" |
#include "src/base/platform/time.h" |
+#include "src/base/safe_conversions.h" |
#include "src/base/utils/random-number-generator.h" |
#include "src/bootstrapper.h" |
#include "src/char-predicates-inl.h" |
@@ -68,6 +69,7 @@ |
#include "src/unicode-inl.h" |
#include "src/v8.h" |
#include "src/v8threads.h" |
+#include "src/value-serializer.h" |
#include "src/version.h" |
#include "src/vm-state-inl.h" |
#include "src/wasm/wasm-module.h" |
@@ -2832,6 +2834,101 @@ MaybeLocal<String> JSON::Stringify(Local<Context> context, |
RETURN_ESCAPED(result); |
} |
+// --- V a l u e S e r i a l i z a t i o n --- |
+ |
+struct ValueSerializer::PrivateData { |
+ explicit PrivateData(i::Isolate* i) : isolate(i), serializer(i) {} |
+ i::Isolate* isolate; |
+ i::ValueSerializer serializer; |
+}; |
+ |
+ValueSerializer::ValueSerializer(Isolate* isolate) |
+ : private_(new PrivateData(reinterpret_cast<i::Isolate*>(isolate))) {} |
+ |
+ValueSerializer::~ValueSerializer() { delete private_; } |
+ |
+void ValueSerializer::WriteHeader() { private_->serializer.WriteHeader(); } |
+ |
+Maybe<bool> ValueSerializer::WriteValue(Local<Context> context, |
+ Local<Value> value) { |
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, ValueSerializer, WriteValue, bool); |
+ i::Handle<i::Object> object = Utils::OpenHandle(*value); |
+ Maybe<bool> result = private_->serializer.WriteObject(object); |
+ if (result.IsNothing()) { |
+ has_pending_exception = private_->isolate->has_pending_exception(); |
+ RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool); |
+ } |
+ return result; |
+} |
+ |
+std::vector<uint8_t> ValueSerializer::ReleaseBuffer() { |
+ return private_->serializer.ReleaseBuffer(); |
+} |
+ |
+struct ValueDeserializer::PrivateData { |
+ PrivateData(i::Isolate* i, i::Vector<const uint8_t> data) |
+ : isolate(i), deserializer(i, data) {} |
+ i::Isolate* isolate; |
+ i::ValueDeserializer deserializer; |
+ bool supports_legacy_wire_format = false; |
+}; |
+ |
+ValueDeserializer::ValueDeserializer(Isolate* isolate, const uint8_t* data, |
+ size_t size) { |
+ if (base::IsValueInRangeForNumericType<int>(size)) { |
+ private_ = |
+ new PrivateData(reinterpret_cast<i::Isolate*>(isolate), |
+ i::Vector<const uint8_t>(data, static_cast<int>(size))); |
+ } else { |
+ private_ = nullptr; |
+ } |
+} |
+ |
+ValueDeserializer::~ValueDeserializer() { delete private_; } |
+ |
+Maybe<bool> ValueDeserializer::ReadHeader() { |
+ // TODO(jbroman): Today, all wire formats are "legacy". When a more supported |
+ // format is added, compare the version of the internal serializer to the |
+ // minimum non-legacy version number. |
+ if (!private_ || !private_->deserializer.ReadHeader().FromMaybe(false) || |
+ !private_->supports_legacy_wire_format) { |
+ delete private_; |
+ private_ = nullptr; |
+ return Nothing<bool>(); |
+ } |
+ return Just(true); |
+} |
+ |
+void ValueDeserializer::SetSupportsLegacyWireFormat( |
+ bool supports_legacy_wire_format) { |
+ if (!private_) return; |
+ private_->supports_legacy_wire_format = supports_legacy_wire_format; |
+} |
+ |
+uint32_t ValueDeserializer::GetWireFormatVersion() const { |
+ CHECK(private_); |
+ return private_->deserializer.GetWireFormatVersion(); |
+} |
+ |
+MaybeLocal<Value> ValueDeserializer::ReadValue(Local<Context> context) { |
+ CHECK(private_); |
+ PREPARE_FOR_EXECUTION(context, ValueDeserializer, ReadValue, Value); |
+ i::MaybeHandle<i::Object> result; |
+ if (GetWireFormatVersion() > 0) { |
+ result = private_->deserializer.ReadObject(); |
+ } else { |
+ result = |
+ private_->deserializer.ReadObjectUsingEntireBufferForLegacyFormat(); |
+ } |
+ Local<Value> value; |
+ if (!ToLocal(result, &value)) { |
+ has_pending_exception = private_->isolate->has_pending_exception(); |
+ RETURN_ON_FAILED_EXECUTION(Value); |
+ return MaybeLocal<Value>(); |
+ } |
+ RETURN_ESCAPED(value); |
+} |
+ |
// --- D a t a --- |
bool Value::FullIsUndefined() const { |