Browse Source

chore: remove native_mate (Part 1) (#20085)

* move Destroyable utilities out of native_mate

* do not set "destroy" in ObjectTemplateBuilder

* remove ObjectTemplateBuilder::MakeDestroyable

* do not pollute gin namespace

* add more comments

* remove hack of Arguments
Cheng Zhao 5 years ago
parent
commit
b601f3a031

+ 2 - 0
filenames.gni

@@ -489,6 +489,8 @@ filenames = {
     "shell/common/gin_converters/net_converter.h",
     "shell/common/gin_converters/std_converter.h",
     "shell/common/gin_converters/value_converter_gin_adapter.h",
+    "shell/common/gin_helper/destroyable.cc",
+    "shell/common/gin_helper/destroyable.h",
     "shell/common/gin_util.h",
     "shell/common/heap_snapshot.cc",
     "shell/common/heap_snapshot.h",

+ 2 - 18
native_mate/native_mate/function_template.h

@@ -6,6 +6,7 @@
 #define NATIVE_MATE_NATIVE_MATE_FUNCTION_TEMPLATE_H_
 
 #include "../shell/common/error_util.h"
+#include "../shell/common/gin_helper/destroyable.h"
 #include "base/callback.h"
 #include "base/logging.h"
 #include "native_mate/arguments.h"
@@ -20,23 +21,6 @@ enum CreateFunctionTemplateFlags {
 
 namespace internal {
 
-struct Destroyable {
-  static void Destroy(Arguments* args) {
-    if (IsDestroyed(args))
-      return;
-
-    v8::Local<v8::Object> holder = args->GetHolder();
-    delete static_cast<WrappableBase*>(
-        holder->GetAlignedPointerFromInternalField(0));
-    holder->SetAlignedPointerInInternalField(0, nullptr);
-  }
-  static bool IsDestroyed(Arguments* args) {
-    v8::Local<v8::Object> holder = args->GetHolder();
-    return holder->InternalFieldCount() == 0 ||
-           holder->GetAlignedPointerFromInternalField(0) == nullptr;
-  }
-};
-
 template <typename T>
 struct CallbackParamTraits {
   typedef T LocalType;
@@ -166,7 +150,7 @@ struct ArgumentHolder {
 
   ArgumentHolder(Arguments* args, int create_flags) {
     if (index == 0 && (create_flags & HolderIsFirstArgument) &&
-        Destroyable::IsDestroyed(args)) {
+        gin_helper::Destroyable::IsDestroyed(args->GetHolder())) {
       args->ThrowError("Object has been destroyed");
       return;
     }

+ 0 - 6
native_mate/native_mate/object_template_builder.cc

@@ -28,12 +28,6 @@ ObjectTemplateBuilder& ObjectTemplateBuilder::SetPropertyImpl(
   return *this;
 }
 
-ObjectTemplateBuilder& ObjectTemplateBuilder::MakeDestroyable() {
-  SetMethod("destroy", base::Bind(internal::Destroyable::Destroy));
-  SetMethod("isDestroyed", base::Bind(internal::Destroyable::IsDestroyed));
-  return *this;
-}
-
 v8::Local<v8::ObjectTemplate> ObjectTemplateBuilder::Build() {
   v8::Local<v8::ObjectTemplate> result = template_;
   template_.Clear();

+ 0 - 3
native_mate/native_mate/object_template_builder.h

@@ -99,9 +99,6 @@ class ObjectTemplateBuilder {
                            CallbackTraits<U>::CreateTemplate(isolate_, setter));
   }
 
-  // Add "destroy" and "isDestroyed" methods.
-  ObjectTemplateBuilder& MakeDestroyable();
-
   v8::Local<v8::ObjectTemplate> Build();
 
  private:

+ 4 - 4
native_mate/native_mate/wrappable_base.h

@@ -5,12 +5,12 @@
 #ifndef NATIVE_MATE_NATIVE_MATE_WRAPPABLE_BASE_H_
 #define NATIVE_MATE_NATIVE_MATE_WRAPPABLE_BASE_H_
 
-namespace mate {
-
-namespace internal {
+namespace gin {
 struct Destroyable;
 }
 
+namespace mate {
+
 // 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.
 //
@@ -48,7 +48,7 @@ class WrappableBase {
   virtual void InitWith(v8::Isolate* isolate, v8::Local<v8::Object> wrapper);
 
  private:
-  friend struct internal::Destroyable;
+  friend struct gin::Destroyable;
 
   static void FirstWeakCallback(
       const v8::WeakCallbackInfo<WrappableBase>& data);

+ 1 - 1
shell/browser/api/atom_api_browser_view.cc

@@ -140,8 +140,8 @@ v8::Local<v8::Value> BrowserView::GetWebContents() {
 void BrowserView::BuildPrototype(v8::Isolate* isolate,
                                  v8::Local<v8::FunctionTemplate> prototype) {
   prototype->SetClassName(mate::StringToV8(isolate, "BrowserView"));
+  gin_helper::Destroyable::MakeDestroyable(isolate, prototype);
   mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
-      .MakeDestroyable()
       .SetMethod("setAutoResize", &BrowserView::SetAutoResize)
       .SetMethod("setBounds", &BrowserView::SetBounds)
       .SetMethod("getBounds", &BrowserView::GetBounds)

+ 1 - 1
shell/browser/api/atom_api_download_item.cc

@@ -190,8 +190,8 @@ double DownloadItem::GetStartTime() const {
 void DownloadItem::BuildPrototype(v8::Isolate* isolate,
                                   v8::Local<v8::FunctionTemplate> prototype) {
   prototype->SetClassName(mate::StringToV8(isolate, "DownloadItem"));
+  gin_helper::Destroyable::MakeDestroyable(isolate, prototype);
   mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
-      .MakeDestroyable()
       .SetMethod("pause", &DownloadItem::Pause)
       .SetMethod("isPaused", &DownloadItem::IsPaused)
       .SetMethod("resume", &DownloadItem::Resume)

+ 1 - 1
shell/browser/api/atom_api_menu.cc

@@ -222,8 +222,8 @@ void Menu::OnMenuWillShow() {
 void Menu::BuildPrototype(v8::Isolate* isolate,
                           v8::Local<v8::FunctionTemplate> prototype) {
   prototype->SetClassName(mate::StringToV8(isolate, "Menu"));
+  gin_helper::Destroyable::MakeDestroyable(isolate, prototype);
   mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
-      .MakeDestroyable()
       .SetMethod("insertItem", &Menu::InsertItemAt)
       .SetMethod("insertCheckItem", &Menu::InsertCheckItemAt)
       .SetMethod("insertRadioItem", &Menu::InsertRadioItemAt)

+ 1 - 1
shell/browser/api/atom_api_notification.cc

@@ -225,8 +225,8 @@ bool Notification::IsSupported() {
 void Notification::BuildPrototype(v8::Isolate* isolate,
                                   v8::Local<v8::FunctionTemplate> prototype) {
   prototype->SetClassName(mate::StringToV8(isolate, "Notification"));
+  gin_helper::Destroyable::MakeDestroyable(isolate, prototype);
   mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
-      .MakeDestroyable()
       .SetMethod("show", &Notification::Show)
       .SetMethod("close", &Notification::Close)
       .SetProperty("title", &Notification::GetTitle, &Notification::SetTitle)

+ 1 - 2
shell/browser/api/atom_api_power_monitor.cc

@@ -115,9 +115,8 @@ v8::Local<v8::Value> PowerMonitor::Create(v8::Isolate* isolate) {
 void PowerMonitor::BuildPrototype(v8::Isolate* isolate,
                                   v8::Local<v8::FunctionTemplate> prototype) {
   prototype->SetClassName(mate::StringToV8(isolate, "PowerMonitor"));
-
+  gin_helper::Destroyable::MakeDestroyable(isolate, prototype);
   mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
-      .MakeDestroyable()
 #if defined(OS_LINUX)
       .SetMethod("blockShutdown", &PowerMonitor::BlockShutdown)
       .SetMethod("unblockShutdown", &PowerMonitor::UnblockShutdown)

+ 1 - 1
shell/browser/api/atom_api_session.cc

@@ -682,8 +682,8 @@ mate::Handle<Session> Session::FromPartition(
 void Session::BuildPrototype(v8::Isolate* isolate,
                              v8::Local<v8::FunctionTemplate> prototype) {
   prototype->SetClassName(mate::StringToV8(isolate, "Session"));
+  gin_helper::Destroyable::MakeDestroyable(isolate, prototype);
   mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
-      .MakeDestroyable()
       .SetMethod("resolveProxy", &Session::ResolveProxy)
       .SetMethod("getCacheSize", &Session::GetCacheSize)
       .SetMethod("clearCache", &Session::ClearCache)

+ 1 - 1
shell/browser/api/atom_api_top_level_window.cc

@@ -1064,8 +1064,8 @@ mate::WrappableBase* TopLevelWindow::New(mate::Arguments* args) {
 void TopLevelWindow::BuildPrototype(v8::Isolate* isolate,
                                     v8::Local<v8::FunctionTemplate> prototype) {
   prototype->SetClassName(mate::StringToV8(isolate, "TopLevelWindow"));
+  gin_helper::Destroyable::MakeDestroyable(isolate, prototype);
   mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
-      .MakeDestroyable()
       .SetMethod("setContentView", &TopLevelWindow::SetContentView)
       .SetMethod("close", &TopLevelWindow::Close)
       .SetMethod("focus", &TopLevelWindow::Focus)

+ 1 - 1
shell/browser/api/atom_api_tray.cc

@@ -246,8 +246,8 @@ gfx::Rect Tray::GetBounds() {
 void Tray::BuildPrototype(v8::Isolate* isolate,
                           v8::Local<v8::FunctionTemplate> prototype) {
   prototype->SetClassName(mate::StringToV8(isolate, "Tray"));
+  gin_helper::Destroyable::MakeDestroyable(isolate, prototype);
   mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
-      .MakeDestroyable()
       .SetMethod("setImage", &Tray::SetImage)
       .SetMethod("setPressedImage", &Tray::SetPressedImage)
       .SetMethod("setToolTip", &Tray::SetToolTip)

+ 1 - 1
shell/browser/api/atom_api_url_request_ns.cc

@@ -520,8 +520,8 @@ mate::WrappableBase* URLRequestNS::New(mate::Arguments* args) {
 void URLRequestNS::BuildPrototype(v8::Isolate* isolate,
                                   v8::Local<v8::FunctionTemplate> prototype) {
   prototype->SetClassName(mate::StringToV8(isolate, "URLRequest"));
+  gin_helper::Destroyable::MakeDestroyable(isolate, prototype);
   mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
-      .MakeDestroyable()
       .SetMethod("write", &URLRequestNS::Write)
       .SetMethod("cancel", &URLRequestNS::Cancel)
       .SetMethod("setExtraHeader", &URLRequestNS::SetExtraHeader)

+ 1 - 1
shell/browser/api/atom_api_web_contents.cc

@@ -2381,8 +2381,8 @@ v8::Local<v8::Promise> WebContents::TakeHeapSnapshot(
 void WebContents::BuildPrototype(v8::Isolate* isolate,
                                  v8::Local<v8::FunctionTemplate> prototype) {
   prototype->SetClassName(mate::StringToV8(isolate, "WebContents"));
+  gin_helper::Destroyable::MakeDestroyable(isolate, prototype);
   mate::ObjectTemplateBuilder(isolate, prototype->PrototypeTemplate())
-      .MakeDestroyable()
       .SetMethod("setBackgroundThrottling",
                  &WebContents::SetBackgroundThrottling)
       .SetMethod("getProcessId", &WebContents::GetProcessID)

+ 66 - 0
shell/common/gin_helper/destroyable.cc

@@ -0,0 +1,66 @@
+// Copyright (c) 2019 GitHub, Inc.
+// Use of this source code is governed by the MIT license that can be
+// found in the LICENSE file.
+
+#include "shell/common/gin_helper/destroyable.h"
+
+#include "gin/converter.h"
+#include "native_mate/wrappable_base.h"
+
+namespace gin_helper {
+
+namespace {
+
+// Cached function templates, leaked on exit. (They are leaked in V8 anyway.)
+v8::Global<v8::FunctionTemplate> g_destroy_func;
+v8::Global<v8::FunctionTemplate> g_is_destroyed_func;
+
+void DestroyFunc(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  v8::Local<v8::Object> holder = info.Holder();
+  if (Destroyable::IsDestroyed(holder))
+    return;
+
+  // TODO(zcbenz): mate::Wrappable will be removed.
+  delete static_cast<mate::WrappableBase*>(
+      holder->GetAlignedPointerFromInternalField(0));
+  holder->SetAlignedPointerInInternalField(0, nullptr);
+}
+
+void IsDestroyedFunc(const v8::FunctionCallbackInfo<v8::Value>& info) {
+  info.GetReturnValue().Set(gin::ConvertToV8(
+      info.GetIsolate(), Destroyable::IsDestroyed(info.Holder())));
+}
+
+}  // namespace
+
+// static
+bool Destroyable::IsDestroyed(v8::Local<v8::Object> object) {
+  // An object is considered destroyed if it has no internal pointer or its
+  // internal has been destroyed.
+  return object->InternalFieldCount() == 0 ||
+         object->GetAlignedPointerFromInternalField(0) == nullptr;
+}
+
+// static
+void Destroyable::MakeDestroyable(v8::Isolate* isolate,
+                                  v8::Local<v8::FunctionTemplate> prototype) {
+  // Cache the FunctionTemplate of "destroy" and "isDestroyed".
+  if (g_destroy_func.IsEmpty()) {
+    auto templ = v8::FunctionTemplate::New(isolate, DestroyFunc);
+    templ->RemovePrototype();
+    g_destroy_func.Reset(isolate, templ);
+    templ = v8::FunctionTemplate::New(isolate, IsDestroyedFunc);
+    templ->RemovePrototype();
+    g_is_destroyed_func.Reset(isolate, templ);
+  }
+
+  auto proto_templ = prototype->PrototypeTemplate();
+  proto_templ->Set(
+      gin::StringToSymbol(isolate, "destroy"),
+      v8::Local<v8::FunctionTemplate>::New(isolate, g_destroy_func));
+  proto_templ->Set(
+      gin::StringToSymbol(isolate, "isDestroyed"),
+      v8::Local<v8::FunctionTemplate>::New(isolate, g_is_destroyed_func));
+}
+
+}  // namespace gin_helper

+ 24 - 0
shell/common/gin_helper/destroyable.h

@@ -0,0 +1,24 @@
+// Copyright (c) 2019 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_DESTROYABLE_H_
+#define SHELL_COMMON_GIN_HELPER_DESTROYABLE_H_
+
+#include "v8/include/v8.h"
+
+namespace gin_helper {
+
+// Manage the native object wrapped in JS wrappers.
+struct Destroyable {
+  // Determine whether the native object has been destroyed.
+  static bool IsDestroyed(v8::Local<v8::Object> object);
+
+  // Add "destroy" and "isDestroyed" to prototype chain.
+  static void MakeDestroyable(v8::Isolate* isolate,
+                              v8::Local<v8::FunctionTemplate> prototype);
+};
+
+}  // namespace gin_helper
+
+#endif  // SHELL_COMMON_GIN_HELPER_DESTROYABLE_H_