diff --git a/filenames.gni b/filenames.gni index 249064a7d216..da606270fef7 100644 --- a/filenames.gni +++ b/filenames.gni @@ -437,7 +437,6 @@ filenames = { "shell/common/api/event_emitter_caller.cc", "shell/common/api/event_emitter_caller.h", "shell/common/api/features.cc", - "shell/common/api/gin_utils.h", "shell/common/api/locker.cc", "shell/common/api/locker.h", "shell/common/api/object_life_monitor.cc", @@ -475,7 +474,7 @@ filenames = { "shell/common/crash_reporter/linux/crash_dump_handler.h", "shell/common/crash_reporter/win/crash_service_main.cc", "shell/common/crash_reporter/win/crash_service_main.h", - "shell/common/gin_converters/callback_converter_gin_adapter.h", + "shell/common/gin_converters/callback_converter.h", "shell/common/gin_converters/file_dialog_converter.cc", "shell/common/gin_converters/file_dialog_converter.h", "shell/common/gin_converters/file_path_converter.h", @@ -489,9 +488,13 @@ 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/callback.cc", + "shell/common/gin_helper/callback.h", "shell/common/gin_helper/destroyable.cc", "shell/common/gin_helper/destroyable.h", - "shell/common/gin_util.h", + "shell/common/gin_helper/dictionary.h", + "shell/common/gin_helper/function_template.cc", + "shell/common/gin_helper/function_template.h", "shell/common/heap_snapshot.cc", "shell/common/heap_snapshot.h", "shell/common/key_weak_map.h", @@ -509,8 +512,8 @@ filenames = { "shell/common/native_mate_converters/accelerator_converter.h", "shell/common/native_mate_converters/blink_converter.cc", "shell/common/native_mate_converters/blink_converter.h", - "shell/common/native_mate_converters/callback.cc", - "shell/common/native_mate_converters/callback.h", + "shell/common/native_mate_converters/callback_converter_deprecated.cc", + "shell/common/native_mate_converters/callback_converter_deprecated.h", "shell/common/native_mate_converters/content_converter.cc", "shell/common/native_mate_converters/content_converter.h", "shell/common/native_mate_converters/file_dialog_converter.h", diff --git a/native_mate/native_mate/arguments.h b/native_mate/native_mate/arguments.h index e6eb278481c6..d646049b2a34 100644 --- a/native_mate/native_mate/arguments.h +++ b/native_mate/native_mate/arguments.h @@ -12,6 +12,10 @@ #include "base/optional.h" #include "native_mate/converter.h" +// =============================== NOTICE =============================== +// Do not add code here, native_mate is being removed. Any new code +// should use gin instead. + namespace mate { // Arguments is a wrapper around v8::FunctionCallbackInfo that integrates diff --git a/native_mate/native_mate/function_template.h b/native_mate/native_mate/function_template.h index ec3f4943f43c..1ee65f3a8342 100644 --- a/native_mate/native_mate/function_template.h +++ b/native_mate/native_mate/function_template.h @@ -13,6 +13,10 @@ #include "native_mate/wrappable_base.h" #include "v8/include/v8.h" +// =============================== NOTICE =============================== +// Do not add code here, native_mate is being removed. Any new code +// should use gin instead. + namespace mate { enum CreateFunctionTemplateFlags { diff --git a/shell/browser/api/atom_api_app.cc b/shell/browser/api/atom_api_app.cc index a9661b3dc0cf..d9e898c4897b 100644 --- a/shell/browser/api/atom_api_app.cc +++ b/shell/browser/api/atom_api_app.cc @@ -42,7 +42,7 @@ #include "shell/browser/relauncher.h" #include "shell/common/application_info.h" #include "shell/common/atom_command_line.h" -#include "shell/common/native_mate_converters/callback.h" +#include "shell/common/native_mate_converters/callback_converter_deprecated.h" #include "shell/common/native_mate_converters/file_path_converter.h" #include "shell/common/native_mate_converters/gurl_converter.h" #include "shell/common/native_mate_converters/image_converter.h" diff --git a/shell/browser/api/atom_api_app.h b/shell/browser/api/atom_api_app.h index ae4ab5fc0e1f..1e0ce0a9498c 100644 --- a/shell/browser/api/atom_api_app.h +++ b/shell/browser/api/atom_api_app.h @@ -28,7 +28,7 @@ #include "shell/browser/browser.h" #include "shell/browser/browser_observer.h" #include "shell/common/error_util.h" -#include "shell/common/native_mate_converters/callback.h" +#include "shell/common/native_mate_converters/callback_converter_deprecated.h" #include "shell/common/promise_util.h" #if defined(USE_NSS_CERTS) diff --git a/shell/browser/api/atom_api_auto_updater.cc b/shell/browser/api/atom_api_auto_updater.cc index 9a0a4ab21da2..c9a9b6e9133c 100644 --- a/shell/browser/api/atom_api_auto_updater.cc +++ b/shell/browser/api/atom_api_auto_updater.cc @@ -11,7 +11,7 @@ #include "shell/browser/native_window.h" #include "shell/browser/window_list.h" #include "shell/common/api/event_emitter_caller.h" -#include "shell/common/native_mate_converters/callback.h" +#include "shell/common/native_mate_converters/callback_converter_deprecated.h" #include "shell/common/node_includes.h" namespace mate { diff --git a/shell/browser/api/atom_api_browser_window.cc b/shell/browser/api/atom_api_browser_window.cc index ca54a90928a5..12abb7320891 100644 --- a/shell/browser/api/atom_api_browser_window.cc +++ b/shell/browser/api/atom_api_browser_window.cc @@ -19,7 +19,7 @@ #include "shell/browser/window_list.h" #include "shell/common/api/constructor.h" #include "shell/common/color_util.h" -#include "shell/common/native_mate_converters/callback.h" +#include "shell/common/native_mate_converters/callback_converter_deprecated.h" #include "shell/common/native_mate_converters/value_converter.h" #include "shell/common/node_includes.h" #include "shell/common/options_switches.h" diff --git a/shell/browser/api/atom_api_content_tracing.cc b/shell/browser/api/atom_api_content_tracing.cc index b2c3ffef2161..537228b5f347 100644 --- a/shell/browser/api/atom_api_content_tracing.cc +++ b/shell/browser/api/atom_api_content_tracing.cc @@ -12,7 +12,7 @@ #include "base/threading/thread_restrictions.h" #include "content/public/browser/tracing_controller.h" #include "native_mate/dictionary.h" -#include "shell/common/native_mate_converters/callback.h" +#include "shell/common/native_mate_converters/callback_converter_deprecated.h" #include "shell/common/native_mate_converters/file_path_converter.h" #include "shell/common/native_mate_converters/value_converter.h" #include "shell/common/node_includes.h" diff --git a/shell/browser/api/atom_api_cookies.cc b/shell/browser/api/atom_api_cookies.cc index f05d00e4486f..1108f479a3cd 100644 --- a/shell/browser/api/atom_api_cookies.cc +++ b/shell/browser/api/atom_api_cookies.cc @@ -20,7 +20,7 @@ #include "net/cookies/cookie_util.h" #include "shell/browser/atom_browser_context.h" #include "shell/browser/cookie_change_notifier.h" -#include "shell/common/native_mate_converters/callback.h" +#include "shell/common/native_mate_converters/callback_converter_deprecated.h" #include "shell/common/native_mate_converters/gurl_converter.h" #include "shell/common/native_mate_converters/value_converter.h" diff --git a/shell/browser/api/atom_api_debugger.cc b/shell/browser/api/atom_api_debugger.cc index cd612329ee99..e50b6a342360 100644 --- a/shell/browser/api/atom_api_debugger.cc +++ b/shell/browser/api/atom_api_debugger.cc @@ -13,7 +13,7 @@ #include "content/public/browser/devtools_agent_host.h" #include "content/public/browser/web_contents.h" #include "native_mate/dictionary.h" -#include "shell/common/native_mate_converters/callback.h" +#include "shell/common/native_mate_converters/callback_converter_deprecated.h" #include "shell/common/native_mate_converters/value_converter.h" #include "shell/common/node_includes.h" diff --git a/shell/browser/api/atom_api_dialog.cc b/shell/browser/api/atom_api_dialog.cc index ee8c668639d7..9575b0353921 100644 --- a/shell/browser/api/atom_api_dialog.cc +++ b/shell/browser/api/atom_api_dialog.cc @@ -6,15 +6,15 @@ #include #include -#include "gin/dictionary.h" #include "shell/browser/ui/certificate_trust.h" #include "shell/browser/ui/file_dialog.h" #include "shell/browser/ui/message_box.h" -#include "shell/common/api/gin_utils.h" +#include "shell/common/gin_converters/callback_converter.h" #include "shell/common/gin_converters/file_dialog_converter.h" #include "shell/common/gin_converters/message_box_converter.h" #include "shell/common/gin_converters/native_window_converter.h" #include "shell/common/gin_converters/net_converter.h" +#include "shell/common/gin_helper/dictionary.h" #include "shell/common/node_includes.h" #include "shell/common/promise_util.h" @@ -87,33 +87,17 @@ void Initialize(v8::Local exports, v8::Local context, void* priv) { v8::Isolate* isolate = context->GetIsolate(); - gin::Dictionary dict(isolate, exports); - dict.Set("showMessageBoxSync", - gin::ConvertCallbackToV8Leaked( - isolate, base::BindRepeating(&ShowMessageBoxSync))); - dict.Set("showMessageBox", - gin::ConvertCallbackToV8Leaked( - isolate, base::BindRepeating(&ShowMessageBox))); - dict.Set("showErrorBox", - gin::ConvertCallbackToV8Leaked( - isolate, base::BindRepeating(&electron::ShowErrorBox))); - dict.Set("showOpenDialogSync", - gin::ConvertCallbackToV8Leaked( - isolate, base::BindRepeating(&ShowOpenDialogSync))); - dict.Set("showOpenDialog", - gin::ConvertCallbackToV8Leaked( - isolate, base::BindRepeating(&ShowOpenDialog))); - dict.Set("showSaveDialogSync", - gin::ConvertCallbackToV8Leaked( - isolate, base::BindRepeating(&ShowSaveDialogSync))); - dict.Set("showSaveDialog", - gin::ConvertCallbackToV8Leaked( - isolate, base::BindRepeating(&ShowSaveDialog))); + gin_helper::Dictionary dict(isolate, exports); + dict.SetMethod("showMessageBoxSync", &ShowMessageBoxSync); + dict.SetMethod("showMessageBox", &ShowMessageBox); + dict.SetMethod("showErrorBox", &electron::ShowErrorBox); + dict.SetMethod("showOpenDialogSync", &ShowOpenDialogSync); + dict.SetMethod("showOpenDialog", &ShowOpenDialog); + dict.SetMethod("showSaveDialogSync", &ShowSaveDialogSync); + dict.SetMethod("showSaveDialog", &ShowSaveDialog); #if defined(OS_MACOSX) || defined(OS_WIN) - dict.Set("showCertificateTrustDialog", - gin::ConvertCallbackToV8Leaked( - isolate, - base::BindRepeating(&certificate_trust::ShowCertificateTrust))); + dict.SetMethod("showCertificateTrustDialog", + &certificate_trust::ShowCertificateTrust); #endif } diff --git a/shell/browser/api/atom_api_download_item.cc b/shell/browser/api/atom_api_download_item.cc index b16d97a848b8..825927e7d00e 100644 --- a/shell/browser/api/atom_api_download_item.cc +++ b/shell/browser/api/atom_api_download_item.cc @@ -11,7 +11,7 @@ #include "native_mate/dictionary.h" #include "net/base/filename_util.h" #include "shell/browser/atom_browser_main_parts.h" -#include "shell/common/native_mate_converters/callback.h" +#include "shell/common/native_mate_converters/callback_converter_deprecated.h" #include "shell/common/native_mate_converters/file_dialog_converter.h" #include "shell/common/native_mate_converters/file_path_converter.h" #include "shell/common/native_mate_converters/gurl_converter.h" diff --git a/shell/browser/api/atom_api_global_shortcut.cc b/shell/browser/api/atom_api_global_shortcut.cc index 5279e1ad1c4f..09e5f1c387ee 100644 --- a/shell/browser/api/atom_api_global_shortcut.cc +++ b/shell/browser/api/atom_api_global_shortcut.cc @@ -12,7 +12,7 @@ #include "native_mate/dictionary.h" #include "shell/browser/api/atom_api_system_preferences.h" #include "shell/common/native_mate_converters/accelerator_converter.h" -#include "shell/common/native_mate_converters/callback.h" +#include "shell/common/native_mate_converters/callback_converter_deprecated.h" #include "shell/common/node_includes.h" #if defined(OS_MACOSX) diff --git a/shell/browser/api/atom_api_in_app_purchase.cc b/shell/browser/api/atom_api_in_app_purchase.cc index a90dc00252b7..dba2ff1c71f2 100644 --- a/shell/browser/api/atom_api_in_app_purchase.cc +++ b/shell/browser/api/atom_api_in_app_purchase.cc @@ -9,7 +9,7 @@ #include #include "native_mate/dictionary.h" -#include "shell/common/native_mate_converters/callback.h" +#include "shell/common/native_mate_converters/callback_converter_deprecated.h" #include "shell/common/node_includes.h" namespace mate { diff --git a/shell/browser/api/atom_api_menu.cc b/shell/browser/api/atom_api_menu.cc index 436d045e683f..ed322a3df701 100644 --- a/shell/browser/api/atom_api_menu.cc +++ b/shell/browser/api/atom_api_menu.cc @@ -11,7 +11,7 @@ #include "native_mate/object_template_builder.h" #include "shell/browser/native_window.h" #include "shell/common/native_mate_converters/accelerator_converter.h" -#include "shell/common/native_mate_converters/callback.h" +#include "shell/common/native_mate_converters/callback_converter_deprecated.h" #include "shell/common/native_mate_converters/image_converter.h" #include "shell/common/native_mate_converters/string16_converter.h" #include "shell/common/node_includes.h" diff --git a/shell/browser/api/atom_api_net_log.cc b/shell/browser/api/atom_api_net_log.cc index 77b10e22ff4d..a81bc3ed900e 100644 --- a/shell/browser/api/atom_api_net_log.cc +++ b/shell/browser/api/atom_api_net_log.cc @@ -16,7 +16,7 @@ #include "native_mate/handle.h" #include "shell/browser/atom_browser_context.h" #include "shell/browser/net/system_network_context_manager.h" -#include "shell/common/native_mate_converters/callback.h" +#include "shell/common/native_mate_converters/callback_converter_deprecated.h" #include "shell/common/native_mate_converters/file_path_converter.h" #include "shell/common/node_includes.h" diff --git a/shell/browser/api/atom_api_power_monitor.cc b/shell/browser/api/atom_api_power_monitor.cc index ea1835c12296..0ffeb9d235b1 100644 --- a/shell/browser/api/atom_api_power_monitor.cc +++ b/shell/browser/api/atom_api_power_monitor.cc @@ -8,7 +8,7 @@ #include "base/power_monitor/power_monitor_device_source.h" #include "native_mate/dictionary.h" #include "shell/browser/browser.h" -#include "shell/common/native_mate_converters/callback.h" +#include "shell/common/native_mate_converters/callback_converter_deprecated.h" #include "shell/common/node_includes.h" namespace mate { diff --git a/shell/browser/api/atom_api_session.cc b/shell/browser/api/atom_api_session.cc index d7748bcab878..55df63765352 100644 --- a/shell/browser/api/atom_api_session.cc +++ b/shell/browser/api/atom_api_session.cc @@ -53,7 +53,7 @@ #include "shell/browser/media/media_device_id_salt.h" #include "shell/browser/net/cert_verifier_client.h" #include "shell/browser/session_preferences.h" -#include "shell/common/native_mate_converters/callback.h" +#include "shell/common/native_mate_converters/callback_converter_deprecated.h" #include "shell/common/native_mate_converters/content_converter.h" #include "shell/common/native_mate_converters/file_path_converter.h" #include "shell/common/native_mate_converters/gurl_converter.h" diff --git a/shell/browser/api/atom_api_system_preferences.cc b/shell/browser/api/atom_api_system_preferences.cc index eb0344ec4a98..504b11676fc7 100644 --- a/shell/browser/api/atom_api_system_preferences.cc +++ b/shell/browser/api/atom_api_system_preferences.cc @@ -5,7 +5,7 @@ #include "shell/browser/api/atom_api_system_preferences.h" #include "native_mate/dictionary.h" -#include "shell/common/native_mate_converters/callback.h" +#include "shell/common/native_mate_converters/callback_converter_deprecated.h" #include "shell/common/native_mate_converters/value_converter.h" #include "shell/common/node_includes.h" #include "ui/gfx/animation/animation.h" diff --git a/shell/browser/api/atom_api_top_level_window.cc b/shell/browser/api/atom_api_top_level_window.cc index 8226e32959de..3a5fe1ddf270 100644 --- a/shell/browser/api/atom_api_top_level_window.cc +++ b/shell/browser/api/atom_api_top_level_window.cc @@ -16,7 +16,7 @@ #include "shell/browser/api/atom_api_view.h" #include "shell/browser/api/atom_api_web_contents.h" #include "shell/common/color_util.h" -#include "shell/common/native_mate_converters/callback.h" +#include "shell/common/native_mate_converters/callback_converter_deprecated.h" #include "shell/common/native_mate_converters/file_path_converter.h" #include "shell/common/native_mate_converters/gfx_converter.h" #include "shell/common/native_mate_converters/image_converter.h" diff --git a/shell/browser/api/atom_api_web_request_ns.cc b/shell/browser/api/atom_api_web_request_ns.cc index c8553d8244ce..a2a06aa557bf 100644 --- a/shell/browser/api/atom_api_web_request_ns.cc +++ b/shell/browser/api/atom_api_web_request_ns.cc @@ -16,7 +16,7 @@ #include "shell/browser/api/atom_api_session.h" #include "shell/browser/api/atom_api_web_contents.h" #include "shell/browser/atom_browser_context.h" -#include "shell/common/gin_converters/callback_converter_gin_adapter.h" +#include "shell/common/gin_converters/callback_converter.h" #include "shell/common/gin_converters/gurl_converter.h" #include "shell/common/gin_converters/net_converter.h" #include "shell/common/gin_converters/std_converter.h" diff --git a/shell/browser/atom_download_manager_delegate.cc b/shell/browser/atom_download_manager_delegate.cc index 7218d3294f24..40fa8e19ffec 100644 --- a/shell/browser/atom_download_manager_delegate.cc +++ b/shell/browser/atom_download_manager_delegate.cc @@ -23,7 +23,7 @@ #include "shell/browser/native_window.h" #include "shell/browser/ui/file_dialog.h" #include "shell/browser/web_contents_preferences.h" -#include "shell/common/native_mate_converters/callback.h" +#include "shell/common/native_mate_converters/callback_converter_deprecated.h" #include "shell/common/options_switches.h" namespace electron { diff --git a/shell/browser/net/node_stream_loader.cc b/shell/browser/net/node_stream_loader.cc index 66b739bbc3c7..d1816fb16e11 100644 --- a/shell/browser/net/node_stream_loader.cc +++ b/shell/browser/net/node_stream_loader.cc @@ -8,7 +8,7 @@ #include "mojo/public/cpp/system/string_data_source.h" #include "shell/common/api/event_emitter_caller.h" -#include "shell/common/native_mate_converters/callback.h" +#include "shell/common/native_mate_converters/callback_converter_deprecated.h" #include "shell/common/node_includes.h" diff --git a/shell/common/api/atom_api_asar.cc b/shell/common/api/atom_api_asar.cc index 84589d8c0817..da3548079df2 100644 --- a/shell/common/api/atom_api_asar.cc +++ b/shell/common/api/atom_api_asar.cc @@ -11,7 +11,7 @@ #include "native_mate/object_template_builder.h" #include "native_mate/wrappable.h" #include "shell/common/asar/archive.h" -#include "shell/common/native_mate_converters/callback.h" +#include "shell/common/native_mate_converters/callback_converter_deprecated.h" #include "shell/common/native_mate_converters/file_path_converter.h" #include "shell/common/node_includes.h" #include "third_party/electron_node/src/node_native_module_env.h" diff --git a/shell/common/api/atom_api_crash_reporter.cc b/shell/common/api/atom_api_crash_reporter.cc index e53104f11552..2b6019409b26 100644 --- a/shell/common/api/atom_api_crash_reporter.cc +++ b/shell/common/api/atom_api_crash_reporter.cc @@ -7,9 +7,9 @@ #include "base/bind.h" #include "gin/data_object_builder.h" -#include "gin/dictionary.h" #include "shell/common/crash_reporter/crash_reporter.h" -#include "shell/common/gin_util.h" +#include "shell/common/gin_converters/callback_converter.h" +#include "shell/common/gin_helper/dictionary.h" #include "shell/common/native_mate_converters/file_path_converter.h" #include "shell/common/native_mate_converters/map_converter.h" @@ -41,23 +41,26 @@ void Initialize(v8::Local exports, v8::Local unused, v8::Local context, void* priv) { - using gin_util::SetMethod; auto reporter = base::Unretained(CrashReporter::GetInstance()); - SetMethod(exports, "start", - base::BindRepeating(&CrashReporter::Start, reporter)); - SetMethod(exports, "addExtraParameter", - base::BindRepeating(&CrashReporter::AddExtraParameter, reporter)); - SetMethod( - exports, "removeExtraParameter", + gin_helper::Dictionary dict(context->GetIsolate(), exports); + dict.SetMethod("start", base::BindRepeating(&CrashReporter::Start, reporter)); + dict.SetMethod( + "addExtraParameter", + base::BindRepeating(&CrashReporter::AddExtraParameter, reporter)); + dict.SetMethod( + "removeExtraParameter", base::BindRepeating(&CrashReporter::RemoveExtraParameter, reporter)); - SetMethod(exports, "getParameters", - base::BindRepeating(&CrashReporter::GetParameters, reporter)); - SetMethod(exports, "getUploadedReports", - base::BindRepeating(&CrashReporter::GetUploadedReports, reporter)); - SetMethod(exports, "setUploadToServer", - base::BindRepeating(&CrashReporter::SetUploadToServer, reporter)); - SetMethod(exports, "getUploadToServer", - base::BindRepeating(&CrashReporter::GetUploadToServer, reporter)); + dict.SetMethod("getParameters", + base::BindRepeating(&CrashReporter::GetParameters, reporter)); + dict.SetMethod( + "getUploadedReports", + base::BindRepeating(&CrashReporter::GetUploadedReports, reporter)); + dict.SetMethod( + "setUploadToServer", + base::BindRepeating(&CrashReporter::SetUploadToServer, reporter)); + dict.SetMethod( + "getUploadToServer", + base::BindRepeating(&CrashReporter::GetUploadToServer, reporter)); } } // namespace diff --git a/shell/common/api/atom_api_shell.cc b/shell/common/api/atom_api_shell.cc index 2f2645f53a87..771341093b42 100644 --- a/shell/common/api/atom_api_shell.cc +++ b/shell/common/api/atom_api_shell.cc @@ -5,7 +5,7 @@ #include #include "native_mate/dictionary.h" -#include "shell/common/native_mate_converters/callback.h" +#include "shell/common/native_mate_converters/callback_converter_deprecated.h" #include "shell/common/native_mate_converters/file_path_converter.h" #include "shell/common/native_mate_converters/gurl_converter.h" #include "shell/common/native_mate_converters/string16_converter.h" diff --git a/shell/common/api/gin_utils.h b/shell/common/api/gin_utils.h deleted file mode 100644 index b3a3978ee8ee..000000000000 --- a/shell/common/api/gin_utils.h +++ /dev/null @@ -1,27 +0,0 @@ -// 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_API_GIN_UTILS_H_ -#define SHELL_COMMON_API_GIN_UTILS_H_ - -#include "gin/function_template.h" - -namespace gin { - -// NOTE: V8 caches FunctionTemplates. Therefore 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 -v8::Local ConvertCallbackToV8Leaked( - v8::Isolate* isolate, - const base::RepeatingCallback& callback) { - // LOG(WARNING) << "Leaky conversion from callback to V8 triggered."; - return gin::CreateFunctionTemplate(isolate, callback) - ->GetFunction(isolate->GetCurrentContext()) - .ToLocalChecked(); -} - -} // namespace gin - -#endif // SHELL_COMMON_API_GIN_UTILS_H_ diff --git a/shell/common/deprecate_util.cc b/shell/common/deprecate_util.cc index 70307fbf8d45..9edc511e0ac7 100644 --- a/shell/common/deprecate_util.cc +++ b/shell/common/deprecate_util.cc @@ -7,7 +7,7 @@ #include "base/callback.h" #include "native_mate/converter.h" #include "native_mate/dictionary.h" -#include "shell/common/native_mate_converters/callback.h" +#include "shell/common/native_mate_converters/callback_converter_deprecated.h" namespace electron { diff --git a/shell/common/gin_converters/callback_converter.h b/shell/common/gin_converters/callback_converter.h new file mode 100644 index 000000000000..7ec4838dc913 --- /dev/null +++ b/shell/common/gin_converters/callback_converter.h @@ -0,0 +1,59 @@ +// 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_CONVERTERS_CALLBACK_CONVERTER_H_ +#define SHELL_COMMON_GIN_CONVERTERS_CALLBACK_CONVERTER_H_ + +#include + +#include "base/callback_helpers.h" +#include "shell/common/gin_helper/callback.h" + +namespace gin { + +template +struct Converter> { + static v8::Local ToV8(v8::Isolate* isolate, + const base::RepeatingCallback& val) { + // We don't use CreateFunctionTemplate here because it creates a new + // FunctionTemplate everytime, which is cached by V8 and causes leaks. + auto translater = + base::Bind(&gin_helper::NativeFunctionInvoker::Go, val); + // To avoid memory leak, we ensure that the callback can only be called + // for once. + return gin_helper::CreateFunctionFromTranslater(isolate, translater, true); + } + static bool FromV8(v8::Isolate* isolate, + v8::Local val, + base::RepeatingCallback* out) { + if (!val->IsFunction()) + return false; + + *out = base::BindRepeating(&gin_helper::V8FunctionInvoker::Go, isolate, + gin_helper::SafeV8Function(isolate, val)); + return true; + } +}; + +template +struct Converter> { + static v8::Local ToV8(v8::Isolate* isolate, + base::OnceCallback in) { + return gin::ConvertToV8(isolate, + base::AdaptCallbackForRepeating(std::move(in))); + } + static bool FromV8(v8::Isolate* isolate, + v8::Local val, + base::OnceCallback* out) { + if (!val->IsFunction()) + return false; + *out = base::BindOnce(&gin_helper::V8FunctionInvoker::Go, isolate, + gin_helper::SafeV8Function(isolate, val)); + return true; + } +}; + +} // namespace gin + +#endif // SHELL_COMMON_GIN_CONVERTERS_CALLBACK_CONVERTER_H_ diff --git a/shell/common/gin_converters/callback_converter_gin_adapter.h b/shell/common/gin_converters/callback_converter_gin_adapter.h deleted file mode 100644 index e26ffdff9e55..000000000000 --- a/shell/common/gin_converters/callback_converter_gin_adapter.h +++ /dev/null @@ -1,44 +0,0 @@ -// 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_CONVERTERS_CALLBACK_CONVERTER_GIN_ADAPTER_H_ -#define SHELL_COMMON_GIN_CONVERTERS_CALLBACK_CONVERTER_GIN_ADAPTER_H_ - -#include "gin/converter.h" -#include "shell/common/native_mate_converters/once_callback.h" - -// TODO(zcbenz): Move the implementations from native_mate_converters to here. - -namespace gin { - -template -struct Converter> { - static v8::Local ToV8(v8::Isolate* isolate, - const base::RepeatingCallback& in) { - return mate::ConvertToV8(isolate, in); - } - static bool FromV8(v8::Isolate* isolate, - v8::Local val, - base::RepeatingCallback* out) { - return mate::ConvertFromV8(isolate, val, out); - } -}; - -template -struct Converter> { - static v8::Local ToV8(v8::Isolate* isolate, - base::OnceCallback in) { - return mate::ConvertToV8(isolate, in); - } - - static bool FromV8(v8::Isolate* isolate, - v8::Local val, - base::OnceCallback* out) { - return mate::ConvertFromV8(isolate, val, out); - } -}; - -} // namespace gin - -#endif // SHELL_COMMON_GIN_CONVERTERS_CALLBACK_CONVERTER_GIN_ADAPTER_H_ diff --git a/shell/common/native_mate_converters/callback.cc b/shell/common/gin_helper/callback.cc similarity index 83% rename from shell/common/native_mate_converters/callback.cc rename to shell/common/gin_helper/callback.cc index 92029f3fc6e1..756dff91a5b7 100644 --- a/shell/common/native_mate_converters/callback.cc +++ b/shell/common/gin_helper/callback.cc @@ -1,18 +1,13 @@ -// Copyright (c) 2015 GitHub, Inc. All rights reserved. +// Copyright (c) 2019 GitHub, Inc. All rights reserved. // Use of this source code is governed by the MIT license that can be // found in the LICENSE file. -#include "shell/common/native_mate_converters/callback.h" -#include "base/stl_util.h" +#include "shell/common/gin_helper/callback.h" + #include "content/public/browser/browser_thread.h" +#include "gin/dictionary.h" -#include "native_mate/dictionary.h" - -using content::BrowserThread; - -namespace mate { - -namespace internal { +namespace gin_helper { namespace { @@ -41,7 +36,7 @@ v8::Persistent g_call_translater; void CallTranslater(v8::Local external, v8::Local state, - mate::Arguments* args) { + gin::Arguments* args) { // Whether the callback should only be called for once. v8::Isolate* isolate = args->isolate(); auto context = isolate->GetCurrentContext(); @@ -52,7 +47,7 @@ void CallTranslater(v8::Local external, if (one_time) { auto called_symbol = mate::StringToSymbol(isolate, "called"); if (state->Has(context, called_symbol).ToChecked()) { - args->ThrowError("callback can only be called for once"); + args->ThrowTypeError("callback can only be called for once"); return; } else { state->Set(context, called_symbol, v8::Boolean::New(isolate, true)) @@ -74,9 +69,10 @@ void CallTranslater(v8::Local external, struct DeleteOnUIThread { template static void Destruct(const T* x) { - if (Locker::IsBrowserProcess() && - !BrowserThread::CurrentlyOn(BrowserThread::UI)) { - BrowserThread::DeleteSoon(BrowserThread::UI, FROM_HERE, x); + if (mate::Locker::IsBrowserProcess() && + !content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) { + content::BrowserThread::DeleteSoon(content::BrowserThread::UI, FROM_HERE, + x); } else { delete x; } @@ -124,21 +120,21 @@ v8::Local CreateFunctionFromTranslater(v8::Isolate* isolate, bool one_time) { // The FunctionTemplate is cached. if (g_call_translater.IsEmpty()) - g_call_translater.Reset(isolate, - mate::CreateFunctionTemplate( - isolate, base::BindRepeating(&CallTranslater))); + g_call_translater.Reset( + isolate, + CreateFunctionTemplate(isolate, base::BindRepeating(&CallTranslater))); v8::Local call_translater = v8::Local::New(isolate, g_call_translater); auto* holder = new TranslaterHolder(isolate); holder->translater = translater; - Dictionary state = mate::Dictionary::CreateEmpty(isolate); + gin::Dictionary state = gin::Dictionary::CreateEmpty(isolate); if (one_time) state.Set("oneTime", true); auto context = isolate->GetCurrentContext(); return BindFunctionWith( isolate, context, call_translater->GetFunction(context).ToLocalChecked(), - holder->handle.Get(isolate), state.GetHandle()); + holder->handle.Get(isolate), gin::ConvertToV8(isolate, state)); } // func.bind(func, arg1). @@ -158,6 +154,4 @@ v8::Local BindFunctionWith(v8::Isolate* isolate, .ToLocalChecked(); } -} // namespace internal - -} // namespace mate +} // namespace gin_helper diff --git a/shell/common/gin_helper/callback.h b/shell/common/gin_helper/callback.h new file mode 100644 index 000000000000..2c8a1ecba6de --- /dev/null +++ b/shell/common/gin_helper/callback.h @@ -0,0 +1,163 @@ +// Copyright (c) 2019 GitHub, Inc. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef SHELL_COMMON_GIN_HELPER_CALLBACK_H_ +#define SHELL_COMMON_GIN_HELPER_CALLBACK_H_ + +#include +#include + +#include "base/bind.h" +#include "shell/common/api/locker.h" +#include "shell/common/gin_helper/function_template.h" + +// Implements safe convertions between JS functions and base::Callback. + +namespace gin { + +// Make it possible to convert move-only types. +template +v8::Local ConvertToV8(v8::Isolate* isolate, T&& input) { + return Converter::type>::ToV8( + isolate, std::move(input)); +} + +} // namespace gin + +namespace gin_helper { + +template +class RefCountedGlobal; + +// Manages the V8 function with RAII. +class SafeV8Function { + public: + SafeV8Function(v8::Isolate* isolate, v8::Local value); + SafeV8Function(const SafeV8Function& other); + ~SafeV8Function(); + + bool IsAlive() const; + v8::Local NewHandle(v8::Isolate* isolate) const; + + private: + scoped_refptr> v8_function_; +}; + +// Helper to invoke a V8 function with C++ parameters. +template +struct V8FunctionInvoker {}; + +template +struct V8FunctionInvoker(ArgTypes...)> { + static v8::Local Go(v8::Isolate* isolate, + const SafeV8Function& function, + ArgTypes... raw) { + mate::Locker locker(isolate); + v8::EscapableHandleScope handle_scope(isolate); + if (!function.IsAlive()) + return v8::Null(isolate); + v8::MicrotasksScope script_scope(isolate, + v8::MicrotasksScope::kRunMicrotasks); + v8::Local holder = function.NewHandle(isolate); + v8::Local context = holder->CreationContext(); + v8::Context::Scope context_scope(context); + std::vector> args{ + gin::ConvertToV8(isolate, std::forward(raw))...}; + v8::MaybeLocal ret = holder->Call( + context, holder, args.size(), args.empty() ? nullptr : &args.front()); + if (ret.IsEmpty()) + return v8::Undefined(isolate); + else + return handle_scope.Escape(ret.ToLocalChecked()); + } +}; + +template +struct V8FunctionInvoker { + static void Go(v8::Isolate* isolate, + const SafeV8Function& function, + ArgTypes... raw) { + mate::Locker locker(isolate); + v8::HandleScope handle_scope(isolate); + if (!function.IsAlive()) + return; + v8::MicrotasksScope script_scope(isolate, + v8::MicrotasksScope::kRunMicrotasks); + v8::Local holder = function.NewHandle(isolate); + v8::Local context = holder->CreationContext(); + v8::Context::Scope context_scope(context); + std::vector> args{ + gin::ConvertToV8(isolate, std::forward(raw))...}; + holder + ->Call(context, holder, args.size(), + args.empty() ? nullptr : &args.front()) + .IsEmpty(); + } +}; + +template +struct V8FunctionInvoker { + static ReturnType Go(v8::Isolate* isolate, + const SafeV8Function& function, + ArgTypes... raw) { + mate::Locker locker(isolate); + v8::HandleScope handle_scope(isolate); + ReturnType ret = ReturnType(); + if (!function.IsAlive()) + return ret; + v8::MicrotasksScope script_scope(isolate, + v8::MicrotasksScope::kRunMicrotasks); + v8::Local holder = function.NewHandle(isolate); + v8::Local context = holder->CreationContext(); + v8::Context::Scope context_scope(context); + std::vector> args{ + gin::ConvertToV8(isolate, std::forward(raw))...}; + v8::Local result; + auto maybe_result = holder->Call(context, holder, args.size(), + args.empty() ? nullptr : &args.front()); + if (maybe_result.ToLocal(&result)) + gin::Converter::FromV8(isolate, result, &ret); + return ret; + } +}; + +// Helper to pass a C++ funtion to JavaScript. +using Translater = base::Callback; +v8::Local CreateFunctionFromTranslater(v8::Isolate* isolate, + const Translater& translater, + bool one_time); +v8::Local BindFunctionWith(v8::Isolate* isolate, + v8::Local context, + v8::Local func, + v8::Local arg1, + v8::Local arg2); + +// Calls callback with Arguments. +template +struct NativeFunctionInvoker {}; + +template +struct NativeFunctionInvoker { + static void Go(base::Callback val, + gin::Arguments* args) { + using Indices = typename IndicesGenerator::type; + Invoker invoker(args, 0); + if (invoker.IsOK()) + invoker.DispatchToCallback(val); + } +}; + +// Convert a callback to V8 without the call number limitation, this can easily +// cause memory leaks so use it with caution. +template +v8::Local CallbackToV8Leaked( + v8::Isolate* isolate, + const base::RepeatingCallback& val) { + Translater translater = base::Bind(&NativeFunctionInvoker::Go, val); + return CreateFunctionFromTranslater(isolate, translater, false); +} + +} // namespace gin_helper + +#endif // SHELL_COMMON_GIN_HELPER_CALLBACK_H_ diff --git a/shell/common/gin_helper/dictionary.h b/shell/common/gin_helper/dictionary.h new file mode 100644 index 000000000000..f3f61a098c63 --- /dev/null +++ b/shell/common/gin_helper/dictionary.h @@ -0,0 +1,84 @@ +// 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_DICTIONARY_H_ +#define SHELL_COMMON_GIN_HELPER_DICTIONARY_H_ + +#include + +#include "base/bind.h" +#include "gin/dictionary.h" +#include "shell/common/gin_helper/function_template.h" + +namespace gin_helper { + +// Base template - used only for non-member function pointers. Other types +// either go to one of the below specializations, or go here and fail to compile +// because of base::Bind(). +template +struct CallbackTraits { + static v8::Local CreateTemplate(v8::Isolate* isolate, + T callback) { + return CreateFunctionTemplate(isolate, base::BindRepeating(callback)); + } +}; + +// Specialization for base::Callback. +template +struct CallbackTraits> { + static v8::Local CreateTemplate( + v8::Isolate* isolate, + const base::RepeatingCallback& callback) { + return CreateFunctionTemplate(isolate, callback); + } +}; + +// Specialization for member function pointers. We need to handle this case +// specially because the first parameter for callbacks to MFP should typically +// come from the the JavaScript "this" object the function was called on, not +// from the first normal parameter. +template +struct CallbackTraits< + T, + typename std::enable_if::value>::type> { + static v8::Local CreateTemplate(v8::Isolate* isolate, + T callback) { + int flags = HolderIsFirstArgument; + return CreateFunctionTemplate(isolate, base::BindRepeating(callback), + flags); + } +}; + +// Adds a few more extends methods to gin::Dictionary. +// +// Note that as the destructor of gin::Dictionary is not virtual, and we want to +// convert between 2 types, we must not add any member. +class Dictionary : public gin::Dictionary { + public: + Dictionary(v8::Isolate* isolate, v8::Local object) + : gin::Dictionary(isolate, object) {} + + template + bool SetMethod(base::StringPiece key, const T& callback) { + auto context = isolate()->GetCurrentContext(); + auto templ = CallbackTraits::CreateTemplate(isolate(), callback); + return GetHandle() + ->Set(context, gin::StringToV8(isolate(), key), + templ->GetFunction(context).ToLocalChecked()) + .ToChecked(); + } + + v8::Local GetHandle() const { + return gin::ConvertToV8(isolate(), + *static_cast(this)) + .As(); + } + + private: + // DO NOT ADD ANY DATA MEMBER. +}; + +} // namespace gin_helper + +#endif // SHELL_COMMON_GIN_HELPER_DICTIONARY_H_ diff --git a/shell/common/gin_helper/function_template.cc b/shell/common/gin_helper/function_template.cc new file mode 100644 index 000000000000..9d844bff35b6 --- /dev/null +++ b/shell/common/gin_helper/function_template.cc @@ -0,0 +1,36 @@ +// Copyright 2019 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/function_template.h" + +namespace gin_helper { + +CallbackHolderBase::CallbackHolderBase(v8::Isolate* isolate) + : v8_ref_(isolate, v8::External::New(isolate, this)) { + v8_ref_.SetWeak(this, &CallbackHolderBase::FirstWeakCallback, + v8::WeakCallbackType::kParameter); +} + +CallbackHolderBase::~CallbackHolderBase() { + DCHECK(v8_ref_.IsEmpty()); +} + +v8::Local CallbackHolderBase::GetHandle(v8::Isolate* isolate) { + return v8::Local::New(isolate, v8_ref_); +} + +// static +void CallbackHolderBase::FirstWeakCallback( + const v8::WeakCallbackInfo& data) { + data.GetParameter()->v8_ref_.Reset(); + data.SetSecondPassCallback(SecondWeakCallback); +} + +// static +void CallbackHolderBase::SecondWeakCallback( + const v8::WeakCallbackInfo& data) { + delete data.GetParameter(); +} + +} // namespace gin_helper diff --git a/shell/common/gin_helper/function_template.h b/shell/common/gin_helper/function_template.h new file mode 100644 index 000000000000..a685eef76cb9 --- /dev/null +++ b/shell/common/gin_helper/function_template.h @@ -0,0 +1,263 @@ +// Copyright 2019 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_FUNCTION_TEMPLATE_H_ +#define SHELL_COMMON_GIN_HELPER_FUNCTION_TEMPLATE_H_ + +#include "base/callback.h" +#include "gin/arguments.h" +#include "shell/common/error_util.h" +#include "shell/common/gin_helper/destroyable.h" + +// This file is forked from gin/function_template.h with 2 differences: +// 1. Support for additional types of arguments. +// 2. Support for warning using destroyed objects. +// +// TODO(zcbenz): We should seek to remove this file after removing native_mate. + +namespace gin_helper { + +enum CreateFunctionTemplateFlags { + HolderIsFirstArgument = 1 << 0, +}; + +template +struct CallbackParamTraits { + typedef T LocalType; +}; +template +struct CallbackParamTraits { + typedef T LocalType; +}; +template +struct CallbackParamTraits { + typedef T* LocalType; +}; + +// CallbackHolder and CallbackHolderBase are used to pass a base::Callback from +// CreateFunctionTemplate through v8 (via v8::FunctionTemplate) to +// DispatchToCallback, where it is invoked. + +// This simple base class is used so that we can share a single object template +// among every CallbackHolder instance. +class CallbackHolderBase { + public: + v8::Local GetHandle(v8::Isolate* isolate); + + protected: + explicit CallbackHolderBase(v8::Isolate* isolate); + virtual ~CallbackHolderBase(); + + private: + static void FirstWeakCallback( + const v8::WeakCallbackInfo& data); + static void SecondWeakCallback( + const v8::WeakCallbackInfo& data); + + v8::Global v8_ref_; + + DISALLOW_COPY_AND_ASSIGN(CallbackHolderBase); +}; + +template +class CallbackHolder : public CallbackHolderBase { + public: + CallbackHolder(v8::Isolate* isolate, + const base::Callback& callback, + int flags) + : CallbackHolderBase(isolate), callback(callback), flags(flags) {} + base::Callback callback; + int flags = 0; + + private: + virtual ~CallbackHolder() = default; + + DISALLOW_COPY_AND_ASSIGN(CallbackHolder); +}; + +template +bool GetNextArgument(gin::Arguments* args, + int create_flags, + bool is_first, + T* result) { + if (is_first && (create_flags & HolderIsFirstArgument) != 0) { + return args->GetHolder(result); + } else { + return args->GetNext(result); + } +} + +// For advanced use cases, we allow callers to request the unparsed Arguments +// object and poke around in it directly. +inline bool GetNextArgument(gin::Arguments* args, + int create_flags, + bool is_first, + gin::Arguments** result) { + *result = args; + return true; +} + +// It's common for clients to just need the isolate, so we make that easy. +inline bool GetNextArgument(gin::Arguments* args, + int create_flags, + bool is_first, + v8::Isolate** result) { + *result = args->isolate(); + return true; +} + +// Allow clients to pass a util::Error to throw errors if they +// don't need the full gin::Arguments +inline bool GetNextArgument(gin::Arguments* args, + int create_flags, + bool is_first, + electron::util::ErrorThrower* result) { + *result = electron::util::ErrorThrower(args->isolate()); + return true; +} + +// Classes for generating and storing an argument pack of integer indices +// (based on well-known "indices trick", see: http://goo.gl/bKKojn): +template +struct IndicesHolder {}; + +template +struct IndicesGenerator { + using type = typename IndicesGenerator::type; +}; +template +struct IndicesGenerator<0, indices...> { + using type = IndicesHolder; +}; + +// Class template for extracting and storing single argument for callback +// at position |index|. +template +struct ArgumentHolder { + using ArgLocalType = typename CallbackParamTraits::LocalType; + + ArgLocalType value; + bool ok = false; + + ArgumentHolder(gin::Arguments* args, int create_flags) { + v8::Local holder; + if (index == 0 && (create_flags & HolderIsFirstArgument) && + args->GetHolder(&holder) && + gin_helper::Destroyable::IsDestroyed(holder)) { + args->ThrowTypeError("Object has been destroyed"); + return; + } + ok = GetNextArgument(args, create_flags, index == 0, &value); + if (!ok) { + // Ideally we would include the expected c++ type in the error + // message which we can access via typeid(ArgType).name() + // however we compile with no-rtti, which disables typeid. + args->ThrowError(); + } + } +}; + +// Class template for converting arguments from JavaScript to C++ and running +// the callback with them. +template +class Invoker {}; + +template +class Invoker, ArgTypes...> + : public ArgumentHolder... { + public: + // Invoker<> inherits from ArgumentHolder<> for each argument. + // C++ has always been strict about the class initialization order, + // so it is guaranteed ArgumentHolders will be initialized (and thus, will + // extract arguments from Arguments) in the right order. + Invoker(gin::Arguments* args, int create_flags) + : ArgumentHolder(args, create_flags)..., args_(args) { + // GCC thinks that create_flags is going unused, even though the + // expansion above clearly makes use of it. Per jyasskin@, casting + // to void is the commonly accepted way to convince the compiler + // that you're actually using a parameter/varible. + (void)create_flags; + } + + bool IsOK() { return And(ArgumentHolder::ok...); } + + template + void DispatchToCallback(base::Callback callback) { + v8::MicrotasksScope script_scope(args_->isolate(), + v8::MicrotasksScope::kRunMicrotasks); + args_->Return(callback.Run(ArgumentHolder::value...)); + } + + // In C++, you can declare the function foo(void), but you can't pass a void + // expression to foo. As a result, we must specialize the case of Callbacks + // that have the void return type. + void DispatchToCallback(base::Callback callback) { + v8::MicrotasksScope script_scope(args_->isolate(), + v8::MicrotasksScope::kRunMicrotasks); + callback.Run(ArgumentHolder::value...); + } + + private: + static bool And() { return true; } + template + static bool And(bool arg1, T... args) { + return arg1 && And(args...); + } + + gin::Arguments* args_; +}; + +// DispatchToCallback converts all the JavaScript arguments to C++ types and +// invokes the base::Callback. +template +struct Dispatcher {}; + +template +struct Dispatcher { + static void DispatchToCallback( + const v8::FunctionCallbackInfo& info) { + gin::Arguments args(info); + v8::Local v8_holder; + args.GetData(&v8_holder); + CallbackHolderBase* holder_base = + reinterpret_cast(v8_holder->Value()); + + typedef CallbackHolder HolderT; + HolderT* holder = static_cast(holder_base); + + using Indices = typename IndicesGenerator::type; + Invoker invoker(&args, holder->flags); + if (invoker.IsOK()) + invoker.DispatchToCallback(holder->callback); + } +}; + +// CreateFunctionTemplate creates a v8::FunctionTemplate that will create +// JavaScript functions that execute a provided C++ function or base::Callback. +// JavaScript arguments are automatically converted via gin::Converter, as is +// the return value of the C++ function, if any. +// +// NOTE: V8 caches FunctionTemplates for a lifetime of a web page for its own +// internal reasons, thus it is generally a good idea to cache the template +// returned by this function. Otherwise, repeated method invocations from JS +// will create substantial memory leaks. See http://crbug.com/463487. +template +v8::Local CreateFunctionTemplate( + v8::Isolate* isolate, + const base::Callback callback, + int callback_flags = 0) { + typedef CallbackHolder HolderT; + HolderT* holder = new HolderT(isolate, callback, callback_flags); + + return v8::FunctionTemplate::New(isolate, + &Dispatcher::DispatchToCallback, + gin::ConvertToV8>( + isolate, holder->GetHandle(isolate))); +} + +} // namespace gin_helper + +#endif // SHELL_COMMON_GIN_HELPER_FUNCTION_TEMPLATE_H_ diff --git a/shell/common/gin_util.h b/shell/common/gin_util.h deleted file mode 100644 index 3cb286444a4c..000000000000 --- a/shell/common/gin_util.h +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) 2018 Slack Technologies, Inc. -// Use of this source code is governed by the MIT license that can be -// found in the LICENSE file. - -#ifndef SHELL_COMMON_GIN_UTIL_H_ -#define SHELL_COMMON_GIN_UTIL_H_ - -#include "gin/converter.h" -#include "gin/function_template.h" - -namespace gin_util { - -template -bool SetMethod(v8::Local recv, - base::StringPiece key, - const T& callback) { - v8::Isolate* isolate = v8::Isolate::GetCurrent(); - auto context = isolate->GetCurrentContext(); - return recv - ->Set(context, gin::StringToV8(isolate, key), - gin::CreateFunctionTemplate(isolate, callback) - ->GetFunction(context) - .ToLocalChecked()) - .ToChecked(); -} - -} // namespace gin_util - -#endif // SHELL_COMMON_GIN_UTIL_H_ diff --git a/shell/common/native_mate_converters/callback_converter_deprecated.cc b/shell/common/native_mate_converters/callback_converter_deprecated.cc new file mode 100644 index 000000000000..baea655485e1 --- /dev/null +++ b/shell/common/native_mate_converters/callback_converter_deprecated.cc @@ -0,0 +1,163 @@ +// Copyright (c) 2015 GitHub, Inc. All rights reserved. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "shell/common/native_mate_converters/callback_converter_deprecated.h" +#include "base/stl_util.h" +#include "content/public/browser/browser_thread.h" + +#include "native_mate/dictionary.h" + +using content::BrowserThread; + +namespace mate { + +namespace internal { + +namespace { + +struct TranslaterHolder { + explicit TranslaterHolder(v8::Isolate* isolate) + : handle(isolate, v8::External::New(isolate, this)) { + handle.SetWeak(this, &GC, v8::WeakCallbackType::kFinalizer); + } + ~TranslaterHolder() { + if (!handle.IsEmpty()) { + handle.ClearWeak(); + handle.Reset(); + } + } + + static void GC(const v8::WeakCallbackInfo& data) { + delete data.GetParameter(); + } + + v8::Global handle; + Translater translater; +}; + +// Cached JavaScript version of |CallTranslater|. +v8::Persistent g_call_translater; + +void CallTranslater(v8::Local external, + v8::Local state, + mate::Arguments* args) { + // Whether the callback should only be called for once. + v8::Isolate* isolate = args->isolate(); + auto context = isolate->GetCurrentContext(); + bool one_time = + state->Has(context, mate::StringToSymbol(isolate, "oneTime")).ToChecked(); + + // Check if the callback has already been called. + if (one_time) { + auto called_symbol = mate::StringToSymbol(isolate, "called"); + if (state->Has(context, called_symbol).ToChecked()) { + args->ThrowError("callback can only be called for once"); + return; + } else { + state->Set(context, called_symbol, v8::Boolean::New(isolate, true)) + .ToChecked(); + } + } + + TranslaterHolder* holder = static_cast(external->Value()); + holder->translater.Run(args); + + // Free immediately for one-time callback. + if (one_time) + delete holder; +} + +} // namespace + +// Destroy the class on UI thread when possible. +struct DeleteOnUIThread { + template + static void Destruct(const T* x) { + if (Locker::IsBrowserProcess() && + !BrowserThread::CurrentlyOn(BrowserThread::UI)) { + BrowserThread::DeleteSoon(BrowserThread::UI, FROM_HERE, x); + } else { + delete x; + } + } +}; + +// Like v8::Global, but ref-counted. +template +class RefCountedGlobal + : public base::RefCountedThreadSafe, DeleteOnUIThread> { + public: + RefCountedGlobal(v8::Isolate* isolate, v8::Local value) + : handle_(isolate, v8::Local::Cast(value)) {} + + bool IsAlive() const { return !handle_.IsEmpty(); } + + v8::Local NewHandle(v8::Isolate* isolate) const { + return v8::Local::New(isolate, handle_); + } + + private: + v8::Global handle_; + + DISALLOW_COPY_AND_ASSIGN(RefCountedGlobal); +}; + +SafeV8Function::SafeV8Function(v8::Isolate* isolate, v8::Local value) + : v8_function_(new RefCountedGlobal(isolate, value)) {} + +SafeV8Function::SafeV8Function(const SafeV8Function& other) + : v8_function_(other.v8_function_) {} + +SafeV8Function::~SafeV8Function() {} + +bool SafeV8Function::IsAlive() const { + return v8_function_.get() && v8_function_->IsAlive(); +} + +v8::Local SafeV8Function::NewHandle(v8::Isolate* isolate) const { + return v8_function_->NewHandle(isolate); +} + +v8::Local CreateFunctionFromTranslater(v8::Isolate* isolate, + const Translater& translater, + bool one_time) { + // The FunctionTemplate is cached. + if (g_call_translater.IsEmpty()) + g_call_translater.Reset(isolate, + mate::CreateFunctionTemplate( + isolate, base::BindRepeating(&CallTranslater))); + + v8::Local call_translater = + v8::Local::New(isolate, g_call_translater); + auto* holder = new TranslaterHolder(isolate); + holder->translater = translater; + Dictionary state = mate::Dictionary::CreateEmpty(isolate); + if (one_time) + state.Set("oneTime", true); + auto context = isolate->GetCurrentContext(); + return BindFunctionWith( + isolate, context, call_translater->GetFunction(context).ToLocalChecked(), + holder->handle.Get(isolate), state.GetHandle()); +} + +// func.bind(func, arg1). +// NB(zcbenz): Using C++11 version crashes VS. +v8::Local BindFunctionWith(v8::Isolate* isolate, + v8::Local context, + v8::Local func, + v8::Local arg1, + v8::Local arg2) { + v8::MaybeLocal bind = + func->Get(context, mate::StringToV8(isolate, "bind")); + CHECK(!bind.IsEmpty()); + v8::Local bind_func = + v8::Local::Cast(bind.ToLocalChecked()); + v8::Local converted[] = {func, arg1, arg2}; + return bind_func->Call(context, func, base::size(converted), converted) + .ToLocalChecked(); +} + +} // namespace internal + +} // namespace mate diff --git a/shell/common/native_mate_converters/callback.h b/shell/common/native_mate_converters/callback_converter_deprecated.h similarity index 94% rename from shell/common/native_mate_converters/callback.h rename to shell/common/native_mate_converters/callback_converter_deprecated.h index df8f19ae7ec0..7edd21bde6ac 100644 --- a/shell/common/native_mate_converters/callback.h +++ b/shell/common/native_mate_converters/callback_converter_deprecated.h @@ -2,8 +2,8 @@ // Use of this source code is governed by the MIT license that can be // found in the LICENSE file. -#ifndef SHELL_COMMON_NATIVE_MATE_CONVERTERS_CALLBACK_H_ -#define SHELL_COMMON_NATIVE_MATE_CONVERTERS_CALLBACK_H_ +#ifndef SHELL_COMMON_NATIVE_MATE_CONVERTERS_CALLBACK_CONVERTER_DEPRECATED_H_ +#define SHELL_COMMON_NATIVE_MATE_CONVERTERS_CALLBACK_CONVERTER_DEPRECATED_H_ #include #include @@ -16,6 +16,10 @@ #include "native_mate/scoped_persistent.h" #include "shell/common/api/locker.h" +// =============================== NOTICE =============================== +// Do not add code here, native_mate is being removed. Any new code +// should use gin instead. + namespace mate { namespace internal { @@ -178,4 +182,4 @@ v8::Local CallbackToV8(v8::Isolate* isolate, } // namespace mate -#endif // SHELL_COMMON_NATIVE_MATE_CONVERTERS_CALLBACK_H_ +#endif // SHELL_COMMON_NATIVE_MATE_CONVERTERS_CALLBACK_CONVERTER_DEPRECATED_H_ diff --git a/shell/common/native_mate_converters/content_converter.cc b/shell/common/native_mate_converters/content_converter.cc index 2db61481cd7b..a03be29a985c 100644 --- a/shell/common/native_mate_converters/content_converter.cc +++ b/shell/common/native_mate_converters/content_converter.cc @@ -13,7 +13,7 @@ #include "shell/browser/api/atom_api_web_contents.h" #include "shell/browser/web_contents_permission_helper.h" #include "shell/common/native_mate_converters/blink_converter.h" -#include "shell/common/native_mate_converters/callback.h" +#include "shell/common/native_mate_converters/callback_converter_deprecated.h" #include "shell/common/native_mate_converters/gurl_converter.h" #include "shell/common/native_mate_converters/string16_converter.h" #include "shell/common/native_mate_converters/ui_base_types_converter.h" diff --git a/shell/common/native_mate_converters/once_callback.h b/shell/common/native_mate_converters/once_callback.h index 89895a9986b5..cb8e46e25631 100644 --- a/shell/common/native_mate_converters/once_callback.h +++ b/shell/common/native_mate_converters/once_callback.h @@ -7,7 +7,7 @@ #include -#include "shell/common/native_mate_converters/callback.h" +#include "shell/common/native_mate_converters/callback_converter_deprecated.h" namespace mate { diff --git a/shell/common/promise_util.h b/shell/common/promise_util.h index a73f585b9fc1..e7dee469120b 100644 --- a/shell/common/promise_util.h +++ b/shell/common/promise_util.h @@ -15,7 +15,7 @@ #include "content/public/browser/browser_thread.h" #include "native_mate/converter.h" #include "shell/common/api/locker.h" -#include "shell/common/native_mate_converters/callback.h" +#include "shell/common/native_mate_converters/callback_converter_deprecated.h" #include "shell/common/native_mate_converters/once_callback.h" namespace electron { diff --git a/shell/renderer/api/atom_api_web_frame.cc b/shell/renderer/api/atom_api_web_frame.cc index 8b00a9d129d9..e8f37aba8c89 100644 --- a/shell/renderer/api/atom_api_web_frame.cc +++ b/shell/renderer/api/atom_api_web_frame.cc @@ -18,7 +18,7 @@ #include "shell/common/api/api.mojom.h" #include "shell/common/api/event_emitter_caller.h" #include "shell/common/native_mate_converters/blink_converter.h" -#include "shell/common/native_mate_converters/callback.h" +#include "shell/common/native_mate_converters/callback_converter_deprecated.h" #include "shell/common/native_mate_converters/gfx_converter.h" #include "shell/common/native_mate_converters/string16_converter.h" #include "shell/common/node_includes.h"