Chromium Code Reviews| Index: src/api.cc |
| diff --git a/src/api.cc b/src/api.cc |
| index 6858a325c40a86dea6b2fa130591d36c4ac09ff5..f832b3071fc82d27a706013735b6f34aa0c30ca2 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,104 @@ 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() { |
| + CHECK(private_); |
|
Jakob Kummerow
2016/08/24 17:41:04
What does this guard against? A future constructor
jbroman
2016/08/24 21:26:36
Fair enough, it's probably premature since there's
|
| + private_->serializer.WriteHeader(); |
| +} |
| + |
| +Maybe<bool> ValueSerializer::WriteValue(Local<Context> context, |
| + Local<Value> value) { |
| + CHECK(private_); |
| + 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() { |
| + CHECK(private_); |
| + 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; |
|
Jakob Kummerow
2016/08/24 17:41:03
How about initializing this?
jbroman
2016/08/24 21:26:36
Done.
|
| +}; |
| + |
| +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))); |
| + } |
|
Jakob Kummerow
2016/08/24 17:41:04
how about: else { private_ = nullptr; } ?
jbroman
2016/08/24 21:26:36
Not one, but two uninitialized variables in one sm
|
| +} |
| + |
| +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) { |
| + CHECK(private_); |
|
Jakob Kummerow
2016/08/24 17:41:04
Presumably this needs to be called before ReadHead
jbroman
2016/08/24 21:26:36
Added a comment to clarify usage, and made it just
|
| + 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 { |