blob: 36bf3e836679c6dfe4bab04746801e4d2b5fd73a [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.
#ifndef CallbackFunctionBase_h
#define CallbackFunctionBase_h
#include "platform/bindings/ScriptState.h"
#include "platform/bindings/TraceWrapperBase.h"
#include "platform/bindings/TraceWrapperV8Reference.h"
#include "platform/heap/Handle.h"
#include "platform/heap/Persistent.h"
namespace blink {
// 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 TraceWrapperBase {
public:
// Custom version of blink::Persistent
template <typename T>
class Persistent;
virtual ~CallbackFunctionBase() = default;
virtual void Trace(blink::Visitor* visitor) {}
void TraceWrappers(const ScriptWrappableVisitor*) const override;
v8::Isolate* GetIsolate() {
return callback_relevant_script_state_->GetIsolate();
}
protected:
explicit CallbackFunctionBase(v8::Local<v8::Function>);
v8::Local<v8::Function> CallbackFunction() {
return callback_function_.NewLocal(GetIsolate());
}
ScriptState* CallbackRelevantScriptState() {
return callback_relevant_script_state_.get();
}
ScriptState* IncumbentScriptState() { return incumbent_script_state_.get(); }
private:
// The "callback function type" value.
TraceWrapperV8Reference<v8::Function> callback_function_;
// The associated Realm of the callback function type value.
scoped_refptr<ScriptState> callback_relevant_script_state_;
// The callback context, i.e. the incumbent Realm when an ECMAScript value is
// converted to an IDL value.
// https://heycam.github.io/webidl/#dfn-callback-context
scoped_refptr<ScriptState> incumbent_script_state_;
};
template <typename T>
class CallbackFunctionBase::Persistent
: public PersistentBase<T,
kNonWeakPersistentConfiguration,
kSingleThreadPersistentConfiguration> {
using Parent = PersistentBase<T,
kNonWeakPersistentConfiguration,
kSingleThreadPersistentConfiguration>;
public:
Persistent(T* raw) : Parent(raw) {
if (raw)
function_.Reset(raw->GetIsolate(), raw->callback_function_.Get());
}
Persistent(const Persistent& other) : Parent(other) {
if (other)
function_.Reset(other->GetIsolate(), other.function_);
}
~Persistent() { function_.Reset(); }
Persistent& operator=(const Persistent& other) {
if (this == &other)
return *this;
if (other) {
Parent::operator=(other);
function_.Reset(other->GetIsolate(), other.function_);
} else {
Clear();
}
return *this;
}
void Clear() {
Parent::Clear();
function_.Reset();
}
private:
v8::Persistent<v8::Function> function_;
};
template <typename T>
typename T::template Persistent<T> WrapPersistentCallbackFunction(T* value) {
return typename T::template Persistent<T>(value);
}
} // namespace blink
#endif // CallbackFunctionBase_h