1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_V8_PRIVATE_PROPERTY_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_V8_PRIVATE_PROPERTY_H_
#include "base/memory/ptr_util.h"
#include "third_party/blink/renderer/platform/bindings/scoped_persistent.h"
#include "third_party/blink/renderer/platform/bindings/v8_binding_macros.h"
#include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h"
#include "third_party/blink/renderer/platform/platform_export.h"
#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
#include "third_party/blink/renderer/platform/wtf/hash_map.h"
#include "v8/include/v8.h"
namespace blink {
// Provides access to V8's private properties with a symbol key.
//
// static const V8PrivateProperty::SymbolKey kPrivateProperty;
// auto private_property = V8PrivateProperty::GetSymbol(
// isolate, kPrivateProperty);
// v8::Local<v8::Object> object = ...;
// v8::Local<v8::Value> value;
// if (!private_property.GetOrUndefined(object).ToLocal(&value)) return;
// value = ...;
// private_property.Set(object, value);
// ...
class PLATFORM_EXPORT V8PrivateProperty {
USING_FAST_MALLOC(V8PrivateProperty);
public:
// Private properties used to implement [CachedAccessor].
enum class CachedAccessor : unsigned {
kNone = 0,
kWindowProxy,
kWindowDocument,
};
V8PrivateProperty() = default;
V8PrivateProperty(const V8PrivateProperty&) = delete;
V8PrivateProperty& operator=(const V8PrivateProperty&) = delete;
// Provides fast access to V8's private properties.
//
// Retrieving/creating a global private symbol from a string is very
// expensive compared to get or set a private property. This class
// provides a way to cache a private symbol and re-use it.
class PLATFORM_EXPORT Symbol {
STACK_ALLOCATED();
public:
bool HasValue(v8::Local<v8::Object> object) const {
return object->HasPrivate(GetContext(), private_symbol_).ToChecked();
}
// Returns the value of the private property if set, or undefined.
[[nodiscard]] v8::MaybeLocal<v8::Value> GetOrUndefined(
v8::Local<v8::Object> object) const {
return object->GetPrivate(GetContext(), private_symbol_);
}
bool Set(v8::Local<v8::Object> object, v8::Local<v8::Value> value) const {
return object->SetPrivate(GetContext(), private_symbol_, value)
.ToChecked();
}
bool DeleteProperty(v8::Local<v8::Object> object) const {
return object->DeletePrivate(GetContext(), private_symbol_).ToChecked();
}
v8::Local<v8::Private> GetPrivate() const { return private_symbol_; }
private:
friend class V8PrivateProperty;
Symbol(v8::Isolate* isolate, v8::Local<v8::Private> private_symbol)
: private_symbol_(private_symbol), isolate_(isolate) {}
// To get/set private property, we should use the current context.
v8::Local<v8::Context> GetContext() const {
return isolate_->GetCurrentContext();
}
v8::Local<v8::Private> private_symbol_;
v8::Isolate* isolate_;
};
// This class is used for a key to get Symbol.
//
// We can improve ability of tracking private properties by using an instance
// of this class.
class PLATFORM_EXPORT SymbolKey final {
public:
SymbolKey() = default;
SymbolKey(const SymbolKey&) = delete;
SymbolKey& operator=(const SymbolKey&) = delete;
};
// TODO(peria): Do not use this specialized hack. See a TODO comment
// on m_symbolWindowDocumentCachedAccessor.
static Symbol GetWindowDocumentCachedAccessor(v8::Isolate* isolate);
static Symbol GetCachedAccessor(v8::Isolate* isolate,
CachedAccessor symbol_id);
// Returns a Symbol to access a private property. Symbol instances from same
// |key| are guaranteed to access the same property.
static Symbol GetSymbol(v8::Isolate* isolate, const SymbolKey& key);
// This function is always called after NOTREACHED(). The Symbol returned from
// this function must not be used.
static Symbol GetEmptySymbol() {
return Symbol(nullptr, v8::Local<v8::Private>());
}
private:
static v8::Local<v8::Private> CreateV8Private(v8::Isolate*,
const char* symbol);
// TODO(peria): Do not use this specialized hack for
// Window#DocumentCachedAccessor. This is required to put v8::Private key in
// a snapshot, and it cannot be a v8::Eternal<> due to V8 serializer's
// requirement.
ScopedPersistent<v8::Private> symbol_window_document_cached_accessor_;
WTF::HashMap<const void*, v8::Eternal<v8::Private>> symbol_map_;
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_BINDINGS_V8_PRIVATE_PROPERTY_H_
|