Commit 65435199 authored by jbroman's avatar jbroman Committed by Commit bot

ValueSerializer: Add an explicit tag for host objects.

This makes it no longer necessary to ensure that V8 and Blink have non-colliding
tags, which makes it easier for them to evolve independently, and also makes
the wire format more suitable for other V8 embedders, who would not
necessarily be surveyed before V8 introduced a new tag that might collide
with theirs.

BUG=chromium:686159

Review-Url: https://codereview.chromium.org/2709023003
Cr-Commit-Position: refs/heads/master@{#43466}
parent 7f570150
......@@ -27,7 +27,9 @@ namespace internal {
// Version 10: one-byte (Latin-1) strings
// Version 11: properly separate undefined from the hole in arrays
// Version 12: regexp and string objects share normal string encoding
static const uint32_t kLatestVersion = 12;
// Version 13: host objects have an explicit tag (rather than handling all
// unknown tags)
static const uint32_t kLatestVersion = 13;
static const int kPretenureThreshold = 100 * KB;
......@@ -124,6 +126,9 @@ enum class SerializationTag : uint8_t {
// wasmWireByteLength:uint32_t, then raw data
// compiledDataLength:uint32_t, then raw data
kWasmModule = 'W',
// The delegate is responsible for processing all following data.
// This "escapes" to whatever wire format the delegate chooses.
kHostObject = '\\',
};
namespace {
......@@ -823,6 +828,7 @@ Maybe<bool> ValueSerializer::WriteWasmModule(Handle<JSObject> object) {
}
Maybe<bool> ValueSerializer::WriteHostObject(Handle<JSObject> object) {
WriteTag(SerializationTag::kHostObject);
if (!delegate_) {
isolate_->Throw(*isolate_->factory()->NewError(
isolate_->error_function(), MessageTemplate::kDataCloneError, object));
......@@ -1144,11 +1150,16 @@ MaybeHandle<Object> ValueDeserializer::ReadObjectInternal() {
}
case SerializationTag::kWasmModule:
return ReadWasmModule();
default:
// TODO(jbroman): Introduce an explicit tag for host objects to avoid
// having to treat every unknown tag as a potential host object.
position_--;
case SerializationTag::kHostObject:
return ReadHostObject();
default:
// Before there was an explicit tag for host objects, all unknown tags
// were delegated to the host.
if (version_ < 13) {
position_--;
return ReadHostObject();
}
return MaybeHandle<Object>();
}
}
......
......@@ -2370,8 +2370,9 @@ class ValueSerializerTestWithHostObject : public ValueSerializerTest {
friend class DeserializerDelegate;
};
// This is a tag that's not used in V8.
const uint8_t ValueSerializerTestWithHostObject::kExampleHostObjectTag = '+';
// This is a tag that is used in V8. Using this ensures that we have separate
// tag namespaces.
const uint8_t ValueSerializerTestWithHostObject::kExampleHostObjectTag = 'T';
TEST_F(ValueSerializerTestWithHostObject, RoundTripUint32) {
// The host can serialize data as uint32_t.
......@@ -2544,6 +2545,19 @@ TEST_F(ValueSerializerTestWithHostObject, RoundTripSameObject) {
});
}
TEST_F(ValueSerializerTestWithHostObject, DecodeSimpleHostObject) {
EXPECT_CALL(deserializer_delegate_, ReadHostObject(isolate()))
.WillRepeatedly(Invoke([this](Isolate*) {
EXPECT_TRUE(ReadExampleHostObjectTag());
return NewHostObject(deserialization_context(), 0, nullptr);
}));
DecodeTest(
{0xff, 0x0d, 0x5c, kExampleHostObjectTag}, [this](Local<Value> value) {
EXPECT_TRUE(EvaluateScriptForResultBool(
"Object.getPrototypeOf(result) === ExampleHostObject.prototype"));
});
}
class ValueSerializerTestWithHostArrayBufferView
: public ValueSerializerTestWithHostObject {
protected:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment