| 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 {
|
|
|