diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-12-10 16:19:40 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2018-12-10 16:01:50 +0000 |
commit | 51f6c2793adab2d864b3d2b360000ef8db1d3e92 (patch) | |
tree | 835b3b4446b012c75e80177cef9fbe6972cc7dbe /chromium/third_party/blink/renderer/bindings/core/v8 | |
parent | 6036726eb981b6c4b42047513b9d3f4ac865daac (diff) | |
download | qtwebengine-chromium-51f6c2793adab2d864b3d2b360000ef8db1d3e92.tar.gz |
BASELINE: Update Chromium to 71.0.3578.93
Change-Id: I6a32086c33670e1b033f8b10e6bf1fd4da1d105d
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/third_party/blink/renderer/bindings/core/v8')
89 files changed, 1967 insertions, 2025 deletions
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/BUILD.gn b/chromium/third_party/blink/renderer/bindings/core/v8/BUILD.gn index 12af3e22fbc..136cb11e63a 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/BUILD.gn +++ b/chromium/third_party/blink/renderer/bindings/core/v8/BUILD.gn @@ -90,6 +90,8 @@ bindings_core_generated_union_type_files = [ "$bindings_core_v8_output_dir/string_or_string_sequence.h", "$bindings_core_v8_output_dir/string_or_trusted_html.cc", "$bindings_core_v8_output_dir/string_or_trusted_html.h", + "$bindings_core_v8_output_dir/string_or_trusted_html_or_trusted_script_or_trusted_script_url_or_trusted_url.cc", + "$bindings_core_v8_output_dir/string_or_trusted_html_or_trusted_script_or_trusted_script_url_or_trusted_url.h", "$bindings_core_v8_output_dir/string_or_trusted_script.cc", "$bindings_core_v8_output_dir/string_or_trusted_script.h", "$bindings_core_v8_output_dir/string_or_trusted_script_url.cc", @@ -128,6 +130,12 @@ generated_core_testing_callback_function_files = [ generated_core_callback_function_files = [ "$bindings_core_v8_output_dir/v8_blob_callback.cc", "$bindings_core_v8_output_dir/v8_blob_callback.h", + "$bindings_core_v8_output_dir/v8_custom_element_constructor.cc", + "$bindings_core_v8_output_dir/v8_custom_element_constructor.h", + "$bindings_core_v8_output_dir/v8_display_lock_callback.cc", + "$bindings_core_v8_output_dir/v8_display_lock_callback.h", + "$bindings_core_v8_output_dir/v8_event_handler_non_null.cc", + "$bindings_core_v8_output_dir/v8_event_handler_non_null.h", "$bindings_core_v8_output_dir/v8_frame_request_callback.cc", "$bindings_core_v8_output_dir/v8_frame_request_callback.h", "$bindings_core_v8_output_dir/v8_function.cc", @@ -156,6 +164,8 @@ generated_core_callback_function_files = [ "$bindings_core_v8_output_dir/v8_create_script_callback.h", "$bindings_core_v8_output_dir/v8_create_url_callback.cc", "$bindings_core_v8_output_dir/v8_create_url_callback.h", + "$bindings_core_v8_output_dir/v8_task_queue_post_callback.cc", + "$bindings_core_v8_output_dir/v8_task_queue_post_callback.h", "$bindings_core_v8_output_dir/v8_void_function.cc", "$bindings_core_v8_output_dir/v8_void_function.h", ] @@ -171,7 +181,7 @@ generate_origin_trial_features("bindings_core_origin_trial_features") { ] } -if ((is_win && is_official_build) || use_jumbo_build) { +if (is_win && is_official_build) { # On Windows Official release builds, we try to preserve symbol space. # is_official_build adds /GL option and /LTCG is automatically enabled in # link.exe. But link.exe cannot make binary smaller than its size limit from @@ -192,7 +202,7 @@ group("bindings_core_v8_generated") { public_deps = [ ":bindings_core_impl_generated", ] - if ((is_win && is_official_build) || use_jumbo_build) { + if (is_win && is_official_build) { public_deps += [ ":generate_bindings_core_v8_all_interfaces" ] } else { public_deps += [ ":generate_bindings_core_v8_interfaces" ] diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/activity_logger_test.cc b/chromium/third_party/blink/renderer/bindings/core/v8/activity_logger_test.cc index bffb605aa8a..a20c1a6c6dc 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/activity_logger_test.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/activity_logger_test.cc @@ -58,8 +58,8 @@ class TestActivityLogger : public V8DOMActivityLogger { void clear() { logged_activities_.clear(); } bool VerifyActivities(const Vector<String>& expected) const { EXPECT_EQ(expected.size(), logged_activities_.size()); - for (size_t i = 0; i < std::min(expected.size(), logged_activities_.size()); - ++i) { + for (wtf_size_t i = 0; + i < std::min(expected.size(), logged_activities_.size()); ++i) { EXPECT_STREQ(expected[i].Utf8().data(), logged_activities_[i].Utf8().data()); } @@ -95,8 +95,8 @@ class ActivityLoggerTest : public testing::Test { void ExecuteScriptInIsolatedWorld(const String& script) const { v8::HandleScope scope(v8::Isolate::GetCurrent()); - script_controller_->ExecuteScriptInIsolatedWorld(kIsolatedWorldId, - ScriptSourceCode(script)); + script_controller_->ExecuteScriptInIsolatedWorld( + kIsolatedWorldId, ScriptSourceCode(script), KURL(), kOpaqueResource); PumpPendingRequestsForFrameToLoad(web_view_helper_.LocalMainFrame()); } diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/binding_security.cc b/chromium/third_party/blink/renderer/bindings/core/v8/binding_security.cc index 8acd39b218c..62c993e3500 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/binding_security.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/binding_security.cc @@ -41,7 +41,6 @@ #include "third_party/blink/renderer/core/frame/settings.h" #include "third_party/blink/renderer/core/frame/use_counter.h" #include "third_party/blink/renderer/core/html/html_frame_element_base.h" -#include "third_party/blink/renderer/core/workers/main_thread_worklet_global_scope.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/wrapper_creation_security_check.h" #include "third_party/blink/renderer/platform/weborigin/security_origin.h" @@ -65,10 +64,22 @@ bool CanAccessWindowInternal(const LocalDOMWindow* accessing_window, const SecurityOrigin* accessing_origin = accessing_window->document()->GetSecurityOrigin(); const LocalDOMWindow* local_target_window = ToLocalDOMWindow(target_window); - if (!accessing_origin->CanAccess( - local_target_window->document()->GetSecurityOrigin())) { - return false; + + SecurityOrigin::AccessResultDomainDetail detail; + bool can_access = accessing_origin->CanAccess( + local_target_window->document()->GetSecurityOrigin(), detail); + if (detail == + SecurityOrigin::AccessResultDomainDetail::kDomainSetByOnlyOneOrigin || + detail == + SecurityOrigin::AccessResultDomainDetail::kDomainMatchNecessary || + detail == SecurityOrigin::AccessResultDomainDetail::kDomainMismatch) { + UseCounter::Count( + accessing_window->GetFrame(), + can_access ? WebFeature::kDocumentDomainEnabledCrossOriginAccess + : WebFeature::kDocumentDomainBlockedCrossOriginAccess); } + if (!can_access) + return false; // Notify the loader's client if the initial document has been accessed. LocalFrame* target_frame = local_target_window->GetFrame(); diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/binding_security_test.cc b/chromium/third_party/blink/renderer/bindings/core/v8/binding_security_test.cc index d1e2a81fe71..fdab78944ac 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/binding_security_test.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/binding_security_test.cc @@ -17,56 +17,97 @@ namespace blink { namespace { const char kMainFrame[] = "https://example.com/main.html"; const char kSameOriginTarget[] = "https://example.com/target.html"; +const char kSameOriginDomainTarget[] = "https://sub.example.com/target.html"; const char kCrossOriginTarget[] = "https://not-example.com/target.html"; + +const char kTargetHTML[] = + "<!DOCTYPE html>" + "<script>" + " (window.opener || window.top).postMessage('yay', '*');" + "</script>"; +const char kSameOriginDomainTargetHTML[] = + "<!DOCTYPE html>" + "<script>" + " document.domain = 'example.com';" + " (window.opener || window.top).postMessage('yay', '*');" + "</script>"; } class BindingSecurityCounterTest : public SimTest, public testing::WithParamInterface<const char*> { public: - enum class OriginDisposition { CrossOrigin, SameOrigin }; + enum class OriginDisposition { CrossOrigin, SameOrigin, SameOriginDomain }; BindingSecurityCounterTest() = default; void LoadWindowAndAccessProperty(OriginDisposition which_origin, const String& property) { + const char* target_url; + const char* target_html; + switch (which_origin) { + case OriginDisposition::CrossOrigin: + target_url = kCrossOriginTarget; + target_html = kTargetHTML; + break; + case OriginDisposition::SameOrigin: + target_url = kSameOriginTarget; + target_html = kTargetHTML; + break; + case OriginDisposition::SameOriginDomain: + target_url = kSameOriginDomainTarget; + target_html = kSameOriginDomainTargetHTML; + break; + } + SimRequest main(kMainFrame, "text/html"); - SimRequest target(which_origin == OriginDisposition::CrossOrigin - ? kCrossOriginTarget - : kSameOriginTarget, - "text/html"); + SimRequest target(target_url, "text/html"); const String& document = String::Format( "<!DOCTYPE html>" "<script>" + " %s" " window.addEventListener('message', e => {" " window.other = e.source.%s;" " console.log('yay');" " });" " var w = window.open('%s');" "</script>", - property.Utf8().data(), - which_origin == OriginDisposition::CrossOrigin ? kCrossOriginTarget - : kSameOriginTarget); + which_origin == OriginDisposition::SameOriginDomain + ? "document.domain = 'example.com';" + : "", + property.Utf8().data(), target_url); LoadURL(kMainFrame); main.Complete(document); - target.Complete( - "<!DOCTYPE html>" - "<script>window.opener.postMessage('yay', '*');</script>"); + target.Complete(target_html); test::RunPendingTasks(); } void LoadFrameAndAccessProperty(OriginDisposition which_origin, const String& property) { + const char* target_url; + const char* target_html; + switch (which_origin) { + case OriginDisposition::CrossOrigin: + target_url = kCrossOriginTarget; + target_html = kTargetHTML; + break; + case OriginDisposition::SameOrigin: + target_url = kSameOriginTarget; + target_html = kTargetHTML; + break; + case OriginDisposition::SameOriginDomain: + target_url = kSameOriginDomainTarget; + target_html = kSameOriginDomainTargetHTML; + break; + } SimRequest main(kMainFrame, "text/html"); - SimRequest target(which_origin == OriginDisposition::CrossOrigin - ? kCrossOriginTarget - : kSameOriginTarget, - "text/html"); + SimRequest target(target_url, "text/html"); const String& document = String::Format( "<!DOCTYPE html>" "<body>" "<script>" + " %s" " var i = document.createElement('iframe');" " window.addEventListener('message', e => {" " window.other = e.source.%s;" @@ -75,15 +116,14 @@ class BindingSecurityCounterTest " i.src = '%s';" " document.body.appendChild(i);" "</script>", - property.Utf8().data(), - which_origin == OriginDisposition::CrossOrigin ? kCrossOriginTarget - : kSameOriginTarget); + which_origin == OriginDisposition::SameOriginDomain + ? "document.domain = 'example.com';" + : "", + property.Utf8().data(), target_url); LoadURL(kMainFrame); main.Complete(document); - target.Complete( - "<!DOCTYPE html>" - "<script>window.top.postMessage('yay', '*');</script>"); + target.Complete(target_html); test::RunPendingTasks(); } }; @@ -110,6 +150,8 @@ TEST_P(BindingSecurityCounterTest, CrossOriginWindow) { WebFeature::kCrossOriginPropertyAccess)); EXPECT_TRUE(GetDocument().Loader()->GetUseCounter().HasRecordedMeasurement( WebFeature::kCrossOriginPropertyAccessFromOpener)); + EXPECT_FALSE(GetDocument().Loader()->GetUseCounter().HasRecordedMeasurement( + WebFeature::kDocumentDomainEnabledCrossOriginAccess)); } TEST_P(BindingSecurityCounterTest, SameOriginWindow) { @@ -118,6 +160,18 @@ TEST_P(BindingSecurityCounterTest, SameOriginWindow) { WebFeature::kCrossOriginPropertyAccess)); EXPECT_FALSE(GetDocument().Loader()->GetUseCounter().HasRecordedMeasurement( WebFeature::kCrossOriginPropertyAccessFromOpener)); + EXPECT_FALSE(GetDocument().Loader()->GetUseCounter().HasRecordedMeasurement( + WebFeature::kDocumentDomainEnabledCrossOriginAccess)); +} + +TEST_P(BindingSecurityCounterTest, SameOriginDomainWindow) { + LoadWindowAndAccessProperty(OriginDisposition::SameOriginDomain, GetParam()); + EXPECT_FALSE(GetDocument().Loader()->GetUseCounter().HasRecordedMeasurement( + WebFeature::kCrossOriginPropertyAccess)); + EXPECT_FALSE(GetDocument().Loader()->GetUseCounter().HasRecordedMeasurement( + WebFeature::kCrossOriginPropertyAccessFromOpener)); + EXPECT_TRUE(GetDocument().Loader()->GetUseCounter().HasRecordedMeasurement( + WebFeature::kDocumentDomainEnabledCrossOriginAccess)); } TEST_P(BindingSecurityCounterTest, CrossOriginFrame) { @@ -126,6 +180,8 @@ TEST_P(BindingSecurityCounterTest, CrossOriginFrame) { WebFeature::kCrossOriginPropertyAccess)); EXPECT_FALSE(GetDocument().Loader()->GetUseCounter().HasRecordedMeasurement( WebFeature::kCrossOriginPropertyAccessFromOpener)); + EXPECT_FALSE(GetDocument().Loader()->GetUseCounter().HasRecordedMeasurement( + WebFeature::kDocumentDomainEnabledCrossOriginAccess)); } TEST_P(BindingSecurityCounterTest, SameOriginFrame) { @@ -134,6 +190,18 @@ TEST_P(BindingSecurityCounterTest, SameOriginFrame) { WebFeature::kCrossOriginPropertyAccess)); EXPECT_FALSE(GetDocument().Loader()->GetUseCounter().HasRecordedMeasurement( WebFeature::kCrossOriginPropertyAccessFromOpener)); + EXPECT_FALSE(GetDocument().Loader()->GetUseCounter().HasRecordedMeasurement( + WebFeature::kDocumentDomainEnabledCrossOriginAccess)); +} + +TEST_P(BindingSecurityCounterTest, SameOriginDomainFrame) { + LoadFrameAndAccessProperty(OriginDisposition::SameOriginDomain, GetParam()); + EXPECT_FALSE(GetDocument().Loader()->GetUseCounter().HasRecordedMeasurement( + WebFeature::kCrossOriginPropertyAccess)); + EXPECT_FALSE(GetDocument().Loader()->GetUseCounter().HasRecordedMeasurement( + WebFeature::kCrossOriginPropertyAccessFromOpener)); + EXPECT_TRUE(GetDocument().Loader()->GetUseCounter().HasRecordedMeasurement( + WebFeature::kDocumentDomainEnabledCrossOriginAccess)); } } // namespace diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_dev_tools_host_custom.cc b/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_dev_tools_host_custom.cc index 852964413d3..2234657ffc5 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_dev_tools_host_custom.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_dev_tools_host_custom.cc @@ -60,7 +60,7 @@ static bool PopulateContextMenuItems(v8::Isolate* isolate, const v8::Local<v8::Array>& item_array, WebVector<WebMenuItemInfo>& items) { v8::Local<v8::Context> context = isolate->GetCurrentContext(); - for (size_t i = 0; i < item_array->Length(); ++i) { + for (uint32_t i = 0; i < item_array->Length(); ++i) { v8::Local<v8::Object> item = item_array->Get(context, i).ToLocalChecked().As<v8::Object>(); v8::Local<v8::Value> type; diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_error_event_custom.cc b/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_error_event_custom.cc index 7465927c5c7..5176f91a49f 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_error_event_custom.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_error_event_custom.cc @@ -31,29 +31,19 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_error_event.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" -#include "third_party/blink/renderer/platform/bindings/v8_private_property.h" namespace blink { void V8ErrorEvent::errorAttributeGetterCustom( const v8::FunctionCallbackInfo<v8::Value>& info) { v8::Isolate* isolate = info.GetIsolate(); - - auto private_error = V8PrivateProperty::GetErrorEventError(isolate); - v8::Local<v8::Value> cached_error; - if (private_error.GetOrUndefined(info.Holder()).ToLocal(&cached_error) && - !cached_error->IsUndefined()) { - V8SetReturnValue(info, cached_error); - return; - } - ErrorEvent* event = V8ErrorEvent::ToImpl(info.Holder()); ScriptState* script_state = ScriptState::From(isolate->GetCurrentContext()); + ScriptValue error = event->error(script_state); v8::Local<v8::Value> error_value = error.IsEmpty() ? v8::Local<v8::Value>(v8::Null(isolate)) : error.V8Value(); - private_error.Set(info.Holder(), error_value); V8SetReturnValue(info, error_value); } diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_window_custom.cc b/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_window_custom.cc index 61a39188ccd..cb3a09fdedb 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_window_custom.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_window_custom.cc @@ -35,7 +35,6 @@ #include "third_party/blink/renderer/bindings/core/v8/script_source_code.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" #include "third_party/blink/renderer/bindings/core/v8/v8_event.h" -#include "third_party/blink/renderer/bindings/core/v8/v8_event_listener_or_event_handler.h" #include "third_party/blink/renderer/bindings/core/v8/v8_html_collection.h" #include "third_party/blink/renderer/bindings/core/v8/v8_node.h" #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h" diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/dictionary.h b/chromium/third_party/blink/renderer/bindings/core/v8/dictionary.h index e9de11c8d69..6fc37eef2cc 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/dictionary.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/dictionary.h @@ -40,7 +40,7 @@ namespace blink { // from a V8 object. Instances of this class must not outlive V8's handle scope // because they hold a V8 value without putting it on persistent handles. class CORE_EXPORT Dictionary final { - DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); + DISALLOW_NEW(); public: Dictionary() : isolate_(nullptr) {} diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/dictionary_helper_for_core.cc b/chromium/third_party/blink/renderer/bindings/core/v8/dictionary_helper_for_core.cc index 8924bb1485e..72e61ab2a13 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/dictionary_helper_for_core.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/dictionary_helper_for_core.cc @@ -226,7 +226,7 @@ CORE_EXPORT bool DictionaryHelper::Get(const Dictionary& dictionary, return false; v8::Local<v8::Array> v8_array = v8::Local<v8::Array>::Cast(v8_value); - for (size_t i = 0; i < v8_array->Length(); ++i) { + for (uint32_t i = 0; i < v8_array->Length(); ++i) { v8::Local<v8::Value> indexed_value; if (!v8_array ->Get(dictionary.V8Context(), diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/dom_wrapper_world_test.cc b/chromium/third_party/blink/renderer/bindings/core/v8/dom_wrapper_world_test.cc index 8a22d007941..ef15fb17869 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/dom_wrapper_world_test.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/dom_wrapper_world_test.cc @@ -37,11 +37,11 @@ Vector<scoped_refptr<DOMWrapperWorld>> CreateWorlds(v8::Isolate* isolate) { DOMWrapperWorld::Create(isolate, DOMWrapperWorld::WorldType::kWorker)); worlds.push_back( DOMWrapperWorld::Create(isolate, DOMWrapperWorld::WorldType::kWorker)); - worlds.push_back(DOMWrapperWorld::Create( - isolate, DOMWrapperWorld::WorldType::kGarbageCollector)); + worlds.push_back( + DOMWrapperWorld::Create(isolate, DOMWrapperWorld::WorldType::kWorker)); EXPECT_TRUE(worlds[0]->IsWorkerWorld()); EXPECT_TRUE(worlds[1]->IsWorkerWorld()); - EXPECT_FALSE(worlds[2]->IsWorkerWorld()); + EXPECT_TRUE(worlds[2]->IsWorkerWorld()); // World ids should be unique. HashSet<int> world_ids; @@ -70,11 +70,6 @@ void WorkerThreadFunc( EXPECT_EQ(worlds.size(), retrieved_worlds.size()); retrieved_worlds.clear(); - // Dispose of the last world. - worlds.pop_back(); - DOMWrapperWorld::AllWorldsInCurrentThread(retrieved_worlds); - EXPECT_EQ(worlds.size(), retrieved_worlds.size()); - // Dispose of remaining worlds. for (scoped_refptr<DOMWrapperWorld>& world : worlds) { if (world->IsWorkerWorld()) @@ -118,7 +113,7 @@ TEST(DOMWrapperWorldTest, Basic) { // Start a worker thread and create worlds on that. std::unique_ptr<WorkerBackingThread> thread = WorkerBackingThread::Create( - WebThreadCreationParams(WebThreadType::kTestThread) + ThreadCreationParams(WebThreadType::kTestThread) .SetThreadNameForTest("DOMWrapperWorld test thread")); scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner = Platform::Current()->CurrentThread()->GetTaskRunner(); diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/generated_code_helper.cc b/chromium/third_party/blink/renderer/bindings/core/v8/generated_code_helper.cc index ead42a890c9..1042a3ef684 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/generated_code_helper.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/generated_code_helper.cc @@ -32,18 +32,28 @@ v8::Local<v8::Value> V8Deserialize(v8::Isolate* isolate, return v8::Null(isolate); } -bool IsCallbackFunctionRunnable( +namespace { + +enum class IgnorePause { kDontIgnore, kIgnore }; + +// 'beforeunload' event listeners are runnable even when execution contexts are +// paused. Use |RespectPause::kPrioritizeOverPause| in such a case. +bool IsCallbackFunctionRunnableInternal( const ScriptState* callback_relevant_script_state, - ScriptState* incumbent_script_state) { + const ScriptState* incumbent_script_state, + IgnorePause ignore_pause) { if (!callback_relevant_script_state->ContextIsValid()) return false; const ExecutionContext* relevant_execution_context = ExecutionContext::From(callback_relevant_script_state); if (!relevant_execution_context || - relevant_execution_context->IsContextPaused() || relevant_execution_context->IsContextDestroyed()) { return false; } + if (relevant_execution_context->IsContextPaused()) { + if (ignore_pause == IgnorePause::kDontIgnore) + return false; + } // TODO(yukishiino): Callback function type value must make the incumbent // environment alive, i.e. the reference to v8::Context must be strong. @@ -60,12 +70,34 @@ bool IsCallbackFunctionRunnable( // the callback. // TODO(crbug.com/608641): move IsMainWorld check into // ExecutionContext::CanExecuteScripts() - return incumbent_execution_context && - !incumbent_execution_context->IsContextPaused() && - !incumbent_execution_context->IsContextDestroyed() && - (!incumbent_script_state->World().IsMainWorld() || - incumbent_execution_context->CanExecuteScripts( - kAboutToExecuteScript)); + if (!incumbent_execution_context || + incumbent_execution_context->IsContextDestroyed()) { + return false; + } + if (incumbent_execution_context->IsContextPaused()) { + if (ignore_pause == IgnorePause::kDontIgnore) + return false; + } + return !incumbent_script_state->World().IsMainWorld() || + incumbent_execution_context->CanExecuteScripts(kAboutToExecuteScript); +} + +} // namespace + +bool IsCallbackFunctionRunnable( + const ScriptState* callback_relevant_script_state, + const ScriptState* incumbent_script_state) { + return IsCallbackFunctionRunnableInternal(callback_relevant_script_state, + incumbent_script_state, + IgnorePause::kDontIgnore); +} + +bool IsCallbackFunctionRunnableIgnoringPause( + const ScriptState* callback_relevant_script_state, + const ScriptState* incumbent_script_state) { + return IsCallbackFunctionRunnableInternal(callback_relevant_script_state, + incumbent_script_state, + IgnorePause::kIgnore); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/generated_code_helper.h b/chromium/third_party/blink/renderer/bindings/core/v8/generated_code_helper.h index 806710d2932..43c33dd3a99 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/generated_code_helper.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/generated_code_helper.h @@ -36,7 +36,7 @@ CORE_EXPORT v8::Local<v8::Value> V8Deserialize(v8::Isolate*, // Promise-returning DOM operations are required to always return a promise // and to never throw an exception. // See also http://heycam.github.io/webidl/#es-operations -class CORE_EXPORT ExceptionToRejectPromiseScope { +class CORE_EXPORT ExceptionToRejectPromiseScope final { STACK_ALLOCATED(); public: @@ -62,7 +62,11 @@ class CORE_EXPORT ExceptionToRejectPromiseScope { CORE_EXPORT bool IsCallbackFunctionRunnable( const ScriptState* callback_relevant_script_state, - ScriptState* incumbent_script_state); + const ScriptState* incumbent_script_state); + +CORE_EXPORT bool IsCallbackFunctionRunnableIgnoringPause( + const ScriptState* callback_relevant_script_state, + const ScriptState* incumbent_script_state); using InstallTemplateFunction = void (*)(v8::Isolate* isolate, diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/idl_dictionary_base.h b/chromium/third_party/blink/renderer/bindings/core/v8/idl_dictionary_base.h index 6b65ea022cd..d8e51b805d6 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/idl_dictionary_base.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/idl_dictionary_base.h @@ -16,7 +16,7 @@ namespace blink { // by auto-generated IDL dictionary impl classes. toV8Impl() is used // in ToV8.h to provide a consistent API of ToV8(). class CORE_EXPORT IDLDictionaryBase { - DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); + DISALLOW_NEW(); public: IDLDictionaryBase() = default; diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/js_based_event_listener.cc b/chromium/third_party/blink/renderer/bindings/core/v8/js_based_event_listener.cc new file mode 100644 index 00000000000..96b6a228e46 --- /dev/null +++ b/chromium/third_party/blink/renderer/bindings/core/v8/js_based_event_listener.cc @@ -0,0 +1,171 @@ +// Copyright 2018 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 file. + +#include "third_party/blink/renderer/bindings/core/v8/js_based_event_listener.h" + +#include "third_party/blink/renderer/bindings/core/v8/source_location.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" +#include "third_party/blink/renderer/core/dom/document.h" +#include "third_party/blink/renderer/core/dom/document_parser.h" +#include "third_party/blink/renderer/core/dom/events/event.h" +#include "third_party/blink/renderer/core/dom/events/event_target.h" +#include "third_party/blink/renderer/platform/instance_counters.h" + +namespace blink { + +JSBasedEventListener::JSBasedEventListener(ListenerType listener_type) + : EventListener(listener_type) { + DCHECK(IsJSBased()); + if (IsMainThread()) { + InstanceCounters::IncrementCounter( + InstanceCounters::kJSEventListenerCounter); + } +} + +JSBasedEventListener::~JSBasedEventListener() { + if (IsMainThread()) { + InstanceCounters::DecrementCounter( + InstanceCounters::kJSEventListenerCounter); + } +} + +bool JSBasedEventListener::BelongsToTheCurrentWorld( + ExecutionContext* execution_context) const { + v8::Isolate* isolate = GetIsolate(); + if (!isolate->GetCurrentContext().IsEmpty() && + &GetWorld() == &DOMWrapperWorld::Current(isolate)) + return true; + // If currently parsing, the parser could be accessing this listener + // outside of any v8 context; check if it belongs to the main world. + if (!isolate->InContext() && execution_context && + execution_context->IsDocument()) { + Document* document = To<Document>(execution_context); + if (document->Parser() && document->Parser()->IsParsing()) + return GetWorld().IsMainWorld(); + } + return false; +} + +// Implements step 2. of "inner invoke". +// https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke +void JSBasedEventListener::handleEvent( + ExecutionContext* execution_context_of_event_target, + Event* event) { + DCHECK(execution_context_of_event_target); + DCHECK(event); + + // TODO(crbug.com/893449): Replace this early return by + // DCHECK(event->target()) and DCHECK(event->currentTarget) because they + // should not be null on dispatching event. + if (!event->target() || !event->currentTarget()) + return; + + v8::Isolate* isolate = GetIsolate(); + + // Don't reenter V8 if execution was terminated in this instance of V8. + // For example, worker can be terminated in event listener, and also window + // can be terminated from inspector by the TerminateExecution method. + if (isolate->IsExecutionTerminating()) + return; + + if (!event->CanBeDispatchedInWorld(GetWorld())) + return; + + { + v8::HandleScope scope(isolate); + + // Calling |GetListenerObject()| here may cause compilation of the + // uncompiled script body in eventHandler's value earlier than standard's + // order, which says it should be done in step 10. There is no behavioral + // difference but the advantage that we can use listener's |ScriptState| + // after it get compiled. + // https://html.spec.whatwg.org/multipage/webappapis.html#event-handler-value + v8::Local<v8::Value> listener = GetListenerObject(*event->target()); + + if (listener.IsEmpty() || !listener->IsObject()) + return; + } + + ScriptState* script_state_of_listener = GetScriptState(); + DCHECK(script_state_of_listener); + if (!script_state_of_listener->ContextIsValid()) + return; + + ScriptState::Scope scope(script_state_of_listener); + + // https://dom.spec.whatwg.org/#firing-events + // Step 2. of firing events: Let event be the result of creating an event + // given eventConstructor, in the relevant Realm of target. + // + // |js_event|, a V8 wrapper object for |event|, must be created in the + // relevant realm of the event target. The world must match the event + // listener's world. + v8::Local<v8::Context> v8_context = + ToV8Context(execution_context_of_event_target, GetWorld()); + if (v8_context.IsEmpty()) + return; + v8::Local<v8::Value> js_event = ToV8(event, v8_context->Global(), isolate); + if (js_event.IsEmpty()) + return; + + // Step 6: Let |global| be listener callback’s associated Realm’s global + // object. + v8::Local<v8::Object> global = + script_state_of_listener->GetContext()->Global(); + + // Step 8: If global is a Window object, then: + // Set currentEvent to global’s current event. + // If tuple’s item-in-shadow-tree is false, then set global’s current event to + // event. + V8PrivateProperty::Symbol event_symbol = + V8PrivateProperty::GetGlobalEvent(isolate); + ExecutionContext* execution_context_of_listener = + ExecutionContext::From(script_state_of_listener); + v8::Local<v8::Value> current_event; + if (execution_context_of_listener->IsDocument()) { + current_event = event_symbol.GetOrUndefined(global).ToLocalChecked(); + // Expose the event object as |window.event|, except when the event's target + // is in a V1 shadow tree. + Node* target_node = event->target()->ToNode(); + if (!(target_node && target_node->IsInV1ShadowTree())) + event_symbol.Set(global, js_event); + } + + { + // Catch exceptions thrown in the event listener if any and report them to + // DevTools console. + v8::TryCatch try_catch(isolate); + try_catch.SetVerbose(true); + + // Step 10: Call a listener with event's currentTarget as receiver and event + // and handle errors if thrown. + CallListenerFunction(*event->currentTarget(), *event, js_event); + + if (try_catch.HasCaught()) { + // Step 10-2: Set legacyOutputDidListenersThrowFlag if given. + event->LegacySetDidListenersThrowFlag(); + } + + // |event_symbol.Set(global, current_event)| cannot and does not have to be + // performed when the isolate is terminating. + if (isolate->IsExecutionTerminating()) + return; + } + + // Step 12: If |global| is a Window object, then set |global|’s current event + // to |current_event|. + if (execution_context_of_listener->IsDocument()) + event_symbol.Set(global, current_event); +} + +std::unique_ptr<SourceLocation> JSBasedEventListener::GetSourceLocation( + EventTarget& target) { + v8::HandleScope handle_scope(GetIsolate()); + v8::Local<v8::Value> effective_function = GetEffectiveFunction(target); + if (effective_function->IsFunction()) + return SourceLocation::FromFunction(effective_function.As<v8::Function>()); + return nullptr; +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/js_based_event_listener.h b/chromium/third_party/blink/renderer/bindings/core/v8/js_based_event_listener.h new file mode 100644 index 00000000000..270d5b4f219 --- /dev/null +++ b/chromium/third_party/blink/renderer/bindings/core/v8/js_based_event_listener.h @@ -0,0 +1,93 @@ +// Copyright 2018 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 file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_JS_BASED_EVENT_LISTENER_H_ +#define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_JS_BASED_EVENT_LISTENER_H_ + +#include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/core/dom/events/event_listener.h" +#include "v8/include/v8.h" + +namespace blink { + +class DOMWrapperWorld; +class Event; +class EventTarget; +class SourceLocation; + +// |JSBasedEventListener| is the base class for JS-based event listeners, +// i.e. EventListener and EventHandler in the standards. +// This provides the essential APIs of JS-based event listeners and also +// implements the common features. +class CORE_EXPORT JSBasedEventListener : public EventListener { + public: + static const JSBasedEventListener* Cast(const EventListener* listener) { + return listener && listener->IsJSBased() + ? static_cast<const JSBasedEventListener*>(listener) + : nullptr; + } + + static JSBasedEventListener* Cast(EventListener* listener) { + return const_cast<JSBasedEventListener*>( + Cast(const_cast<const EventListener*>(listener))); + } + + // TODO(bindings): consider to remove this (and use GetListenerObject() + // instead) because this method is used in mostly only generated classes. + static v8::Local<v8::Value> GetListenerOrNull(v8::Isolate* isolate, + EventTarget* event_target, + EventListener* listener) { + if (auto* v8_listener = Cast(listener)) + return v8_listener->GetListenerObject(*event_target); + return v8::Null(isolate); + } + + ~JSBasedEventListener() override; + + // blink::EventListener overrides: + bool BelongsToTheCurrentWorld(ExecutionContext*) const final; + // Implements step 2. of "inner invoke". + // See: https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke + void handleEvent(ExecutionContext*, Event*) final; + + // |GetListenerObject()| and |GetEffectiveFunction()| may cause JS in the + // content attribute to get compiled, potentially unsuccessfully. + // + // Implements "get the current value of the event handler". + // https://html.spec.whatwg.org/multipage/webappapis.html#getting-the-current-value-of-the-event-handler + // Returns v8::Null with firing error event instead of throwing an exception + // on failing to compile the uncompiled script body in eventHandler's value. + // Also, this can return empty because of crbug.com/881688 . + virtual v8::Local<v8::Value> GetListenerObject(EventTarget&) = 0; + + // Returns v8::Function that handles invoked event or v8::Undefined without + // throwing any exception. + virtual v8::Local<v8::Value> GetEffectiveFunction(EventTarget&) = 0; + + // Only DevTools is allowed to use this method. + DOMWrapperWorld& GetWorldForInspector() const { return GetWorld(); } + + virtual std::unique_ptr<SourceLocation> GetSourceLocation(EventTarget&); + + protected: + explicit JSBasedEventListener(ListenerType); + virtual v8::Isolate* GetIsolate() const = 0; + virtual ScriptState* GetScriptState() const = 0; + virtual DOMWrapperWorld& GetWorld() const = 0; + + private: + // Performs "call a user object's operation", required in "inner-invoke". + // "The event handler processing algorithm" corresponds to this in the case of + // EventHandler. + // This may throw an exception on invoking the listener. + // See step 2-10: + // https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke + virtual void CallListenerFunction(EventTarget&, + Event&, + v8::Local<v8::Value> js_event) = 0; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_JS_BASED_EVENT_LISTENER_H_ diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/js_event_handler.cc b/chromium/third_party/blink/renderer/bindings/core/v8/js_event_handler.cc new file mode 100644 index 00000000000..5efd94e1e60 --- /dev/null +++ b/chromium/third_party/blink/renderer/bindings/core/v8/js_event_handler.cc @@ -0,0 +1,178 @@ +// Copyright 2018 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 file. + +#include "third_party/blink/renderer/bindings/core/v8/js_event_handler.h" + +#include "third_party/blink/renderer/bindings/core/v8/script_value.h" +#include "third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_string_resource.h" +#include "third_party/blink/renderer/core/dom/events/event_target.h" +#include "third_party/blink/renderer/core/events/before_unload_event.h" +#include "third_party/blink/renderer/core/events/error_event.h" + +namespace blink { + +v8::Local<v8::Value> JSEventHandler::GetEffectiveFunction(EventTarget& target) { + v8::Local<v8::Value> v8_listener = GetListenerObject(target); + if (!v8_listener.IsEmpty() && v8_listener->IsFunction()) + return GetBoundFunction(v8_listener.As<v8::Function>()); + return v8::Undefined(GetIsolate()); +} + +void JSEventHandler::SetCompiledHandler( + ScriptState* script_state, + v8::Local<v8::Function> listener, + const V8PrivateProperty::Symbol& property) { + DCHECK(!HasCompiledHandler()); + v8::Context::BackupIncumbentScope backup_incumbent_scope( + script_state->GetContext()); + event_handler_ = V8EventHandlerNonNull::Create(listener); + Attach(script_state, listener, property, this); +} + +// https://html.spec.whatwg.org/C/webappapis.html#the-event-handler-processing-algorithm +void JSEventHandler::CallListenerFunction(EventTarget& event_target, + Event& event, + v8::Local<v8::Value> js_event) { + DCHECK(!js_event.IsEmpty()); + + // Step 1. Let callback be the result of getting the current value of the + // event handler given eventTarget and name. + // Step 2. If callback is null, then return. + v8::Local<v8::Value> listener_value = GetListenerObject(event_target); + if (listener_value.IsEmpty() || listener_value->IsNull()) + return; + DCHECK(HasCompiledHandler()); + + // Step 3. Let special error event handling be true if event is an ErrorEvent + // object, event's type is error, and event's currentTarget implements the + // WindowOrWorkerGlobalScope mixin. Otherwise, let special error event + // handling be false. + const bool special_error_event_handling = + event.IsErrorEvent() && event.type() == EventTypeNames::error && + event.currentTarget()->IsWindowOrWorkerGlobalScope(); + + // Step 4. Process the Event object event as follows: + // If special error event handling is true + // Invoke callback with five arguments, the first one having the value of + // event's message attribute, the second having the value of event's + // filename attribute, the third having the value of event's lineno + // attribute, the fourth having the value of event's colno attribute, the + // fifth having the value of event's error attribute, and with the + // callback this value set to event's currentTarget. Let return value be + // the callback's return value. + // Otherwise + // Invoke callback with one argument, the value of which is the Event + // object event, with the callback this value set to event's + // currentTarget. Let return value be the callback's return value. + // If an exception gets thrown by the callback, end these steps and allow + // the exception to propagate. (It will propagate to the DOM event dispatch + // logic, which will then report the exception.) + Vector<ScriptValue> arguments; + ScriptState* script_state_of_listener = + event_handler_->CallbackRelevantScriptState(); + + if (special_error_event_handling) { + ErrorEvent* error_event = ToErrorEvent(&event); + + // The error argument should be initialized to null for dedicated workers. + // https://html.spec.whatwg.org/C/workers.html#runtime-script-errors-2 + ScriptValue error_attribute = error_event->error(script_state_of_listener); + if (error_attribute.IsEmpty() || + error_event->target()->InterfaceName() == EventTargetNames::Worker) + error_attribute = ScriptValue::CreateNull(script_state_of_listener); + + arguments = { + ScriptValue::From(script_state_of_listener, error_event->message()), + ScriptValue::From(script_state_of_listener, error_event->filename()), + ScriptValue::From(script_state_of_listener, error_event->lineno()), + ScriptValue::From(script_state_of_listener, error_event->colno()), + error_attribute}; + } else { + arguments = {ScriptValue::From(script_state_of_listener, js_event)}; + } + + const bool is_beforeunload_event = + event.IsBeforeUnloadEvent() && + event.type() == EventTypeNames::beforeunload; + const bool is_print_event = + // TODO(yukishiino): Should check event.Is{Before,After}PrintEvent. + event.type() == EventTypeNames::beforeprint || + event.type() == EventTypeNames::afterprint; + if (!event_handler_->IsRunnableOrThrowException( + (is_beforeunload_event || is_print_event) + ? V8EventHandlerNonNull::IgnorePause::kIgnore + : V8EventHandlerNonNull::IgnorePause::kDontIgnore)) { + return; + } + ScriptValue result; + if (!event_handler_ + ->InvokeWithoutRunnabilityCheck(event.currentTarget(), arguments) + .To(&result) || + GetIsolate()->IsExecutionTerminating()) + return; + v8::Local<v8::Value> v8_return_value = result.V8Value(); + + // There is nothing to do if |v8_return_value| is null or undefined. + // See Step 5. for more information. + if (v8_return_value->IsNullOrUndefined()) + return; + + // https://heycam.github.io/webidl/#invoke-a-callback-function + // step 13: Set completion to the result of converting callResult.[[Value]] to + // an IDL value of the same type as the operation's return type. + // + // OnBeforeUnloadEventHandler returns DOMString? while OnErrorEventHandler and + // EventHandler return any, so converting |v8_return_value| to return type is + // necessary only for OnBeforeUnloadEventHandler. + String result_for_beforeunload; + if (IsOnBeforeUnloadEventHandler()) { + // TODO(yukiy): use |NativeValueTraits|. + V8StringResource<> native_result(v8_return_value); + + // |native_result.Prepare()| throws exception if it fails to convert + // |native_result| to String. + if (!native_result.Prepare()) + return; + result_for_beforeunload = native_result; + } + + // Step 5. Process return value as follows: + // If event is a BeforeUnloadEvent object and event's type is beforeunload + // If return value is not null, then: + // 1. Set event's canceled flag. + // 2. If event's returnValue attribute's value is the empty string, then + // set event's returnValue attribute's value to return value. + // If special error event handling is true + // If return value is true, then set event's canceled flag. + // Otherwise + // If return value is false, then set event's canceled flag. + // Note: If we've gotten to this "Otherwise" clause because event's type + // is beforeunload but event is not a BeforeUnloadEvent object, + // then return value will never be false, since in such cases + // return value will have been coerced into either null or a + // DOMString. + if (is_beforeunload_event) { + if (result_for_beforeunload) { + event.preventDefault(); + BeforeUnloadEvent* before_unload_event = ToBeforeUnloadEvent(&event); + if (before_unload_event->returnValue().IsEmpty()) + before_unload_event->setReturnValue(result_for_beforeunload); + } + } else if (!IsOnBeforeUnloadEventHandler()) { + if (special_error_event_handling && v8_return_value->IsBoolean() && + v8_return_value.As<v8::Boolean>()->Value()) + event.preventDefault(); + else if (!special_error_event_handling && v8_return_value->IsBoolean() && + !v8_return_value.As<v8::Boolean>()->Value()) + event.preventDefault(); + } +} + +void JSEventHandler::Trace(blink::Visitor* visitor) { + visitor->Trace(event_handler_); + JSBasedEventListener::Trace(visitor); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/js_event_handler.h b/chromium/third_party/blink/renderer/bindings/core/v8/js_event_handler.h new file mode 100644 index 00000000000..3aca6a5448a --- /dev/null +++ b/chromium/third_party/blink/renderer/bindings/core/v8/js_event_handler.h @@ -0,0 +1,107 @@ +// Copyright 2018 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 file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_JS_EVENT_HANDLER_H_ +#define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_JS_EVENT_HANDLER_H_ + +#include "third_party/blink/renderer/bindings/core/v8/js_based_event_listener.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_event_handler_non_null.h" +#include "third_party/blink/renderer/platform/bindings/trace_wrapper_member.h" + +namespace blink { + +// |JSEventHandler| implements EventHandler in the HTML standard. +// https://html.spec.whatwg.org/C/webappapis.html#event-handler-attributes +class CORE_EXPORT JSEventHandler : public JSBasedEventListener { + public: + enum class HandlerType { + kEventHandler, + // For kOnErrorEventHandler + // https://html.spec.whatwg.org/C/webappapis.html#onerroreventhandler + kOnErrorEventHandler, + // For OnBeforeUnloadEventHandler + // https://html.spec.whatwg.org/C/webappapis.html#onbeforeunloadeventhandler + kOnBeforeUnloadEventHandler, + }; + + static JSEventHandler* Create(ScriptState* script_state, + v8::Local<v8::Object> listener, + const V8PrivateProperty::Symbol& property, + HandlerType type) { + return new JSEventHandler(script_state, listener, property, type); + } + + // blink::CustomWrappable overrides: + void Trace(blink::Visitor* visitor) override; + + // blink::EventListener overrides: + bool operator==(const EventListener& other) const override { + return this == &other; + } + bool IsEventHandler() const final { return true; } + + // blink::JSBasedEventListener overrides: + // TODO(crbug.com/881688): remove empty check for this method. This method + // should return v8::Object or v8::Null. + v8::Local<v8::Value> GetListenerObject(EventTarget&) override { + return event_handler_->CallbackObject(); + } + v8::Local<v8::Value> GetEffectiveFunction(EventTarget&) override; + + protected: + JSEventHandler(ScriptState* script_state, + v8::Local<v8::Object> listener, + const V8PrivateProperty::Symbol& property, + HandlerType type) + : JSBasedEventListener(kJSEventHandlerType), + event_handler_(V8EventHandlerNonNull::Create(listener)), + type_(type) { + Attach(script_state, listener, property, this); + } + + explicit JSEventHandler(HandlerType type) + : JSBasedEventListener(kJSEventHandlerType), type_(type) {} + + // blink::JSBasedEventListener override: + v8::Isolate* GetIsolate() const override { + return event_handler_->GetIsolate(); + } + ScriptState* GetScriptState() const override { + return event_handler_->CallbackRelevantScriptState(); + } + DOMWrapperWorld& GetWorld() const override { + return event_handler_->CallbackRelevantScriptState()->World(); + } + + // Initializes |event_handler_| with |listener|. This method must be used only + // when content attribute gets lazily compiled. + void SetCompiledHandler(ScriptState* script_state, + v8::Local<v8::Function> listener, + const V8PrivateProperty::Symbol& property); + + bool HasCompiledHandler() const { return event_handler_; } + + // For checking special types of EventHandler. + bool IsOnErrorEventHandler() const { + return type_ == HandlerType::kOnErrorEventHandler; + } + bool IsOnBeforeUnloadEventHandler() const { + return type_ == HandlerType::kOnBeforeUnloadEventHandler; + } + + private: + // blink::JSBasedEventListener override: + // Performs "The event handler processing algorithm" + // https://html.spec.whatwg.org/C/webappapis.html#the-event-handler-processing-algorithm + void CallListenerFunction(EventTarget&, + Event&, + v8::Local<v8::Value> js_event) override; + + TraceWrapperMember<V8EventHandlerNonNull> event_handler_; + const HandlerType type_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_JS_EVENT_HANDLER_H_ diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/js_event_handler_for_content_attribute.cc b/chromium/third_party/blink/renderer/bindings/core/v8/js_event_handler_for_content_attribute.cc new file mode 100644 index 00000000000..cc79a175a4d --- /dev/null +++ b/chromium/third_party/blink/renderer/bindings/core/v8/js_event_handler_for_content_attribute.cc @@ -0,0 +1,208 @@ +// Copyright 2018 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 file. + +#include "third_party/blink/renderer/bindings/core/v8/js_event_handler_for_content_attribute.h" + +#include "third_party/blink/renderer/bindings/core/v8/source_location.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" +#include "third_party/blink/renderer/core/dom/events/event_target.h" +#include "third_party/blink/renderer/core/events/error_event.h" +#include "third_party/blink/renderer/core/frame/local_dom_window.h" +#include "third_party/blink/renderer/core/html/forms/html_form_element.h" + +namespace blink { + +v8::Local<v8::Value> JSEventHandlerForContentAttribute::GetListenerObject( + EventTarget& event_target) { + // Step 3. of get the current value of the event handler should be executed + // only if EventHandler's value is an internal raw uncompiled handler and it + // has never tried to get compiled. + if (HasCompiledHandler()) + return JSEventHandler::GetListenerObject(event_target); + if (did_compile_) + return v8::Null(GetIsolate()); + + return GetCompiledHandler(event_target); +} + +// Implements Step 3. of "get the current value of the event handler" +// https://html.spec.whatwg.org/multipage/webappapis.html#getting-the-current-value-of-the-event-handler +v8::Local<v8::Value> JSEventHandlerForContentAttribute::GetCompiledHandler( + EventTarget& event_target) { + // Do not compile the same code twice. + DCHECK(!did_compile_); + did_compile_ = true; + + ExecutionContext* execution_context_of_event_target = + event_target.GetExecutionContext(); + if (!execution_context_of_event_target) + return v8::Null(GetIsolate()); + + v8::Local<v8::Context> v8_context_of_event_target = + ToV8Context(execution_context_of_event_target, GetWorld()); + if (v8_context_of_event_target.IsEmpty()) + return v8::Null(GetIsolate()); + + ScriptState* script_state_of_event_target = + ScriptState::From(v8_context_of_event_target); + if (!script_state_of_event_target->ContextIsValid()) + return v8::Null(GetIsolate()); + + // Step 1. If eventTarget is an element, then let element be eventTarget, and + // document be element's node document. Otherwise, eventTarget is a Window + // object, let element be null, and document be eventTarget's associated + // Document. + Element* element = nullptr; + Document* document = nullptr; + Node* node = event_target.ToNode(); + const DOMWindow* window = event_target.ToDOMWindow(); + if (node && node->IsElementNode()) { + element = ToElement(node); + document = &node->GetDocument(); + } else if (node && node->IsDocumentNode()) { + // Attributes for |blink::HTMLBodyElement| is treated as ones for + // |blink::Document| unlike the definition in standards. + document = &node->GetDocument(); + } else { + // TODO(crbug.com/891635): Add these checks here: + // DCHECK(window); + // DCHECK(event_target.ToLocalDOMWindow()); + // DCHECK_EQ(event_target.ToLocalDOMWindow()->document(), document); + document = To<Document>(execution_context_of_event_target); + } + DCHECK(document); + + // Step 6. Let settings object be the relevant settings object of document. + // Step 9. Push settings object's realm execution context onto the JavaScript + // execution context stack; it is now the running JavaScript execution + // context. + // + // |document->AllowInlineEventHandler()| checks the world of current context, + // so this scope needs to be defined before calling it. + v8::Context::Scope event_target_context_scope(v8_context_of_event_target); + + // Step 2. If scripting is disabled for document, then return null. + if (!document->AllowInlineEventHandler(node, this, source_url_, + position_.line_)) + return v8::Null(GetIsolate()); + + // Step 5. If element is not null and element has a form owner, let form owner + // be that form owner. Otherwise, let form owner be null. + HTMLFormElement* form_owner = nullptr; + if (element && element->IsHTMLElement()) { + form_owner = ToHTMLElement(element)->formOwner(); + } + + // Step 10. Let function be the result of calling FunctionCreate, with + // arguments: + // kind + // Normal + // ParameterList + // If eventHandler is an onerror event handler of a Window object + // Let the function have five arguments, named event, source, lineno, + // colno, and error. + // Otherwise + // Let the function have a single argument called event. + // Body + // The result of parsing body above. + // Scope + // 1. If eventHandler is an element's event handler, then let Scope be + // NewObjectEnvironment(document, the global environment). Otherwise, + // eventHandler is a Window object's event handler: let Scope be the + // global environment. + // 2. If form owner is not null, let Scope be NewObjectEnvironment(form + // owner, Scope). + // 3. If element is not null, let Scope be NewObjectEnvironment(element, + // Scope). + // Strict + // The value of strict. + // + // Note: Strict is set by V8. + v8::Isolate* isolate = script_state_of_event_target->GetIsolate(); + v8::Local<v8::String> parameter_list[5]; + size_t parameter_list_size = 0; + if (IsOnErrorEventHandler() && window) { + // SVG requires to introduce evt as an alias to event in event handlers. + // See ANNOTATION 3: https://www.w3.org/TR/SVG/interact.html#SVGEvents + parameter_list[parameter_list_size++] = + V8String(isolate, node && node->IsSVGElement() ? "evt" : "event"); + parameter_list[parameter_list_size++] = V8String(isolate, "source"); + parameter_list[parameter_list_size++] = V8String(isolate, "lineno"); + parameter_list[parameter_list_size++] = V8String(isolate, "colno"); + parameter_list[parameter_list_size++] = V8String(isolate, "error"); + } else { + // SVG requires to introduce evt as an alias to event in event handlers. + // See ANNOTATION 3: https://www.w3.org/TR/SVG/interact.html#SVGEvents + parameter_list[parameter_list_size++] = + V8String(isolate, node && node->IsSVGElement() ? "evt" : "event"); + } + DCHECK_LE(parameter_list_size, base::size(parameter_list)); + + v8::Local<v8::Object> scopes[3]; + size_t scopes_size = 0; + if (element) { + scopes[scopes_size++] = + ToV8(document, script_state_of_event_target).As<v8::Object>(); + } + if (form_owner) { + scopes[scopes_size++] = + ToV8(form_owner, script_state_of_event_target).As<v8::Object>(); + } + if (element) { + scopes[scopes_size++] = + ToV8(element, script_state_of_event_target).As<v8::Object>(); + } + DCHECK_LE(scopes_size, base::size(scopes)); + + v8::ScriptOrigin origin( + V8String(isolate, source_url_), + v8::Integer::New(isolate, position_.line_.ZeroBasedInt()), + v8::Integer::New(isolate, position_.column_.ZeroBasedInt()), + // TODO(yukiy): consider which value should be passed here. + v8::True(isolate)); + v8::ScriptCompiler::Source source(V8String(isolate, code_), origin); + + v8::Local<v8::Function> compiled_function; + { + v8::TryCatch block(isolate); + block.SetVerbose(true); + v8::MaybeLocal<v8::Function> maybe_result = + v8::ScriptCompiler::CompileFunctionInContext( + v8_context_of_event_target, &source, parameter_list_size, + parameter_list, scopes_size, scopes); + + // Step 7. If body is not parsable as FunctionBody or if parsing detects an + // early error, then follow these substeps: + // 1. Set eventHandler's value to null. + // 2. Report the error for the appropriate script and with the appropriate + // position (line number and column number) given by location, using + // settings object's global object. If the error is still not handled + // after this, then the error may be reported to a developer console. + // 3. Return null. + if (!maybe_result.ToLocal(&compiled_function)) + return v8::Null(isolate); + } + + // Step 12. Set eventHandler's value to the result of creating a Web IDL + // EventHandler callback function object whose object reference is function + // and whose callback context is settings object. + compiled_function->SetName(V8String(isolate, function_name_)); + SetCompiledHandler( + script_state_of_event_target, compiled_function, + V8PrivateProperty::GetCustomWrappableEventHandler(GetIsolate())); + + return JSEventHandler::GetListenerObject(event_target); +} + +std::unique_ptr<SourceLocation> +JSEventHandlerForContentAttribute::GetSourceLocation(EventTarget& target) { + auto source_location = JSEventHandler::GetSourceLocation(target); + if (source_location) + return source_location; + // Fallback to uncompiled source info. + return SourceLocation::Create(source_url_, position_.line_.ZeroBasedInt(), + position_.column_.ZeroBasedInt(), nullptr); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/js_event_handler_for_content_attribute.h b/chromium/third_party/blink/renderer/bindings/core/v8/js_event_handler_for_content_attribute.h new file mode 100644 index 00000000000..86b6a3bfd11 --- /dev/null +++ b/chromium/third_party/blink/renderer/bindings/core/v8/js_event_handler_for_content_attribute.h @@ -0,0 +1,87 @@ +// Copyright 2018 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 file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_JS_EVENT_HANDLER_FOR_CONTENT_ATTRIBUTE_H_ +#define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_JS_EVENT_HANDLER_FOR_CONTENT_ATTRIBUTE_H_ + +#include "third_party/blink/renderer/bindings/core/v8/js_event_handler.h" +#include "third_party/blink/renderer/platform/wtf/text/text_position.h" + +namespace blink { + +// |JSEventHandlerForContentAttribute| supports lazy compilation for content +// attribute. This performs in the same way as |JSEventHandler| after it gets +// compiled. +class JSEventHandlerForContentAttribute final : public JSEventHandler { + public: + static JSEventHandlerForContentAttribute* Create( + const AtomicString& function_name, + const String& code, + const String& source_url, + const TextPosition& position, + v8::Isolate* isolate, + DOMWrapperWorld& world, + HandlerType type = HandlerType::kEventHandler) { + return new JSEventHandlerForContentAttribute( + isolate, world, function_name, code, source_url, position, type); + } + + // blink::EventListener overrides: + bool IsEventHandlerForContentAttribute() const override { return true; } + + // blink::JSBasedEventListener overrides: + v8::Local<v8::Value> GetListenerObject(EventTarget&) override; + std::unique_ptr<SourceLocation> GetSourceLocation(EventTarget&) override; + + const String& Code() const override { return code_; } + + protected: + // blink::JSBasedEventListener override: + v8::Isolate* GetIsolate() const override { return isolate_; } + ScriptState* GetScriptState() const override { + DCHECK(HasCompiledHandler()); + return JSEventHandler::GetScriptState(); + } + DOMWrapperWorld& GetWorld() const override { return *world_; } + + private: + JSEventHandlerForContentAttribute(v8::Isolate* isolate, + DOMWrapperWorld& world, + const AtomicString& function_name, + const String& code, + const String& source_url, + const TextPosition& position, + HandlerType type) + : JSEventHandler(type), + did_compile_(false), + function_name_(function_name), + code_(code), + source_url_(source_url), + position_(position), + isolate_(isolate), + world_(&world) {} + + // Implements Step 3. of "get the current value of the event handler". + // The compiled v8::Function is returned and |JSEventHandler::event_handler_| + // gets initialized with it if lazy compilation succeeds. + // Otherwise, v8::Null is returned. + // https://html.spec.whatwg.org/multipage/webappapis.html#getting-the-current-value-of-the-event-handler + v8::Local<v8::Value> GetCompiledHandler(EventTarget&); + + // Lazy compilation for content attribute should be tried only once, but we + // cannot see whether it had never tried to compile or it has already failed + // when |HasCompiledHandler()| returns false. |did_compile_| is used for + // checking that. + bool did_compile_; + const AtomicString function_name_; + String code_; + String source_url_; + TextPosition position_; + v8::Isolate* isolate_; + scoped_refptr<DOMWrapperWorld> world_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_JS_EVENT_HANDLER_FOR_CONTENT_ATTRIBUTE_H_ diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/js_event_listener.cc b/chromium/third_party/blink/renderer/bindings/core/v8/js_event_listener.cc new file mode 100644 index 00000000000..901f6577469 --- /dev/null +++ b/chromium/third_party/blink/renderer/bindings/core/v8/js_event_listener.cc @@ -0,0 +1,73 @@ +// Copyright 2018 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 file. + +#include "third_party/blink/renderer/bindings/core/v8/js_event_listener.h" + +#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" +#include "third_party/blink/renderer/core/dom/events/event.h" +#include "third_party/blink/renderer/core/dom/events/event_target.h" + +namespace blink { + +v8::Local<v8::Value> JSEventListener::GetEffectiveFunction( + EventTarget& target) { + v8::Isolate* isolate = GetIsolate(); + v8::Local<v8::Value> v8_listener = GetListenerObject(target); + if (v8_listener.IsEmpty()) + return v8::Undefined(isolate); + + if (v8_listener->IsFunction()) + return GetBoundFunction(v8_listener.As<v8::Function>()); + + if (v8_listener->IsObject()) { + // Do not propagate any exceptions. + v8::TryCatch try_catch(isolate); + + v8::Local<v8::Value> property; + + // Try the "handleEvent" method (EventListener interface). + // v8::Object::Get() may throw if "handleEvent" is an accessor and its + // getter throws. + if (v8_listener.As<v8::Object>() + ->Get(isolate->GetCurrentContext(), + V8AtomicString(isolate, "handleEvent")) + .ToLocal(&property) && + property->IsFunction()) { + return GetBoundFunction(property.As<v8::Function>()); + } + } + + return v8::Undefined(isolate); +} + +// https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke +void JSEventListener::CallListenerFunction(EventTarget&, + Event& event, + v8::Local<v8::Value> js_event) { + // Step 10: Call a listener with event's currentTarget as receiver and event + // and handle errors if thrown. + const bool is_beforeunload_event = + event.IsBeforeUnloadEvent() && + event.type() == EventTypeNames::beforeunload; + const bool is_print_event = + // TODO(yukishiino): Should check event.Is{Before,After}PrintEvent. + event.type() == EventTypeNames::beforeprint || + event.type() == EventTypeNames::afterprint; + if (!event_listener_->IsRunnableOrThrowException( + (is_beforeunload_event || is_print_event) + ? V8EventListener::IgnorePause::kIgnore + : V8EventListener::IgnorePause::kDontIgnore)) { + return; + } + v8::Maybe<void> maybe_result = event_listener_->InvokeWithoutRunnabilityCheck( + event.currentTarget(), &event); + ALLOW_UNUSED_LOCAL(maybe_result); +} + +void JSEventListener::Trace(blink::Visitor* visitor) { + visitor->Trace(event_listener_); + JSBasedEventListener::Trace(visitor); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/js_event_listener.h b/chromium/third_party/blink/renderer/bindings/core/v8/js_event_listener.h new file mode 100644 index 00000000000..c6644678294 --- /dev/null +++ b/chromium/third_party/blink/renderer/bindings/core/v8/js_event_listener.h @@ -0,0 +1,80 @@ +// Copyright 2018 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 file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_JS_EVENT_LISTENER_H_ +#define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_JS_EVENT_LISTENER_H_ + +#include "third_party/blink/renderer/bindings/core/v8/js_based_event_listener.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_event_listener.h" +#include "third_party/blink/renderer/platform/bindings/trace_wrapper_member.h" + +namespace blink { + +// |JSEventListener| implements EventListener in the DOM standard. +// https://dom.spec.whatwg.org/#callbackdef-eventlistener +class CORE_EXPORT JSEventListener final : public JSBasedEventListener { + public: + static JSEventListener* Create(ScriptState* script_state, + v8::Local<v8::Object> listener, + const V8PrivateProperty::Symbol& property) { + return new JSEventListener(script_state, listener, property); + } + + // blink::CustomWrappable overrides: + void Trace(blink::Visitor*) override; + + // blink::EventListener overrides: + // + // Check the identity of |V8EventListener::callback_object_|. There can be + // multiple CallbackInterfaceBase objects that have the same + // |CallbackInterfaceBase::callback_object_| but have different + // |CallbackInterfaceBase::incumbent_script_state_|s. + bool operator==(const EventListener& other) const override { + if (other.GetType() != kJSEventListenerType) + return false; + return event_listener_->HasTheSameCallbackObject( + *static_cast<const JSEventListener*>(&other)->event_listener_); + } + + // blink::JSBasedEventListener overrides: + // TODO(crbug.com/881688): remove empty check for this method. This method + // should return v8::Object or v8::Null. + v8::Local<v8::Value> GetListenerObject(EventTarget&) override { + return event_listener_->CallbackObject(); + } + v8::Local<v8::Value> GetEffectiveFunction(EventTarget&) override; + + protected: + // blink::JSBasedEventListener overrides: + v8::Isolate* GetIsolate() const override { + return event_listener_->GetIsolate(); + } + ScriptState* GetScriptState() const override { + return event_listener_->CallbackRelevantScriptState(); + } + DOMWrapperWorld& GetWorld() const override { + return event_listener_->CallbackRelevantScriptState()->World(); + } + + private: + JSEventListener(ScriptState* script_state, + v8::Local<v8::Object> listener, + const V8PrivateProperty::Symbol& property) + : JSBasedEventListener(kJSEventListenerType), + event_listener_(V8EventListener::CreateOrNull(listener)) { + DCHECK(event_listener_); + Attach(script_state, listener, property, this); + } + + // blink::JSBasedEventListener override: + void CallListenerFunction(EventTarget&, + Event&, + v8::Local<v8::Value> js_event) override; + + const TraceWrapperMember<V8EventListener> event_listener_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_JS_EVENT_LISTENER_H_ diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h b/chromium/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h index ac4a9d03dfd..7edeae127f3 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h @@ -478,7 +478,7 @@ struct NativeValueTraits<IDLRecord<K, V>> // the end while at the same time requiring fast checks for previous insert // of a given key. |seenKeys| is a key/position in |result| map that aids in // the latter part. - HashMap<String, size_t> seen_keys; + HashMap<String, uint32_t> seen_keys; for (uint32_t i = 0; i < keys->Length(); ++i) { // "4. Repeat, for each element key of keys in List order:" @@ -539,13 +539,13 @@ struct NativeValueTraits<IDLRecord<K, V>> // "4.2.4. If typedKey is already a key in result, set its value to // typedValue. // Note: This can happen when O is a proxy object." - const size_t pos = seen_keys.at(typed_key); + const uint32_t pos = seen_keys.at(typed_key); result[pos] = std::make_pair(typed_key, typed_value); } else { // "4.2.5. Otherwise, append to result a mapping (typedKey, // typedValue)." // Note we can take this shortcut because we are always appending. - const size_t pos = result.size(); + const uint32_t pos = result.size(); seen_keys.Set(typed_key, pos); result.UncheckedAppend(std::make_pair(typed_key, typed_value)); } diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/rejected_promises.cc b/chromium/third_party/blink/renderer/bindings/core/v8/rejected_promises.cc index d19d56b970b..628179002b8 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/rejected_promises.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/rejected_promises.cc @@ -8,7 +8,6 @@ #include "base/memory/ptr_util.h" #include "third_party/blink/public/platform/platform.h" -#include "third_party/blink/public/platform/web_thread.h" #include "third_party/blink/renderer/bindings/core/v8/script_value.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" #include "third_party/blink/renderer/core/dom/events/event_target.h" @@ -18,6 +17,7 @@ #include "third_party/blink/renderer/platform/bindings/scoped_persistent.h" #include "third_party/blink/renderer/platform/bindings/script_state.h" #include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread.h" #include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" #include "third_party/blink/renderer/platform/wtf/functional.h" @@ -216,7 +216,7 @@ void RejectedPromises::HandlerAdded(v8::PromiseRejectMessage data) { } // Then look it up in the reported errors. - for (size_t i = 0; i < reported_as_errors_.size(); ++i) { + for (wtf_size_t i = 0; i < reported_as_errors_.size(); ++i) { std::unique_ptr<Message>& message = reported_as_errors_.at(i); if (!message->IsCollected() && message->HasPromise(data.GetPromise())) { message->MakePromiseStrong(); @@ -261,7 +261,8 @@ void RejectedPromises::ProcessQueueNow(MessageQueue queue) { auto* new_end = std::remove_if( reported_as_errors_.begin(), reported_as_errors_.end(), [](const auto& message) { return message->IsCollected(); }); - reported_as_errors_.Shrink(new_end - reported_as_errors_.begin()); + reported_as_errors_.Shrink( + static_cast<wtf_size_t>(new_end - reported_as_errors_.begin())); for (auto& message : queue) { if (message->IsCollected()) diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/scheduled_action.cc b/chromium/third_party/blink/renderer/bindings/core/v8/scheduled_action.cc index 6b96f3d1277..94b91e7e15c 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/scheduled_action.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/scheduled_action.cc @@ -47,6 +47,7 @@ #include "third_party/blink/renderer/core/workers/worker_thread.h" #include "third_party/blink/renderer/platform/bindings/script_state.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" +#include "third_party/blink/renderer/platform/wtf/casting.h" namespace blink { @@ -58,7 +59,7 @@ ScheduledAction* ScheduledAction::Create(ScriptState* script_state, if (!script_state->World().IsWorkerWorld()) { if (!BindingSecurity::ShouldAllowAccessToFrame( EnteredDOMWindow(script_state->GetIsolate()), - ToDocument(target)->GetFrame(), + To<Document>(target)->GetFrame(), BindingSecurity::ErrorReportOption::kDoNotReport)) { UseCounter::Count(target, WebFeature::kScheduledActionIgnored); return new ScheduledAction(script_state); @@ -73,7 +74,7 @@ ScheduledAction* ScheduledAction::Create(ScriptState* script_state, if (!script_state->World().IsWorkerWorld()) { if (!BindingSecurity::ShouldAllowAccessToFrame( EnteredDOMWindow(script_state->GetIsolate()), - ToDocument(target)->GetFrame(), + To<Document>(target)->GetFrame(), BindingSecurity::ErrorReportOption::kDoNotReport)) { UseCounter::Count(target, WebFeature::kScheduledActionIgnored); return new ScheduledAction(script_state); @@ -108,8 +109,8 @@ void ScheduledAction::Execute(ExecutionContext* context) { // determine if it is allowed. Enter the scope here. ScriptState::Scope scope(script_state_->Get()); - if (context->IsDocument()) { - LocalFrame* frame = ToDocument(context)->GetFrame(); + if (auto* document = DynamicTo<Document>(context)) { + LocalFrame* frame = document->GetFrame(); if (!frame) { DVLOG(1) << "ScheduledAction::execute " << this << ": no frame"; return; @@ -170,10 +171,15 @@ void ScheduledAction::Execute(LocalFrame* frame) { } else { DVLOG(1) << "ScheduledAction::execute " << this << ": executing from source"; + // We're using |kSharableCrossOrigin| to keep the existing behavior, but + // this causes failures on + // wpt/html/webappapis/scripting/processing-model-2/compile-error-cross-origin-setTimeout.html + // and friends. frame->GetScriptController().ExecuteScriptAndReturnValue( script_state_->GetContext(), ScriptSourceCode(code_, - ScriptSourceLocationType::kEvalForScheduledAction)); + ScriptSourceLocationType::kEvalForScheduledAction), + KURL(), kSharableCrossOrigin); } // The frame might be invalid at this point because JavaScript could have @@ -205,15 +211,22 @@ void ScheduledAction::Execute(WorkerGlobalScope* worker) { function, worker, script_state_->GetContext()->Global(), info.size(), info.data(), script_state_->GetIsolate()); } else { - worker->ScriptController()->Evaluate(ScriptSourceCode( - code_, ScriptSourceLocationType::kEvalForScheduledAction)); + // We're using |kSharableCrossOrigin| to keep the existing behavior, but + // this causes failures on + // wpt/html/webappapis/scripting/processing-model-2/compile-error-cross-origin-setTimeout.html + // and friends. + worker->ScriptController()->Evaluate( + ScriptSourceCode(code_, + ScriptSourceLocationType::kEvalForScheduledAction), + kSharableCrossOrigin); } } void ScheduledAction::CreateLocalHandlesForArgs( Vector<v8::Local<v8::Value>>* handles) { - handles->ReserveCapacity(info_.Size()); - for (size_t i = 0; i < info_.Size(); ++i) + wtf_size_t handle_count = SafeCast<wtf_size_t>(info_.Size()); + handles->ReserveCapacity(handle_count); + for (wtf_size_t i = 0; i < handle_count; ++i) handles->push_back(info_.Get(i)); } diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_controller.cc b/chromium/third_party/blink/renderer/bindings/core/v8/script_controller.cc index a875e304b0d..913248754c8 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/script_controller.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_controller.cc @@ -88,8 +88,8 @@ v8::Local<v8::Value> ScriptController::ExecuteScriptAndReturnValue( v8::Local<v8::Context> context, const ScriptSourceCode& source, const KURL& base_url, - const ScriptFetchOptions& fetch_options, - AccessControlStatus access_control_status) { + AccessControlStatus access_control_status, + const ScriptFetchOptions& fetch_options) { TRACE_EVENT1( "devtools.timeline", "EvaluateScript", "data", InspectorEvaluateScriptEvent::Data(GetFrame(), source.Url().GetString(), @@ -188,7 +188,7 @@ V8Extensions& ScriptController::RegisteredExtensions() { void ScriptController::RegisterExtensionIfNeeded(v8::Extension* extension) { const V8Extensions& extensions = RegisteredExtensions(); - for (size_t i = 0; i < extensions.size(); ++i) { + for (wtf_size_t i = 0; i < extensions.size(); ++i) { if (extensions[i] == extension) return; } @@ -251,9 +251,10 @@ bool ScriptController::ExecuteScriptIfJavaScriptURL(const KURL& url, // Step 12.9 "Let script be result of creating a classic script given script // source, settings, base URL, and the default classic script fetch options." // [spec text] + // We pass |kSharableCrossOrigin| because |muted errors| is false by default. v8::Local<v8::Value> result = EvaluateScriptInMainWorld( ScriptSourceCode(script_source, ScriptSourceLocationType::kJavascriptUrl), - base_url, ScriptFetchOptions(), kNotSharableCrossOrigin, + base_url, kSharableCrossOrigin, ScriptFetchOptions(), kDoNotExecuteScriptWhenScriptsDisabled); // If executing script caused this frame to be removed from the page, we @@ -285,35 +286,36 @@ void ScriptController::ExecuteScriptInMainWorld( ExecuteScriptPolicy policy) { v8::HandleScope handle_scope(GetIsolate()); EvaluateScriptInMainWorld(ScriptSourceCode(script, source_location_type), - KURL(), ScriptFetchOptions(), - kNotSharableCrossOrigin, policy); + KURL(), kOpaqueResource, ScriptFetchOptions(), + policy); } void ScriptController::ExecuteScriptInMainWorld( const ScriptSourceCode& source_code, const KURL& base_url, - const ScriptFetchOptions& fetch_options, - AccessControlStatus access_control_status) { + AccessControlStatus access_control_status, + const ScriptFetchOptions& fetch_options) { v8::HandleScope handle_scope(GetIsolate()); - EvaluateScriptInMainWorld(source_code, base_url, fetch_options, - access_control_status, + EvaluateScriptInMainWorld(source_code, base_url, access_control_status, + fetch_options, kDoNotExecuteScriptWhenScriptsDisabled); } v8::Local<v8::Value> ScriptController::ExecuteScriptInMainWorldAndReturnValue( const ScriptSourceCode& source_code, const KURL& base_url, + AccessControlStatus access_control_status, const ScriptFetchOptions& fetch_options, ExecuteScriptPolicy policy) { - return EvaluateScriptInMainWorld(source_code, base_url, fetch_options, - kNotSharableCrossOrigin, policy); + return EvaluateScriptInMainWorld(source_code, base_url, access_control_status, + fetch_options, policy); } v8::Local<v8::Value> ScriptController::EvaluateScriptInMainWorld( const ScriptSourceCode& source_code, const KURL& base_url, - const ScriptFetchOptions& fetch_options, AccessControlStatus access_control_status, + const ScriptFetchOptions& fetch_options, ExecuteScriptPolicy policy) { if (policy == kDoNotExecuteScriptWhenScriptsDisabled && !GetFrame()->GetDocument()->CanExecuteScripts(kAboutToExecuteScript)) @@ -331,8 +333,8 @@ v8::Local<v8::Value> ScriptController::EvaluateScriptInMainWorld( GetFrame()->Loader().DidAccessInitialDocument(); v8::Local<v8::Value> object = ExecuteScriptAndReturnValue( - script_state->GetContext(), source_code, base_url, fetch_options, - access_control_status); + script_state->GetContext(), source_code, base_url, access_control_status, + fetch_options); if (object.IsEmpty()) return v8::Local<v8::Value>(); @@ -342,7 +344,9 @@ v8::Local<v8::Value> ScriptController::EvaluateScriptInMainWorld( v8::Local<v8::Value> ScriptController::ExecuteScriptInIsolatedWorld( int world_id, - const ScriptSourceCode& source) { + const ScriptSourceCode& source, + const KURL& base_url, + AccessControlStatus access_control_status) { DCHECK_GT(world_id, 0); scoped_refptr<DOMWrapperWorld> world = @@ -354,8 +358,8 @@ v8::Local<v8::Value> ScriptController::ExecuteScriptInIsolatedWorld( isolated_world_window_proxy->ContextIfInitialized(); v8::Context::Scope scope(context); - v8::Local<v8::Value> evaluation_result = - ExecuteScriptAndReturnValue(context, source); + v8::Local<v8::Value> evaluation_result = ExecuteScriptAndReturnValue( + context, source, base_url, access_control_status); if (!evaluation_result.IsEmpty()) return evaluation_result; return v8::Local<v8::Value>::New(GetIsolate(), v8::Undefined(GetIsolate())); diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_controller.h b/chromium/third_party/blink/renderer/bindings/core/v8/script_controller.h index 024678dc8d1..01501bfcc0a 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/script_controller.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_controller.h @@ -89,20 +89,21 @@ class CORE_EXPORT ScriptController final ExecuteScriptPolicy = kDoNotExecuteScriptWhenScriptsDisabled); void ExecuteScriptInMainWorld( const ScriptSourceCode&, - const KURL& base_url = KURL(), - const ScriptFetchOptions& = ScriptFetchOptions(), - AccessControlStatus = kNotSharableCrossOrigin); + const KURL& base_url, + AccessControlStatus, + const ScriptFetchOptions& = ScriptFetchOptions()); v8::Local<v8::Value> ExecuteScriptInMainWorldAndReturnValue( const ScriptSourceCode&, - const KURL& base_url = KURL(), + const KURL& base_url, + AccessControlStatus, const ScriptFetchOptions& = ScriptFetchOptions(), ExecuteScriptPolicy = kDoNotExecuteScriptWhenScriptsDisabled); v8::Local<v8::Value> ExecuteScriptAndReturnValue( v8::Local<v8::Context>, const ScriptSourceCode&, - const KURL& base_url = KURL(), - const ScriptFetchOptions& = ScriptFetchOptions(), - AccessControlStatus = kNotSharableCrossOrigin); + const KURL& base_url, + AccessControlStatus, + const ScriptFetchOptions& = ScriptFetchOptions()); // Executes JavaScript in an isolated world. The script gets its own global // scope, its own prototypes for intrinsic JavaScript objects (String, Array, @@ -110,8 +111,11 @@ class CORE_EXPORT ScriptController final // // If an isolated world with the specified ID already exists, it is reused. // Otherwise, a new world is created. - v8::Local<v8::Value> ExecuteScriptInIsolatedWorld(int world_id, - const ScriptSourceCode&); + v8::Local<v8::Value> ExecuteScriptInIsolatedWorld( + int world_id, + const ScriptSourceCode&, + const KURL& base_url, + AccessControlStatus access_control_status); // Returns true if argument is a JavaScript URL. bool ExecuteScriptIfJavaScriptURL(const KURL&, Element*); @@ -156,8 +160,8 @@ class CORE_EXPORT ScriptController final v8::Local<v8::Value> EvaluateScriptInMainWorld(const ScriptSourceCode&, const KURL& base_url, - const ScriptFetchOptions&, AccessControlStatus, + const ScriptFetchOptions&, ExecuteScriptPolicy); const Member<LocalFrame> frame_; diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition.cc b/chromium/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition.cc index 68a09410524..0ed5ed957f3 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition.cc @@ -5,9 +5,10 @@ #include "third_party/blink/renderer/bindings/core/v8/script_custom_element_definition.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_custom_element_constructor.h" #include "third_party/blink/renderer/bindings/core/v8/v8_custom_element_registry.h" #include "third_party/blink/renderer/bindings/core/v8/v8_element.h" -#include "third_party/blink/renderer/bindings/core/v8/v8_error_handler.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_function.h" #include "third_party/blink/renderer/bindings/core/v8/v8_script_runner.h" #include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h" #include "third_party/blink/renderer/core/dom/document.h" @@ -29,7 +30,7 @@ class CSSStyleSheet; ScriptCustomElementDefinition* ScriptCustomElementDefinition::ForConstructor( ScriptState* script_state, CustomElementRegistry* registry, - const v8::Local<v8::Value>& constructor) { + v8::Local<v8::Value> constructor) { V8PerContextData* per_context_data = script_state->PerContextData(); // TODO(yukishiino): Remove this check when crbug.com/583429 is fixed. if (UNLIKELY(!per_context_data)) @@ -72,26 +73,25 @@ ScriptCustomElementDefinition* ScriptCustomElementDefinition::Create( CustomElementRegistry* registry, const CustomElementDescriptor& descriptor, CustomElementDefinition::Id id, - const v8::Local<v8::Object>& constructor, - const v8::Local<v8::Function>& connected_callback, - const v8::Local<v8::Function>& disconnected_callback, - const v8::Local<v8::Function>& adopted_callback, - const v8::Local<v8::Function>& attribute_changed_callback, - HashSet<AtomicString>&& observed_attributes, - CSSStyleSheet* default_style_sheet) { + V8CustomElementConstructor* constructor, + V8Function* connected_callback, + V8Function* disconnected_callback, + V8Function* adopted_callback, + V8Function* attribute_changed_callback, + HashSet<AtomicString>&& observed_attributes) { ScriptCustomElementDefinition* definition = new ScriptCustomElementDefinition( script_state, descriptor, constructor, connected_callback, disconnected_callback, adopted_callback, attribute_changed_callback, - std::move(observed_attributes), default_style_sheet); + std::move(observed_attributes)); // Tag the JavaScript constructor object with its ID. v8::Local<v8::Value> id_value = v8::Integer::NewFromUnsigned(script_state->GetIsolate(), id); auto private_id = script_state->PerContextData()->GetPrivateCustomElementDefinitionId(); - CHECK( - constructor->SetPrivate(script_state->GetContext(), private_id, id_value) - .ToChecked()); + CHECK(constructor->CallbackObject() + ->SetPrivate(script_state->GetContext(), private_id, id_value) + .ToChecked()); return definition; } @@ -99,36 +99,27 @@ ScriptCustomElementDefinition* ScriptCustomElementDefinition::Create( ScriptCustomElementDefinition::ScriptCustomElementDefinition( ScriptState* script_state, const CustomElementDescriptor& descriptor, - const v8::Local<v8::Object>& constructor, - const v8::Local<v8::Function>& connected_callback, - const v8::Local<v8::Function>& disconnected_callback, - const v8::Local<v8::Function>& adopted_callback, - const v8::Local<v8::Function>& attribute_changed_callback, - HashSet<AtomicString>&& observed_attributes, - CSSStyleSheet* default_style_sheet) - : CustomElementDefinition(descriptor, - default_style_sheet, - std::move(observed_attributes)), + V8CustomElementConstructor* constructor, + V8Function* connected_callback, + V8Function* disconnected_callback, + V8Function* adopted_callback, + V8Function* attribute_changed_callback, + HashSet<AtomicString>&& observed_attributes) + : CustomElementDefinition(descriptor, std::move(observed_attributes)), script_state_(script_state), - constructor_(script_state->GetIsolate(), constructor) { - v8::Isolate* isolate = script_state->GetIsolate(); - if (!connected_callback.IsEmpty()) - connected_callback_.Set(isolate, connected_callback); - if (!disconnected_callback.IsEmpty()) - disconnected_callback_.Set(isolate, disconnected_callback); - if (!adopted_callback.IsEmpty()) - adopted_callback_.Set(isolate, adopted_callback); - if (!attribute_changed_callback.IsEmpty()) - attribute_changed_callback_.Set(isolate, attribute_changed_callback); -} + constructor_(constructor), + connected_callback_(connected_callback), + disconnected_callback_(disconnected_callback), + adopted_callback_(adopted_callback), + attribute_changed_callback_(attribute_changed_callback) {} void ScriptCustomElementDefinition::Trace(Visitor* visitor) { - visitor->Trace(constructor_.Cast<v8::Value>()); - visitor->Trace(connected_callback_.Cast<v8::Value>()); - visitor->Trace(disconnected_callback_.Cast<v8::Value>()); - visitor->Trace(adopted_callback_.Cast<v8::Value>()); - visitor->Trace(attribute_changed_callback_.Cast<v8::Value>()); visitor->Trace(script_state_); + visitor->Trace(constructor_); + visitor->Trace(connected_callback_); + visitor->Trace(disconnected_callback_); + visitor->Trace(adopted_callback_); + visitor->Trace(attribute_changed_callback_); CustomElementDefinition::Trace(visitor); } @@ -199,6 +190,7 @@ HTMLElement* ScriptCustomElementDefinition::CreateAutonomousCustomElementSync( if (element->prefix() != tag_name.Prefix()) element->SetTagNameForCreateElementNS(tag_name); DCHECK_EQ(element->GetCustomElementState(), CustomElementState::kCustom); + AddDefaultStylesTo(*element); return ToHTMLElement(element); } @@ -238,21 +230,17 @@ bool ScriptCustomElementDefinition::RunConstructor(Element* element) { } Element* ScriptCustomElementDefinition::CallConstructor() { - v8::Isolate* isolate = script_state_->GetIsolate(); - DCHECK(ScriptState::Current(isolate) == script_state_); - ExecutionContext* execution_context = ExecutionContext::From(script_state_); - v8::Local<v8::Value> result; - if (!V8ScriptRunner::CallAsConstructor(isolate, Constructor(), - execution_context, 0, nullptr) - .ToLocal(&result)) { + ScriptValue result; + if (!constructor_->Construct().To(&result)) { return nullptr; } - return V8Element::ToImplWithTypeCheck(isolate, result); + + return V8Element::ToImplWithTypeCheck(constructor_->GetIsolate(), + result.V8Value()); } v8::Local<v8::Object> ScriptCustomElementDefinition::Constructor() const { - DCHECK(!constructor_.IsEmpty()); - return constructor_.NewLocal(script_state_->GetIsolate()); + return constructor_->CallbackObject(); } // CustomElementDefinition @@ -261,66 +249,47 @@ ScriptValue ScriptCustomElementDefinition::GetConstructorForScript() { } bool ScriptCustomElementDefinition::HasConnectedCallback() const { - return !connected_callback_.IsEmpty(); + return connected_callback_; } bool ScriptCustomElementDefinition::HasDisconnectedCallback() const { - return !disconnected_callback_.IsEmpty(); + return disconnected_callback_; } bool ScriptCustomElementDefinition::HasAdoptedCallback() const { - return !adopted_callback_.IsEmpty(); -} - -void ScriptCustomElementDefinition::RunCallback( - v8::Local<v8::Function> callback, - Element* element, - int argc, - v8::Local<v8::Value> argv[]) { - DCHECK(ScriptState::Current(script_state_->GetIsolate()) == script_state_); - v8::Isolate* isolate = script_state_->GetIsolate(); - - // Invoke custom element reactions - // https://html.spec.whatwg.org/multipage/scripting.html#invoke-custom-element-reactions - // If this throws any exception, then report the exception. - v8::TryCatch try_catch(isolate); - try_catch.SetVerbose(true); - - ExecutionContext* execution_context = ExecutionContext::From(script_state_); - v8::Local<v8::Value> element_handle = - ToV8(element, script_state_->GetContext()->Global(), isolate); - V8ScriptRunner::CallFunction(callback, execution_context, element_handle, - argc, argv, isolate); + return adopted_callback_; } void ScriptCustomElementDefinition::RunConnectedCallback(Element* element) { - if (!script_state_->ContextIsValid()) + if (!connected_callback_) return; - ScriptState::Scope scope(script_state_); - v8::Isolate* isolate = script_state_->GetIsolate(); - RunCallback(connected_callback_.NewLocal(isolate), element); + + connected_callback_->InvokeAndReportException(element, Vector<ScriptValue>()); } void ScriptCustomElementDefinition::RunDisconnectedCallback(Element* element) { - if (!script_state_->ContextIsValid()) + if (!disconnected_callback_) return; - ScriptState::Scope scope(script_state_); - v8::Isolate* isolate = script_state_->GetIsolate(); - RunCallback(disconnected_callback_.NewLocal(isolate), element); + + disconnected_callback_->InvokeAndReportException(element, + Vector<ScriptValue>()); } void ScriptCustomElementDefinition::RunAdoptedCallback(Element* element, Document* old_owner, Document* new_owner) { - if (!script_state_->ContextIsValid()) + if (!adopted_callback_) return; - ScriptState::Scope scope(script_state_); - v8::Isolate* isolate = script_state_->GetIsolate(); - v8::Local<v8::Value> argv[] = { - ToV8(old_owner, script_state_->GetContext()->Global(), isolate), - ToV8(new_owner, script_state_->GetContext()->Global(), isolate)}; - RunCallback(adopted_callback_.NewLocal(isolate), element, base::size(argv), - argv); + + ScriptState* script_state = adopted_callback_->CallbackRelevantScriptState(); + if (!script_state->ContextIsValid()) + return; + ScriptState::Scope scope(script_state); + Vector<ScriptValue> args({ + ScriptValue(script_state, ToV8(old_owner, script_state)), + ScriptValue(script_state, ToV8(new_owner, script_state)), + }); + adopted_callback_->InvokeAndReportException(element, args); } void ScriptCustomElementDefinition::RunAttributeChangedCallback( @@ -328,17 +297,22 @@ void ScriptCustomElementDefinition::RunAttributeChangedCallback( const QualifiedName& name, const AtomicString& old_value, const AtomicString& new_value) { - if (!script_state_->ContextIsValid()) + if (!attribute_changed_callback_) return; - ScriptState::Scope scope(script_state_); - v8::Isolate* isolate = script_state_->GetIsolate(); - v8::Local<v8::Value> argv[] = { - V8String(isolate, name.LocalName()), V8StringOrNull(isolate, old_value), - V8StringOrNull(isolate, new_value), - V8StringOrNull(isolate, name.NamespaceURI()), - }; - RunCallback(attribute_changed_callback_.NewLocal(isolate), element, - base::size(argv), argv); + + v8::Isolate* isolate = attribute_changed_callback_->GetIsolate(); + ScriptState* script_state = + attribute_changed_callback_->CallbackRelevantScriptState(); + if (!script_state->ContextIsValid()) + return; + ScriptState::Scope scope(script_state); + Vector<ScriptValue> args({ + ScriptValue(script_state, V8String(isolate, name.LocalName())), + ScriptValue(script_state, V8StringOrNull(isolate, old_value)), + ScriptValue(script_state, V8StringOrNull(isolate, new_value)), + ScriptValue(script_state, V8StringOrNull(isolate, name.NamespaceURI())), + }); + attribute_changed_callback_->InvokeAndReportException(element, args); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition.h b/chromium/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition.h index 611de74f9cd..b27f7254d2c 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition.h @@ -17,6 +17,8 @@ namespace blink { class CustomElementDescriptor; class CustomElementRegistry; +class V8CustomElementConstructor; +class V8Function; class CORE_EXPORT ScriptCustomElementDefinition final : public CustomElementDefinition { @@ -26,20 +28,19 @@ class CORE_EXPORT ScriptCustomElementDefinition final static ScriptCustomElementDefinition* ForConstructor( ScriptState*, CustomElementRegistry*, - const v8::Local<v8::Value>& constructor); + v8::Local<v8::Value> constructor); static ScriptCustomElementDefinition* Create( ScriptState*, CustomElementRegistry*, const CustomElementDescriptor&, CustomElementDefinition::Id, - const v8::Local<v8::Object>& constructor, - const v8::Local<v8::Function>& connected_callback, - const v8::Local<v8::Function>& disconnected_callback, - const v8::Local<v8::Function>& adopted_callback, - const v8::Local<v8::Function>& attribute_changed_callback, - HashSet<AtomicString>&& observed_attributes, - CSSStyleSheet*); + V8CustomElementConstructor* constructor, + V8Function* connected_callback, + V8Function* disconnected_callback, + V8Function* adopted_callback, + V8Function* attribute_changed_callback, + HashSet<AtomicString>&& observed_attributes); ~ScriptCustomElementDefinition() override = default; @@ -65,16 +66,14 @@ class CORE_EXPORT ScriptCustomElementDefinition final const AtomicString& new_value) override; private: - ScriptCustomElementDefinition( - ScriptState*, - const CustomElementDescriptor&, - const v8::Local<v8::Object>& constructor, - const v8::Local<v8::Function>& connected_callback, - const v8::Local<v8::Function>& disconnected_callback, - const v8::Local<v8::Function>& adopted_callback, - const v8::Local<v8::Function>& attribute_changed_callback, - HashSet<AtomicString>&& observed_attributes, - CSSStyleSheet*); + ScriptCustomElementDefinition(ScriptState*, + const CustomElementDescriptor&, + V8CustomElementConstructor* constructor, + V8Function* connected_callback, + V8Function* disconnected_callback, + V8Function* adopted_callback, + V8Function* attribute_changed_callback, + HashSet<AtomicString>&& observed_attributes); // Implementations of |CustomElementDefinition| ScriptValue GetConstructorForScript() final; @@ -83,22 +82,17 @@ class CORE_EXPORT ScriptCustomElementDefinition final // Calls the constructor. The script scope, etc. must already be set up. Element* CallConstructor(); - void RunCallback(v8::Local<v8::Function>, - Element*, - int argc = 0, - v8::Local<v8::Value> argv[] = nullptr); - HTMLElement* HandleCreateElementSyncException(Document&, const QualifiedName& tag_name, v8::Isolate*, ExceptionState&); Member<ScriptState> script_state_; - TraceWrapperV8Reference<v8::Object> constructor_; - TraceWrapperV8Reference<v8::Function> connected_callback_; - TraceWrapperV8Reference<v8::Function> disconnected_callback_; - TraceWrapperV8Reference<v8::Function> adopted_callback_; - TraceWrapperV8Reference<v8::Function> attribute_changed_callback_; + TraceWrapperMember<V8CustomElementConstructor> constructor_; + TraceWrapperMember<V8Function> connected_callback_; + TraceWrapperMember<V8Function> disconnected_callback_; + TraceWrapperMember<V8Function> adopted_callback_; + TraceWrapperMember<V8Function> attribute_changed_callback_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition_builder.cc b/chromium/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition_builder.cc index 9896762b866..e57011a1cde 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition_builder.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition_builder.cc @@ -9,7 +9,9 @@ #include "third_party/blink/renderer/bindings/core/v8/script_custom_element_definition.h" #include "third_party/blink/renderer/bindings/core/v8/script_value.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" -#include "third_party/blink/renderer/core/css/css_style_sheet.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_custom_element_constructor.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_function.h" +#include "third_party/blink/renderer/platform/bindings/callback_method_retriever.h" #include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/script_state.h" @@ -20,23 +22,16 @@ namespace blink { ScriptCustomElementDefinitionBuilder::ScriptCustomElementDefinitionBuilder( ScriptState* script_state, CustomElementRegistry* registry, - CSSStyleSheet* default_style_sheet, - const ScriptValue& constructor, + V8CustomElementConstructor* constructor, ExceptionState& exception_state) : script_state_(script_state), + exception_state_(exception_state), registry_(registry), - default_style_sheet_(default_style_sheet), - constructor_value_(constructor.V8Value()), - exception_state_(exception_state) {} + constructor_(constructor) {} bool ScriptCustomElementDefinitionBuilder::CheckConstructorIntrinsics() { DCHECK(script_state_->World().IsMainWorld()); - // The signature of CustomElementRegistry.define says this is a - // Function - // https://html.spec.whatwg.org/multipage/scripting.html#customelementsregistry - CHECK(constructor_value_->IsFunction()); - constructor_ = constructor_value_.As<v8::Object>(); if (!constructor_->IsConstructor()) { exception_state_.ThrowTypeError( "constructor argument is not a constructor"); @@ -46,8 +41,8 @@ bool ScriptCustomElementDefinitionBuilder::CheckConstructorIntrinsics() { } bool ScriptCustomElementDefinitionBuilder::CheckConstructorNotRegistered() { - if (!ScriptCustomElementDefinition::ForConstructor(script_state_, registry_, - constructor_)) + if (!ScriptCustomElementDefinition::ForConstructor( + script_state_, registry_, constructor_->CallbackObject())) return true; // Constructor is already registered. @@ -57,99 +52,78 @@ bool ScriptCustomElementDefinitionBuilder::CheckConstructorNotRegistered() { return false; } -bool ScriptCustomElementDefinitionBuilder::ValueForName( - v8::Isolate* isolate, - v8::Local<v8::Context>& context, - const v8::TryCatch& try_catch, - const v8::Local<v8::Object>& object, - const StringView& name, - v8::Local<v8::Value>& value) const { - v8::Local<v8::String> name_string = V8AtomicString(isolate, name); - if (!object->Get(context, name_string).ToLocal(&value)) { - exception_state_.RethrowV8Exception(try_catch.Exception()); +bool ScriptCustomElementDefinitionBuilder::RememberOriginalProperties() { + // https://html.spec.whatwg.org/C/custom-elements.html#element-definition + // step 10. Run the following substeps while catching any exceptions: + CallbackMethodRetriever retriever(constructor_); + + retriever.GetPrototypeObject(exception_state_); + if (exception_state_.HadException()) return false; - } - return script_state_->ContextIsValid(); -} -bool ScriptCustomElementDefinitionBuilder::CheckPrototype() { - v8::Isolate* isolate = script_state_->GetIsolate(); - v8::Local<v8::Context> context = script_state_->GetContext(); - v8::TryCatch try_catch(isolate); - v8::Local<v8::Value> prototype_value; - if (!ValueForName(isolate, context, try_catch, constructor_, "prototype", - prototype_value)) + v8_connected_callback_ = + retriever.GetMethodOrUndefined("connectedCallback", exception_state_); + if (exception_state_.HadException()) return false; - if (!prototype_value->IsObject()) { - exception_state_.ThrowTypeError("constructor prototype is not an object"); + if (v8_connected_callback_->IsFunction()) { + connected_callback_ = + V8Function::Create(v8_connected_callback_.As<v8::Function>()); + } + v8_disconnected_callback_ = + retriever.GetMethodOrUndefined("disconnectedCallback", exception_state_); + if (exception_state_.HadException()) return false; + if (v8_disconnected_callback_->IsFunction()) { + disconnected_callback_ = + V8Function::Create(v8_disconnected_callback_.As<v8::Function>()); } - prototype_ = prototype_value.As<v8::Object>(); - // If retrieving the prototype destroyed the context, indicate that - // defining the element should not proceed. - return true; -} - -bool ScriptCustomElementDefinitionBuilder::CallableForName( - v8::Isolate* isolate, - v8::Local<v8::Context>& context, - const v8::TryCatch& try_catch, - const StringView& name, - v8::Local<v8::Function>& callback) const { - v8::Local<v8::Value> value; - if (!ValueForName(isolate, context, try_catch, prototype_, name, value)) + v8_adopted_callback_ = + retriever.GetMethodOrUndefined("adoptedCallback", exception_state_); + if (exception_state_.HadException()) return false; - // "undefined" means "omitted", which is valid. - if (value->IsUndefined()) - return true; - if (!value->IsFunction()) { - exception_state_.ThrowTypeError(String::Format( - "\"%s\" is not a callable object", name.ToString().Ascii().data())); + if (v8_adopted_callback_->IsFunction()) { + adopted_callback_ = + V8Function::Create(v8_adopted_callback_.As<v8::Function>()); + } + v8_attribute_changed_callback_ = retriever.GetMethodOrUndefined( + "attributeChangedCallback", exception_state_); + if (exception_state_.HadException()) return false; + if (v8_attribute_changed_callback_->IsFunction()) { + attribute_changed_callback_ = + V8Function::Create(v8_attribute_changed_callback_.As<v8::Function>()); } - callback = value.As<v8::Function>(); - return true; -} -bool ScriptCustomElementDefinitionBuilder::RetrieveObservedAttributes( - v8::Isolate* isolate, - v8::Local<v8::Context>& context, - const v8::TryCatch& try_catch) { - v8::Local<v8::Value> observed_attributes_value; - if (!ValueForName(isolate, context, try_catch, constructor_, - "observedAttributes", observed_attributes_value)) - return false; - if (observed_attributes_value->IsUndefined()) - return true; - Vector<String> list = NativeValueTraits<IDLSequence<IDLString>>::NativeValue( - isolate, observed_attributes_value, exception_state_); - if (exception_state_.HadException() || !script_state_->ContextIsValid()) - return false; - if (list.IsEmpty()) - return true; - observed_attributes_.ReserveCapacityForSize(list.size()); - for (const auto& attribute : list) - observed_attributes_.insert(AtomicString(attribute)); - return true; -} + // step 10.6. If the value of the entry in lifecycleCallbacks with key + // "attributeChangedCallback" is not null, then: + if (attribute_changed_callback_) { + v8::Isolate* isolate = script_state_->GetIsolate(); + v8::Local<v8::Context> current_context = isolate->GetCurrentContext(); + v8::TryCatch try_catch(script_state_->GetIsolate()); + v8::Local<v8::Value> v8_observed_attributes; -bool ScriptCustomElementDefinitionBuilder::RememberOriginalProperties() { - // Spec requires to use values of these properties at the point - // CustomElementDefinition is built, even if JS changes them afterwards. - v8::Isolate* isolate = script_state_->GetIsolate(); - v8::Local<v8::Context> context = script_state_->GetContext(); - v8::TryCatch try_catch(isolate); - return CallableForName(isolate, context, try_catch, "connectedCallback", - connected_callback_) && - CallableForName(isolate, context, try_catch, "disconnectedCallback", - disconnected_callback_) && - CallableForName(isolate, context, try_catch, "adoptedCallback", - adopted_callback_) && - CallableForName(isolate, context, try_catch, - "attributeChangedCallback", - attribute_changed_callback_) && - (attribute_changed_callback_.IsEmpty() || - RetrieveObservedAttributes(isolate, context, try_catch)); + if (!constructor_->CallbackObject() + ->Get(current_context, + V8AtomicString(isolate, "observedAttributes")) + .ToLocal(&v8_observed_attributes)) { + exception_state_.RethrowV8Exception(try_catch.Exception()); + return false; + } + + if (v8_observed_attributes->IsUndefined()) + return true; + + const Vector<String>& observed_attrs = + NativeValueTraits<IDLSequence<IDLString>>::NativeValue( + isolate, v8_observed_attributes, exception_state_); + if (exception_state_.HadException()) + return false; + observed_attributes_.ReserveCapacityForSize(observed_attrs.size()); + for (const auto& attribute : observed_attrs) + observed_attributes_.insert(AtomicString(attribute)); + } + + return true; } CustomElementDefinition* ScriptCustomElementDefinitionBuilder::Build( @@ -158,8 +132,7 @@ CustomElementDefinition* ScriptCustomElementDefinitionBuilder::Build( return ScriptCustomElementDefinition::Create( script_state_, registry_, descriptor, id, constructor_, connected_callback_, disconnected_callback_, adopted_callback_, - attribute_changed_callback_, std::move(observed_attributes_), - default_style_sheet_); + attribute_changed_callback_, std::move(observed_attributes_)); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition_builder.h b/chromium/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition_builder.h index a6c6f9885d2..eeb90940474 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition_builder.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_custom_element_definition_builder.h @@ -19,11 +19,11 @@ namespace blink { -class CSSStyleSheet; class CustomElementRegistry; class ExceptionState; class ScriptState; -class ScriptValue; +class V8CustomElementConstructor; +class V8Function; class CORE_EXPORT ScriptCustomElementDefinitionBuilder : public CustomElementDefinitionBuilder { @@ -31,51 +31,35 @@ class CORE_EXPORT ScriptCustomElementDefinitionBuilder WTF_MAKE_NONCOPYABLE(ScriptCustomElementDefinitionBuilder); public: - ScriptCustomElementDefinitionBuilder( - ScriptState*, - CustomElementRegistry*, - CSSStyleSheet*, - const ScriptValue& constructor_script_value, - ExceptionState&); + ScriptCustomElementDefinitionBuilder(ScriptState*, + CustomElementRegistry*, + V8CustomElementConstructor* constructor, + ExceptionState&); ~ScriptCustomElementDefinitionBuilder() = default; bool CheckConstructorIntrinsics() override; bool CheckConstructorNotRegistered() override; - bool CheckPrototype() override; bool RememberOriginalProperties() override; CustomElementDefinition* Build(const CustomElementDescriptor&, CustomElementDefinition::Id) override; private: - static ScriptCustomElementDefinitionBuilder* stack_; - Member<ScriptState> script_state_; + ExceptionState& exception_state_; Member<CustomElementRegistry> registry_; - const Member<CSSStyleSheet> default_style_sheet_; - v8::Local<v8::Value> constructor_value_; - v8::Local<v8::Object> constructor_; - v8::Local<v8::Object> prototype_; - v8::Local<v8::Function> connected_callback_; - v8::Local<v8::Function> disconnected_callback_; - v8::Local<v8::Function> adopted_callback_; - v8::Local<v8::Function> attribute_changed_callback_; + const Member<V8CustomElementConstructor> constructor_; + // These v8::Local handles on stack make the function objects alive until we + // finish building the CustomElementDefinition and wrapper-tracing on it gets + // available. + v8::Local<v8::Value> v8_connected_callback_; + v8::Local<v8::Value> v8_disconnected_callback_; + v8::Local<v8::Value> v8_adopted_callback_; + v8::Local<v8::Value> v8_attribute_changed_callback_; + Member<V8Function> connected_callback_; + Member<V8Function> disconnected_callback_; + Member<V8Function> adopted_callback_; + Member<V8Function> attribute_changed_callback_; HashSet<AtomicString> observed_attributes_; - ExceptionState& exception_state_; - - bool ValueForName(v8::Isolate*, - v8::Local<v8::Context>&, - const v8::TryCatch&, - const v8::Local<v8::Object>&, - const StringView&, - v8::Local<v8::Value>&) const; - bool CallableForName(v8::Isolate*, - v8::Local<v8::Context>&, - const v8::TryCatch&, - const StringView&, - v8::Local<v8::Function>&) const; - bool RetrieveObservedAttributes(v8::Isolate*, - v8::Local<v8::Context>&, - const v8::TryCatch&); }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_event_listener.cc b/chromium/third_party/blink/renderer/bindings/core/v8/script_event_listener.cc index 3450578d7e1..15576be91de 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/script_event_listener.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_event_listener.cc @@ -30,26 +30,22 @@ #include "third_party/blink/renderer/bindings/core/v8/script_event_listener.h" -#include "third_party/blink/renderer/bindings/core/v8/scheduled_action.h" +#include "third_party/blink/renderer/bindings/core/v8/js_event_handler_for_content_attribute.h" #include "third_party/blink/renderer/bindings/core/v8/script_controller.h" -#include "third_party/blink/renderer/bindings/core/v8/source_location.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" -#include "third_party/blink/renderer/bindings/core/v8/v8_lazy_event_listener.h" -#include "third_party/blink/renderer/bindings/core/v8/window_proxy.h" #include "third_party/blink/renderer/core/dom/document.h" -#include "third_party/blink/renderer/core/dom/document_parser.h" #include "third_party/blink/renderer/core/dom/qualified_name.h" #include "third_party/blink/renderer/core/frame/local_frame.h" -#include "third_party/blink/renderer/platform/bindings/script_state.h" #include "v8/include/v8.h" namespace blink { -EventListener* CreateAttributeEventListener( - Node* node, - const QualifiedName& name, - const AtomicString& value, - const AtomicString& event_parameter_name) { +// TODO(yukiy): make this method receive |Document*| instead of |Node*|, which +// is no longer necessary. +EventListener* CreateAttributeEventListener(Node* node, + const QualifiedName& name, + const AtomicString& value, + JSEventHandler::HandlerType type) { DCHECK(node); if (value.IsNull()) return nullptr; @@ -60,6 +56,8 @@ EventListener* CreateAttributeEventListener( String source_url; v8::Isolate* isolate = ToIsolate(&node->GetDocument()); + v8::HandleScope scope(isolate); + if (LocalFrame* frame = node->GetDocument().GetFrame()) { ScriptController& script_controller = frame->GetScriptController(); if (!node->GetDocument().CanExecuteScripts(kAboutToExecuteScript)) @@ -68,16 +66,22 @@ EventListener* CreateAttributeEventListener( source_url = node->GetDocument().Url().GetString(); } - return V8LazyEventListener::Create(name.LocalName(), event_parameter_name, - value, source_url, position, node, - isolate); + // |v8_context| can be an empty handle when this listener is added as content + // attribute like <hoge onclick="fuga"></hoge> because there is no JS context + // when parsing HTML. In that case we should assume the main world. + v8::Local<v8::Context> v8_context = isolate->GetCurrentContext(); + + return JSEventHandlerForContentAttribute::Create( + name.LocalName(), value, source_url, position, isolate, + v8_context.IsEmpty() ? DOMWrapperWorld::MainWorld() + : ScriptState::From(v8_context)->World(), + type); } -EventListener* CreateAttributeEventListener( - LocalFrame* frame, - const QualifiedName& name, - const AtomicString& value, - const AtomicString& event_parameter_name) { +EventListener* CreateAttributeEventListener(LocalFrame* frame, + const QualifiedName& name, + const AtomicString& value, + JSEventHandler::HandlerType type) { if (!frame) return nullptr; @@ -90,69 +94,19 @@ EventListener* CreateAttributeEventListener( TextPosition position = frame->GetScriptController().EventHandlerPosition(); String source_url = frame->GetDocument()->Url().GetString(); - return V8LazyEventListener::Create(name.LocalName(), event_parameter_name, - value, source_url, position, nullptr, - ToIsolate(frame)); -} - -v8::Local<v8::Object> EventListenerHandler(ExecutionContext* execution_context, - EventListener* listener) { - if (listener->GetType() != EventListener::kJSEventListenerType) - return v8::Local<v8::Object>(); - V8AbstractEventListener* v8_listener = - static_cast<V8AbstractEventListener*>(listener); - return v8_listener->GetListenerObject(execution_context); -} - -v8::Local<v8::Function> EventListenerEffectiveFunction( - v8::Isolate* isolate, - v8::Local<v8::Object> handler) { - v8::Local<v8::Function> function; - if (handler->IsFunction()) { - function = handler.As<v8::Function>(); - } else if (handler->IsObject()) { - v8::Local<v8::Value> property; - // Try the "handleEvent" method (EventListener interface). - if (handler - ->Get(handler->CreationContext(), - V8AtomicString(isolate, "handleEvent")) - .ToLocal(&property) && - property->IsFunction()) - function = property.As<v8::Function>(); - // Fall back to the "constructor" property. - else if (handler - ->Get(handler->CreationContext(), - V8AtomicString(isolate, "constructor")) - .ToLocal(&property) && - property->IsFunction()) - function = property.As<v8::Function>(); - } - if (!function.IsEmpty()) - return GetBoundFunction(function); - return v8::Local<v8::Function>(); -} + v8::Isolate* isolate = ToIsolate(frame); + v8::HandleScope scope(isolate); -void GetFunctionLocation(v8::Local<v8::Function> function, - String& script_id, - int& line_number, - int& column_number) { - int script_id_value = function->ScriptId(); - script_id = String::Number(script_id_value); - line_number = function->GetScriptLineNumber(); - column_number = function->GetScriptColumnNumber(); -} + // |v8_context| can be an empty handle when this listener is added as content + // attribute like <hoge onclick="fuga"></hoge> because there is no JS context + // when parsing HTML. In that case we should assume the main world. + v8::Local<v8::Context> v8_context = isolate->GetCurrentContext(); -std::unique_ptr<SourceLocation> GetFunctionLocation( - ExecutionContext* execution_context, - EventListener* listener) { - v8::Isolate* isolate = ToIsolate(execution_context); - v8::HandleScope handle_scope(isolate); - v8::Local<v8::Object> handler = - EventListenerHandler(execution_context, listener); - if (handler.IsEmpty()) - return nullptr; - return SourceLocation::FromFunction( - EventListenerEffectiveFunction(isolate, handler)); + return JSEventHandlerForContentAttribute::Create( + name.LocalName(), value, source_url, position, isolate, + v8_context.IsEmpty() ? DOMWrapperWorld::MainWorld() + : ScriptState::From(v8_context)->World(), + type); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_event_listener.h b/chromium/third_party/blink/renderer/bindings/core/v8/script_event_listener.h index f55adff7187..108227a3206 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/script_event_listener.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_event_listener.h @@ -33,34 +33,26 @@ #include <memory> -#include "third_party/blink/renderer/core/dom/events/event_listener.h" +#include "third_party/blink/renderer/bindings/core/v8/js_event_handler.h" namespace blink { class LocalFrame; class QualifiedName; -class SourceLocation; +// TODO(bindings): consider to remove these functions. EventListener* CreateAttributeEventListener( Node*, - const QualifiedName&, + const QualifiedName& name, const AtomicString& value, - const AtomicString& event_parameter_name); + JSEventHandler::HandlerType type = + JSEventHandler::HandlerType::kEventHandler); EventListener* CreateAttributeEventListener( LocalFrame*, - const QualifiedName&, + const QualifiedName& name, const AtomicString& value, - const AtomicString& event_parameter_name); -v8::Local<v8::Object> EventListenerHandler(ExecutionContext*, EventListener*); -v8::Local<v8::Function> EventListenerEffectiveFunction( - v8::Isolate*, - v8::Local<v8::Object> handler); -void GetFunctionLocation(v8::Local<v8::Function>, - String& script_id, - int& line_number, - int& column_number); -std::unique_ptr<SourceLocation> GetFunctionLocation(ExecutionContext*, - EventListener*); + JSEventHandler::HandlerType type = + JSEventHandler::HandlerType::kEventHandler); } // namespace blink diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_module.h b/chromium/third_party/blink/renderer/bindings/core/v8/script_module.h index b9f3f2be8b0..8570d790323 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/script_module.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_module.h @@ -30,7 +30,7 @@ class ScriptValue; // Currently all ScriptModule users can easily access its context Modulator, so // we use it to fill ScriptState in. class CORE_EXPORT ScriptModule final { - DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); + DISALLOW_NEW(); public: static ScriptModule Compile(v8::Isolate*, diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_module_test.cc b/chromium/third_party/blink/renderer/bindings/core/v8/script_module_test.cc index 5817c36f600..2390b8d8f05 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/script_module_test.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_module_test.cc @@ -15,6 +15,7 @@ #include "third_party/blink/renderer/core/testing/dummy_modulator.h" #include "third_party/blink/renderer/platform/bindings/v8_binding.h" #include "third_party/blink/renderer/platform/bindings/v8_per_context_data.h" +#include "third_party/blink/renderer/platform/loader/fetch/access_control_status.h" #include "v8/include/v8.h" namespace blink { @@ -277,10 +278,11 @@ TEST(ScriptModuleTest, Evaluate) { ASSERT_TRUE(exception.IsEmpty()); EXPECT_TRUE(module.Evaluate(scope.GetScriptState()).IsEmpty()); - v8::Local<v8::Value> value = scope.GetFrame() - .GetScriptController() - .ExecuteScriptInMainWorldAndReturnValue( - ScriptSourceCode("window.foo")); + v8::Local<v8::Value> value = + scope.GetFrame() + .GetScriptController() + .ExecuteScriptInMainWorldAndReturnValue( + ScriptSourceCode("window.foo"), KURL(), kOpaqueResource); ASSERT_TRUE(value->IsString()); EXPECT_EQ("bar", ToCoreString(v8::Local<v8::String>::Cast(value))); diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_promise.cc b/chromium/third_party/blink/renderer/bindings/core/v8/script_promise.cc index 0bde57d4c49..d79efd16401 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/script_promise.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_promise.cc @@ -68,7 +68,7 @@ class PromiseAllHandler final static v8::Local<v8::Function> Create(ScriptState* script_state, ResolveType resolve_type, - size_t index, + wtf_size_t index, PromiseAllHandler* handler) { AdapterFunction* self = new AdapterFunction(script_state, resolve_type, index, handler); @@ -83,7 +83,7 @@ class PromiseAllHandler final private: AdapterFunction(ScriptState* script_state, ResolveType resolve_type, - size_t index, + wtf_size_t index, PromiseAllHandler* handler) : ScriptFunction(script_state), resolve_type_(resolve_type), @@ -100,7 +100,7 @@ class PromiseAllHandler final } const ResolveType resolve_type_; - const size_t index_; + const wtf_size_t index_; Member<PromiseAllHandler> handler_; }; @@ -108,13 +108,13 @@ class PromiseAllHandler final : number_of_pending_promises_(promises.size()), resolver_(script_state) { DCHECK(!promises.IsEmpty()); values_.resize(promises.size()); - for (size_t i = 0; i < promises.size(); ++i) + for (wtf_size_t i = 0; i < promises.size(); ++i) promises[i].Then(CreateFulfillFunction(script_state, i), CreateRejectFunction(script_state)); } v8::Local<v8::Function> CreateFulfillFunction(ScriptState* script_state, - size_t index) { + wtf_size_t index) { return AdapterFunction::Create(script_state, AdapterFunction::kFulfilled, index, this); } @@ -124,7 +124,7 @@ class PromiseAllHandler final this); } - void OnFulfilled(size_t index, const ScriptValue& value) { + void OnFulfilled(wtf_size_t index, const ScriptValue& value) { if (is_settled_) return; @@ -135,7 +135,7 @@ class PromiseAllHandler final v8::Local<v8::Array> values = v8::Array::New(value.GetIsolate(), values_.size()); - for (size_t i = 0; i < values_.size(); ++i) { + for (wtf_size_t i = 0; i < values_.size(); ++i) { if (!V8CallBoolean(values->CreateDataProperty(value.GetContext(), i, values_[i].V8Value()))) return; diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_promise.h b/chromium/third_party/blink/renderer/bindings/core/v8/script_promise.h index 4d5416c9e4d..1015e4057c2 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/script_promise.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_promise.h @@ -53,7 +53,7 @@ class ExceptionState; // terminated). In such cases operations will silently fail, so you should not // use promises for critical use such as releasing a resource. class CORE_EXPORT ScriptPromise final { - DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); + DISALLOW_NEW(); public: // Constructs an empty promise. diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_property_base.cc b/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_property_base.cc index 14c8c8e76d0..fa1fb64ec8b 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_property_base.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_property_base.cc @@ -75,7 +75,7 @@ void ScriptPromisePropertyBase::ResolveOrReject(State target_state) { state_ = target_state; v8::HandleScope handle_scope(isolate_); - size_t i = 0; + wtf_size_t i = 0; while (i < wrappers_.size()) { const std::unique_ptr<ScopedPersistent<v8::Object>>& persistent = wrappers_[i]; @@ -129,7 +129,7 @@ void ScriptPromisePropertyBase::ResolveOrRejectInternal( v8::Local<v8::Object> ScriptPromisePropertyBase::EnsureHolderWrapper( ScriptState* script_state) { v8::Local<v8::Context> context = script_state->GetContext(); - size_t i = 0; + wtf_size_t i = 0; while (i < wrappers_.size()) { const std::unique_ptr<ScopedPersistent<v8::Object>>& persistent = wrappers_[i]; diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_property_test.cc b/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_property_test.cc index 5bc3a1935bd..27078675eb7 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_property_test.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_property_test.cc @@ -187,10 +187,7 @@ class ScriptPromisePropertyNonScriptWrappableResolutionTargetTest public testing::Test { public: template <typename T> - void Test(const T& value, - const char* expected, - const char* file, - size_t line) { + void Test(const T& value, const char* expected, const char* file, int line) { typedef ScriptPromiseProperty<Member<GarbageCollectedScriptWrappable>, T, ToV8UndefinedGenerator> Property; diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_resolver_test.cc b/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_resolver_test.cc index 85f10c93503..2e5e2075c60 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_resolver_test.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_resolver_test.cc @@ -7,7 +7,6 @@ #include <memory> #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/public/platform/web_thread.h" #include "third_party/blink/renderer/bindings/core/v8/script_function.h" #include "third_party/blink/renderer/bindings/core/v8/script_value.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" @@ -15,6 +14,7 @@ #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/core/testing/dummy_page_holder.h" #include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread.h" #include "v8/include/v8.h" namespace blink { diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_source_code.h b/chromium/third_party/blink/renderer/bindings/core/v8/script_source_code.h index 04a6480225a..2a3bbe32925 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/script_source_code.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_source_code.h @@ -46,7 +46,7 @@ class ScriptResource; class SingleCachedMetadataHandler; class CORE_EXPORT ScriptSourceCode final { - DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); + DISALLOW_NEW(); public: // For inline scripts. diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_streamer.cc b/chromium/third_party/blink/renderer/bindings/core/v8/script_streamer.cc index d2f490e8a18..486ef2544fb 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/script_streamer.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_streamer.cc @@ -15,6 +15,7 @@ #include "third_party/blink/renderer/core/html/parser/text_resource_decoder.h" #include "third_party/blink/renderer/core/inspector/inspector_trace_events.h" #include "third_party/blink/renderer/core/script/classic_pending_script.h" +#include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h" #include "third_party/blink/renderer/platform/cross_thread_functional.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" #include "third_party/blink/renderer/platform/loader/fetch/cached_metadata.h" @@ -35,8 +36,7 @@ class SourceStreamDataQueue { WTF_MAKE_NONCOPYABLE(SourceStreamDataQueue); public: - SourceStreamDataQueue() : finished_(false) {} - + SourceStreamDataQueue() : finished_(false), have_data_(mutex_) {} ~SourceStreamDataQueue() { DiscardQueuedData(); } void Clear() { @@ -61,7 +61,7 @@ class SourceStreamDataQueue { void Consume(const uint8_t** data, size_t* length) { MutexLocker locker(mutex_); while (!TryGetData(data, length)) - have_data_.Wait(mutex_); + have_data_.Wait(); } private: @@ -339,11 +339,6 @@ void RunNonBlockingScriptStreamingTask( } // namespace bool ScriptStreamer::HasEnoughDataForStreaming(size_t resource_buffer_size) { - if (RuntimeEnabledFeatures::ScheduledScriptStreamingEnabled()) { - // Enable streaming for small scripts, but we must still check the BOM - // before starting streaming. - return resource_buffer_size >= kMaximumLengthOfBOM; - } // Only stream larger scripts. return resource_buffer_size >= small_script_threshold_; } @@ -399,11 +394,6 @@ void ScriptStreamer::NotifyAppendData(ScriptResource* resource) { return; } - if (!script_state_->ContextIsValid()) { - SuppressStreaming(kContextNotValid); - return; - } - DCHECK(!stream_); DCHECK(!source_); stream_ = new SourceStream; @@ -411,11 +401,11 @@ void ScriptStreamer::NotifyAppendData(ScriptResource* resource) { source_ = std::make_unique<v8::ScriptCompiler::StreamedSource>(stream_, encoding_); - ScriptState::Scope scope(script_state_); std::unique_ptr<v8::ScriptCompiler::ScriptStreamingTask> script_streaming_task( base::WrapUnique(v8::ScriptCompiler::StartStreamingScript( - script_state_->GetIsolate(), source_.get(), compile_options_))); + V8PerIsolateData::MainThreadIsolate(), source_.get(), + compile_options_))); if (!script_streaming_task) { // V8 cannot stream the script. SuppressStreaming(kV8CannotStream); @@ -465,6 +455,10 @@ void ScriptStreamer::NotifyFinished() { } if (stream_) { + // Mark the stream as finished loading before potentially re-posting the + // task to avoid a race between this finish and the task's first read. + stream_->DidFinishLoading(); + // If the corresponding blocking task hasn't started yet, cancel it and post // a non-blocking task, since we know now that all the data is received and // we will no longer block. @@ -473,11 +467,10 @@ void ScriptStreamer::NotifyFinished() { // existing task as no longer MayBlock. if (RuntimeEnabledFeatures::ScheduledScriptStreamingEnabled() && !blocking_task_started_or_cancelled_.test_and_set()) { - ScriptState::Scope scope(script_state_); std::unique_ptr<v8::ScriptCompiler::ScriptStreamingTask> script_streaming_task( base::WrapUnique(v8::ScriptCompiler::StartStreamingScript( - script_state_->GetIsolate(), source_.get(), + V8PerIsolateData::MainThreadIsolate(), source_.get(), compile_options_))); // The task creation shouldn't fail, since it didn't fail before during @@ -489,8 +482,6 @@ void ScriptStreamer::NotifyFinished() { WTF::Passed(std::move(script_streaming_task)), WrapCrossThreadPersistent(this))); } - - stream_->DidFinishLoading(); } loading_finished_ = true; @@ -499,7 +490,6 @@ void ScriptStreamer::NotifyFinished() { ScriptStreamer::ScriptStreamer( ClassicPendingScript* script, - ScriptState* script_state, v8::ScriptCompiler::CompileOptions compile_options, scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner) : pending_script_(script), @@ -511,7 +501,6 @@ ScriptStreamer::ScriptStreamer( streaming_suppressed_(false), suppressed_reason_(kInvalid), compile_options_(compile_options), - script_state_(script_state), script_url_string_(script->GetResource()->Url().Copy().GetString()), script_resource_identifier_(script->GetResource()->Identifier()), // Unfortunately there's no dummy encoding value in the enum; let's use @@ -521,9 +510,13 @@ ScriptStreamer::ScriptStreamer( ScriptStreamer::~ScriptStreamer() = default; +void ScriptStreamer::Prefinalize() { + Cancel(); + prefinalizer_called_ = true; +} + void ScriptStreamer::Trace(blink::Visitor* visitor) { visitor->Trace(pending_script_); - visitor->Trace(script_state_); } void ScriptStreamer::StreamingComplete() { @@ -561,12 +554,9 @@ void ScriptStreamer::NotifyFinishedToClient() { void ScriptStreamer::StartStreaming( ClassicPendingScript* script, - Settings* settings, - ScriptState* script_state, scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner, NotStreamingReason* not_streaming_reason) { DCHECK(IsMainThread()); - DCHECK(script_state->ContextIsValid()); *not_streaming_reason = kInvalid; ScriptResource* resource = ToScriptResource(script->GetResource()); if (!resource->Url().ProtocolIsInHTTPFamily()) { @@ -591,9 +581,9 @@ void ScriptStreamer::StartStreaming( // to arrive: the Content-Length HTTP header is not sent for chunked // downloads. - ScriptStreamer* streamer = new ScriptStreamer( - script, script_state, v8::ScriptCompiler::kNoCompileOptions, - std::move(loading_task_runner)); + ScriptStreamer* streamer = + new ScriptStreamer(script, v8::ScriptCompiler::kNoCompileOptions, + std::move(loading_task_runner)); // If this script was ready when streaming began, no callbacks will be // received to populate the data for the ScriptStreamer, so send them now. diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_streamer.h b/chromium/third_party/blink/renderer/bindings/core/v8/script_streamer.h index 578fb0b45dd..0891268a3cf 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/script_streamer.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_streamer.h @@ -19,8 +19,6 @@ namespace blink { class ClassicPendingScript; class ScriptResource; -class ScriptState; -class Settings; class SourceStream; // ScriptStreamer streams incomplete script data to V8 so that it can be parsed @@ -33,6 +31,7 @@ class SourceStream; class CORE_EXPORT ScriptStreamer final : public GarbageCollectedFinalized<ScriptStreamer> { WTF_MAKE_NONCOPYABLE(ScriptStreamer); + USING_PRE_FINALIZER(ScriptStreamer, Prefinalize); public: // For tracking why some scripts are not streamed. Not streaming is part of @@ -42,7 +41,7 @@ class CORE_EXPORT ScriptStreamer final kAlreadyLoaded, // DEPRECATED kNotHTTP, kReload, - kContextNotValid, + kContextNotValid, // DEPRECATED kEncodingNotSupported, kThreadBusy, kV8CannotStream, @@ -65,8 +64,6 @@ class CORE_EXPORT ScriptStreamer final // Launches a task (on a background thread) which will stream the given // ClassicPendingScript into V8 as it loads. static void StartStreaming(ClassicPendingScript*, - Settings*, - ScriptState*, scoped_refptr<base::SingleThreadTaskRunner>, NotStreamingReason* not_streaming_reason); @@ -126,10 +123,11 @@ class CORE_EXPORT ScriptStreamer final static constexpr size_t kMaximumLengthOfBOM = 4; ScriptStreamer(ClassicPendingScript*, - ScriptState*, v8::ScriptCompiler::CompileOptions, scoped_refptr<base::SingleThreadTaskRunner>); + void Prefinalize(); + void StreamingComplete(); void NotifyFinishedToClient(); bool HasEnoughDataForStreaming(size_t resource_buffer_size); @@ -160,8 +158,6 @@ class CORE_EXPORT ScriptStreamer final // What kind of cached data V8 produces during streaming. v8::ScriptCompiler::CompileOptions compile_options_; - Member<ScriptState> script_state_; - // Keep the script URL string for event tracing. const String script_url_string_; @@ -172,6 +168,12 @@ class CORE_EXPORT ScriptStreamer final v8::ScriptCompiler::StreamedSource::Encoding encoding_; scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner_; + + // This is a temporary flag to confirm that ScriptStreamer is not + // touched after its refinalizer call and thus https://crbug.com/715309 + // doesn't break assumptions. + // TODO(hiroshige): Check the state in more general way. + bool prefinalizer_called_ = false; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_streamer_test.cc b/chromium/third_party/blink/renderer/bindings/core/v8/script_streamer_test.cc index 7ec1d5270e3..7d033b0912c 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/script_streamer_test.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_streamer_test.cc @@ -23,6 +23,7 @@ #include "third_party/blink/renderer/core/script/classic_script.h" #include "third_party/blink/renderer/core/script/mock_script_element_base.h" #include "third_party/blink/renderer/core/testing/dummy_page_holder.h" +#include "third_party/blink/renderer/platform/cross_origin_attribute_value.h" #include "third_party/blink/renderer/platform/exported/wrapped_resource_response.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_loader.h" @@ -56,7 +57,8 @@ class ScriptStreamingTest : public testing::Test { url, WrappedResourceResponse(ResourceResponse()), ""); pending_script_ = ClassicPendingScript::Fetch( url, dummy_page_holder_->GetDocument(), ScriptFetchOptions(), - UTF8Encoding(), element, FetchParameters::kNoDefer); + kCrossOriginAttributeNotSet, UTF8Encoding(), element, + FetchParameters::kNoDefer); pending_script_->SetSchedulingType(ScriptSchedulingType::kParserBlocking); ScriptStreamer::SetSmallScriptThresholdForTesting(0); Platform::Current()->GetURLLoaderMockFactory()->UnregisterURL(url); @@ -90,8 +92,8 @@ class ScriptStreamingTest : public testing::Test { } protected: - void AppendData(const char* data) { - GetResource()->AppendData(data, strlen(data)); + void AppendData(ScriptResource* resource, const char* data) { + resource->AppendData(data, strlen(data)); // Yield control to the background thread, so that V8 gets a chance to // process the data before the main thread adds more. Note that we // cannot fully control in what kind of chunks the data is passed to V8 @@ -100,17 +102,23 @@ class ScriptStreamingTest : public testing::Test { test::YieldCurrentThread(); } - void AppendPadding() { + void AppendData(const char* data) { AppendData(GetResource(), data); } + + void AppendPadding(ScriptResource* resource) { for (int i = 0; i < 10; ++i) { - AppendData( - " /* this is padding to make the script long enough, so " - "that V8's buffer gets filled and it starts processing " - "the data */ "); + AppendData(resource, + " /* this is padding to make the script long enough, so " + "that V8's buffer gets filled and it starts processing " + "the data */ "); } } + void AppendPadding() { AppendPadding(GetResource()); } + void Finish() { - GetResource()->Loader()->DidFinishLoading(TimeTicks(), 0, 0, 0, false); + GetResource()->Loader()->DidFinishLoading( + TimeTicks(), 0, 0, 0, false, + std::vector<network::cors::PreflightTimingInfo>()); GetResource()->SetStatus(ResourceStatus::kCached); } @@ -152,8 +160,7 @@ TEST_F(ScriptStreamingTest, CompilingStreamedScript) { // Test that we can successfully compile a streamed script. V8TestingScope scope; ScriptStreamer::NotStreamingReason reason; - ScriptStreamer::StartStreaming(GetPendingScript(), GetSettings(), - scope.GetScriptState(), loading_task_runner_, + ScriptStreamer::StartStreaming(GetPendingScript(), loading_task_runner_, &reason); GetPendingScript()->SetNotStreamingReasonForTest(reason); TestPendingScriptClient* client = new TestPendingScriptClient; @@ -193,8 +200,7 @@ TEST_F(ScriptStreamingTest, CompilingStreamedScriptWithParseError) { // handle it gracefully. V8TestingScope scope; ScriptStreamer::NotStreamingReason reason; - ScriptStreamer::StartStreaming(GetPendingScript(), GetSettings(), - scope.GetScriptState(), loading_task_runner_, + ScriptStreamer::StartStreaming(GetPendingScript(), loading_task_runner_, &reason); GetPendingScript()->SetNotStreamingReasonForTest(reason); TestPendingScriptClient* client = new TestPendingScriptClient; @@ -235,8 +241,7 @@ TEST_F(ScriptStreamingTest, CancellingStreaming) { // while streaming is ongoing, and ScriptStreamer handles it gracefully. V8TestingScope scope; ScriptStreamer::NotStreamingReason reason; - ScriptStreamer::StartStreaming(GetPendingScript(), GetSettings(), - scope.GetScriptState(), loading_task_runner_, + ScriptStreamer::StartStreaming(GetPendingScript(), loading_task_runner_, &reason); GetPendingScript()->SetNotStreamingReasonForTest(reason); TestPendingScriptClient* client = new TestPendingScriptClient; @@ -259,6 +264,42 @@ TEST_F(ScriptStreamingTest, CancellingStreaming) { EXPECT_FALSE(client->Finished()); } +TEST_F(ScriptStreamingTest, DataAfterCancellingStreaming) { + // Test that the upper layers (PendingScript and up) can be ramped down + // before streaming is started, and ScriptStreamer handles it gracefully. + V8TestingScope scope; + ScriptStreamer::NotStreamingReason reason; + ScriptStreamer::StartStreaming(GetPendingScript(), loading_task_runner_, + &reason); + GetPendingScript()->SetNotStreamingReasonForTest(reason); + TestPendingScriptClient* client = new TestPendingScriptClient; + GetPendingScript()->WatchForLoad(client); + + // In general, we cannot control what the background thread is doing + // (whether it's parsing or waiting for more data). In this test, we have + // given it so little data that it's surely waiting for more. + + EXPECT_FALSE(client->Finished()); + + // Keep the resource alive + Persistent<ScriptResource> resource = GetResource(); + + // Simulate cancelling the network load (e.g., because the user navigated + // away). + GetPendingScript()->Dispose(); + pending_script_ = nullptr; // This would destroy m_resource, but we are still + // holding on to it here. + + // Make sure the streaming starts. + AppendPadding(resource); + resource.Clear(); + + // The V8 side will complete too. This should not crash. We don't receive + // any results from the streaming and the client doesn't get notified. + ProcessTasksUntilStreamingComplete(); + EXPECT_FALSE(client->Finished()); +} + TEST_F(ScriptStreamingTest, SuppressingStreaming) { // If we notice during streaming that there is a code cache, streaming // is suppressed (V8 doesn't parse while the script is loading), and the @@ -266,8 +307,7 @@ TEST_F(ScriptStreamingTest, SuppressingStreaming) { // script is loaded. V8TestingScope scope; ScriptStreamer::NotStreamingReason reason; - ScriptStreamer::StartStreaming(GetPendingScript(), GetSettings(), - scope.GetScriptState(), loading_task_runner_, + ScriptStreamer::StartStreaming(GetPendingScript(), loading_task_runner_, &reason); GetPendingScript()->SetNotStreamingReasonForTest(reason); TestPendingScriptClient* client = new TestPendingScriptClient; @@ -299,8 +339,7 @@ TEST_F(ScriptStreamingTest, EmptyScripts) { // loaded. V8TestingScope scope; ScriptStreamer::NotStreamingReason reason; - ScriptStreamer::StartStreaming(GetPendingScript(), GetSettings(), - scope.GetScriptState(), loading_task_runner_, + ScriptStreamer::StartStreaming(GetPendingScript(), loading_task_runner_, &reason); GetPendingScript()->SetNotStreamingReasonForTest(reason); TestPendingScriptClient* client = new TestPendingScriptClient; @@ -322,8 +361,7 @@ TEST_F(ScriptStreamingTest, SmallScripts) { ScriptStreamer::SetSmallScriptThresholdForTesting(100); ScriptStreamer::NotStreamingReason reason; - ScriptStreamer::StartStreaming(GetPendingScript(), GetSettings(), - scope.GetScriptState(), loading_task_runner_, + ScriptStreamer::StartStreaming(GetPendingScript(), loading_task_runner_, &reason); GetPendingScript()->SetNotStreamingReasonForTest(reason); TestPendingScriptClient* client = new TestPendingScriptClient; @@ -348,8 +386,7 @@ TEST_F(ScriptStreamingTest, ScriptsWithSmallFirstChunk) { ScriptStreamer::SetSmallScriptThresholdForTesting(100); ScriptStreamer::NotStreamingReason reason; - ScriptStreamer::StartStreaming(GetPendingScript(), GetSettings(), - scope.GetScriptState(), loading_task_runner_, + ScriptStreamer::StartStreaming(GetPendingScript(), loading_task_runner_, &reason); GetPendingScript()->SetNotStreamingReasonForTest(reason); TestPendingScriptClient* client = new TestPendingScriptClient; @@ -388,8 +425,7 @@ TEST_F(ScriptStreamingTest, EncodingChanges) { GetResource()->SetEncodingForTest("windows-1252"); ScriptStreamer::NotStreamingReason reason; - ScriptStreamer::StartStreaming(GetPendingScript(), GetSettings(), - scope.GetScriptState(), loading_task_runner_, + ScriptStreamer::StartStreaming(GetPendingScript(), loading_task_runner_, &reason); GetPendingScript()->SetNotStreamingReasonForTest(reason); TestPendingScriptClient* client = new TestPendingScriptClient; @@ -430,8 +466,7 @@ TEST_F(ScriptStreamingTest, EncodingFromBOM) { GetResource()->SetEncodingForTest("windows-1252"); ScriptStreamer::NotStreamingReason reason; - ScriptStreamer::StartStreaming(GetPendingScript(), GetSettings(), - scope.GetScriptState(), loading_task_runner_, + ScriptStreamer::StartStreaming(GetPendingScript(), loading_task_runner_, &reason); GetPendingScript()->SetNotStreamingReasonForTest(reason); TestPendingScriptClient* client = new TestPendingScriptClient; @@ -466,8 +501,7 @@ TEST_F(ScriptStreamingTest, EncodingFromBOM) { TEST_F(ScriptStreamingTest, GarbageCollectDuringStreaming) { V8TestingScope scope; ScriptStreamer::NotStreamingReason reason; - ScriptStreamer::StartStreaming(GetPendingScript(), GetSettings(), - scope.GetScriptState(), loading_task_runner_, + ScriptStreamer::StartStreaming(GetPendingScript(), loading_task_runner_, &reason); GetPendingScript()->SetNotStreamingReasonForTest(reason); diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_streamer_thread.cc b/chromium/third_party/blink/renderer/bindings/core/v8/script_streamer_thread.cc index 9051edde3d2..4bd5bf7cedb 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/script_streamer_thread.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_streamer_thread.cc @@ -7,11 +7,11 @@ #include <memory> #include "base/location.h" #include "third_party/blink/public/platform/platform.h" -#include "third_party/blink/public/platform/web_thread.h" #include "third_party/blink/renderer/bindings/core/v8/script_streamer.h" #include "third_party/blink/renderer/core/inspector/inspector_trace_events.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread.h" #include "third_party/blink/renderer/platform/web_task_runner.h" namespace blink { @@ -55,10 +55,10 @@ void ScriptStreamerThread::TaskDone() { running_task_ = false; } -WebThread& ScriptStreamerThread::PlatformThread() { +Thread& ScriptStreamerThread::PlatformThread() { if (!IsRunning()) { thread_ = Platform::Current()->CreateThread( - WebThreadCreationParams(WebThreadType::kScriptStreamerThread)); + ThreadCreationParams(WebThreadType::kScriptStreamerThread)); } return *thread_; } diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_streamer_thread.h b/chromium/third_party/blink/renderer/bindings/core/v8/script_streamer_thread.h index 2af307dd638..913aeaefbeb 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/script_streamer_thread.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_streamer_thread.h @@ -9,6 +9,7 @@ #include "base/macros.h" #include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread.h" #include "third_party/blink/renderer/platform/wtf/functional.h" #include "third_party/blink/renderer/platform/wtf/threading_primitives.h" #include "v8/include/v8.h" @@ -16,7 +17,6 @@ namespace blink { class ScriptStreamer; -class WebThread; // A singleton thread for running background tasks for script streaming. class CORE_EXPORT ScriptStreamerThread { @@ -44,11 +44,11 @@ class CORE_EXPORT ScriptStreamerThread { bool IsRunning() const { return !!thread_; } - WebThread& PlatformThread(); + Thread& PlatformThread(); // At the moment, we only use one thread, so we can only stream one script // at a time. FIXME: Use a thread pool and stream multiple scripts. - std::unique_ptr<WebThread> thread_; + std::unique_ptr<Thread> thread_; bool running_task_; mutable Mutex mutex_; // Guards m_runningTask. diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_value.h b/chromium/third_party/blink/renderer/bindings/core/v8/script_value.h index 0af66de8880..457c56aabff 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/script_value.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_value.h @@ -43,7 +43,7 @@ namespace blink { class CORE_EXPORT ScriptValue final { - DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); + DISALLOW_NEW(); public: // Defined in ToV8.h due to circular dependency diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_wrappable_v8_gc_integration_test.cc b/chromium/third_party/blink/renderer/bindings/core/v8/script_wrappable_v8_gc_integration_test.cc index e2f550d54ec..dc15fa3ab23 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/script_wrappable_v8_gc_integration_test.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_wrappable_v8_gc_integration_test.cc @@ -18,12 +18,19 @@ void PreciselyCollectGarbage() { ThreadState::Current()->CollectAllGarbage(); } -void RunV8Scavenger(v8::Isolate* isolate) { - V8GCController::CollectGarbage(isolate, true); +// The following directly calls testing GCs in V8 to avoid cluttering a globally +// visible interface with calls that have to be carefully staged. + +void RunV8MinorGC(v8::Isolate* isolate) { + CHECK(isolate); + isolate->RequestGarbageCollectionForTesting( + v8::Isolate::GarbageCollectionType::kMinorGarbageCollection); } -void RunV8FullGc(v8::Isolate* isolate) { - V8GCController::CollectGarbage(isolate, false); +void RunV8FullGC(v8::Isolate* isolate) { + CHECK(isolate); + isolate->RequestGarbageCollectionForTesting( + v8::Isolate::GarbageCollectionType::kFullGarbageCollection); } } // namespace v8_gc_integration_test @@ -47,7 +54,7 @@ TEST(ScriptWrappableV8GCIntegrationTest, V8ReportsLiveObjectsDuringFullGc) { holder.Reset(isolate, ToV8(object, scope.GetContext()->Global(), isolate)); } - v8_gc_integration_test::RunV8FullGc(isolate); + v8_gc_integration_test::RunV8MinorGC(isolate); v8_gc_integration_test::PreciselyCollectGarbage(); EXPECT_FALSE(observer.WasCollected()); holder.Reset(); @@ -78,7 +85,7 @@ TEST(ScriptWrappableV8GCIntegrationTest, V8ReportsLiveObjectsDuringScavenger) { // Scavenger should not collect JavaScript wrappers that are modified, even if // they are otherwise unreachable. - v8_gc_integration_test::RunV8Scavenger(isolate); + v8_gc_integration_test::RunV8MinorGC(isolate); v8_gc_integration_test::PreciselyCollectGarbage(); EXPECT_FALSE(observer.WasCollected()); @@ -100,8 +107,8 @@ TEST(ScriptWrappableV8GCIntegrationTest, holder.Reset(isolate, ToV8(object, scope.GetContext()->Global(), isolate)); } - v8_gc_integration_test::RunV8Scavenger(isolate); - v8_gc_integration_test::RunV8FullGc(isolate); + v8_gc_integration_test::RunV8MinorGC(isolate); + v8_gc_integration_test::RunV8FullGC(isolate); v8_gc_integration_test::PreciselyCollectGarbage(); EXPECT_FALSE(observer.WasCollected()); @@ -123,8 +130,8 @@ TEST(ScriptWrappableV8GCIntegrationTest, ToV8(object, scope.GetContext()->Global(), isolate); } - v8_gc_integration_test::RunV8Scavenger(isolate); - v8_gc_integration_test::RunV8FullGc(isolate); + v8_gc_integration_test::RunV8MinorGC(isolate); + v8_gc_integration_test::RunV8FullGC(isolate); v8_gc_integration_test::PreciselyCollectGarbage(); EXPECT_TRUE(observer.WasCollected()); diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.cc b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.cc index 25efed8921a..278b2ec8f25 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.cc @@ -94,7 +94,7 @@ PostMessageHelper::CreateUserActivationSnapshot( if (LocalFrame* frame = dom_window->GetFrame()) { return mojom::blink::UserActivationSnapshot::New( frame->HasBeenActivated(), - Frame::HasTransientUserActivation(frame, false)); + LocalFrame::HasTransientUserActivation(frame, false)); } } return nullptr; diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.h b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.h index 4adfc46554d..2c9a498b731 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.h @@ -6,7 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_SERIALIZATION_POST_MESSAGE_HELPER_H_ #include "base/memory/scoped_refptr.h" -#include "third_party/blink/public/mojom/message_port/message_port.mojom-blink.h" +#include "third_party/blink/public/mojom/messaging/user_activation_snapshot.mojom-blink.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/platform/wtf/allocator.h" #include "v8/include/v8.h" diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialization_tag.h b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialization_tag.h index adb208c929a..33d2b21f40d 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialization_tag.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialization_tag.h @@ -93,7 +93,15 @@ enum SerializationTag { // namedCurve:uint32_t kRTCCertificateTag = 'k', // length:uint32_t, pemPrivateKey:WebCoreString, // pemCertificate:WebCoreString - kVersionTag = 0xFF // version:uint32_t -> Uses this as the file version. + kDetectedBarcodeTag = + 'B', // raw_value:WebCoreString, bounding_box:DOMRectReadOnly, + // corner_points:Point2D[length] -> DetectedBarcode (ref) + kDetectedFaceTag = + 'F', // raw_value:WebCoreString, bounding_box:DOMRectReadOnly, + // corner_points:Point2D[length] -> DetectedText (ref) + kDetectedTextTag = 't', // bounding_box:DOMRectReadOnly, + // landmarks:Landmark[length] -> DetectedFace (ref) + kVersionTag = 0xFF // version:uint32_t -> Uses this as the file version. }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.cc b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.cc index 33e3eed2151..037f145ed13 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.cc @@ -61,6 +61,7 @@ #include "third_party/blink/renderer/platform/shared_buffer.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" #include "third_party/blink/renderer/platform/wtf/dtoa/utils.h" +#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" #include "third_party/blink/renderer/platform/wtf/text/string_buffer.h" #include "third_party/blink/renderer/platform/wtf/text/string_hash.h" #include "third_party/blink/renderer/platform/wtf/vector.h" @@ -293,7 +294,8 @@ String SerializedScriptValue::ToWireString() const { // Add the padding '\0', but don't put it in |m_dataBuffer|. // This requires direct use of uninitialized strings, though. UChar* destination; - size_t string_size_bytes = (data_buffer_size_ + 1) & ~1; + wtf_size_t string_size_bytes = + SafeCast<wtf_size_t>((data_buffer_size_ + 1) & ~1); String wire_string = String::CreateUninitialized(string_size_bytes / 2, destination); memcpy(destination, data_buffer_.get(), data_buffer_size_); @@ -312,7 +314,7 @@ SerializedScriptValue::TransferImageBitmapContents( if (!image_bitmaps.size()) return contents; - for (size_t i = 0; i < image_bitmaps.size(); ++i) { + for (wtf_size_t i = 0; i < image_bitmaps.size(); ++i) { if (image_bitmaps[i]->IsNeutered()) { exception_state.ThrowDOMException(DOMExceptionCode::kDataCloneError, "ImageBitmap at index " + @@ -323,7 +325,7 @@ SerializedScriptValue::TransferImageBitmapContents( } HeapHashSet<Member<ImageBitmap>> visited; - for (size_t i = 0; i < image_bitmaps.size(); ++i) { + for (wtf_size_t i = 0; i < image_bitmaps.size(); ++i) { if (visited.Contains(image_bitmaps[i])) continue; visited.insert(image_bitmaps[i]); @@ -348,7 +350,7 @@ void SerializedScriptValue::TransferOffscreenCanvas( return; HeapHashSet<Member<OffscreenCanvas>> visited; - for (size_t i = 0; i < offscreen_canvases.size(); i++) { + for (wtf_size_t i = 0; i < offscreen_canvases.size(); i++) { if (visited.Contains(offscreen_canvases[i].Get())) continue; if (offscreen_canvases[i]->IsNeutered()) { @@ -385,7 +387,7 @@ void SerializedScriptValue::CloneSharedArrayBuffers( HeapHashSet<Member<DOMArrayBufferBase>> visited; shared_array_buffers_contents_.Grow(array_buffers.size()); - size_t i = 0; + wtf_size_t i = 0; for (auto* it = array_buffers.begin(); it != array_buffers.end(); ++it) { DOMSharedArrayBuffer* shared_array_buffer = *it; if (visited.Contains(shared_array_buffer)) @@ -446,7 +448,7 @@ bool SerializedScriptValue::ExtractTransferables( Transferables& transferables, ExceptionState& exception_state) { // Validate the passed array of transferables. - uint32_t i = 0; + wtf_size_t i = 0; for (const auto& script_value : object_sequence) { v8::Local<v8::Value> transferable_object = script_value.V8Value(); // Validation of non-null objects, per HTML5 spec 10.3.3. @@ -550,8 +552,9 @@ ArrayBufferArray SerializedScriptValue::ExtractNonSharedArrayBuffers( // Copy the non-shared array buffers into result, and remove them from // array_buffers. result.AppendRange(non_shared_begin, array_buffers.end()); - array_buffers.EraseAt(non_shared_begin - array_buffers.begin(), - array_buffers.end() - non_shared_begin); + array_buffers.EraseAt( + static_cast<wtf_size_t>(non_shared_begin - array_buffers.begin()), + static_cast<wtf_size_t>(array_buffers.end() - non_shared_begin)); return result; } @@ -568,7 +571,8 @@ SerializedScriptValue::TransferArrayBufferContents( for (auto* it = array_buffers.begin(); it != array_buffers.end(); ++it) { DOMArrayBufferBase* array_buffer = *it; if (array_buffer->IsNeutered()) { - size_t index = std::distance(array_buffers.begin(), it); + wtf_size_t index = + static_cast<wtf_size_t>(std::distance(array_buffers.begin(), it)); exception_state.ThrowDOMException(DOMExceptionCode::kDataCloneError, "ArrayBuffer at index " + String::Number(index) + @@ -585,7 +589,8 @@ SerializedScriptValue::TransferArrayBufferContents( continue; visited.insert(array_buffer_base); - size_t index = std::distance(array_buffers.begin(), it); + wtf_size_t index = + static_cast<wtf_size_t>(std::distance(array_buffers.begin(), it)); if (array_buffer_base->IsShared()) { exception_state.ThrowDOMException(DOMExceptionCode::kDataCloneError, "SharedArrayBuffer at index " + diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h index 5dc7bbfa12f..68ebafe597b 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h @@ -88,6 +88,7 @@ class CORE_EXPORT SerializedScriptValue // Version 17: Remove unnecessary byte swapping. // Version 18: Add a list of key-value pairs for ImageBitmap and ImageData to // support color space information, compression, etc. + // Version 19: Add DetectedBarcode, DetectedFace, and DetectedText support. // // The following versions cannot be used, in order to be able to // deserialize version 0 SSVs. The class implementation has details. @@ -100,7 +101,7 @@ class CORE_EXPORT SerializedScriptValue // // Recent changes are routinely reverted in preparation for branch, and this // has been the cause of at least one bug in the past. - static constexpr uint32_t kWireFormatVersion = 18; + static constexpr uint32_t kWireFormatVersion = 19; // This enumeration specifies whether we're serializing a value for storage; // e.g. when writing to IndexedDB. This corresponds to the forStorage flag of diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value_fuzzer.cc b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value_fuzzer.cc index 448fea0a4e9..a75067bffdd 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value_fuzzer.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value_fuzzer.cc @@ -8,6 +8,7 @@ #include <cstddef> #include <cstdint> +#include "base/numerics/safe_conversions.h" #include "build/build_config.h" #include "third_party/blink/public/platform/web_blob_info.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" @@ -52,12 +53,15 @@ int LLVMFuzzerInitialize(int* argc, char*** argv) { return 0; } -int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { +int LLVMFuzzerTestOneInput(const uint8_t* data, size_t data_size) { // Odd sizes are handled in various ways, depending how they arrive. // Let's not worry about that case here. - if (size % sizeof(UChar)) + if (data_size % sizeof(UChar)) return 0; + // Truncate the input. + wtf_size_t size = base::saturated_cast<wtf_size_t>(data_size); + // Used to control what kind of extra data is provided to the deserializer. unsigned hash = StringHasher::HashMemory(data, size); diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.cc b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.cc index a7f18c5ad7d..298cc58efdd 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.cc @@ -419,11 +419,7 @@ ScriptWrappable* V8ScriptValueDeserializer::ReadDOMObject( return DOMRect::Create(x, y, width, height); } case kDOMRectReadOnlyTag: { - double x = 0, y = 0, width = 0, height = 0; - if (!ReadDouble(&x) || !ReadDouble(&y) || !ReadDouble(&width) || - !ReadDouble(&height)) - return nullptr; - return DOMRectReadOnly::Create(x, y, width, height); + return ReadDOMRectReadOnly(); } case kDOMQuadTag: { DOMPointInit pointInits[4]; @@ -560,6 +556,14 @@ File* V8ScriptValueDeserializer::ReadFileIndex() { blob_handle); } +DOMRectReadOnly* V8ScriptValueDeserializer::ReadDOMRectReadOnly() { + double x = 0, y = 0, width = 0, height = 0; + if (!ReadDouble(&x) || !ReadDouble(&y) || !ReadDouble(&width) || + !ReadDouble(&height)) + return nullptr; + return DOMRectReadOnly::Create(x, y, width, height); +} + scoped_refptr<BlobDataHandle> V8ScriptValueDeserializer::GetOrCreateBlobDataHandle(const String& uuid, const String& type, diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.h b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.h index 3582fcbce79..c020791b310 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.h @@ -17,6 +17,7 @@ namespace blink { +class DOMRectReadOnly; class File; class UnpackedSerializedScriptValue; @@ -65,6 +66,7 @@ class CORE_EXPORT V8ScriptValueDeserializer return deserializer_.ReadRawBytes(size, data); } bool ReadUTF8String(String* string_out); + DOMRectReadOnly* ReadDOMRectReadOnly(); template <typename E> bool ReadUint32Enum(E* value) { diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer.cc b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer.cc index 9c23be48326..dd2f4e0c668 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer.cc @@ -170,7 +170,6 @@ void V8ScriptValueSerializer::WriteUTF8String(const String& string) { // TODO(jbroman): Ideally this method would take a WTF::StringView, but the // StringUTF8Adaptor trick doesn't yet work with StringView. StringUTF8Adaptor utf8(string); - DCHECK_LT(utf8.length(), std::numeric_limits<uint32_t>::max()); WriteUint32(utf8.length()); WriteRawBytes(utf8.Data(), utf8.length()); } @@ -268,8 +267,10 @@ bool V8ScriptValueSerializer::WriteDOMObject(ScriptWrappable* wrappable, WriteUint32(image_data->width()); WriteUint32(image_data->height()); DOMArrayBufferBase* pixel_buffer = image_data->BufferBase(); - WriteUint32(pixel_buffer->ByteLength()); - WriteRawBytes(pixel_buffer->Data(), pixel_buffer->ByteLength()); + uint32_t pixel_buffer_length = + SafeCast<uint32_t>(pixel_buffer->ByteLength()); + WriteUint32(pixel_buffer_length); + WriteRawBytes(pixel_buffer->Data(), pixel_buffer_length); return true; } if (wrapper_type_info == &V8DOMPoint::wrapperTypeInfo) { @@ -446,7 +447,7 @@ bool V8ScriptValueSerializer::WriteDOMObject(ScriptWrappable* wrappable, WriteTag(kOffscreenCanvasTransferTag); WriteUint32(canvas->width()); WriteUint32(canvas->height()); - WriteUint32(canvas->PlaceholderCanvasId()); + WriteUint64(canvas->PlaceholderCanvasId()); WriteUint32(canvas->ClientId()); WriteUint32(canvas->SinkId()); return true; @@ -555,7 +556,7 @@ v8::Maybe<uint32_t> V8ScriptValueSerializer::GetSharedArrayBufferId( // The index returned from this function will be serialized into the data // stream. When deserializing, this will be used to index into the // sharedArrayBufferContents array of the SerializedScriptValue. - size_t index = shared_array_buffers_.Find(shared_array_buffer); + uint32_t index = shared_array_buffers_.Find(shared_array_buffer); if (index == kNotFound) { shared_array_buffers_.push_back(shared_array_buffer); index = shared_array_buffers_.size() - 1; diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc index 5e3a9cb8b29..8e3f54805d5 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer_test.cc @@ -106,7 +106,7 @@ v8::Local<v8::Value> RoundTrip( v8::Local<v8::Value> Eval(const String& source, V8TestingScope& scope) { return scope.GetFrame() .GetScriptController() - .ExecuteScriptInMainWorldAndReturnValue(source); + .ExecuteScriptInMainWorldAndReturnValue(source, KURL(), kOpaqueResource); } String ToJSON(v8::Local<v8::Object> object, const V8TestingScope& scope) { diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/source_location.cc b/chromium/third_party/blink/renderer/bindings/core/v8/source_location.cc index 216a21763fd..476a14a5577 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/source_location.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/source_location.cc @@ -56,10 +56,7 @@ std::unique_ptr<SourceLocation> SourceLocation::Capture( return SourceLocation::CreateFromNonEmptyV8StackTrace( std::move(stack_trace), 0); - Document* document = execution_context && execution_context->IsDocument() - ? ToDocument(execution_context) - : nullptr; - if (document) { + if (Document* document = DynamicTo<Document>(execution_context)) { unsigned line_number = 0; if (document->GetScriptableDocumentParser() && !document->IsInDocumentWrite()) { @@ -87,7 +84,8 @@ std::unique_ptr<SourceLocation> SourceLocation::FromMessage( if (debugger) stack_trace = debugger->GetV8Inspector()->createStackTrace(stack); - int script_id = message->GetScriptOrigin().ScriptID()->Value(); + int script_id = + static_cast<int>(message->GetScriptOrigin().ScriptID()->Value()); if (!stack.IsEmpty() && stack->GetFrameCount() > 0) { int top_script_id = stack->GetFrame(isolate, 0)->GetScriptId(); if (top_script_id == script_id) diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/trace_wrapper_member_test.cc b/chromium/third_party/blink/renderer/bindings/core/v8/trace_wrapper_member_test.cc index 90a00beeeca..7e215c00df8 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/trace_wrapper_member_test.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/trace_wrapper_member_test.cc @@ -47,10 +47,10 @@ TEST(TraceWrapperMemberTest, HeapVectorSwap2) { } TEST(TraceWrapperMemberTest, HeapHashSet) { - const size_t kContainerSize = 10000; + const wtf_size_t kContainerSize = 10000; HeapHashSet<Wrapper> set; // Loop enough so that underlying HashTable will rehash several times. - for (size_t i = 1; i <= kContainerSize; ++i) { + for (wtf_size_t i = 1; i <= kContainerSize; ++i) { DeathAwareScriptWrappable* entry = DeathAwareScriptWrappable::Create(); set.insert(entry); } @@ -63,18 +63,18 @@ TEST(TraceWrapperMemberTest, HeapHashSet) { } TEST(TraceWrapperMemberTest, HeapHashMapValue) { - const size_t kContainerSize = 10000; - HeapHashMap<int, Wrapper> map; + const wtf_size_t kContainerSize = 10000; + HeapHashMap<uint32_t, Wrapper> map; HeapVector<Wrapper> verification_vector; // Loop enough so that underlying HashTable will rehash several times. - for (size_t i = 1; i <= kContainerSize; ++i) { + for (wtf_size_t i = 1; i <= kContainerSize; ++i) { DeathAwareScriptWrappable* entry = DeathAwareScriptWrappable::Create(); map.insert(i, entry); verification_vector.push_back(entry); } EXPECT_EQ(kContainerSize, map.size()); - for (size_t i = 1; i <= kContainerSize; ++i) { + for (wtf_size_t i = 1; i <= kContainerSize; ++i) { auto wrapper = map.Take(i); EXPECT_EQ(verification_vector[i - 1], wrapper.Get()); } diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/use_counter_callback.cc b/chromium/third_party/blink/renderer/bindings/core/v8/use_counter_callback.cc index 170c063b8c7..e615bd3bbb9 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/use_counter_callback.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/use_counter_callback.cc @@ -157,6 +157,12 @@ void UseCounterCallback(v8::Isolate* isolate, case v8::Isolate::kWasmThreadOpcodes: blink_feature = WebFeature::kV8WasmThreadOpcodes; break; + case v8::Isolate::kAtomicsNotify: + blink_feature = WebFeature::kV8AtomicsNotify; + break; + case v8::Isolate::kAtomicsWake: + blink_feature = WebFeature::kV8AtomicsWake; + break; default: // This can happen if V8 has added counters that this version of Blink // does not know about. It's harmless. diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_abstract_event_listener.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_abstract_event_listener.cc deleted file mode 100644 index 2c686f39546..00000000000 --- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_abstract_event_listener.cc +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Copyright (C) 2006, 2007, 2008, 2009 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "third_party/blink/renderer/bindings/core/v8/v8_abstract_event_listener.h" - -#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" -#include "third_party/blink/renderer/bindings/core/v8/v8_event.h" -#include "third_party/blink/renderer/bindings/core/v8/v8_event_listener_helper.h" -#include "third_party/blink/renderer/bindings/core/v8/v8_event_target.h" -#include "third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h" -#include "third_party/blink/renderer/core/dom/document.h" -#include "third_party/blink/renderer/core/dom/document_parser.h" -#include "third_party/blink/renderer/core/dom/events/event.h" -#include "third_party/blink/renderer/core/dom/events/event_target.h" -#include "third_party/blink/renderer/core/events/before_unload_event.h" -#include "third_party/blink/renderer/core/execution_context/execution_context.h" -#include "third_party/blink/renderer/core/probe/core_probes.h" -#include "third_party/blink/renderer/core/workers/worker_or_worklet_global_scope.h" -#include "third_party/blink/renderer/platform/bindings/v8_private_property.h" -#include "third_party/blink/renderer/platform/instance_counters.h" - -namespace blink { - -V8AbstractEventListener::V8AbstractEventListener(v8::Isolate* isolate, - bool is_attribute, - DOMWrapperWorld& world) - : EventListener(kJSEventListenerType), - is_attribute_(is_attribute), - world_(&world), - isolate_(isolate) { - if (IsMainThread()) - InstanceCounters::IncrementCounter( - InstanceCounters::kJSEventListenerCounter); -} - -V8AbstractEventListener::~V8AbstractEventListener() { - // For non-main threads a termination garbage collection clears out the - // wrapper links to CustomWrappable which result in CustomWrappable not being - // rooted by JavaScript objects anymore. This means that - // V8AbstractEventListener can be collected without while still holding a - // valid weak references. - if (IsMainThread()) { - DCHECK(listener_.IsEmpty()); - InstanceCounters::DecrementCounter( - InstanceCounters::kJSEventListenerCounter); - } -} - -// static -v8::Local<v8::Value> V8AbstractEventListener::GetListenerOrNull( - v8::Isolate* isolate, - EventTarget* event_target, - EventListener* listener) { - if (listener && listener->GetType() == kJSEventListenerType) { - v8::Local<v8::Object> v8_listener = - static_cast<V8AbstractEventListener*>(listener) - ->GetListenerObjectInternal(event_target->GetExecutionContext()); - if (!v8_listener.IsEmpty()) - return v8_listener; - } - return v8::Null(isolate); -} - -void V8AbstractEventListener::handleEvent(ExecutionContext* execution_context, - Event* event) { - if (!execution_context) - return; - // Don't reenter V8 if execution was terminated in this instance of V8. - if (execution_context->IsJSExecutionForbidden()) - return; - - // A ScriptState used by the event listener needs to be calculated based on - // the ExecutionContext that fired the the event listener and the world - // that installed the event listener. - DCHECK(event); - v8::HandleScope handle_scope(ToIsolate(execution_context)); - v8::Local<v8::Context> v8_context = ToV8Context(execution_context, World()); - if (v8_context.IsEmpty()) - return; - ScriptState* script_state = ScriptState::From(v8_context); - if (!script_state->ContextIsValid()) - return; - HandleEvent(script_state, event); -} - -void V8AbstractEventListener::HandleEvent(ScriptState* script_state, - Event* event) { - ScriptState::Scope scope(script_state); - - // Get the V8 wrapper for the event object. - v8::Local<v8::Value> js_event = - ToV8(event, script_state->GetContext()->Global(), GetIsolate()); - if (js_event.IsEmpty()) - return; - InvokeEventHandler(script_state, event, - v8::Local<v8::Value>::New(GetIsolate(), js_event)); -} - -void V8AbstractEventListener::SetListenerObject( - ScriptState* script_state, - v8::Local<v8::Object> listener, - const V8PrivateProperty::Symbol& property) { - DCHECK(listener_.IsEmpty()); - listener_.Set(GetIsolate(), listener, this, &WrapperCleared); - Attach(script_state, listener, property, this); -} - -void V8AbstractEventListener::InvokeEventHandler( - ScriptState* script_state, - Event* event, - v8::Local<v8::Value> js_event) { - if (!event->CanBeDispatchedInWorld(World())) - return; - - v8::Local<v8::Value> return_value; - v8::Local<v8::Context> context = script_state->GetContext(); - { - // Catch exceptions thrown in the event handler so they do not propagate to - // javascript code that caused the event to fire. - v8::TryCatch try_catch(GetIsolate()); - try_catch.SetVerbose(true); - - v8::Local<v8::Object> global = context->Global(); - V8PrivateProperty::Symbol event_symbol = - V8PrivateProperty::GetGlobalEvent(GetIsolate()); - // Save the old 'event' property so we can restore it later. - v8::Local<v8::Value> saved_event; - if (!event_symbol.GetOrUndefined(global).ToLocal(&saved_event)) - return; - try_catch.Reset(); - - // Expose the event object as |window.event|, except when the event's target - // is in a V1 shadow tree, in which case |window.event| should be - // |undefined|. - Node* target_node = event->target()->ToNode(); - if (target_node && target_node->IsInV1ShadowTree()) { - event_symbol.Set(global, v8::Undefined(GetIsolate())); - } else { - event_symbol.Set(global, js_event); - } - try_catch.Reset(); - - return_value = CallListenerFunction(script_state, js_event, event); - if (try_catch.HasCaught()) - event->LegacySetDidListenersThrowFlag(); - - if (!try_catch.CanContinue()) { // Result of TerminateExecution(). - ExecutionContext* execution_context = ToExecutionContext(context); - if (execution_context->IsWorkerOrWorkletGlobalScope()) - ToWorkerOrWorkletGlobalScope(execution_context) - ->ScriptController() - ->ForbidExecution(); - return; - } - try_catch.Reset(); - - // Restore the old event. This must be done for all exit paths through this - // method. - event_symbol.Set(global, saved_event); - try_catch.Reset(); - } - - if (return_value.IsEmpty()) - return; - - // Because OnBeforeUnloadEventHandler is currently not implemented, the - // following special handling of BeforeUnloadEvents and events with the type - // beforeunload is needed in accordance with the spec at - // https://html.spec.whatwg.org/multipage/webappapis.html#the-event-handler-processing-algorithm - // TODO(rakina): remove special handling after OnBeforeUnloadEventHandler - // is implemented - - if (!is_attribute_) { - return; - } - - if (event->IsBeforeUnloadEvent() && - event->type() == EventTypeNames::beforeunload) { - if (!return_value->IsUndefined() && !return_value->IsNull()) { - event->preventDefault(); - if (ToBeforeUnloadEvent(event)->returnValue().IsEmpty()) { - TOSTRING_VOID(V8StringResource<>, string_return_value, return_value); - ToBeforeUnloadEvent(event)->setReturnValue(string_return_value); - } - } - } else if (ShouldPreventDefault(return_value, event) && - event->type() != EventTypeNames::beforeunload) { - event->preventDefault(); - } -} - -bool V8AbstractEventListener::ShouldPreventDefault( - v8::Local<v8::Value> return_value, - Event*) { - // Prevent default action if the return value is false in accord with the spec - // http://www.w3.org/TR/html5/webappapis.html#event-handler-attributes - return return_value->IsBoolean() && !return_value.As<v8::Boolean>()->Value(); -} - -v8::Local<v8::Object> V8AbstractEventListener::GetReceiverObject( - ScriptState* script_state, - Event* event) { - v8::Local<v8::Object> listener = listener_.NewLocal(GetIsolate()); - if (!listener_.IsEmpty() && !listener->IsFunction()) - return listener; - - EventTarget* target = event->currentTarget(); - v8::Local<v8::Value> value = - ToV8(target, script_state->GetContext()->Global(), GetIsolate()); - if (value.IsEmpty()) - return v8::Local<v8::Object>(); - return v8::Local<v8::Object>::New(GetIsolate(), - v8::Local<v8::Object>::Cast(value)); -} - -bool V8AbstractEventListener::BelongsToTheCurrentWorld( - ExecutionContext* execution_context) const { - if (!GetIsolate()->GetCurrentContext().IsEmpty() && - &World() == &DOMWrapperWorld::Current(GetIsolate())) - return true; - // If currently parsing, the parser could be accessing this listener - // outside of any v8 context; check if it belongs to the main world. - if (!GetIsolate()->InContext() && execution_context && - execution_context->IsDocument()) { - Document* document = ToDocument(execution_context); - if (document->Parser() && document->Parser()->IsParsing()) - return World().IsMainWorld(); - } - return false; -} - -void V8AbstractEventListener::ClearListenerObject() { - if (!HasExistingListenerObject()) - return; - probe::AsyncTaskCanceled(GetIsolate(), this); - listener_.Clear(); -} - -void V8AbstractEventListener::WrapperCleared( - const v8::WeakCallbackInfo<V8AbstractEventListener>& data) { - data.GetParameter()->ClearListenerObject(); -} - -void V8AbstractEventListener::Trace(blink::Visitor* visitor) { - visitor->Trace(listener_.Cast<v8::Value>()); - EventListener::Trace(visitor); -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_abstract_event_listener.h b/chromium/third_party/blink/renderer/bindings/core/v8/v8_abstract_event_listener.h deleted file mode 100644 index 7ecb25f9e2c..00000000000 --- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_abstract_event_listener.h +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright (C) 2006, 2007, 2008, 2009 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_V8_ABSTRACT_EVENT_LISTENER_H_ -#define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_V8_ABSTRACT_EVENT_LISTENER_H_ - -#include "third_party/blink/renderer/core/core_export.h" -#include "third_party/blink/renderer/core/dom/events/event_listener.h" -#include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h" -#include "third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h" -#include "third_party/blink/renderer/platform/heap/self_keep_alive.h" -#include "v8/include/v8.h" - -namespace blink { - -class Event; -class EventTarget; - -// There are two kinds of event listeners: HTML or non-HMTL. onload, -// onfocus, etc (attributes) are always HTML event handler type; Event -// listeners added by Window.addEventListener or -// EventTargetNode::addEventListener are non-HTML type. -// -// Why does this matter? -// WebKit does not allow duplicated HTML event handlers of the same type, -// but ALLOWs duplicated non-HTML event handlers. -class CORE_EXPORT V8AbstractEventListener : public EventListener { - public: - ~V8AbstractEventListener() override; - - static const V8AbstractEventListener* Cast(const EventListener* listener) { - return listener->GetType() == kJSEventListenerType - ? static_cast<const V8AbstractEventListener*>(listener) - : nullptr; - } - - static V8AbstractEventListener* Cast(EventListener* listener) { - return const_cast<V8AbstractEventListener*>( - Cast(const_cast<const EventListener*>(listener))); - } - - static v8::Local<v8::Value> GetListenerOrNull(v8::Isolate*, - EventTarget*, - EventListener*); - - // Implementation of EventListener interface. - - bool operator==(const EventListener& other) const override { - return this == &other; - } - - void handleEvent(ExecutionContext*, Event*) final; - virtual void HandleEvent(ScriptState*, Event*); - - // Returns the listener object, either a function or an object, or the empty - // handle if the user script is not compilable. No exception will be thrown - // even if the user script is not compilable. - v8::Local<v8::Object> GetListenerObjectForInspector( - ExecutionContext* execution_context) final { - return GetListenerObjectInternal(execution_context); - } - - v8::Local<v8::Object> GetListenerObject(ExecutionContext* execution_context) { - return GetListenerObjectInternal(execution_context); - } - - v8::Local<v8::Object> GetExistingListenerObject() { - return listener_.NewLocal(isolate_); - } - - // Provides access to the underlying handle for GC. Returned - // value is a weak handle and so not guaranteed to stay alive. - v8::Persistent<v8::Object>& ExistingListenerObjectPersistentHandle() { - return listener_.Get(); - } - - bool HasExistingListenerObject() { return !listener_.IsEmpty(); } - - void ClearListenerObject(); - - bool BelongsToTheCurrentWorld(ExecutionContext*) const final; - - bool IsAttribute() const final { return is_attribute_; } - - v8::Isolate* GetIsolate() const { return isolate_; } - DOMWrapperWorld* GetWorldForInspector() const final { return world_.get(); } - - void Trace(blink::Visitor*) override; - - protected: - V8AbstractEventListener(v8::Isolate*, bool is_attribute, DOMWrapperWorld&); - - virtual v8::Local<v8::Object> GetListenerObjectInternal( - ExecutionContext* execution_context) { - return GetExistingListenerObject(); - } - - void SetListenerObject(ScriptState*, - v8::Local<v8::Object>, - const V8PrivateProperty::Symbol&); - - void InvokeEventHandler(ScriptState*, Event*, v8::Local<v8::Value>); - - // Get the receiver object to use for event listener call. - v8::Local<v8::Object> GetReceiverObject(ScriptState*, Event*); - DOMWrapperWorld& World() const { return *world_; } - - private: - // This could return an empty handle and callers need to check return value. - // We don't use v8::MaybeLocal because it can fail without exception. - virtual v8::Local<v8::Value> - CallListenerFunction(ScriptState*, v8::Local<v8::Value> jsevent, Event*) = 0; - - virtual bool ShouldPreventDefault(v8::Local<v8::Value> return_value, Event*); - - static void WrapperCleared( - const v8::WeakCallbackInfo<V8AbstractEventListener>&); - - TraceWrapperV8Reference<v8::Object> listener_; - - // true if the listener is created through a DOM attribute. - bool is_attribute_; - - scoped_refptr<DOMWrapperWorld> world_; - v8::Isolate* isolate_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_V8_ABSTRACT_EVENT_LISTENER_H_ diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.cc index 71d591e7aef..5833fe9690b 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.cc @@ -34,7 +34,6 @@ #include "third_party/blink/renderer/bindings/core/v8/idl_types.h" #include "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h" #include "third_party/blink/renderer/bindings/core/v8/script_controller.h" -#include "third_party/blink/renderer/bindings/core/v8/v8_abstract_event_listener.h" #include "third_party/blink/renderer/bindings/core/v8/v8_array_buffer_view.h" #include "third_party/blink/renderer/bindings/core/v8/v8_element.h" #include "third_party/blink/renderer/bindings/core/v8/v8_event_target.h" @@ -714,12 +713,11 @@ static ScriptState* ToScriptStateImpl(LocalFrame* frame, v8::Local<v8::Context> ToV8Context(ExecutionContext* context, DOMWrapperWorld& world) { DCHECK(context); - if (context->IsDocument()) { - if (LocalFrame* frame = ToDocument(context)->GetFrame()) + if (auto* document = DynamicTo<Document>(context)) { + if (LocalFrame* frame = document->GetFrame()) return ToV8Context(frame, world); - } else if (context->IsWorkerOrWorkletGlobalScope()) { - if (WorkerOrWorkletScriptController* script = - ToWorkerOrWorkletGlobalScope(context)->ScriptController()) { + } else if (auto* scope = DynamicTo<WorkerOrWorkletGlobalScope>(context)) { + if (WorkerOrWorkletScriptController* script = scope->ScriptController()) { if (script->GetScriptState()->ContextIsValid()) return script->GetScriptState()->GetContext(); } diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_context_snapshot.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_context_snapshot.cc index 374e9031bbc..ccaa8507ba1 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_context_snapshot.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_context_snapshot.cc @@ -114,9 +114,12 @@ const WrapperTypeInfo* FieldTypeToWrapperTypeInfo(InternalFieldType type) { struct DataForDeserializer { STACK_ALLOCATED(); - public: + DataForDeserializer(Document* document) : document(document) {} + Member<Document> document; + // Figures if we failed the deserialization. + bool did_fail = false; }; } // namespace @@ -132,13 +135,22 @@ v8::Local<v8::Context> V8ContextSnapshot::CreateContextFromSnapshot( } const int index = GetSnapshotIndexForWorld(world); - DataForDeserializer data{document}; + DataForDeserializer data(document); v8::DeserializeInternalFieldsCallback callback = v8::DeserializeInternalFieldsCallback(&DeserializeInternalField, &data); v8::Local<v8::Context> context = v8::Context::FromSnapshot(isolate, index, callback, extension_configuration, global_proxy) .ToLocalChecked(); + + // In case we fail to deserialize v8::Context from snapshot, + // disable the snapshot feature and returns an empty handle. + // TODO(peria): Drop this fallback routine. crbug.com/881417 + if (data.did_fail) { + V8PerIsolateData::From(isolate)->BailoutAndDisableV8ContextSnapshot(); + return v8::Local<v8::Context>(); + } + VLOG(1) << "A context is created from snapshot for " << (world.IsMainWorld() ? "" : "non-") << "main world"; @@ -351,27 +363,45 @@ void V8ContextSnapshot::DeserializeInternalField(v8::Local<v8::Object> object, *reinterpret_cast<const InternalFieldType*>(payload.data); const WrapperTypeInfo* wrapper_type_info = FieldTypeToWrapperTypeInfo(type); + DataForDeserializer* embed_data = static_cast<DataForDeserializer*>(ptr); switch (type) { case InternalFieldType::kNodeType: case InternalFieldType::kDocumentType: case InternalFieldType::kHTMLDocumentType: { - CHECK_EQ(index, kV8DOMWrapperTypeIndex); + // TODO(peria): Make this branch back to CHECK_EQ. crbug.com/881417 + if (index != kV8DOMWrapperTypeIndex) { + LOG(ERROR) << "Invalid index for wrpper type info: " << index; + embed_data->did_fail = true; + return; + } object->SetAlignedPointerInInternalField( index, const_cast<WrapperTypeInfo*>(wrapper_type_info)); return; } case InternalFieldType::kHTMLDocumentObject: { + // There seems to be few crash reports with invalid |index|. + // In such cases, we fallback to create v8::Context without snapshots. + // TODO(peria): Make this branch back to CHECK_EQ. crbug.com/881417 + if (index != kV8DOMWrapperObjectIndex) { + LOG(ERROR) << "Invalid index for HTMLDocument object: " << index; + embed_data->did_fail = true; + return; + } + // The below code handles window.document on the main world. - CHECK_EQ(index, kV8DOMWrapperObjectIndex); v8::Isolate* isolate = v8::Isolate::GetCurrent(); - DataForDeserializer* data = static_cast<DataForDeserializer*>(ptr); - ScriptWrappable* document = data->document; + ScriptWrappable* document = embed_data->document; DCHECK(document); // Make reference from wrapper to document object->SetAlignedPointerInInternalField(index, document); // Make reference from document to wrapper - CHECK(document->SetWrapper(isolate, wrapper_type_info, object)); + // TODO(peria): Make this branch back to CHECK. crbug.com/881417 + if (!document->SetWrapper(isolate, wrapper_type_info, object)) { + LOG(ERROR) << "Failed to set HTMLDocument wrapper on Blink object."; + embed_data->did_fail = true; + return; + } WrapperTypeInfo::WrapperCreated(); return; } diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_cross_origin_setter_info.h b/chromium/third_party/blink/renderer/bindings/core/v8/v8_cross_origin_setter_info.h deleted file mode 100644 index 3ad6d461568..00000000000 --- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_cross_origin_setter_info.h +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2016 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 file. - -#ifndef THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_V8_CROSS_ORIGIN_SETTER_INFO_H_ -#define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_V8_CROSS_ORIGIN_SETTER_INFO_H_ - -#include "third_party/blink/renderer/platform/wtf/allocator.h" -#include "v8/include/v8.h" - -namespace blink { - -// Simple adapter that is used in place of v8::PropertyCallbackInfo for setters -// that are accessible cross-origin. This is needed because a named access check -// interceptor takes a v8::PropertyCallbackInfo<v8::Value> argument, while a -// normal setter interceptor takes a v8::PropertyCallbackInfo<void> argument. -// -// Since the generated bindings only care about two fields (the isolate and the -// holder), the generated bindings just substitutes this for the normal -// v8::PropertyCallbackInfo argument, so the same generated function can be used -// to handle intercepted cross-origin sets and normal sets. -class V8CrossOriginSetterInfo { - STACK_ALLOCATED(); - - public: - V8CrossOriginSetterInfo(v8::Isolate* isolate, v8::Local<v8::Object> holder) - : isolate_(isolate), holder_(holder) {} - - v8::Isolate* GetIsolate() const { return isolate_; } - v8::Local<v8::Object> Holder() const { return holder_; } - - private: - v8::Isolate* isolate_; - v8::Local<v8::Object> holder_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_V8_CROSS_ORIGIN_SETTER_INFO_H_ diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_dom_configuration.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_dom_configuration.cc index 02c13e9fa53..53a5417b0dd 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_dom_configuration.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_dom_configuration.cc @@ -31,6 +31,7 @@ #include "third_party/blink/renderer/platform/bindings/v8_object_constructor.h" #include "third_party/blink/renderer/platform/bindings/v8_per_context_data.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" +#include "third_party/blink/renderer/platform/wtf/text/string_builder.h" namespace blink { @@ -155,6 +156,11 @@ void InstallAttributeInternal( NOTREACHED(); } +enum class AccessorType { + Getter, + Setter, +}; + template <class FunctionOrTemplate> v8::Local<FunctionOrTemplate> CreateAccessorFunctionOrTemplate( v8::Isolate*, @@ -162,7 +168,8 @@ v8::Local<FunctionOrTemplate> CreateAccessorFunctionOrTemplate( V8PrivateProperty::CachedAccessorSymbol, v8::Local<v8::Value> data, v8::Local<v8::Signature>, - int length, + const char* name, + AccessorType, v8::SideEffectType side_effect_type = v8::SideEffectType::kHasSideEffect); template <> @@ -173,10 +180,20 @@ CreateAccessorFunctionOrTemplate<v8::FunctionTemplate>( V8PrivateProperty::CachedAccessorSymbol cached_property_key, v8::Local<v8::Value> data, v8::Local<v8::Signature> signature, - int length, + const char* name, + AccessorType type, v8::SideEffectType side_effect_type) { v8::Local<v8::FunctionTemplate> function_template; if (callback) { + // https://heycam.github.io/webidl/#dfn-attribute-getter has: + // + // 5. Perform ! SetFunctionLength(|F|, 0). + // + // https://heycam.github.io/webidl/#dfn-attribute-setter has: + // + // 7. Perform ! SetFunctionLength(|F|, 1). + int length = type == AccessorType::Getter ? 0 : 1; + if (cached_property_key != V8PrivateProperty::kNoCachedAccessor) { function_template = v8::FunctionTemplate::NewWithCache( isolate, callback, @@ -192,6 +209,28 @@ CreateAccessorFunctionOrTemplate<v8::FunctionTemplate>( if (!function_template.IsEmpty()) { function_template->RemovePrototype(); function_template->SetAcceptAnyReceiver(false); + + // https://heycam.github.io/webidl/#dfn-attribute-getter has: + // + // 3. Let |name| be the string "get " prepended to |attribute|’s + // identifier. + // + // 4. Perform ! SetFunctionName(|F|, |name|). + // + // https://heycam.github.io/webidl/#dfn-attribute-setter has: + // + // 5. Let |name| be the string "set " prepended to |id|. + // + // 6. Perform ! SetFunctionName(|F|, |name|). + // + // SetClassName on a FunctionTemplate that doesn't have a prototype just + // sets the .name property of the generated function. + WTF::StringBuilder full_name_builder; + full_name_builder.Append(type == AccessorType::Getter ? "get " : "set ", + 4); + full_name_builder.Append(name); + function_template->SetClassName( + V8AtomicString(isolate, full_name_builder.ToString())); } } return function_template; @@ -204,7 +243,8 @@ v8::Local<v8::Function> CreateAccessorFunctionOrTemplate<v8::Function>( V8PrivateProperty::CachedAccessorSymbol, v8::Local<v8::Value> data, v8::Local<v8::Signature> signature, - int length, + const char* name, + AccessorType type, v8::SideEffectType side_effect_type) { if (!callback) return v8::Local<v8::Function>(); @@ -212,7 +252,7 @@ v8::Local<v8::Function> CreateAccessorFunctionOrTemplate<v8::Function>( v8::Local<v8::FunctionTemplate> function_template = CreateAccessorFunctionOrTemplate<v8::FunctionTemplate>( isolate, callback, V8PrivateProperty::kNoCachedAccessor, data, - signature, length, side_effect_type); + signature, name, type, side_effect_type); if (function_template.IsEmpty()) return v8::Local<v8::Function>(); @@ -257,7 +297,7 @@ void InstallAccessorInternal( if (!WorldConfigurationApplies(config, world)) return; - v8::Local<v8::Name> name = V8AtomicString(isolate, config.name); + v8::Local<v8::String> name = V8AtomicString(isolate, config.name); v8::FunctionCallback getter_callback = config.getter; v8::FunctionCallback setter_callback = config.setter; auto cached_property_key = V8PrivateProperty::kNoCachedAccessor; @@ -285,11 +325,13 @@ void InstallAccessorInternal( v8::Local<FunctionOrTemplate> getter = CreateAccessorFunctionOrTemplate<FunctionOrTemplate>( isolate, getter_callback, cached_property_key, - v8::Local<v8::Value>(), signature, 0, getter_side_effect_type); + v8::Local<v8::Value>(), signature, config.name, + AccessorType::Getter, getter_side_effect_type); v8::Local<FunctionOrTemplate> setter = CreateAccessorFunctionOrTemplate<FunctionOrTemplate>( isolate, setter_callback, V8PrivateProperty::kNoCachedAccessor, - v8::Local<v8::Value>(), signature, 1); + v8::Local<v8::Value>(), signature, config.name, + AccessorType::Setter); if (location & V8DOMConfiguration::kOnInstance && !IsObjectAndEmpty(instance_or_template)) { instance_or_template->SetAccessorProperty( @@ -311,12 +353,13 @@ void InstallAccessorInternal( v8::Local<FunctionOrTemplate> getter = CreateAccessorFunctionOrTemplate<FunctionOrTemplate>( isolate, getter_callback, V8PrivateProperty::kNoCachedAccessor, - v8::Local<v8::Value>(), v8::Local<v8::Signature>(), 0, - getter_side_effect_type); + v8::Local<v8::Value>(), v8::Local<v8::Signature>(), config.name, + AccessorType::Getter, getter_side_effect_type); v8::Local<FunctionOrTemplate> setter = CreateAccessorFunctionOrTemplate<FunctionOrTemplate>( isolate, setter_callback, V8PrivateProperty::kNoCachedAccessor, - v8::Local<v8::Value>(), v8::Local<v8::Signature>(), 1); + v8::Local<v8::Value>(), v8::Local<v8::Signature>(), config.name, + AccessorType::Setter); interface_or_template->SetAccessorProperty( name, getter, setter, static_cast<v8::PropertyAttribute>(config.attribute)); @@ -736,7 +779,7 @@ void V8DOMConfiguration::InitializeDOMInterfaceTemplate( v8::Local<v8::FunctionTemplate> interface_template, const char* interface_name, v8::Local<v8::FunctionTemplate> parent_interface_template, - size_t v8_internal_field_count) { + uint32_t v8_internal_field_count) { interface_template->SetClassName(V8AtomicString(isolate, interface_name)); interface_template->ReadOnlyPrototype(); v8::Local<v8::ObjectTemplate> instance_template = diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_dom_configuration.h b/chromium/third_party/blink/renderer/bindings/core/v8/v8_dom_configuration.h index e41cea3c713..488dc8864fc 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_dom_configuration.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_dom_configuration.h @@ -348,7 +348,7 @@ class CORE_EXPORT V8DOMConfiguration final { v8::Local<v8::FunctionTemplate> interface_template, const char* interface_name, v8::Local<v8::FunctionTemplate> parent_interface_template, - size_t v8_internal_field_count); + uint32_t v8_internal_field_count); static v8::Local<v8::FunctionTemplate> DomClassTemplate( v8::Isolate*, diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_error_handler.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_error_handler.cc deleted file mode 100644 index 24f422f2818..00000000000 --- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_error_handler.cc +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (C) 2010 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "third_party/blink/renderer/bindings/core/v8/v8_error_handler.h" - -#include "third_party/blink/renderer/bindings/core/v8/script_controller.h" -#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" -#include "third_party/blink/renderer/bindings/core/v8/v8_error_event.h" -#include "third_party/blink/renderer/bindings/core/v8/v8_script_runner.h" -#include "third_party/blink/renderer/core/execution_context/execution_context.h" -#include "third_party/blink/renderer/platform/bindings/v8_private_property.h" - -namespace blink { - -V8ErrorHandler::V8ErrorHandler(bool is_inline, ScriptState* script_state) - : V8EventListenerOrEventHandler(is_inline, script_state) {} - -v8::Local<v8::Value> V8ErrorHandler::CallListenerFunction( - ScriptState* script_state, - v8::Local<v8::Value> js_event, - Event* event) { - DCHECK(!js_event.IsEmpty()); - if (!event->HasInterface(EventNames::ErrorEvent)) { - return V8EventListenerOrEventHandler::CallListenerFunction(script_state, - js_event, event); - } - - ErrorEvent* error_event = static_cast<ErrorEvent*>(event); - v8::Local<v8::Context> context = script_state->GetContext(); - ExecutionContext* execution_context = ToExecutionContext(context); - v8::Local<v8::Object> listener = GetListenerObjectInternal(execution_context); - if (listener.IsEmpty() || !listener->IsFunction()) - return v8::Null(GetIsolate()); - - v8::Local<v8::Function> call_function = - v8::Local<v8::Function>::Cast(listener); - v8::Local<v8::Object> this_value = context->Global(); - - v8::Local<v8::Object> event_object; - if (!js_event->ToObject(context).ToLocal(&event_object)) - return v8::Null(GetIsolate()); - auto private_error = V8PrivateProperty::GetErrorEventError(GetIsolate()); - v8::Local<v8::Value> error; - if (!private_error.GetOrUndefined(event_object).ToLocal(&error) || - error->IsUndefined()) - error = v8::Null(GetIsolate()); - - v8::Local<v8::Value> parameters[5] = { - V8String(GetIsolate(), error_event->message()), - V8String(GetIsolate(), error_event->filename()), - v8::Integer::New(GetIsolate(), error_event->lineno()), - v8::Integer::New(GetIsolate(), error_event->colno()), error}; - v8::TryCatch try_catch(GetIsolate()); - try_catch.SetVerbose(true); - - v8::MaybeLocal<v8::Value> result = V8ScriptRunner::CallFunction( - call_function, execution_context, this_value, base::size(parameters), - parameters, GetIsolate()); - v8::Local<v8::Value> return_value; - if (!result.ToLocal(&return_value)) - return v8::Null(GetIsolate()); - - return return_value; -} - -// static -void V8ErrorHandler::StoreExceptionOnErrorEventWrapper( - ScriptState* script_state, - ErrorEvent* event, - v8::Local<v8::Value> data, - v8::Local<v8::Object> creation_context) { - v8::Local<v8::Value> wrapped_event = - ToV8(event, creation_context, script_state->GetIsolate()); - if (wrapped_event.IsEmpty()) - return; - - DCHECK(wrapped_event->IsObject()); - auto private_error = - V8PrivateProperty::GetErrorEventError(script_state->GetIsolate()); - private_error.Set(wrapped_event.As<v8::Object>(), data); -} - -// static -v8::Local<v8::Value> V8ErrorHandler::LoadExceptionFromErrorEventWrapper( - ScriptState* script_state, - ErrorEvent* event, - v8::Local<v8::Object> creation_context) { - v8::Local<v8::Value> wrapped_event = - ToV8(event, creation_context, script_state->GetIsolate()); - if (wrapped_event.IsEmpty() || !wrapped_event->IsObject()) - return v8::Local<v8::Value>(); - - DCHECK(wrapped_event->IsObject()); - auto private_error = - V8PrivateProperty::GetErrorEventError(script_state->GetIsolate()); - v8::Local<v8::Value> error; - if (!private_error.GetOrUndefined(wrapped_event.As<v8::Object>()) - .ToLocal(&error) || - error->IsUndefined()) { - return v8::Local<v8::Value>(); - } - return error; -} - -bool V8ErrorHandler::ShouldPreventDefault(v8::Local<v8::Value> return_value, - Event* event) { - // Special event handling should be done here according to HTML Standard: - // https://html.spec.whatwg.org/multipage/webappapis.html#the-event-handler-processing-algorithm - // We do not need to check current target of event because it must be window - // or worker on calling this method. - if (event->HasInterface(EventNames::ErrorEvent) && event->type() == "error") - return return_value->IsBoolean() && return_value.As<v8::Boolean>()->Value(); - return return_value->IsBoolean() && !return_value.As<v8::Boolean>()->Value(); -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_error_handler.h b/chromium/third_party/blink/renderer/bindings/core/v8/v8_error_handler.h deleted file mode 100644 index 7a5d197dabe..00000000000 --- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_error_handler.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2010 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_V8_ERROR_HANDLER_H_ -#define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_V8_ERROR_HANDLER_H_ - -#include "base/memory/scoped_refptr.h" -#include "third_party/blink/renderer/bindings/core/v8/v8_event_listener_or_event_handler.h" -#include "v8/include/v8.h" - -namespace blink { - -class ErrorEvent; - -class V8ErrorHandler final : public V8EventListenerOrEventHandler { - public: - static V8ErrorHandler* Create(v8::Local<v8::Object> listener, - bool is_inline, - ScriptState* script_state, - const V8PrivateProperty::Symbol& property) { - V8ErrorHandler* event_listener = - new V8ErrorHandler(is_inline, script_state); - event_listener->SetListenerObject(script_state, listener, property); - return event_listener; - } - static void StoreExceptionOnErrorEventWrapper( - ScriptState*, - ErrorEvent*, - v8::Local<v8::Value>, - v8::Local<v8::Object> creation_context); - static v8::Local<v8::Value> LoadExceptionFromErrorEventWrapper( - ScriptState*, - ErrorEvent*, - v8::Local<v8::Object> creation_context); - - private: - V8ErrorHandler(bool is_inline, ScriptState*); - v8::Local<v8::Value> CallListenerFunction(ScriptState*, - v8::Local<v8::Value>, - Event*) override; - bool ShouldPreventDefault(v8::Local<v8::Value> return_value, Event*) override; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_V8_ERROR_HANDLER_H_ diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_event_listener_helper.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_event_listener_helper.cc index 45c29da9c77..a21fa6020eb 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_event_listener_helper.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_event_listener_helper.cc @@ -31,9 +31,9 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_event_listener_helper.h" #include "third_party/blink/renderer/bindings/core/v8/custom_wrappable_adapter.h" +#include "third_party/blink/renderer/bindings/core/v8/js_event_handler.h" +#include "third_party/blink/renderer/bindings/core/v8/js_event_listener.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" -#include "third_party/blink/renderer/bindings/core/v8/v8_error_handler.h" -#include "third_party/blink/renderer/bindings/core/v8/v8_event_listener_or_event_handler.h" #include "third_party/blink/renderer/bindings/core/v8/v8_window.h" #include "third_party/blink/renderer/platform/bindings/v8_private_property.h" @@ -62,7 +62,6 @@ ListenerType* GetEventListenerInternal( EventListener* V8EventListenerHelper::GetEventListener( ScriptState* script_state, v8::Local<v8::Value> value, - bool is_attribute, ListenerLookupType lookup) { RUNTIME_CALL_TIMER_SCOPE(script_state->GetIsolate(), RuntimeCallStats::CounterId::kGetEventListener); @@ -72,37 +71,37 @@ EventListener* V8EventListenerHelper::GetEventListener( v8::Local<v8::Object> object = value.As<v8::Object>(); v8::Isolate* isolate = script_state->GetIsolate(); V8PrivateProperty::Symbol listener_property = - is_attribute - ? V8PrivateProperty:: - GetV8EventListenerOrEventHandlerAttributeListener(isolate) - : V8PrivateProperty::GetV8EventListenerOrEventHandlerListener( - isolate); + V8PrivateProperty::GetCustomWrappableEventListener(isolate); - return GetEventListenerInternal<V8AbstractEventListener>( + return GetEventListenerInternal<EventListener>( script_state, object, listener_property, lookup, - [object, is_attribute, script_state, listener_property]() { - return V8EventListenerOrEventHandler::Create( - object, is_attribute, script_state, listener_property); + [object, script_state, listener_property]() { + return static_cast<EventListener*>( + JSEventListener::Create(script_state, object, listener_property)); }); } // static -EventListener* V8EventListenerHelper::EnsureErrorHandler( +EventListener* V8EventListenerHelper::GetEventHandler( ScriptState* script_state, - v8::Local<v8::Value> value) { + v8::Local<v8::Value> value, + JSEventHandler::HandlerType handler_type, + ListenerLookupType lookup) { + RUNTIME_CALL_TIMER_SCOPE(script_state->GetIsolate(), + RuntimeCallStats::CounterId::kGetEventListener); + if (!value->IsObject()) return nullptr; v8::Local<v8::Object> object = value.As<v8::Object>(); v8::Isolate* isolate = script_state->GetIsolate(); V8PrivateProperty::Symbol listener_property = - V8PrivateProperty::GetV8ErrorHandlerErrorHandler(isolate); + V8PrivateProperty::GetCustomWrappableEventHandler(isolate); - return GetEventListenerInternal<V8ErrorHandler>( - script_state, object, listener_property, kListenerFindOrCreate, - [object, script_state, listener_property]() { - const bool is_attribute = true; - return V8ErrorHandler::Create(object, is_attribute, script_state, - listener_property); + return GetEventListenerInternal<EventListener>( + script_state, object, listener_property, lookup, + [object, script_state, listener_property, handler_type]() { + return static_cast<EventListener*>(JSEventHandler::Create( + script_state, object, listener_property, handler_type)); }); } diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_event_listener_helper.h b/chromium/third_party/blink/renderer/bindings/core/v8/v8_event_listener_helper.h index e1052102cd9..4ac4d83a574 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_event_listener_helper.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_event_listener_helper.h @@ -31,6 +31,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_V8_EVENT_LISTENER_HELPER_H_ #define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_V8_EVENT_LISTENER_HELPER_H_ +#include "third_party/blink/renderer/bindings/core/v8/js_event_handler.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/platform/wtf/allocator.h" @@ -51,11 +52,11 @@ class V8EventListenerHelper { public: CORE_EXPORT static EventListener* GetEventListener(ScriptState*, v8::Local<v8::Value>, - bool is_attribute, ListenerLookupType); - - CORE_EXPORT static EventListener* EnsureErrorHandler(ScriptState*, - v8::Local<v8::Value>); + CORE_EXPORT static EventListener* GetEventHandler(ScriptState*, + v8::Local<v8::Value>, + JSEventHandler::HandlerType, + ListenerLookupType); }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_event_listener_info.h b/chromium/third_party/blink/renderer/bindings/core/v8/v8_event_listener_info.h index 7d637931169..09a92c38350 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_event_listener_info.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_event_listener_info.h @@ -11,19 +11,21 @@ namespace blink { -class V8EventListenerInfo { +struct V8EventListenerInfo { public: V8EventListenerInfo(AtomicString event_type, bool use_capture, bool passive, bool once, v8::Local<v8::Object> handler, - int backend_node_id) + v8::Local<v8::Function> effective_function, + uint64_t backend_node_id) : event_type(event_type), use_capture(use_capture), passive(passive), once(once), handler(handler), + effective_function(effective_function), backend_node_id(backend_node_id) {} AtomicString event_type; @@ -31,7 +33,8 @@ class V8EventListenerInfo { bool passive; bool once; v8::Local<v8::Object> handler; - int backend_node_id; + v8::Local<v8::Function> effective_function; + uint64_t backend_node_id; }; using V8EventListenerInfoList = Vector<V8EventListenerInfo>; diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_event_listener_or_event_handler.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_event_listener_or_event_handler.cc deleted file mode 100644 index 4a87e264292..00000000000 --- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_event_listener_or_event_handler.cc +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (C) 2006, 2007, 2008, 2009 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "third_party/blink/renderer/bindings/core/v8/v8_event_listener_or_event_handler.h" - -#include "third_party/blink/renderer/bindings/core/v8/script_controller.h" -#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" -#include "third_party/blink/renderer/core/dom/document.h" -#include "third_party/blink/renderer/core/dom/events/event.h" -#include "third_party/blink/renderer/core/execution_context/execution_context.h" -#include "third_party/blink/renderer/core/frame/local_frame.h" - -namespace blink { - -V8EventListenerOrEventHandler::V8EventListenerOrEventHandler( - bool is_attribute, - ScriptState* script_state) - : V8AbstractEventListener(script_state->GetIsolate(), - is_attribute, - script_state->World()) {} - -v8::Local<v8::Function> V8EventListenerOrEventHandler::GetListenerFunction( - ScriptState* script_state) { - v8::Local<v8::Object> listener = - GetListenerObjectInternal(ExecutionContext::From(script_state)); - - // Has the listener been disposed? - if (listener.IsEmpty()) - return v8::Local<v8::Function>(); - - if (listener->IsFunction()) - return v8::Local<v8::Function>::Cast(listener); - - // The EventHandler callback function type (used for event handler - // attributes in HTML) has [TreatNonObjectAsNull], which implies that - // non-function objects should be treated as no-op functions that return - // undefined. - if (IsAttribute()) - return v8::Local<v8::Function>(); - - // Getting the handleEvent property can runs script in the getter. - if (ScriptForbiddenScope::IsScriptForbidden()) { - V8ThrowException::ThrowError(GetIsolate(), - "Script execution is forbidden."); - return v8::Local<v8::Function>(); - } - - if (listener->IsObject()) { - // Check that no exceptions were thrown when getting the - // handleEvent property and that the value is a function. - v8::Local<v8::Value> property; - if (listener - ->Get(script_state->GetContext(), - V8AtomicString(GetIsolate(), "handleEvent")) - .ToLocal(&property) && - property->IsFunction()) - return v8::Local<v8::Function>::Cast(property); - } - - return v8::Local<v8::Function>(); -} - -v8::Local<v8::Value> V8EventListenerOrEventHandler::CallListenerFunction( - ScriptState* script_state, - v8::Local<v8::Value> js_event, - Event* event) { - DCHECK(!js_event.IsEmpty()); - v8::Local<v8::Function> handler_function = GetListenerFunction(script_state); - v8::Local<v8::Object> receiver = GetReceiverObject(script_state, event); - if (handler_function.IsEmpty() || receiver.IsEmpty()) - return v8::Local<v8::Value>(); - - ExecutionContext* execution_context = - ToExecutionContext(script_state->GetContext()); - - // TODO(jochen): Consider moving this check into canExecuteScripts. - // http://crbug.com/608641 - if (script_state->World().IsMainWorld() && - !execution_context->CanExecuteScripts(kAboutToExecuteScript)) - return v8::Local<v8::Value>(); - - v8::Local<v8::Value> parameters[1] = {js_event}; - v8::Local<v8::Value> result; - if (!V8ScriptRunner::CallFunction(handler_function, execution_context, - receiver, base::size(parameters), - parameters, script_state->GetIsolate()) - .ToLocal(&result)) - return v8::Local<v8::Value>(); - return result; -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_event_listener_or_event_handler.h b/chromium/third_party/blink/renderer/bindings/core/v8/v8_event_listener_or_event_handler.h deleted file mode 100644 index c6c968023d7..00000000000 --- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_event_listener_or_event_handler.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2006, 2007, 2008, 2009 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_V8_EVENT_LISTENER_OR_EVENT_HANDLER_H_ -#define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_V8_EVENT_LISTENER_OR_EVENT_HANDLER_H_ - -#include "base/memory/scoped_refptr.h" -#include "third_party/blink/renderer/bindings/core/v8/v8_abstract_event_listener.h" -#include "v8/include/v8.h" - -namespace blink { - -class Event; - -// V8EventListenerOrEventHandler is a wrapper of a JS object implements -// EventListener interface (has handleEvent(event) method), or a JS function -// that can handle the event. -class V8EventListenerOrEventHandler : public V8AbstractEventListener { - public: - static V8EventListenerOrEventHandler* Create( - v8::Local<v8::Object> listener, - bool is_attribute, - ScriptState* script_state, - const V8PrivateProperty::Symbol& property) { - V8EventListenerOrEventHandler* event_listener = - new V8EventListenerOrEventHandler(is_attribute, script_state); - event_listener->SetListenerObject(script_state, listener, property); - return event_listener; - } - - protected: - V8EventListenerOrEventHandler(bool is_attribute, ScriptState*); - v8::Local<v8::Function> GetListenerFunction(ScriptState*); - v8::Local<v8::Value> CallListenerFunction(ScriptState*, - v8::Local<v8::Value>, - Event*) override; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_V8_EVENT_LISTENER_OR_EVENT_HANDLER_H_ diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_gc_controller.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_gc_controller.cc index af266464044..d0f3e987df9 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_gc_controller.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_gc_controller.cc @@ -38,7 +38,6 @@ #include "third_party/blink/public/platform/platform.h" #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h" #include "third_party/blink/renderer/bindings/core/v8/script_source_code.h" -#include "third_party/blink/renderer/bindings/core/v8/v8_abstract_event_listener.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" #include "third_party/blink/renderer/bindings/core/v8/v8_node.h" #include "third_party/blink/renderer/bindings/core/v8/v8_script_runner.h" @@ -52,6 +51,7 @@ #include "third_party/blink/renderer/platform/heap/heap_stats_collector.h" #include "third_party/blink/renderer/platform/histogram.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" +#include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/wtf/allocator/partitions.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" @@ -75,6 +75,8 @@ Node* V8GCController::OpaqueRootForGC(v8::Isolate*, Node* node) { return node; } +namespace { + bool IsDOMWrapperClassId(uint16_t class_id) { return class_id == WrapperTypeInfo::kNodeClassId || class_id == WrapperTypeInfo::kObjectClassId || @@ -134,14 +136,12 @@ class MinorGCUnmodifiedWrapperVisitor : public v8::PersistentHandleVisitor { v8::Isolate* isolate_; }; -static unsigned long long UsedHeapSize(v8::Isolate* isolate) { +size_t UsedHeapSize(v8::Isolate* isolate) { v8::HeapStatistics heap_statistics; isolate->GetHeapStatistics(&heap_statistics); return heap_statistics.used_heap_size(); } -namespace { - void VisitWeakHandlesForMinorGC(v8::Isolate* isolate) { MinorGCUnmodifiedWrapperVisitor visitor(isolate); isolate->VisitWeakHandles(&visitor); @@ -210,6 +210,54 @@ void UpdateCollectedPhantomHandles(v8::Isolate* isolate) { stats_collector->IncreaseCollectedWrapperCount(count); } +void ScheduleFollowupGCs(ThreadState* thread_state, + v8::GCCallbackFlags flags, + bool is_unified) { + DCHECK(!thread_state->IsGCForbidden()); + // Schedules followup garbage collections. Such garbage collections may be + // needed when: + // 1. GC is not precise because it has to scan on-stack pointers. + // 2. GC needs to reclaim chains persistent handles. + + // v8::kGCCallbackFlagForced is used for testing GCs that need to verify + // that objects indeed died. + if (flags & v8::kGCCallbackFlagForced) { + if (!is_unified) { + thread_state->CollectGarbage( + BlinkGC::kHeapPointersOnStack, BlinkGC::kAtomicMarking, + BlinkGC::kEagerSweeping, BlinkGC::GCReason::kForcedGC); + } + + // Forces a precise GC at the end of the current event loop. + thread_state->ScheduleFullGC(); + } + + // In the unified world there is little need to schedule followup garbage + // collections as the current GC already computed the whole transitive + // closure. We ignore chains of persistent handles here. Cleanup of such + // handle chains requires GC loops at the caller side, e.g., see thread + // termination. + if (is_unified) + return; + + if ((flags & v8::kGCCallbackFlagCollectAllAvailableGarbage) || + (flags & v8::kGCCallbackFlagCollectAllExternalMemory)) { + // This single GC is not enough. See the above comment. + thread_state->CollectGarbage( + BlinkGC::kHeapPointersOnStack, BlinkGC::kAtomicMarking, + BlinkGC::kEagerSweeping, BlinkGC::GCReason::kForcedGC); + + // The conservative GC might have left floating garbage. Schedule + // precise GC to ensure that we collect all available garbage. + thread_state->SchedulePreciseGC(); + } + + // Schedules a precise GC for the next idle time period. + if (flags & v8::kGCCallbackScheduleIdleGarbageCollection) { + thread_state->ScheduleIdleGC(); + } +} + } // namespace void V8GCController::GcEpilogue(v8::Isolate* isolate, @@ -254,50 +302,9 @@ void V8GCController::GcEpilogue(v8::Isolate* isolate, ThreadState* current_thread_state = ThreadState::Current(); if (current_thread_state && !current_thread_state->IsGCForbidden()) { - // v8::kGCCallbackFlagForced forces a Blink heap garbage collection - // when a garbage collection was forced from V8. This is either used - // for tests that force GCs from JavaScript to verify that objects die - // when expected. - if (flags & v8::kGCCallbackFlagForced) { - // This single GC is not enough for two reasons: - // (1) The GC is not precise because the GC scans on-stack pointers - // conservatively. - // (2) One GC is not enough to break a chain of persistent handles. It's - // possible that some heap allocated objects own objects that - // contain persistent handles pointing to other heap allocated - // objects. To break the chain, we need multiple GCs. - // - // Regarding (1), we force a precise GC at the end of the current event - // loop. So if you want to collect all garbage, you need to wait until the - // next event loop. Regarding (2), it would be OK in practice to trigger - // only one GC per gcEpilogue, because GCController.collectAll() forces - // multiple V8's GC. - current_thread_state->CollectGarbage( - BlinkGC::kHeapPointersOnStack, BlinkGC::kAtomicMarking, - BlinkGC::kEagerSweeping, BlinkGC::GCReason::kForcedGC); - - // Forces a precise GC at the end of the current event loop. - current_thread_state->ScheduleFullGC(); - } - - // v8::kGCCallbackFlagCollectAllAvailableGarbage is used when V8 handles - // low memory notifications. - if ((flags & v8::kGCCallbackFlagCollectAllAvailableGarbage) || - (flags & v8::kGCCallbackFlagCollectAllExternalMemory)) { - // This single GC is not enough. See the above comment. - current_thread_state->CollectGarbage( - BlinkGC::kHeapPointersOnStack, BlinkGC::kAtomicMarking, - BlinkGC::kEagerSweeping, BlinkGC::GCReason::kForcedGC); - - // The conservative GC might have left floating garbage. Schedule - // precise GC to ensure that we collect all available garbage. - current_thread_state->SchedulePreciseGC(); - } - - // Schedules a precise GC for the next idle time period. - if (flags & v8::kGCCallbackScheduleIdleGarbageCollection) { - current_thread_state->ScheduleIdleGC(); - } + ScheduleFollowupGCs( + ThreadState::Current(), flags, + RuntimeEnabledFeatures::HeapUnifiedGarbageCollectionEnabled()); } TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), @@ -305,26 +312,28 @@ void V8GCController::GcEpilogue(v8::Isolate* isolate, InspectorUpdateCountersEvent::Data()); } -void V8GCController::CollectGarbage(v8::Isolate* isolate, bool only_minor_gc) { - v8::HandleScope handle_scope(isolate); - ScriptState* script_state = ScriptState::Create( - v8::Context::New(isolate), - DOMWrapperWorld::Create(isolate, - DOMWrapperWorld::WorldType::kGarbageCollector)); - ScriptState::Scope scope(script_state); - StringBuilder builder; - builder.Append("if (gc) gc("); - builder.Append(only_minor_gc ? "true" : "false"); - builder.Append(");"); - V8ScriptRunner::CompileAndRunInternalScript( - isolate, script_state, - ScriptSourceCode(builder.ToString(), ScriptSourceLocationType::kInternal, - nullptr, KURL(), TextPosition())); - script_state->DisposePerContextData(); -} +void V8GCController::CollectAllGarbageForTesting( + v8::Isolate* isolate, + v8::EmbedderHeapTracer::EmbedderStackState stack_state) { + constexpr unsigned kNumberOfGCs = 5; + + if (stack_state != v8::EmbedderHeapTracer::EmbedderStackState::kUnknown) { + V8PerIsolateData* data = V8PerIsolateData::From(isolate); + v8::EmbedderHeapTracer* tracer = + RuntimeEnabledFeatures::HeapUnifiedGarbageCollectionEnabled() + ? static_cast<v8::EmbedderHeapTracer*>( + data->GetUnifiedHeapController()) + : static_cast<v8::EmbedderHeapTracer*>( + data->GetScriptWrappableMarkingVisitor()); + // Passing a stack state is only supported when either wrapper tracing or + // unified heap is enabled. + CHECK(tracer); + for (unsigned i = 0; i < kNumberOfGCs; i++) + tracer->GarbageCollectionForTesting(stack_state); + return; + } -void V8GCController::CollectAllGarbageForTesting(v8::Isolate* isolate) { - for (unsigned i = 0; i < 5; i++) + for (unsigned i = 0; i < kNumberOfGCs; i++) isolate->RequestGarbageCollectionForTesting( v8::Isolate::kFullGarbageCollection); } diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_gc_controller.h b/chromium/third_party/blink/renderer/bindings/core/v8/v8_gc_controller.h index 4b877d74670..8a99e256337 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_gc_controller.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_gc_controller.h @@ -45,17 +45,23 @@ class CORE_EXPORT V8GCController { STATIC_ONLY(V8GCController); public: + static Node* OpaqueRootForGC(v8::Isolate*, Node*); + + // Prologue and epilogue callbacks for V8 garbage collections. static void GcPrologue(v8::Isolate*, v8::GCType, v8::GCCallbackFlags); static void GcEpilogue(v8::Isolate*, v8::GCType, v8::GCCallbackFlags); - static void CollectGarbage(v8::Isolate*, bool only_minor_gc = false); - // You should use collectAllGarbageForTesting() when you want to collect all - // V8 & Blink objects. It runs multiple V8 GCs to collect references - // that cross the binding boundary. collectAllGarbage() also runs multipe - // Oilpan GCs to collect a chain of persistent handles. - static void CollectAllGarbageForTesting(v8::Isolate*); - - static Node* OpaqueRootForGC(v8::Isolate*, Node*); + // Collects V8 and Blink objects in multiple garbage collection passes. Also + // triggers follow up garbage collections in Oilpan to collect chains of + // persistent handles. + // + // Usage: Testing that objects do indeed get collected. Note that this may + // depend on the EmbedderStackState, i.e., Blink may keep objects alive that + // are reachabe from the stack if necessary. + static void CollectAllGarbageForTesting( + v8::Isolate*, + v8::EmbedderHeapTracer::EmbedderStackState stack_state = + v8::EmbedderHeapTracer::EmbedderStackState::kUnknown); // Called when Oilpan traces references from V8 wrappers to DOM wrappables. static void TraceDOMWrappers(v8::Isolate*, Visitor*); diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_gc_for_context_dispose.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_gc_for_context_dispose.cc index ca7df9ddace..c776ce8655c 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_gc_for_context_dispose.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_gc_for_context_dispose.cc @@ -62,7 +62,8 @@ V8GCForContextDispose::V8GCForContextDispose() : pseudo_idle_timer_( Platform::Current()->MainThread()->Scheduler()->V8TaskRunner(), this, - &V8GCForContextDispose::PseudoIdleTimerFired) { + &V8GCForContextDispose::PseudoIdleTimerFired), + force_page_navigation_gc_(false) { Reset(); } diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_idle_task_runner.h b/chromium/third_party/blink/renderer/bindings/core/v8/v8_idle_task_runner.h index 05c4a5b045c..1cd32bfe656 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_idle_task_runner.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_idle_task_runner.h @@ -32,9 +32,9 @@ #include "base/memory/ptr_util.h" #include "gin/public/v8_idle_task_runner.h" #include "third_party/blink/public/platform/platform.h" -#include "third_party/blink/public/platform/web_thread.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread.h" #include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" namespace blink { diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc index de5c4b11829..5db87633802 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc @@ -32,7 +32,6 @@ #include "services/metrics/public/cpp/ukm_builders.h" #include "services/metrics/public/cpp/ukm_recorder.h" #include "third_party/blink/public/platform/platform.h" -#include "third_party/blink/public/platform/web_thread.h" #include "third_party/blink/renderer/bindings/core/v8/binding_security.h" #include "third_party/blink/renderer/bindings/core/v8/referrer_script_info.h" #include "third_party/blink/renderer/bindings/core/v8/rejected_promises.h" @@ -46,7 +45,6 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_dom_exception.h" #include "third_party/blink/renderer/bindings/core/v8/v8_embedder_graph_builder.h" #include "third_party/blink/renderer/bindings/core/v8/v8_error_event.h" -#include "third_party/blink/renderer/bindings/core/v8/v8_error_handler.h" #include "third_party/blink/renderer/bindings/core/v8/v8_gc_controller.h" #include "third_party/blink/renderer/bindings/core/v8/v8_idle_task_runner.h" #include "third_party/blink/renderer/bindings/core/v8/v8_wasm_response_extensions.h" @@ -68,6 +66,7 @@ #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" #include "third_party/blink/renderer/platform/loader/fetch/access_control_status.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" +#include "third_party/blink/renderer/platform/scheduler/public/thread.h" #include "third_party/blink/renderer/platform/scheduler/public/thread_scheduler.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" #include "third_party/blink/renderer/platform/weborigin/security_violation_reporting_policy.h" @@ -263,22 +262,17 @@ void V8Initializer::MessageHandlerInMainThread(v8::Local<v8::Message> message, return; } - AccessControlStatus access_control_status = kNotSharableCrossOrigin; - if (message->IsOpaque()) - access_control_status = kOpaqueResource; - else if (message->IsSharedCrossOrigin()) - access_control_status = kSharableCrossOrigin; + AccessControlStatus access_control_status = + message->IsSharedCrossOrigin() ? kSharableCrossOrigin : kOpaqueResource; - ErrorEvent* event = - ErrorEvent::Create(ToCoreStringWithNullCheck(message->Get()), - std::move(location), &script_state->World()); + ErrorEvent* event = ErrorEvent::Create( + ToCoreStringWithNullCheck(message->Get()), std::move(location), + ScriptValue::From(script_state, data), &script_state->World()); String message_for_console = ExtractMessageForConsole(isolate, data); if (!message_for_console.IsEmpty()) event->SetUnsanitizedMessage("Uncaught " + message_for_console); - V8ErrorHandler::StoreExceptionOnErrorEventWrapper( - script_state, event, data, script_state->GetContext()->Global()); context->DispatchErrorEvent(event, access_control_status); } @@ -312,21 +306,18 @@ void V8Initializer::MessageHandlerInWorker(v8::Local<v8::Message> message, return; } - ErrorEvent* event = - ErrorEvent::Create(ToCoreStringWithNullCheck(message->Get()), - std::move(location), &script_state->World()); + ErrorEvent* event = ErrorEvent::Create( + ToCoreStringWithNullCheck(message->Get()), std::move(location), + ScriptValue::From(script_state, data), &script_state->World()); - AccessControlStatus cors_status = message->IsSharedCrossOrigin() - ? kSharableCrossOrigin - : kNotSharableCrossOrigin; + AccessControlStatus access_control_status = + message->IsSharedCrossOrigin() ? kSharableCrossOrigin : kOpaqueResource; // If execution termination has been triggered as part of constructing // the error event from the v8::Message, quietly leave. if (!isolate->IsExecutionTerminating()) { - V8ErrorHandler::StoreExceptionOnErrorEventWrapper( - script_state, event, data, script_state->GetContext()->Global()); ExecutionContext::From(script_state) - ->DispatchErrorEvent(event, cors_status); + ->DispatchErrorEvent(event, access_control_status); } per_isolate_data->SetReportingException(false); @@ -379,7 +370,7 @@ static void PromiseRejectHandler(v8::PromiseRejectMessage data, } String error_message; - AccessControlStatus cors_status = kNotSharableCrossOrigin; + AccessControlStatus cors_status = kOpaqueResource; std::unique_ptr<SourceLocation> location; v8::Local<v8::Message> message = @@ -483,7 +474,7 @@ static bool WasmCodeGenerationCheckCallbackInMainThread( v8::Local<v8::String> source) { if (ExecutionContext* execution_context = ToExecutionContext(context)) { if (ContentSecurityPolicy* policy = - ToDocument(execution_context)->GetContentSecurityPolicy()) { + To<Document>(execution_context)->GetContentSecurityPolicy()) { v8::String::Value source_str(context->GetIsolate(), source); UChar snippet[ContentSecurityPolicy::kMaxSampleLength + 1]; size_t len = std::min((sizeof(snippet) / sizeof(UChar)) - 1, @@ -576,7 +567,6 @@ static v8::MaybeLocal<v8::Promise> HostImportModuleDynamically( v8::Local<v8::Context> context, v8::Local<v8::ScriptOrModule> v8_referrer, v8::Local<v8::String> v8_specifier) { - CHECK(RuntimeEnabledFeatures::ModuleScriptsDynamicImportEnabled()); ScriptState* script_state = ScriptState::From(context); ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); ScriptPromise promise = resolver->Promise(); @@ -609,7 +599,6 @@ static v8::MaybeLocal<v8::Promise> HostImportModuleDynamically( static void HostGetImportMetaProperties(v8::Local<v8::Context> context, v8::Local<v8::Module> module, v8::Local<v8::Object> meta) { - CHECK(RuntimeEnabledFeatures::ModuleScriptsImportMetaUrlEnabled()); ScriptState* script_state = ScriptState::From(context); v8::Isolate* isolate = context->GetIsolate(); v8::HandleScope handle_scope(isolate); @@ -633,7 +622,12 @@ static void InitializeV8Common(v8::Isolate* isolate) { isolate->AddGCEpilogueCallback(V8GCController::GcEpilogue); isolate->SetEmbedderHeapTracer( - V8PerIsolateData::From(isolate)->GetScriptWrappableMarkingVisitor()); + RuntimeEnabledFeatures::HeapUnifiedGarbageCollectionEnabled() + ? static_cast<v8::EmbedderHeapTracer*>( + V8PerIsolateData::From(isolate)->GetUnifiedHeapController()) + : static_cast<v8::EmbedderHeapTracer*>( + V8PerIsolateData::From(isolate) + ->GetScriptWrappableMarkingVisitor())); isolate->SetMicrotasksPolicy(v8::MicrotasksPolicy::kScoped); @@ -641,14 +635,9 @@ static void InitializeV8Common(v8::Isolate* isolate) { isolate->SetWasmModuleCallback(WasmModuleOverride); isolate->SetWasmInstanceCallback(WasmInstanceOverride); isolate->SetWasmThreadsEnabledCallback(WasmThreadsEnabledCallback); - if (RuntimeEnabledFeatures::ModuleScriptsDynamicImportEnabled()) { - isolate->SetHostImportModuleDynamicallyCallback( - HostImportModuleDynamically); - } - if (RuntimeEnabledFeatures::ModuleScriptsImportMetaUrlEnabled()) { - isolate->SetHostInitializeImportMetaObjectCallback( - HostGetImportMetaProperties); - } + isolate->SetHostImportModuleDynamicallyCallback(HostImportModuleDynamically); + isolate->SetHostInitializeImportMetaObjectCallback( + HostGetImportMetaProperties); V8ContextSnapshot::EnsureInterfaceTemplates(isolate); @@ -732,6 +721,20 @@ void V8Initializer::InitializeMainThread(const intptr_t* reference_table) { : Platform::Current()->CurrentThread()->GetTaskRunner(), v8_context_snapshot_mode); + // ThreadState::isolate_ needs to be set before setting the EmbedderHeapTracer + // as setting the tracer indicates that a V8 garbage collection should trace + // over to Blink. + DCHECK(ThreadState::MainThreadState()); + if (RuntimeEnabledFeatures::HeapUnifiedGarbageCollectionEnabled()) { + ThreadState::MainThreadState()->RegisterTraceDOMWrappers( + isolate, V8GCController::TraceDOMWrappers, nullptr, nullptr); + } else { + ThreadState::MainThreadState()->RegisterTraceDOMWrappers( + isolate, V8GCController::TraceDOMWrappers, + ScriptWrappableMarkingVisitor::InvalidateDeadObjectsInMarkingDeque, + ScriptWrappableMarkingVisitor::PerformCleanup); + } + InitializeV8Common(isolate); isolate->SetOOMErrorHandler(ReportOOMErrorInMainThread); @@ -765,12 +768,6 @@ void V8Initializer::InitializeMainThread(const intptr_t* reference_table) { &V8EmbedderGraphBuilder::BuildEmbedderGraphCallback, nullptr); } - DCHECK(ThreadState::MainThreadState()); - ThreadState::MainThreadState()->RegisterTraceDOMWrappers( - isolate, V8GCController::TraceDOMWrappers, - ScriptWrappableMarkingVisitor::InvalidateDeadObjectsInMarkingDeque, - ScriptWrappableMarkingVisitor::PerformCleanup); - V8PerIsolateData::From(isolate)->SetThreadDebugger( std::make_unique<MainThreadDebugger>(isolate)); diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_lazy_event_listener.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_lazy_event_listener.cc deleted file mode 100644 index 8f79c2fea09..00000000000 --- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_lazy_event_listener.cc +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright (C) 2006, 2007, 2008, 2009 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "third_party/blink/renderer/bindings/core/v8/v8_lazy_event_listener.h" - -#include "third_party/blink/renderer/bindings/core/v8/script_controller.h" -#include "third_party/blink/renderer/bindings/core/v8/script_source_code.h" -#include "third_party/blink/renderer/bindings/core/v8/source_location.h" -#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" -#include "third_party/blink/renderer/bindings/core/v8/v8_document.h" -#include "third_party/blink/renderer/bindings/core/v8/v8_html_form_element.h" -#include "third_party/blink/renderer/bindings/core/v8/v8_node.h" -#include "third_party/blink/renderer/bindings/core/v8/v8_script_runner.h" -#include "third_party/blink/renderer/core/dom/document.h" -#include "third_party/blink/renderer/core/dom/node.h" -#include "third_party/blink/renderer/core/events/error_event.h" -#include "third_party/blink/renderer/core/execution_context/execution_context.h" -#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h" -#include "third_party/blink/renderer/core/frame/local_frame.h" -#include "third_party/blink/renderer/core/html/forms/html_form_element.h" -#include "third_party/blink/renderer/core/html/html_element.h" -#include "third_party/blink/renderer/platform/bindings/v8_dom_wrapper.h" -#include "third_party/blink/renderer/platform/bindings/v8_private_property.h" -#include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" - -namespace blink { - -V8LazyEventListener::V8LazyEventListener( - v8::Isolate* isolate, - const AtomicString& function_name, - const AtomicString& event_parameter_name, - const String& code, - const String source_url, - const TextPosition& position, - Node* node) - : V8AbstractEventListener(isolate, true, DOMWrapperWorld::MainWorld()), - was_compilation_failed_(false), - function_name_(function_name), - event_parameter_name_(event_parameter_name), - code_(code), - source_url_(source_url), - node_(node), - position_(position) {} - -template <typename T> -v8::Local<v8::Object> ToObjectWrapper(T* dom_object, - ScriptState* script_state) { - if (!dom_object) - return v8::Object::New(script_state->GetIsolate()); - v8::Local<v8::Value> value = - ToV8(dom_object, script_state->GetContext()->Global(), - script_state->GetIsolate()); - if (value.IsEmpty()) - return v8::Object::New(script_state->GetIsolate()); - return v8::Local<v8::Object>::New(script_state->GetIsolate(), - value.As<v8::Object>()); -} - -v8::Local<v8::Value> V8LazyEventListener::CallListenerFunction( - ScriptState* script_state, - v8::Local<v8::Value> js_event, - Event* event) { - DCHECK(!js_event.IsEmpty()); - ExecutionContext* execution_context = - ToExecutionContext(script_state->GetContext()); - v8::Local<v8::Object> listener_object = - GetListenerObjectInternal(execution_context); - if (listener_object.IsEmpty()) - return v8::Local<v8::Value>(); - - v8::Local<v8::Function> handler_function = listener_object.As<v8::Function>(); - v8::Local<v8::Object> receiver = GetReceiverObject(script_state, event); - if (handler_function.IsEmpty() || receiver.IsEmpty()) - return v8::Local<v8::Value>(); - - if (!execution_context->IsDocument()) - return v8::Local<v8::Value>(); - - LocalFrame* frame = ToDocument(execution_context)->GetFrame(); - if (!frame) - return v8::Local<v8::Value>(); - - if (!execution_context->CanExecuteScripts(kAboutToExecuteScript)) - return v8::Local<v8::Value>(); - - v8::Local<v8::Value> parameters[1] = {js_event}; - v8::Local<v8::Value> result; - if (!V8ScriptRunner::CallFunction(handler_function, frame->GetDocument(), - receiver, base::size(parameters), - parameters, script_state->GetIsolate()) - .ToLocal(&result)) - return v8::Local<v8::Value>(); - return result; -} - -v8::Local<v8::Object> V8LazyEventListener::GetListenerObjectInternal( - ExecutionContext* execution_context) { - if (!execution_context) - return v8::Local<v8::Object>(); - - // A ScriptState used by the event listener needs to be calculated based on - // the ExecutionContext that fired the the event listener and the world - // that installed the event listener. - v8::EscapableHandleScope handle_scope(ToIsolate(execution_context)); - v8::Local<v8::Context> v8_context = ToV8Context(execution_context, World()); - if (v8_context.IsEmpty()) - return v8::Local<v8::Object>(); - ScriptState* script_state = ScriptState::From(v8_context); - if (!script_state->ContextIsValid()) - return v8::Local<v8::Object>(); - - if (!execution_context->IsDocument()) - return v8::Local<v8::Object>(); - - if (!ToDocument(execution_context) - ->AllowInlineEventHandler(node_, this, source_url_, position_.line_)) - return v8::Local<v8::Object>(); - - // All checks passed and it's now okay to return the function object. - - // We may need to compile the same script twice or more because the compiled - // function object may be garbage-collected, however, we should behave as if - // we compile the code only once, i.e. we must not throw an error twice. - if (!HasExistingListenerObject() && !was_compilation_failed_) - CompileScript(script_state, execution_context); - - return handle_scope.Escape(GetExistingListenerObject()); -} - -void V8LazyEventListener::CompileScript(ScriptState* script_state, - ExecutionContext* execution_context) { - DCHECK(!HasExistingListenerObject()); - - ScriptState::Scope scope(script_state); - - // Nodes other than the document object, when executing inline event - // handlers push document, form owner, and the target node on the scope chain. - // We do this by using 'with' statement. - // See fast/forms/form-action.html - // fast/forms/selected-index-value.html - // fast/overflow/onscroll-layer-self-destruct.html - HTMLFormElement* form_element = nullptr; - if (node_ && node_->IsHTMLElement()) - form_element = ToHTMLElement(node_)->formOwner(); - - v8::Local<v8::Object> scopes[3]; - scopes[2] = ToObjectWrapper<Node>(node_, script_state); - scopes[1] = ToObjectWrapper<HTMLFormElement>(form_element, script_state); - scopes[0] = ToObjectWrapper<Document>( - node_ ? node_->ownerDocument() : nullptr, script_state); - - v8::Local<v8::String> parameter_name = - V8String(GetIsolate(), event_parameter_name_); - v8::ScriptOrigin origin( - V8String(GetIsolate(), source_url_), - v8::Integer::New(GetIsolate(), position_.line_.ZeroBasedInt()), - v8::Integer::New(GetIsolate(), position_.column_.ZeroBasedInt()), - v8::True(GetIsolate())); - v8::ScriptCompiler::Source source(V8String(GetIsolate(), code_), origin); - - v8::Local<v8::Function> wrapped_function; - { - // JavaScript compilation error shouldn't be reported as a runtime - // exception because we're not running any program code. Instead, - // it should be reported as an ErrorEvent. - v8::TryCatch block(GetIsolate()); - v8::MaybeLocal<v8::Function> maybe_result = - v8::ScriptCompiler::CompileFunctionInContext( - script_state->GetContext(), &source, 1, ¶meter_name, 3, scopes); - if (!maybe_result.ToLocal(&wrapped_function)) { - was_compilation_failed_ = true; // Do not compile the same code twice. - FireErrorEvent(script_state->GetContext(), execution_context, - block.Message()); - return; - } - } - - wrapped_function->SetName(V8String(GetIsolate(), function_name_)); - - SetListenerObject(script_state, wrapped_function, - V8PrivateProperty::GetV8EventListenerOrEventHandlerListener( - GetIsolate())); -} - -void V8LazyEventListener::FireErrorEvent(v8::Local<v8::Context> v8_context, - ExecutionContext* execution_context, - v8::Local<v8::Message> message) { - ErrorEvent* event = ErrorEvent::Create( - ToCoreStringWithNullCheck(message->Get()), - SourceLocation::FromMessage(GetIsolate(), message, execution_context), - &World()); - - AccessControlStatus access_control_status = kNotSharableCrossOrigin; - if (message->IsOpaque()) - access_control_status = kOpaqueResource; - else if (message->IsSharedCrossOrigin()) - access_control_status = kSharableCrossOrigin; - - execution_context->DispatchErrorEvent(event, access_control_status); -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_lazy_event_listener.h b/chromium/third_party/blink/renderer/bindings/core/v8/v8_lazy_event_listener.h deleted file mode 100644 index 9bddefecf12..00000000000 --- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_lazy_event_listener.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (C) 2006, 2007, 2008, 2009 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_V8_LAZY_EVENT_LISTENER_H_ -#define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_V8_LAZY_EVENT_LISTENER_H_ - -#include "base/memory/scoped_refptr.h" -#include "third_party/blink/renderer/bindings/core/v8/v8_abstract_event_listener.h" -#include "third_party/blink/renderer/platform/wtf/text/text_position.h" -#include "v8/include/v8.h" - -namespace blink { - -class Event; -class Node; - -// V8LazyEventListener is a wrapper for a JavaScript code string that is -// compiled and evaluated when an event is fired. A V8LazyEventListener is -// either a HTML or SVG event handler. -class V8LazyEventListener final : public V8AbstractEventListener { - public: - static V8LazyEventListener* Create(const AtomicString& function_name, - const AtomicString& event_parameter_name, - const String& code, - const String& source_url, - const TextPosition& position, - Node* node, - v8::Isolate* isolate) { - return new V8LazyEventListener(isolate, function_name, event_parameter_name, - code, source_url, position, node); - } - - void Trace(blink::Visitor* visitor) override { - visitor->Trace(node_); - V8AbstractEventListener::Trace(visitor); - } - - const String& Code() const override { return code_; } - - protected: - v8::Local<v8::Object> GetListenerObjectInternal(ExecutionContext*) override; - - private: - V8LazyEventListener(v8::Isolate*, - const AtomicString& function_name, - const AtomicString& event_parameter_name, - const String& code, - const String source_url, - const TextPosition&, - Node*); - - v8::Local<v8::Value> CallListenerFunction(ScriptState*, - v8::Local<v8::Value>, - Event*) override; - - // Return true, so that event handlers from markup are not cloned twice when - // building the shadow tree for SVGUseElements. - bool WasCreatedFromMarkup() const override { return true; } - - void CompileScript(ScriptState*, ExecutionContext*); - - void FireErrorEvent(v8::Local<v8::Context>, - ExecutionContext*, - v8::Local<v8::Message>); - - bool was_compilation_failed_; - AtomicString function_name_; - AtomicString event_parameter_name_; - String code_; - String source_url_; - Member<Node> node_; - TextPosition position_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_V8_LAZY_EVENT_LISTENER_H_ diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_page_popup_controller_binding.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_page_popup_controller_binding.cc index 418e3c35d4d..7aafaad7334 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_page_popup_controller_binding.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_page_popup_controller_binding.cc @@ -39,10 +39,9 @@ void PagePopupControllerAttributeGetterCallback( void V8PagePopupControllerBinding::InstallPagePopupController( v8::Local<v8::Context> context, v8::Local<v8::Object> window_wrapper) { - ExecutionContext* execution_context = - ToExecutionContext(window_wrapper->CreationContext()); - if (!(execution_context && execution_context->IsDocument() && - ContextFeatures::PagePopupEnabled(ToDocument(execution_context)))) + Document* document = DynamicTo<Document>( + ToExecutionContext(window_wrapper->CreationContext())); + if (!document || !ContextFeatures::PagePopupEnabled(document)) return; window_wrapper diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_persistent_value_vector.h b/chromium/third_party/blink/renderer/bindings/core/v8/v8_persistent_value_vector.h index 4e44d822181..75517624596 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_persistent_value_vector.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_persistent_value_vector.h @@ -49,10 +49,11 @@ class WTFVectorPersistentValueVectorTraits { static bool IsEmpty(const Impl* impl) { return impl->IsEmpty(); } static size_t Size(const Impl* impl) { return impl->size(); } static v8::PersistentContainerValue Get(const Impl* impl, size_t i) { - return (i < impl->size()) ? impl->at(i) : v8::kPersistentContainerNotFound; + return (i < impl->size()) ? impl->at(static_cast<wtf_size_t>(i)) + : v8::kPersistentContainerNotFound; } static void ReserveCapacity(Impl* impl, size_t capacity) { - impl->ReserveCapacity(capacity); + impl->ReserveCapacity(static_cast<wtf_size_t>(capacity)); } static void Clear(Impl* impl) { impl->clear(); } }; diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc index 4388d8fc3cc..695d6b777c0 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_script_runner.cc @@ -153,10 +153,9 @@ v8::MaybeLocal<v8::Script> CompileScriptInternal( } return script; } - case v8::ScriptCompiler::kProduceCodeCache: - case v8::ScriptCompiler::kProduceFullCodeCache: - case v8::ScriptCompiler::kProduceParserCache: - case v8::ScriptCompiler::kConsumeParserCache: + // TODO(v8:8252): Remove the default case once deprecated options are + // removed from v8::ScriptCompiler::CompileOptions. + default: NOTREACHED(); break; } @@ -254,7 +253,7 @@ v8::MaybeLocal<v8::Value> V8ScriptRunner::RunCompiledScript( ExecutionContext* context) { DCHECK(!script.IsEmpty()); ScopedFrameBlamer frame_blamer( - context->IsDocument() ? ToDocument(context)->GetFrame() : nullptr); + IsA<Document>(context) ? To<Document>(context)->GetFrame() : nullptr); v8::Local<v8::Value> script_name = script->GetUnboundScript()->GetScriptName(); @@ -278,10 +277,14 @@ v8::MaybeLocal<v8::Value> V8ScriptRunner::RunCompiledScript( v8::Isolate::SafeForTerminationScope safe_for_termination(isolate); v8::MicrotasksScope microtasks_scope(isolate, v8::MicrotasksScope::kRunMicrotasks); + v8::Local<v8::String> script_url; + if (!script_name->ToString(isolate->GetCurrentContext()) + .ToLocal(&script_url)) + return result; + // ToCoreString here should be zero copy due to externalized string // unpacked. - String script_url = ToCoreString(script_name->ToString(isolate)); - probe::ExecuteScript probe(context, script_url); + probe::ExecuteScript probe(context, ToCoreString(script_url)); result = script->Run(isolate->GetCurrentContext()); } @@ -371,7 +374,7 @@ v8::MaybeLocal<v8::Value> V8ScriptRunner::CallFunction( v8::Local<v8::Value> args[], v8::Isolate* isolate) { LocalFrame* frame = - context->IsDocument() ? ToDocument(context)->GetFrame() : nullptr; + IsA<Document>(context) ? To<Document>(context)->GetFrame() : nullptr; ScopedFrameBlamer frame_blamer(frame); TRACE_EVENT0("v8", "v8.callFunction"); RuntimeCallStatsScopedTracer rcs_scoped_tracer(isolate); @@ -452,7 +455,7 @@ void V8ScriptRunner::ReportException(v8::Isolate* isolate, v8::MaybeLocal<v8::Value> V8ScriptRunner::CallExtraHelper( ScriptState* script_state, const char* name, - size_t num_args, + uint32_t num_args, v8::Local<v8::Value>* args) { v8::Isolate* isolate = script_state->GetIsolate(); v8::Local<v8::Value> function_value; diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_script_runner.h b/chromium/third_party/blink/renderer/bindings/core/v8/v8_script_runner.h index a6e4920b3a9..ffa79e6ed3a 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_script_runner.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_script_runner.h @@ -98,7 +98,7 @@ class CORE_EXPORT V8ScriptRunner final { const WTF::TextPosition&); // Calls a function on the V8 extras binding object. - template <size_t N> + template <uint32_t N> static v8::MaybeLocal<v8::Value> CallExtra(ScriptState* script_state, const char* name, v8::Local<v8::Value> (&args)[N]) { @@ -115,7 +115,7 @@ class CORE_EXPORT V8ScriptRunner final { private: static v8::MaybeLocal<v8::Value> CallExtraHelper(ScriptState*, const char* name, - size_t num_args, + uint32_t num_args, v8::Local<v8::Value>* args); }; diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_script_runner_test.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_script_runner_test.cc index 0f989bb09ec..edbdba257e0 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_script_runner_test.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_script_runner_test.cc @@ -63,7 +63,7 @@ class V8ScriptRunnerTest : public testing::Test { std::tie(compile_options, produce_cache_options, no_cache_reason) = V8CodeCache::GetCompileOptions(cache_options, source_code); v8::MaybeLocal<v8::Script> compiled_script = V8ScriptRunner::CompileScript( - script_state, source_code, kNotSharableCrossOrigin, compile_options, + script_state, source_code, kOpaqueResource, compile_options, no_cache_reason, ReferrerScriptInfo()); if (compiled_script.IsEmpty()) { return false; @@ -81,7 +81,7 @@ class V8ScriptRunnerTest : public testing::Test { v8::ScriptCompiler::NoCacheReason no_cache_reason, V8CodeCache::ProduceCacheOptions produce_cache_options) { v8::MaybeLocal<v8::Script> compiled_script = V8ScriptRunner::CompileScript( - script_state, source_code, kNotSharableCrossOrigin, compile_options, + script_state, source_code, kOpaqueResource, compile_options, no_cache_reason, ReferrerScriptInfo()); if (compiled_script.IsEmpty()) { return false; diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_wasm_response_extensions.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_wasm_response_extensions.cc index fd56d312f37..9b8c92bfff9 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_wasm_response_extensions.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_wasm_response_extensions.cc @@ -13,6 +13,7 @@ #include "third_party/blink/renderer/core/fetch/fetch_data_loader.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/script_state.h" +#include "third_party/blink/renderer/platform/bindings/trace_wrapper_member.h" #include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h" #include "third_party/blink/renderer/platform/heap/handle.h" @@ -108,7 +109,7 @@ class FetchDataLoaderForWasmStreaming final : public FetchDataLoader, streaming_->Abort(v8::Local<v8::Value>()); } } - Member<BytesConsumer> consumer_; + TraceWrapperMember<BytesConsumer> consumer_; Member<FetchDataLoader::Client> client_; std::shared_ptr<v8::WasmStreaming> streaming_; const Member<ScriptState> script_state_; @@ -205,7 +206,7 @@ class FetchDataLoaderAsWasmModule final : public FetchDataLoader, builder_.Abort(v8::Local<v8::Value>()); } } - Member<BytesConsumer> consumer_; + TraceWrapperMember<BytesConsumer> consumer_; Member<FetchDataLoader::Client> client_; v8::WasmModuleObjectBuilderStreaming builder_; const Member<ScriptState> script_state_; @@ -425,10 +426,8 @@ void WasmCompileStreamingImpl(const v8::FunctionCallbackInfo<v8::Value>& args) { } // namespace void WasmResponseExtensions::Initialize(v8::Isolate* isolate) { - if (RuntimeEnabledFeatures::WebAssemblyStreamingEnabled()) { - isolate->SetWasmCompileStreamingCallback(WasmCompileStreamingImpl); - isolate->SetWasmStreamingCallback(StreamFromResponseCallback); - } + isolate->SetWasmCompileStreamingCallback(WasmCompileStreamingImpl); + isolate->SetWasmStreamingCallback(StreamFromResponseCallback); } } // namespace blink diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc b/chromium/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc index 73fca4f4623..3746a1fe999 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.cc @@ -40,7 +40,6 @@ #include "third_party/blink/renderer/bindings/core/v8/script_value.h" #include "third_party/blink/renderer/bindings/core/v8/source_location.h" #include "third_party/blink/renderer/bindings/core/v8/v8_code_cache.h" -#include "third_party/blink/renderer/bindings/core/v8/v8_error_handler.h" #include "third_party/blink/renderer/bindings/core/v8/v8_initializer.h" #include "third_party/blink/renderer/bindings/core/v8/v8_script_runner.h" #include "third_party/blink/renderer/core/events/error_event.h" @@ -261,6 +260,7 @@ bool WorkerOrWorkletScriptController::InitializeContextIfNeeded( ScriptValue WorkerOrWorkletScriptController::EvaluateInternal( const ScriptSourceCode& source_code, + AccessControlStatus access_control_status, V8CacheOptions v8_cache_options) { DCHECK(IsContextInitialized()); @@ -284,7 +284,7 @@ ScriptValue WorkerOrWorkletScriptController::EvaluateInternal( std::tie(compile_options, produce_cache_options, no_cache_reason) = V8CodeCache::GetCompileOptions(v8_cache_options, source_code); if (V8ScriptRunner::CompileScript(script_state_, source_code, - kSharableCrossOrigin, compile_options, + access_control_status, compile_options, no_cache_reason, referrer_info) .ToLocal(&compiled_script)) { maybe_result = V8ScriptRunner::RunCompiledScript(isolate_, compiled_script, @@ -319,13 +319,14 @@ ScriptValue WorkerOrWorkletScriptController::EvaluateInternal( bool WorkerOrWorkletScriptController::Evaluate( const ScriptSourceCode& source_code, + AccessControlStatus access_control_status, ErrorEvent** error_event, V8CacheOptions v8_cache_options) { if (IsExecutionForbidden()) return false; ExecutionState state(this); - EvaluateInternal(source_code, v8_cache_options); + EvaluateInternal(source_code, access_control_status, v8_cache_options); if (IsExecutionForbidden()) return false; @@ -338,19 +339,16 @@ bool WorkerOrWorkletScriptController::Evaluate( return false; } if (global_scope_->ShouldSanitizeScriptError(state.location_->Url(), - kNotSharableCrossOrigin)) { + access_control_status)) { *error_event = ErrorEvent::CreateSanitizedError(world_.get()); } else { *error_event = ErrorEvent::Create(state.error_message, state.location_->Clone(), state.exception, world_.get()); } - V8ErrorHandler::StoreExceptionOnErrorEventWrapper( - script_state_, *error_event, state.exception.V8Value(), - script_state_->GetContext()->Global()); } else { - DCHECK(!global_scope_->ShouldSanitizeScriptError( - state.location_->Url(), kNotSharableCrossOrigin)); + DCHECK(!global_scope_->ShouldSanitizeScriptError(state.location_->Url(), + access_control_status)); ErrorEvent* event = nullptr; if (state.error_event_from_imported_script_) { event = state.error_event_from_imported_script_.Release(); @@ -359,7 +357,7 @@ bool WorkerOrWorkletScriptController::Evaluate( ErrorEvent::Create(state.error_message, state.location_->Clone(), state.exception, world_.get()); } - global_scope_->DispatchErrorEvent(event, kNotSharableCrossOrigin); + global_scope_->DispatchErrorEvent(event, access_control_status); } return false; } @@ -369,7 +367,7 @@ bool WorkerOrWorkletScriptController::Evaluate( ScriptValue WorkerOrWorkletScriptController::EvaluateAndReturnValueForTest( const ScriptSourceCode& source_code) { ExecutionState state(this); - return EvaluateInternal(source_code, kV8CacheOptionsDefault); + return EvaluateInternal(source_code, kOpaqueResource, kV8CacheOptionsDefault); } void WorkerOrWorkletScriptController::ForbidExecution() { diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h b/chromium/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h index 9d405829580..0f01f1c2d02 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h @@ -36,6 +36,7 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" #include "third_party/blink/renderer/bindings/core/v8/v8_cache_options.h" #include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/platform/loader/fetch/access_control_status.h" #include "third_party/blink/renderer/platform/wtf/allocator.h" #include "third_party/blink/renderer/platform/wtf/text/text_position.h" #include "v8/include/v8.h" @@ -61,6 +62,7 @@ class CORE_EXPORT WorkerOrWorkletScriptController final // Returns true if the evaluation completed with no uncaught exception. bool Evaluate(const ScriptSourceCode&, + AccessControlStatus access_control_status, ErrorEvent** = nullptr, V8CacheOptions = kV8CacheOptionsDefault); @@ -69,10 +71,10 @@ class CORE_EXPORT WorkerOrWorkletScriptController final // Used by WorkerThread. Returns true if the context is successfully // initialized or already initialized. - // For WorkerGlobalScope and ThreadedWorkletGlobalScope, |url_for_debugger| is - // and should be used only for setting name/origin that appears in DevTools. - // For other global scopes, |human_readable_name| is used for setting - // DOMWrapperWorld's human readable name. + // For WorkerGlobalScope and threaded WorkletGlobalScope, |url_for_debugger| + // is and should be used only for setting name/origin that appears in + // DevTools. For other global scopes, |human_readable_name| is used for + // setting DOMWrapperWorld's human readable name. bool InitializeContextIfNeeded(const String& human_readable_name, const KURL& url_for_debugger); @@ -107,6 +109,7 @@ class CORE_EXPORT WorkerOrWorkletScriptController final // Evaluate a script file in the current execution environment. ScriptValue EvaluateInternal(const ScriptSourceCode&, + AccessControlStatus, V8CacheOptions); void DisposeContextIfNeeded(); |