diff --git a/atom/browser/api/atom_api_browser_window.cc b/atom/browser/api/atom_api_browser_window.cc index 04712a7f1..4e79e4524 100644 --- a/atom/browser/api/atom_api_browser_window.cc +++ b/atom/browser/api/atom_api_browser_window.cc @@ -20,6 +20,7 @@ #include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/render_view_host.h" +#include "gin/converter.h" #include "native_mate/dictionary.h" #include "ui/gl/gpu_switching_manager.h" @@ -311,7 +312,7 @@ void BrowserWindow::SetBrowserView(v8::Local value) { void BrowserWindow::SetVibrancy(v8::Isolate* isolate, v8::Local value) { - std::string type = mate::V8ToString(value); + std::string type = gin::V8ToString(isolate, value); auto* render_view_host = web_contents()->GetRenderViewHost(); if (render_view_host) { diff --git a/atom/browser/api/atom_api_session.cc b/atom/browser/api/atom_api_session.cc index 9451f2258..ffb1589f9 100644 --- a/atom/browser/api/atom_api_session.cc +++ b/atom/browser/api/atom_api_session.cc @@ -359,7 +359,7 @@ void DestroyGlobalHandle(v8::Isolate* isolate, if (!global_handle.IsEmpty()) { v8::Local local_handle = global_handle.Get(isolate); if (local_handle->IsObject()) { - v8::Local object = local_handle->ToObject(); + v8::Local object = local_handle->ToObject(isolate); void* ptr = object->GetAlignedPointerFromInternalField(0); if (!ptr) return; diff --git a/atom/browser/api/atom_api_top_level_window.cc b/atom/browser/api/atom_api_top_level_window.cc index 0dda932e2..d93149b65 100644 --- a/atom/browser/api/atom_api_top_level_window.cc +++ b/atom/browser/api/atom_api_top_level_window.cc @@ -20,6 +20,7 @@ #include "atom/common/native_mate_converters/value_converter.h" #include "atom/common/options_switches.h" #include "electron/buildflags/buildflags.h" +#include "gin/converter.h" #include "native_mate/handle.h" #include "native_mate/persistent_dictionary.h" @@ -643,7 +644,8 @@ void TopLevelWindow::SetFocusable(bool focusable) { void TopLevelWindow::SetMenu(v8::Isolate* isolate, v8::Local value) { mate::Handle menu; if (value->IsObject() && - mate::V8ToString(value->ToObject()->GetConstructorName()) == "Menu" && + gin::V8ToString( + isolate, value->ToObject(isolate)->GetConstructorName()) == "Menu" && mate::ConvertFromV8(isolate, value, &menu) && !menu.IsEmpty()) { menu_.Reset(isolate, menu.ToV8()); window_->SetMenu(menu->model()); @@ -740,7 +742,7 @@ void TopLevelWindow::SetAutoHideCursor(bool auto_hide) { void TopLevelWindow::SetVibrancy(v8::Isolate* isolate, v8::Local value) { - std::string type = mate::V8ToString(value); + std::string type = gin::V8ToString(isolate, value); window_->SetVibrancy(type); } diff --git a/atom/browser/api/event_emitter.h b/atom/browser/api/event_emitter.h index 2ae93b706..c57ace640 100644 --- a/atom/browser/api/event_emitter.h +++ b/atom/browser/api/event_emitter.h @@ -103,7 +103,8 @@ class EventEmitter : public Wrappable { v8::HandleScope handle_scope(isolate()); EmitEvent(isolate(), GetWrapper(), name, event, args...); return event->Get(StringToV8(isolate(), "defaultPrevented")) - ->BooleanValue(); + ->BooleanValue(isolate()->GetCurrentContext()) + .ToChecked(); } DISALLOW_COPY_AND_ASSIGN(EventEmitter); diff --git a/atom/common/api/atom_api_asar.cc b/atom/common/api/atom_api_asar.cc index cb7c6dffb..b915c6492 100644 --- a/atom/common/api/atom_api_asar.cc +++ b/atom/common/api/atom_api_asar.cc @@ -131,7 +131,7 @@ void InitAsarSupport(v8::Isolate* isolate, result = asar_init->Run(context).ToLocalChecked(); // Initialize asar support. - CHECK(result->IsFunction()); + DCHECK(result->IsFunction()); v8::Local args[] = { source, diff --git a/atom/common/native_mate_converters/blink_converter.cc b/atom/common/native_mate_converters/blink_converter.cc index 336323555..80be52039 100644 --- a/atom/common/native_mate_converters/blink_converter.cc +++ b/atom/common/native_mate_converters/blink_converter.cc @@ -12,6 +12,7 @@ #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "content/public/browser/native_web_keyboard_event.h" +#include "gin/converter.h" #include "native_mate/dictionary.h" #include "third_party/blink/public/platform/web_input_event.h" #include "third_party/blink/public/platform/web_mouse_event.h" @@ -41,7 +42,7 @@ struct Converter { static bool FromV8(v8::Isolate* isolate, v8::Handle val, base::char16* out) { - base::string16 code = base::UTF8ToUTF16(V8ToString(val)); + base::string16 code = base::UTF8ToUTF16(gin::V8ToString(isolate, val)); if (code.length() != 1) return false; *out = code[0]; @@ -54,7 +55,7 @@ struct Converter { static bool FromV8(v8::Isolate* isolate, v8::Handle val, blink::WebInputEvent::Type* out) { - std::string type = base::ToLowerASCII(V8ToString(val)); + std::string type = base::ToLowerASCII(gin::V8ToString(isolate, val)); if (type == "mousedown") *out = blink::WebInputEvent::kMouseDown; else if (type == "mouseup") @@ -92,7 +93,7 @@ struct Converter { static bool FromV8(v8::Isolate* isolate, v8::Handle val, blink::WebMouseEvent::Button* out) { - std::string button = base::ToLowerASCII(V8ToString(val)); + std::string button = base::ToLowerASCII(gin::V8ToString(isolate, val)); if (button == "left") *out = blink::WebMouseEvent::Button::kLeft; else if (button == "middle") @@ -110,7 +111,7 @@ struct Converter { static bool FromV8(v8::Isolate* isolate, v8::Handle val, blink::WebInputEvent::Modifiers* out) { - std::string modifier = base::ToLowerASCII(V8ToString(val)); + std::string modifier = base::ToLowerASCII(gin::V8ToString(isolate, val)); if (modifier == "shift") *out = blink::WebInputEvent::kShiftKey; else if (modifier == "control" || modifier == "ctrl") @@ -516,7 +517,7 @@ bool Converter::FromV8( v8::Isolate* isolate, v8::Handle val, blink::WebReferrerPolicy* out) { - std::string policy = base::ToLowerASCII(V8ToString(val)); + std::string policy = base::ToLowerASCII(gin::V8ToString(isolate, val)); if (policy == "default") *out = blink::kWebReferrerPolicyDefault; else if (policy == "unsafe-url") diff --git a/atom/renderer/atom_render_frame_observer.cc b/atom/renderer/atom_render_frame_observer.cc index 09f2a2f32..a9bb53b39 100644 --- a/atom/renderer/atom_render_frame_observer.cc +++ b/atom/renderer/atom_render_frame_observer.cc @@ -46,7 +46,7 @@ bool GetIPCObject(v8::Isolate* isolate, return false; if (value.IsEmpty() || !value->IsObject()) return false; - *ipc = value->ToObject(); + *ipc = value->ToObject(isolate); return true; } diff --git a/atom/renderer/atom_renderer_client.cc b/atom/renderer/atom_renderer_client.cc index d14aa9b36..ac59c9507 100644 --- a/atom/renderer/atom_renderer_client.cc +++ b/atom/renderer/atom_renderer_client.cc @@ -198,12 +198,13 @@ void AtomRendererClient::SetupMainWorldOverrides( std::string left = "(function (binding, require) {\n"; std::string right = "\n})"; auto source = v8::String::Concat( - mate::ConvertToV8(isolate, left)->ToString(), - v8::String::Concat(node::isolated_bundle_value.ToStringChecked(isolate), - mate::ConvertToV8(isolate, right)->ToString())); + isolate, mate::ConvertToV8(isolate, left)->ToString(isolate), + v8::String::Concat(isolate, + node::isolated_bundle_value.ToStringChecked(isolate), + mate::ConvertToV8(isolate, right)->ToString(isolate))); auto result = RunScript(context, source); - CHECK(result->IsFunction()); + DCHECK(result->IsFunction()); auto binding = v8::Object::New(isolate); api::Initialize(binding, v8::Null(isolate), context, nullptr); diff --git a/atom/renderer/atom_sandboxed_renderer_client.cc b/atom/renderer/atom_sandboxed_renderer_client.cc index ac3cf4101..7c492714a 100644 --- a/atom/renderer/atom_sandboxed_renderer_client.cc +++ b/atom/renderer/atom_sandboxed_renderer_client.cc @@ -19,6 +19,7 @@ #include "base/path_service.h" #include "base/process/process_handle.h" #include "content/public/renderer/render_frame.h" +#include "gin/converter.h" #include "native_mate/dictionary.h" #include "third_party/blink/public/web/blink.h" #include "third_party/blink/public/web/web_document.h" @@ -52,7 +53,7 @@ v8::Local GetModuleCache(v8::Isolate* isolate) { global.SetHidden(kModuleCacheKey, cache); } - return cache->ToObject(); + return cache->ToObject(isolate); } // adapted from node.cc @@ -60,7 +61,7 @@ v8::Local GetBinding(v8::Isolate* isolate, v8::Local key, mate::Arguments* margs) { v8::Local exports; - std::string module_key = mate::V8ToString(key); + std::string module_key = gin::V8ToString(isolate, key); mate::Dictionary cache(isolate, GetModuleCache(isolate)); if (cache.Get(module_key.c_str(), &exports)) { @@ -85,6 +86,12 @@ v8::Local GetBinding(v8::Isolate* isolate, return exports; } +v8::Local CreatePreloadScript(v8::Isolate* isolate, + v8::Local preloadSrc) { + return RendererClientBase::RunScript(isolate->GetCurrentContext(), + preloadSrc); +} + class AtomSandboxedRenderFrameObserver : public AtomRenderFrameObserver { public: AtomSandboxedRenderFrameObserver(content::RenderFrame* render_frame, @@ -134,7 +141,7 @@ void AtomSandboxedRendererClient::InitializeBindings( auto* isolate = context->GetIsolate(); mate::Dictionary b(isolate, binding); b.SetMethod("get", GetBinding); - b.SetMethod("createPreloadScript", RunScript); + b.SetMethod("createPreloadScript", CreatePreloadScript); mate::Dictionary process = mate::Dictionary::CreateEmpty(isolate); b.Set("process", process); @@ -184,12 +191,13 @@ void AtomSandboxedRendererClient::DidCreateScriptContext( std::string right = "\n})"; // Compile the wrapper and run it to get the function object auto source = v8::String::Concat( - mate::ConvertToV8(isolate, left)->ToString(), - v8::String::Concat(node::preload_bundle_value.ToStringChecked(isolate), - mate::ConvertToV8(isolate, right)->ToString())); + isolate, mate::ConvertToV8(isolate, left)->ToString(isolate), + v8::String::Concat(isolate, + node::preload_bundle_value.ToStringChecked(isolate), + mate::ConvertToV8(isolate, right)->ToString(isolate))); auto result = RunScript(context, source); - CHECK(result->IsFunction()); + DCHECK(result->IsFunction()); // Create and initialize the binding object auto binding = v8::Object::New(isolate); InitializeBindings(binding, context); @@ -218,7 +226,7 @@ void AtomSandboxedRendererClient::InvokeIpcCallback( const std::string& callback_name, std::vector> args) { auto* isolate = context->GetIsolate(); - auto binding_key = mate::ConvertToV8(isolate, kIpcKey)->ToString(); + auto binding_key = mate::ConvertToV8(isolate, kIpcKey)->ToString(isolate); auto private_binding_key = v8::Private::ForApi(isolate, binding_key); auto global_object = context->Global(); v8::Local value; @@ -226,8 +234,9 @@ void AtomSandboxedRendererClient::InvokeIpcCallback( return; if (value.IsEmpty() || !value->IsObject()) return; - auto binding = value->ToObject(); - auto callback_key = mate::ConvertToV8(isolate, callback_name)->ToString(); + auto binding = value->ToObject(isolate); + auto callback_key = + mate::ConvertToV8(isolate, callback_name)->ToString(isolate); auto callback_value = binding->Get(callback_key); DCHECK(callback_value->IsFunction()); // set by sandboxed_renderer/init.js auto callback = v8::Handle::Cast(callback_value); diff --git a/atom/renderer/renderer_client_base.cc b/atom/renderer/renderer_client_base.cc index fae80e78e..e4588876d 100644 --- a/atom/renderer/renderer_client_base.cc +++ b/atom/renderer/renderer_client_base.cc @@ -277,8 +277,9 @@ v8::Local RendererClientBase::GetContext( return frame->MainWorldScriptContext(); } -v8::Local RunScript(v8::Local context, - v8::Local source) { +v8::Local RendererClientBase::RunScript( + v8::Local context, + v8::Local source) { auto maybe_script = v8::Script::Compile(context, source); v8::Local script; if (!maybe_script.ToLocal(&script)) diff --git a/atom/renderer/renderer_client_base.h b/atom/renderer/renderer_client_base.h index 6ff87d9e7..4700c1cc0 100644 --- a/atom/renderer/renderer_client_base.h +++ b/atom/renderer/renderer_client_base.h @@ -40,7 +40,7 @@ class RendererClientBase : public content::ContentRendererClient { v8::Local GetContext(blink::WebLocalFrame* frame, v8::Isolate* isolate) const; // Executes a given v8 Script - inline v8::Local RunScript(v8::Local context, + static v8::Local RunScript(v8::Local context, v8::Local source); protected: diff --git a/native_mate/native_mate/converter.cc b/native_mate/native_mate/converter.cc index a6998d091..c8260be16 100644 --- a/native_mate/native_mate/converter.cc +++ b/native_mate/native_mate/converter.cc @@ -10,17 +10,33 @@ using v8::Array; using v8::Boolean; using v8::External; using v8::Function; +using v8::Int32; using v8::Integer; using v8::Isolate; using v8::Local; +using v8::Maybe; +using v8::MaybeLocal; using v8::Number; using v8::Object; using v8::Promise; using v8::String; +using v8::Uint32; using v8::Value; namespace mate { +namespace { + +template +bool FromMaybe(Maybe maybe, U* out) { + if (maybe.IsNothing()) + return false; + *out = static_cast(maybe.FromJust()); + return true; +} + +} // namespace + Local Converter::ToV8(Isolate* isolate, bool val) { return v8::Boolean::New(isolate, val); } @@ -28,7 +44,7 @@ Local Converter::ToV8(Isolate* isolate, bool val) { bool Converter::FromV8(Isolate* isolate, Local val, bool* out) { if (!val->IsBoolean()) return false; - *out = val->BooleanValue(); + *out = val.As()->Value(); return true; } @@ -43,8 +59,7 @@ bool Converter::FromV8(Isolate* isolate, unsigned long* out) { if (!val->IsNumber()) return false; - *out = val->IntegerValue(); - return true; + return FromMaybe(val->IntegerValue(isolate->GetCurrentContext()), out); } #endif @@ -57,7 +72,7 @@ bool Converter::FromV8(Isolate* isolate, int32_t* out) { if (!val->IsInt32()) return false; - *out = val->Int32Value(); + *out = val.As()->Value(); return true; } @@ -70,7 +85,7 @@ bool Converter::FromV8(Isolate* isolate, uint32_t* out) { if (!val->IsUint32()) return false; - *out = val->Uint32Value(); + *out = val.As()->Value(); return true; } @@ -85,8 +100,7 @@ bool Converter::FromV8(Isolate* isolate, return false; // Even though IntegerValue returns int64_t, JavaScript cannot represent // the full precision of int64_t, which means some rounding might occur. - *out = val->IntegerValue(); - return true; + return FromMaybe(val->IntegerValue(isolate->GetCurrentContext()), out); } Local Converter::ToV8(Isolate* isolate, uint64_t val) { @@ -98,8 +112,7 @@ bool Converter::FromV8(Isolate* isolate, uint64_t* out) { if (!val->IsNumber()) return false; - *out = static_cast(val->IntegerValue()); - return true; + return FromMaybe(val->IntegerValue(isolate->GetCurrentContext()), out); } Local Converter::ToV8(Isolate* isolate, float val) { @@ -109,7 +122,7 @@ Local Converter::ToV8(Isolate* isolate, float val) { bool Converter::FromV8(Isolate* isolate, Local val, float* out) { if (!val->IsNumber()) return false; - *out = static_cast(val->NumberValue()); + *out = static_cast(val.As()->Value()); return true; } @@ -122,7 +135,7 @@ bool Converter::FromV8(Isolate* isolate, double* out) { if (!val->IsNumber()) return false; - *out = val->NumberValue(); + *out = val.As()->Value(); return true; } @@ -147,9 +160,10 @@ bool Converter::FromV8(Isolate* isolate, if (!val->IsString()) return false; Local str = Local::Cast(val); - int length = str->Utf8Length(); + int length = str->Utf8Length(isolate); out->resize(length); - str->WriteUtf8(&(*out)[0], length, NULL, String::NO_NULL_TERMINATION); + str->WriteUtf8(isolate, &(*out)[0], length, NULL, + String::NO_NULL_TERMINATION); return true; } @@ -245,13 +259,4 @@ v8::Local StringToSymbol(v8::Isolate* isolate, static_cast(val.length())); } -std::string V8ToString(v8::Local value) { - if (value.IsEmpty()) - return std::string(); - std::string result; - if (!ConvertFromV8(NULL, value, &result)) - return std::string(); - return result; -} - } // namespace mate diff --git a/native_mate/native_mate/converter.h b/native_mate/native_mate/converter.h index 9c1bc615c..dfe97edaf 100644 --- a/native_mate/native_mate/converter.h +++ b/native_mate/native_mate/converter.h @@ -11,6 +11,7 @@ #include #include "base/strings/string_piece.h" +#include "gin/converter.h" #include "v8/include/v8.h" namespace mate { @@ -136,8 +137,6 @@ struct Converter { v8::Local StringToSymbol(v8::Isolate* isolate, const base::StringPiece& input); -std::string V8ToString(v8::Local value); - template <> struct Converter> { static v8::Local ToV8(v8::Isolate* isolate, @@ -276,13 +275,14 @@ struct Converter> { if (!val->IsObject()) return false; - v8::Local dict = val->ToObject(); + v8::Local context = isolate->GetCurrentContext(); + v8::Local dict = val->ToObject(context).ToLocalChecked(); v8::Local keys = dict->GetOwnPropertyNames(); for (uint32_t i = 0; i < keys->Length(); ++i) { v8::Local key = keys->Get(i); T value; if (Converter::FromV8(isolate, dict->Get(key), &value)) - (*out)[V8ToString(key)] = std::move(value); + (*out)[gin::V8ToString(isolate, key)] = std::move(value); } return true; } diff --git a/native_mate/native_mate/handle.h b/native_mate/native_mate/handle.h index 60bd2348d..10bd6a32a 100644 --- a/native_mate/native_mate/handle.h +++ b/native_mate/native_mate/handle.h @@ -13,15 +13,13 @@ namespace mate { // Currently we don't have a mechanism for retaining a mate::Wrappable object // in the C++ heap because strong references from C++ to V8 can cause memory // leaks. -template +template class Handle { public: Handle() : object_(NULL) {} Handle(v8::Local wrapper, T* object) - : wrapper_(wrapper), - object_(object) { - } + : wrapper_(wrapper), object_(object) {} bool IsEmpty() const { return !object_; } @@ -39,13 +37,14 @@ class Handle { T* object_; }; -template -struct Converter > { +template +struct Converter> { static v8::Local ToV8(v8::Isolate* isolate, - const mate::Handle& val) { + const mate::Handle& val) { return val.ToV8(); } - static bool FromV8(v8::Isolate* isolate, v8::Local val, + static bool FromV8(v8::Isolate* isolate, + v8::Local val, mate::Handle* out) { T* object = NULL; if (val->IsNull() || val->IsUndefined()) { @@ -55,14 +54,15 @@ struct Converter > { if (!Converter::FromV8(isolate, val, &object)) { return false; } - *out = mate::Handle(val->ToObject(), object); + v8::Local context = isolate->GetCurrentContext(); + *out = mate::Handle(val->ToObject(context).ToLocalChecked(), object); return true; } }; // This function is a convenient way to create a handle from a raw pointer // without having to write out the type of the object explicitly. -template +template mate::Handle CreateHandle(v8::Isolate* isolate, T* object) { return mate::Handle(object->GetWrapper(), object); }