chore: remove native_mate (Part 14) (#21365)
* chore: remove uses of mate::Dictionary and mate::Handle * chore: move CreateConstructor to gin_helper * chore: remove native_mate * chore: remove unneeded gin patch
This commit is contained in:
parent
113b47d871
commit
0a741670a9
74 changed files with 215 additions and 2120 deletions
|
@ -6,18 +6,18 @@
|
|||
|
||||
#include <vector>
|
||||
|
||||
#include "native_mate/wrappable.h"
|
||||
#include "shell/common/asar/archive.h"
|
||||
#include "shell/common/asar/asar_util.h"
|
||||
#include "shell/common/gin_converters/callback_converter.h"
|
||||
#include "shell/common/gin_converters/file_path_converter.h"
|
||||
#include "shell/common/gin_helper/dictionary.h"
|
||||
#include "shell/common/gin_helper/object_template_builder.h"
|
||||
#include "shell/common/gin_helper/wrappable.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
#include "shell/common/node_util.h"
|
||||
namespace {
|
||||
|
||||
class Archive : public mate::Wrappable<Archive> {
|
||||
class Archive : public gin_helper::Wrappable<Archive> {
|
||||
public:
|
||||
static v8::Local<v8::Value> Create(v8::Isolate* isolate,
|
||||
const base::FilePath& path) {
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
#ifndef SHELL_COMMON_API_ATOM_API_KEY_WEAK_MAP_H_
|
||||
#define SHELL_COMMON_API_ATOM_API_KEY_WEAK_MAP_H_
|
||||
|
||||
#include "native_mate/handle.h"
|
||||
#include "native_mate/wrappable.h"
|
||||
#include "gin/handle.h"
|
||||
#include "shell/common/gin_converters/std_converter.h"
|
||||
#include "shell/common/gin_helper/object_template_builder.h"
|
||||
#include "shell/common/gin_helper/wrappable.h"
|
||||
#include "shell/common/key_weak_map.h"
|
||||
|
||||
namespace electron {
|
||||
|
@ -16,10 +16,10 @@ namespace electron {
|
|||
namespace api {
|
||||
|
||||
template <typename K>
|
||||
class KeyWeakMap : public mate::Wrappable<KeyWeakMap<K>> {
|
||||
class KeyWeakMap : public gin_helper::Wrappable<KeyWeakMap<K>> {
|
||||
public:
|
||||
static mate::Handle<KeyWeakMap<K>> Create(v8::Isolate* isolate) {
|
||||
return mate::CreateHandle(isolate, new KeyWeakMap<K>(isolate));
|
||||
static gin::Handle<KeyWeakMap<K>> Create(v8::Isolate* isolate) {
|
||||
return gin::CreateHandle(isolate, new KeyWeakMap<K>(isolate));
|
||||
}
|
||||
|
||||
static void BuildPrototype(v8::Isolate* isolate,
|
||||
|
@ -34,7 +34,7 @@ class KeyWeakMap : public mate::Wrappable<KeyWeakMap<K>> {
|
|||
|
||||
protected:
|
||||
explicit KeyWeakMap(v8::Isolate* isolate) {
|
||||
mate::Wrappable<KeyWeakMap<K>>::Init(isolate);
|
||||
gin_helper::Wrappable<KeyWeakMap<K>>::Init(isolate);
|
||||
}
|
||||
~KeyWeakMap() override {}
|
||||
|
||||
|
|
|
@ -558,8 +558,8 @@ bool Converter<electron::api::NativeImage*>::FromV8(
|
|||
}
|
||||
|
||||
*out = static_cast<electron::api::NativeImage*>(
|
||||
static_cast<mate::WrappableBase*>(
|
||||
mate::internal::FromV8Impl(isolate, val)));
|
||||
static_cast<gin_helper::WrappableBase*>(
|
||||
gin_helper::internal::FromV8Impl(isolate, val)));
|
||||
return *out != nullptr;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
|
||||
#include "base/values.h"
|
||||
#include "gin/handle.h"
|
||||
#include "native_mate/wrappable.h"
|
||||
#include "shell/common/gin_helper/error_thrower.h"
|
||||
#include "shell/common/gin_helper/wrappable.h"
|
||||
#include "ui/gfx/image/image.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
|
@ -38,7 +38,7 @@ namespace electron {
|
|||
|
||||
namespace api {
|
||||
|
||||
class NativeImage : public mate::Wrappable<NativeImage> {
|
||||
class NativeImage : public gin_helper::Wrappable<NativeImage> {
|
||||
public:
|
||||
static gin::Handle<NativeImage> CreateEmpty(v8::Isolate* isolate);
|
||||
static gin::Handle<NativeImage> Create(v8::Isolate* isolate,
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
// Copyright (c) 2018 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_COMMON_API_CONSTRUCTOR_H_
|
||||
#define SHELL_COMMON_API_CONSTRUCTOR_H_
|
||||
|
||||
#include "native_mate/constructor.h"
|
||||
|
||||
namespace mate {
|
||||
|
||||
// Create a FunctionTemplate that can be "new"ed in JavaScript.
|
||||
// It is user's responsibility to ensure this function is called for one type
|
||||
// only ONCE in the program's whole lifetime, otherwise we would have memory
|
||||
// leak.
|
||||
template <typename T, typename Sig>
|
||||
v8::Local<v8::Function> CreateConstructor(
|
||||
v8::Isolate* isolate,
|
||||
const base::RepeatingCallback<Sig>& func) {
|
||||
#ifndef NDEBUG
|
||||
static bool called = false;
|
||||
CHECK(!called) << "CreateConstructor can only be called for one type once";
|
||||
called = true;
|
||||
#endif
|
||||
v8::Local<v8::FunctionTemplate> templ = CreateFunctionTemplate(
|
||||
isolate, base::BindRepeating(&mate::internal::InvokeNew<Sig>, func));
|
||||
templ->InstanceTemplate()->SetInternalFieldCount(1);
|
||||
T::BuildPrototype(isolate, templ);
|
||||
return templ->GetFunction(isolate->GetCurrentContext()).ToLocalChecked();
|
||||
}
|
||||
|
||||
} // namespace mate
|
||||
|
||||
#endif // SHELL_COMMON_API_CONSTRUCTOR_H_
|
|
@ -3,8 +3,8 @@
|
|||
// found in the LICENSE file.
|
||||
|
||||
#include "electron/buildflags/buildflags.h"
|
||||
#include "native_mate/dictionary.h"
|
||||
#include "printing/buildflags/buildflags.h"
|
||||
#include "shell/common/gin_helper/dictionary.h"
|
||||
#include "shell/common/node_includes.h"
|
||||
|
||||
namespace {
|
||||
|
@ -65,7 +65,7 @@ void Initialize(v8::Local<v8::Object> exports,
|
|||
v8::Local<v8::Value> unused,
|
||||
v8::Local<v8::Context> context,
|
||||
void* priv) {
|
||||
mate::Dictionary dict(context->GetIsolate(), exports);
|
||||
gin_helper::Dictionary dict(context->GetIsolate(), exports);
|
||||
dict.SetMethod("isDesktopCapturerEnabled", &IsDesktopCapturerEnabled);
|
||||
dict.SetMethod("isOffscreenRenderingEnabled", &IsOffscreenRenderingEnabled);
|
||||
dict.SetMethod("isRemoteModuleEnabled", &IsRemoteModuleEnabled);
|
||||
|
|
|
@ -22,9 +22,8 @@ struct Converter<electron::NativeWindow*> {
|
|||
}
|
||||
|
||||
electron::api::TopLevelWindow* window;
|
||||
// TODO(deermichel): remove mate:: after dropping mate
|
||||
if (!mate::Converter<electron::api::TopLevelWindow*>::FromV8(isolate, val,
|
||||
&window))
|
||||
if (!gin::Converter<electron::api::TopLevelWindow*>::FromV8(isolate, val,
|
||||
&window))
|
||||
return false;
|
||||
*out = window->window();
|
||||
return true;
|
||||
|
|
169
shell/common/gin_helper/constructor.h
Normal file
169
shell/common/gin_helper/constructor.h
Normal file
|
@ -0,0 +1,169 @@
|
|||
// Copyright (c) 2018 GitHub, Inc.
|
||||
// Use of this source code is governed by the MIT license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef SHELL_COMMON_GIN_HELPER_CONSTRUCTOR_H_
|
||||
#define SHELL_COMMON_GIN_HELPER_CONSTRUCTOR_H_
|
||||
|
||||
#include "shell/common/gin_helper/function_template.h"
|
||||
#include "shell/common/gin_helper/wrappable_base.h"
|
||||
|
||||
namespace gin_helper {
|
||||
|
||||
namespace internal {
|
||||
|
||||
// This set of templates invokes a base::Callback by converting the Arguments
|
||||
// into native types. It relies on the function_template.h to provide helper
|
||||
// templates.
|
||||
inline WrappableBase* InvokeFactory(
|
||||
gin::Arguments* args,
|
||||
const base::Callback<WrappableBase*()>& callback) {
|
||||
return callback.Run();
|
||||
}
|
||||
|
||||
template <typename P1>
|
||||
inline WrappableBase* InvokeFactory(
|
||||
gin::Arguments* args,
|
||||
const base::Callback<WrappableBase*(P1)>& callback) {
|
||||
typename CallbackParamTraits<P1>::LocalType a1;
|
||||
if (!gin_helper::GetNextArgument(args, 0, true, &a1))
|
||||
return nullptr;
|
||||
return callback.Run(a1);
|
||||
}
|
||||
|
||||
template <typename P1, typename P2>
|
||||
inline WrappableBase* InvokeFactory(
|
||||
gin::Arguments* args,
|
||||
const base::Callback<WrappableBase*(P1, P2)>& callback) {
|
||||
typename CallbackParamTraits<P1>::LocalType a1;
|
||||
typename CallbackParamTraits<P2>::LocalType a2;
|
||||
if (!gin_helper::GetNextArgument(args, 0, true, &a1) ||
|
||||
!gin_helper::GetNextArgument(args, 0, false, &a2))
|
||||
return nullptr;
|
||||
return callback.Run(a1, a2);
|
||||
}
|
||||
|
||||
template <typename P1, typename P2, typename P3>
|
||||
inline WrappableBase* InvokeFactory(
|
||||
gin::Arguments* args,
|
||||
const base::Callback<WrappableBase*(P1, P2, P3)>& callback) {
|
||||
typename CallbackParamTraits<P1>::LocalType a1;
|
||||
typename CallbackParamTraits<P2>::LocalType a2;
|
||||
typename CallbackParamTraits<P3>::LocalType a3;
|
||||
if (!gin_helper::GetNextArgument(args, 0, true, &a1) ||
|
||||
!gin_helper::GetNextArgument(args, 0, false, &a2) ||
|
||||
!gin_helper::GetNextArgument(args, 0, false, &a3))
|
||||
return nullptr;
|
||||
return callback.Run(a1, a2, a3);
|
||||
}
|
||||
|
||||
template <typename P1, typename P2, typename P3, typename P4>
|
||||
inline WrappableBase* InvokeFactory(
|
||||
gin::Arguments* args,
|
||||
const base::Callback<WrappableBase*(P1, P2, P3, P4)>& callback) {
|
||||
typename CallbackParamTraits<P1>::LocalType a1;
|
||||
typename CallbackParamTraits<P2>::LocalType a2;
|
||||
typename CallbackParamTraits<P3>::LocalType a3;
|
||||
typename CallbackParamTraits<P4>::LocalType a4;
|
||||
if (!gin_helper::GetNextArgument(args, 0, true, &a1) ||
|
||||
!gin_helper::GetNextArgument(args, 0, false, &a2) ||
|
||||
!gin_helper::GetNextArgument(args, 0, false, &a3) ||
|
||||
!gin_helper::GetNextArgument(args, 0, false, &a4))
|
||||
return nullptr;
|
||||
return callback.Run(a1, a2, a3, a4);
|
||||
}
|
||||
|
||||
template <typename P1, typename P2, typename P3, typename P4, typename P5>
|
||||
inline WrappableBase* InvokeFactory(
|
||||
gin::Arguments* args,
|
||||
const base::Callback<WrappableBase*(P1, P2, P3, P4, P5)>& callback) {
|
||||
typename CallbackParamTraits<P1>::LocalType a1;
|
||||
typename CallbackParamTraits<P2>::LocalType a2;
|
||||
typename CallbackParamTraits<P3>::LocalType a3;
|
||||
typename CallbackParamTraits<P4>::LocalType a4;
|
||||
typename CallbackParamTraits<P5>::LocalType a5;
|
||||
if (!gin_helper::GetNextArgument(args, 0, true, &a1) ||
|
||||
!gin_helper::GetNextArgument(args, 0, false, &a2) ||
|
||||
!gin_helper::GetNextArgument(args, 0, false, &a3) ||
|
||||
!gin_helper::GetNextArgument(args, 0, false, &a4) ||
|
||||
!gin_helper::GetNextArgument(args, 0, false, &a5))
|
||||
return nullptr;
|
||||
return callback.Run(a1, a2, a3, a4, a5);
|
||||
}
|
||||
|
||||
template <typename P1,
|
||||
typename P2,
|
||||
typename P3,
|
||||
typename P4,
|
||||
typename P5,
|
||||
typename P6>
|
||||
inline WrappableBase* InvokeFactory(
|
||||
gin::Arguments* args,
|
||||
const base::Callback<WrappableBase*(P1, P2, P3, P4, P5, P6)>& callback) {
|
||||
typename CallbackParamTraits<P1>::LocalType a1;
|
||||
typename CallbackParamTraits<P2>::LocalType a2;
|
||||
typename CallbackParamTraits<P3>::LocalType a3;
|
||||
typename CallbackParamTraits<P4>::LocalType a4;
|
||||
typename CallbackParamTraits<P5>::LocalType a5;
|
||||
typename CallbackParamTraits<P6>::LocalType a6;
|
||||
if (!gin_helper::GetNextArgument(args, 0, true, &a1) ||
|
||||
!gin_helper::GetNextArgument(args, 0, false, &a2) ||
|
||||
!gin_helper::GetNextArgument(args, 0, false, &a3) ||
|
||||
!gin_helper::GetNextArgument(args, 0, false, &a4) ||
|
||||
!gin_helper::GetNextArgument(args, 0, false, &a5) ||
|
||||
!gin_helper::GetNextArgument(args, 0, false, &a6))
|
||||
return nullptr;
|
||||
return callback.Run(a1, a2, a3, a4, a5, a6);
|
||||
}
|
||||
|
||||
template <typename Sig>
|
||||
void InvokeNew(const base::Callback<Sig>& factory,
|
||||
v8::Isolate* isolate,
|
||||
gin_helper::Arguments* args) {
|
||||
if (!args->IsConstructCall()) {
|
||||
args->ThrowError("Requires constructor call");
|
||||
return;
|
||||
}
|
||||
|
||||
WrappableBase* object;
|
||||
{
|
||||
// Don't continue if the constructor throws an exception.
|
||||
v8::TryCatch try_catch(isolate);
|
||||
object = internal::InvokeFactory(args, factory);
|
||||
if (try_catch.HasCaught()) {
|
||||
try_catch.ReThrow();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!object)
|
||||
args->ThrowError();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// Create a FunctionTemplate that can be "new"ed in JavaScript.
|
||||
// It is user's responsibility to ensure this function is called for one type
|
||||
// only ONCE in the program's whole lifetime, otherwise we would have memory
|
||||
// leak.
|
||||
template <typename T, typename Sig>
|
||||
v8::Local<v8::Function> CreateConstructor(
|
||||
v8::Isolate* isolate,
|
||||
const base::RepeatingCallback<Sig>& func) {
|
||||
#ifndef NDEBUG
|
||||
static bool called = false;
|
||||
CHECK(!called) << "CreateConstructor can only be called for one type once";
|
||||
called = true;
|
||||
#endif
|
||||
v8::Local<v8::FunctionTemplate> templ = CreateFunctionTemplate(
|
||||
isolate, base::BindRepeating(&internal::InvokeNew<Sig>, func));
|
||||
templ->InstanceTemplate()->SetInternalFieldCount(1);
|
||||
T::BuildPrototype(isolate, templ);
|
||||
return templ->GetFunction(isolate->GetCurrentContext()).ToLocalChecked();
|
||||
}
|
||||
|
||||
} // namespace gin_helper
|
||||
|
||||
#endif // SHELL_COMMON_GIN_HELPER_CONSTRUCTOR_H_
|
|
@ -5,7 +5,7 @@
|
|||
#include "shell/common/gin_helper/destroyable.h"
|
||||
|
||||
#include "gin/converter.h"
|
||||
#include "native_mate/wrappable_base.h"
|
||||
#include "shell/common/gin_helper/wrappable_base.h"
|
||||
|
||||
namespace gin_helper {
|
||||
|
||||
|
@ -20,8 +20,8 @@ void DestroyFunc(const v8::FunctionCallbackInfo<v8::Value>& info) {
|
|||
if (Destroyable::IsDestroyed(holder))
|
||||
return;
|
||||
|
||||
// TODO(zcbenz): mate::Wrappable will be removed.
|
||||
delete static_cast<mate::WrappableBase*>(
|
||||
// TODO(zcbenz): gin_helper::Wrappable will be removed.
|
||||
delete static_cast<gin_helper::WrappableBase*>(
|
||||
holder->GetAlignedPointerFromInternalField(0));
|
||||
holder->SetAlignedPointerInInternalField(0, nullptr);
|
||||
}
|
||||
|
|
|
@ -48,8 +48,6 @@ class Dictionary : public gin::Dictionary {
|
|||
|
||||
// Differences from the Set method in gin::Dictionary:
|
||||
// 1. It accepts arbitrary type of key.
|
||||
// 2. It forces using gin::ConvertFromV8 (would no longer be needed after
|
||||
// removing native_mate).
|
||||
template <typename K, typename V>
|
||||
bool Set(const K& key, const V& val) {
|
||||
v8::Local<v8::Value> v8_value;
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "electron/shell/common/api/api.mojom.h"
|
||||
#include "native_mate/wrappable.h"
|
||||
#include "shell/common/gin_helper/event_emitter_caller.h"
|
||||
#include "shell/common/gin_helper/wrappable.h"
|
||||
|
||||
namespace content {
|
||||
class RenderFrameHost;
|
||||
|
@ -36,9 +36,9 @@ v8::Local<v8::Object> CreateNativeEvent(
|
|||
|
||||
// Provide helperers to emit event in JavaScript.
|
||||
template <typename T>
|
||||
class EventEmitter : public mate::Wrappable<T> {
|
||||
class EventEmitter : public gin_helper::Wrappable<T> {
|
||||
public:
|
||||
using Base = mate::Wrappable<T>;
|
||||
using Base = gin_helper::Wrappable<T>;
|
||||
using ValueArray = std::vector<v8::Local<v8::Value>>;
|
||||
|
||||
// Make the convinient methods visible:
|
||||
|
|
|
@ -55,14 +55,14 @@ class TrackableObject : public TrackableObjectBase, public EventEmitter<T> {
|
|||
public:
|
||||
// Mark the JS object as destroyed.
|
||||
void MarkDestroyed() {
|
||||
v8::Local<v8::Object> wrapper = mate::Wrappable<T>::GetWrapper();
|
||||
v8::Local<v8::Object> wrapper = gin_helper::Wrappable<T>::GetWrapper();
|
||||
if (!wrapper.IsEmpty()) {
|
||||
wrapper->SetAlignedPointerInInternalField(0, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
bool IsDestroyed() {
|
||||
v8::Local<v8::Object> wrapper = mate::Wrappable<T>::GetWrapper();
|
||||
v8::Local<v8::Object> wrapper = gin_helper::Wrappable<T>::GetWrapper();
|
||||
return wrapper->InternalFieldCount() == 0 ||
|
||||
wrapper->GetAlignedPointerFromInternalField(0) == nullptr;
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ class TrackableObject : public TrackableObjectBase, public EventEmitter<T> {
|
|||
~TrackableObject() override { RemoveFromWeakMap(); }
|
||||
|
||||
void InitWith(v8::Isolate* isolate, v8::Local<v8::Object> wrapper) override {
|
||||
mate::WrappableBase::InitWith(isolate, wrapper);
|
||||
gin_helper::WrappableBase::InitWith(isolate, wrapper);
|
||||
if (!weak_map_) {
|
||||
weak_map_ = new electron::KeyWeakMap<int32_t>;
|
||||
}
|
||||
|
|
89
shell/common/gin_helper/wrappable.cc
Normal file
89
shell/common/gin_helper/wrappable.cc
Normal file
|
@ -0,0 +1,89 @@
|
|||
// Copyright 2013 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.chromium file.
|
||||
|
||||
#include "shell/common/gin_helper/wrappable.h"
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "shell/common/gin_helper/dictionary.h"
|
||||
|
||||
namespace gin_helper {
|
||||
|
||||
WrappableBase::WrappableBase() = default;
|
||||
|
||||
WrappableBase::~WrappableBase() {
|
||||
if (wrapper_.IsEmpty())
|
||||
return;
|
||||
|
||||
GetWrapper()->SetAlignedPointerInInternalField(0, nullptr);
|
||||
wrapper_.ClearWeak();
|
||||
wrapper_.Reset();
|
||||
}
|
||||
|
||||
v8::Local<v8::Object> WrappableBase::GetWrapper() const {
|
||||
if (!wrapper_.IsEmpty())
|
||||
return v8::Local<v8::Object>::New(isolate_, wrapper_);
|
||||
else
|
||||
return v8::Local<v8::Object>();
|
||||
}
|
||||
|
||||
v8::MaybeLocal<v8::Object> WrappableBase::GetWrapper(
|
||||
v8::Isolate* isolate) const {
|
||||
if (!wrapper_.IsEmpty())
|
||||
return v8::MaybeLocal<v8::Object>(
|
||||
v8::Local<v8::Object>::New(isolate, wrapper_));
|
||||
else
|
||||
return v8::MaybeLocal<v8::Object>();
|
||||
}
|
||||
|
||||
void WrappableBase::InitWithArgs(gin::Arguments* args) {
|
||||
v8::Local<v8::Object> holder;
|
||||
args->GetHolder(&holder);
|
||||
InitWith(args->isolate(), holder);
|
||||
}
|
||||
|
||||
void WrappableBase::InitWith(v8::Isolate* isolate,
|
||||
v8::Local<v8::Object> wrapper) {
|
||||
CHECK(wrapper_.IsEmpty());
|
||||
isolate_ = isolate;
|
||||
wrapper->SetAlignedPointerInInternalField(0, this);
|
||||
wrapper_.Reset(isolate, wrapper);
|
||||
wrapper_.SetWeak(this, FirstWeakCallback, v8::WeakCallbackType::kParameter);
|
||||
|
||||
// Call object._init if we have one.
|
||||
v8::Local<v8::Function> init;
|
||||
if (Dictionary(isolate, wrapper).Get("_init", &init))
|
||||
init->Call(isolate->GetCurrentContext(), wrapper, 0, nullptr).IsEmpty();
|
||||
|
||||
AfterInit(isolate);
|
||||
}
|
||||
|
||||
// static
|
||||
void WrappableBase::FirstWeakCallback(
|
||||
const v8::WeakCallbackInfo<WrappableBase>& data) {
|
||||
WrappableBase* wrappable = data.GetParameter();
|
||||
wrappable->wrapper_.Reset();
|
||||
data.SetSecondPassCallback(SecondWeakCallback);
|
||||
}
|
||||
|
||||
// static
|
||||
void WrappableBase::SecondWeakCallback(
|
||||
const v8::WeakCallbackInfo<WrappableBase>& data) {
|
||||
WrappableBase* wrappable = data.GetParameter();
|
||||
delete wrappable;
|
||||
}
|
||||
|
||||
namespace internal {
|
||||
|
||||
void* FromV8Impl(v8::Isolate* isolate, v8::Local<v8::Value> val) {
|
||||
if (!val->IsObject())
|
||||
return nullptr;
|
||||
v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast(val);
|
||||
if (obj->InternalFieldCount() != 1)
|
||||
return nullptr;
|
||||
return obj->GetAlignedPointerFromInternalField(0);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
} // namespace gin_helper
|
103
shell/common/gin_helper/wrappable.h
Normal file
103
shell/common/gin_helper/wrappable.h
Normal file
|
@ -0,0 +1,103 @@
|
|||
// Copyright 2013 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.chromium file.
|
||||
|
||||
#ifndef SHELL_COMMON_GIN_HELPER_WRAPPABLE_H_
|
||||
#define SHELL_COMMON_GIN_HELPER_WRAPPABLE_H_
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "gin/per_isolate_data.h"
|
||||
#include "shell/common/gin_helper/constructor.h"
|
||||
|
||||
namespace gin_helper {
|
||||
|
||||
namespace internal {
|
||||
|
||||
void* FromV8Impl(v8::Isolate* isolate, v8::Local<v8::Value> val);
|
||||
|
||||
} // namespace internal
|
||||
|
||||
template <typename T>
|
||||
class Wrappable : public WrappableBase {
|
||||
public:
|
||||
Wrappable() = default;
|
||||
|
||||
template <typename Sig>
|
||||
static void SetConstructor(v8::Isolate* isolate,
|
||||
const base::Callback<Sig>& constructor) {
|
||||
v8::Local<v8::FunctionTemplate> templ = CreateFunctionTemplate(
|
||||
isolate, base::Bind(&internal::InvokeNew<Sig>, constructor));
|
||||
templ->InstanceTemplate()->SetInternalFieldCount(1);
|
||||
T::BuildPrototype(isolate, templ);
|
||||
gin::PerIsolateData::From(isolate)->SetFunctionTemplate(&kWrapperInfo,
|
||||
templ);
|
||||
}
|
||||
|
||||
static v8::Local<v8::FunctionTemplate> GetConstructor(v8::Isolate* isolate) {
|
||||
// Fill the object template.
|
||||
auto* data = gin::PerIsolateData::From(isolate);
|
||||
auto templ = data->GetFunctionTemplate(&kWrapperInfo);
|
||||
if (templ.IsEmpty()) {
|
||||
templ = v8::FunctionTemplate::New(isolate);
|
||||
templ->InstanceTemplate()->SetInternalFieldCount(1);
|
||||
T::BuildPrototype(isolate, templ);
|
||||
data->SetFunctionTemplate(&kWrapperInfo, templ);
|
||||
}
|
||||
return templ;
|
||||
}
|
||||
|
||||
protected:
|
||||
// Init the class with T::BuildPrototype.
|
||||
void Init(v8::Isolate* isolate) {
|
||||
v8::Local<v8::FunctionTemplate> templ = GetConstructor(isolate);
|
||||
|
||||
// |wrapper| may be empty in some extreme cases, e.g., when
|
||||
// Object.prototype.constructor is overwritten.
|
||||
v8::Local<v8::Object> wrapper;
|
||||
if (!templ->InstanceTemplate()
|
||||
->NewInstance(isolate->GetCurrentContext())
|
||||
.ToLocal(&wrapper)) {
|
||||
// The current wrappable object will be no longer managed by V8. Delete
|
||||
// this now.
|
||||
delete this;
|
||||
return;
|
||||
}
|
||||
InitWith(isolate, wrapper);
|
||||
}
|
||||
|
||||
private:
|
||||
static gin::WrapperInfo kWrapperInfo;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Wrappable);
|
||||
};
|
||||
|
||||
// static
|
||||
template <typename T>
|
||||
gin::WrapperInfo Wrappable<T>::kWrapperInfo = {gin::kEmbedderNativeGin};
|
||||
|
||||
} // namespace gin_helper
|
||||
|
||||
namespace gin {
|
||||
|
||||
template <typename T>
|
||||
struct Converter<
|
||||
T*,
|
||||
typename std::enable_if<
|
||||
std::is_convertible<T*, gin_helper::WrappableBase*>::value>::type> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate, T* val) {
|
||||
if (val)
|
||||
return val->GetWrapper();
|
||||
else
|
||||
return v8::Null(isolate);
|
||||
}
|
||||
|
||||
static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val, T** out) {
|
||||
*out = static_cast<T*>(static_cast<gin_helper::WrappableBase*>(
|
||||
gin_helper::internal::FromV8Impl(isolate, val)));
|
||||
return *out != nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace gin
|
||||
|
||||
#endif // SHELL_COMMON_GIN_HELPER_WRAPPABLE_H_
|
69
shell/common/gin_helper/wrappable_base.h
Normal file
69
shell/common/gin_helper/wrappable_base.h
Normal file
|
@ -0,0 +1,69 @@
|
|||
// Copyright 2013 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.chromium file.
|
||||
|
||||
#ifndef SHELL_COMMON_GIN_HELPER_WRAPPABLE_BASE_H_
|
||||
#define SHELL_COMMON_GIN_HELPER_WRAPPABLE_BASE_H_
|
||||
|
||||
#include "v8/include/v8.h"
|
||||
|
||||
namespace gin {
|
||||
class Arguments;
|
||||
} // namespace gin
|
||||
|
||||
namespace gin_helper {
|
||||
|
||||
// Wrappable is a base class for C++ objects that have corresponding v8 wrapper
|
||||
// objects. To retain a Wrappable object on the stack, use a gin::Handle.
|
||||
//
|
||||
// USAGE:
|
||||
// // my_class.h
|
||||
// class MyClass : Wrappable<MyClass> {
|
||||
// public:
|
||||
// ...
|
||||
// };
|
||||
//
|
||||
// Subclasses should also typically have private constructors and expose a
|
||||
// static Create function that returns a gin::Handle. Forcing creators through
|
||||
// this static Create function will enforce that clients actually create a
|
||||
// wrapper for the object. If clients fail to create a wrapper for a wrappable
|
||||
// object, the object will leak because we use the weak callback from the
|
||||
// wrapper as the signal to delete the wrapped object.
|
||||
class WrappableBase {
|
||||
public:
|
||||
WrappableBase();
|
||||
virtual ~WrappableBase();
|
||||
|
||||
// Retrieve the v8 wrapper object cooresponding to this object.
|
||||
v8::Local<v8::Object> GetWrapper() const;
|
||||
v8::MaybeLocal<v8::Object> GetWrapper(v8::Isolate* isolate) const;
|
||||
|
||||
// Returns the Isolate this object is created in.
|
||||
v8::Isolate* isolate() const { return isolate_; }
|
||||
|
||||
protected:
|
||||
// Called after the "_init" method gets called in JavaScript.
|
||||
virtual void AfterInit(v8::Isolate* isolate) {}
|
||||
|
||||
// Bind the C++ class to the JS wrapper.
|
||||
// This method should only be called by classes using Constructor.
|
||||
virtual void InitWith(v8::Isolate* isolate, v8::Local<v8::Object> wrapper);
|
||||
|
||||
// Helper to init with arguments.
|
||||
void InitWithArgs(gin::Arguments* args);
|
||||
|
||||
private:
|
||||
static void FirstWeakCallback(
|
||||
const v8::WeakCallbackInfo<WrappableBase>& data);
|
||||
static void SecondWeakCallback(
|
||||
const v8::WeakCallbackInfo<WrappableBase>& data);
|
||||
|
||||
v8::Isolate* isolate_ = nullptr;
|
||||
v8::Global<v8::Object> wrapper_; // Weak
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(WrappableBase);
|
||||
};
|
||||
|
||||
} // namespace gin_helper
|
||||
|
||||
#endif // SHELL_COMMON_GIN_HELPER_WRAPPABLE_BASE_H_
|
Loading…
Add table
Add a link
Reference in a new issue