blob: cc38447a2ad178d43f5c5a779f58d87f114b906b [file] [log] [blame]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/platform/bindings/name_client.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
namespace blink {
class V8PersistentCallbackFunctionBase;
// CallbackFunctionBase is the common base class of all the callback function
// classes. Most importantly this class provides a way of type dispatching (e.g.
// overload resolutions, SFINAE technique, etc.) so that it's possible to
// distinguish callback functions from anything else. Also it provides a common
// implementation of callback functions.
// As the signatures of callback functions vary, this class does not implement
// |Invoke| member function that performs "invoke" steps. Subclasses will
// implement it.
class PLATFORM_EXPORT CallbackFunctionBase
: public GarbageCollectedFinalized<CallbackFunctionBase>,
public NameClient {
virtual ~CallbackFunctionBase() = default;
virtual void Trace(blink::Visitor* visitor);
v8::Local<v8::Object> CallbackObject() {
return callback_function_.NewLocal(GetIsolate());
v8::Isolate* GetIsolate() const {
return callback_relevant_script_state_->GetIsolate();
ScriptState* CallbackRelevantScriptState() {
return callback_relevant_script_state_;
// Returns true if the ES function has a [[Construct]] internal method.
bool IsConstructor() const { return CallbackFunction()->IsConstructor(); }
explicit CallbackFunctionBase(v8::Local<v8::Object>);
v8::Local<v8::Function> CallbackFunction() const {
return callback_function_.NewLocal(GetIsolate()).As<v8::Function>();
ScriptState* IncumbentScriptState() { return incumbent_script_state_; }
// The "callback function type" value.
// Use v8::Object instead of v8::Function in order to handle
// [TreatNonObjectAsNull].
TraceWrapperV8Reference<v8::Object> callback_function_;
// The associated Realm of the callback function type value.
Member<ScriptState> callback_relevant_script_state_;
// The callback context, i.e. the incumbent Realm when an ECMAScript value is
// converted to an IDL value.
Member<ScriptState> incumbent_script_state_;
friend class V8PersistentCallbackFunctionBase;
friend v8::Local<v8::Value> ToV8(CallbackFunctionBase* callback,
v8::Local<v8::Object> creation_context,
// V8PersistentCallbackFunctionBase retains the underlying v8::Function of a
// CallbackFunctionBase without wrapper-tracing. This class is necessary and
// useful where wrapper-tracing is not suitable. Remember that, as a nature of
// v8::Persistent, abuse of V8PersistentCallbackFunctionBase would result in
// memory leak, so the use of V8PersistentCallbackFunctionBase should be limited
// to those which are guaranteed to release the persistents in a finite time
// period.
class PLATFORM_EXPORT V8PersistentCallbackFunctionBase
: public GarbageCollectedFinalized<V8PersistentCallbackFunctionBase> {
virtual ~V8PersistentCallbackFunctionBase() { v8_function_.Reset(); }
virtual void Trace(blink::Visitor*);
explicit V8PersistentCallbackFunctionBase(CallbackFunctionBase*);
template <typename V8CallbackFunction>
V8CallbackFunction* As() {
std::is_base_of<CallbackFunctionBase, V8CallbackFunction>::value,
"V8CallbackFunction must be a subclass of CallbackFunctionBase.");
return static_cast<V8CallbackFunction*>(callback_function_.Get());
Member<CallbackFunctionBase> callback_function_;
// Use v8::Object instead of v8::Function in order to handle
// [TreatNonObjectAsNull].
v8::Persistent<v8::Object> v8_function_;
// V8PersistentCallbackFunction<V8CallbackFunction> is a counter-part of
// V8CallbackFunction. While V8CallbackFunction uses wrapper-tracing,
// V8PersistentCallbackFunction<V8CallbackFunction> uses v8::Persistent to make
// the underlying v8::Function alive.
// Since the signature of |Invoke| varies depending on the IDL definition,
// the class definition is specialized and generated by the bindings code
// generator.
template <typename V8CallbackFunction>
class V8PersistentCallbackFunction;
// Converts the wrapper-tracing version of a callback function to the
// v8::Persistent version of it.
template <typename V8CallbackFunction>
inline V8PersistentCallbackFunction<V8CallbackFunction>*
ToV8PersistentCallbackFunction(V8CallbackFunction* callback_function) {
std::is_base_of<CallbackFunctionBase, V8CallbackFunction>::value,
"V8CallbackFunction must be a subclass of CallbackFunctionBase.");
return callback_function
? new V8PersistentCallbackFunction<V8CallbackFunction>(
: nullptr;
// CallbackFunctionBase is designed to be used with wrapper-tracing. As
// blink::Persistent does not perform wrapper-tracing, use of |WrapPersistent|
// for callback functions is likely (if not always) misuse. Thus, this code
// prohibits such a use case. The call sites should explicitly use
// WrapPersistent(V8PersistentCallbackFunction<T>*).
Persistent<CallbackFunctionBase> WrapPersistent(CallbackFunctionBase*) = delete;
} // namespace blink