// 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 ELECTRON_SHELL_COMMON_GIN_CONVERTERS_CALLBACK_CONVERTER_H_ #define ELECTRON_SHELL_COMMON_GIN_CONVERTERS_CALLBACK_CONVERTER_H_ #include #include "base/functional/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 translator = base::BindRepeating(&gin_helper::NativeFunctionInvoker::Go, val); // To avoid memory leak, we ensure that the callback can only be called // for once. return gin_helper::CreateFunctionFromTranslator(isolate, translator, 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 // ELECTRON_SHELL_COMMON_GIN_CONVERTERS_CALLBACK_CONVERTER_H_