diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-12 14:27:29 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-13 09:35:20 +0000 |
commit | c30a6232df03e1efbd9f3b226777b07e087a1122 (patch) | |
tree | e992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/third_party/blink/renderer/bindings | |
parent | 7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff) | |
download | qtwebengine-chromium-85-based.tar.gz |
BASELINE: Update Chromium to 85.0.4183.14085-based
Change-Id: Iaa42f4680837c57725b1344f108c0196741f6057
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/third_party/blink/renderer/bindings')
130 files changed, 2078 insertions, 1096 deletions
diff --git a/chromium/third_party/blink/renderer/bindings/BUILD.gn b/chromium/third_party/blink/renderer/bindings/BUILD.gn index 9f9b9b62249..1dfcb97e654 100644 --- a/chromium/third_party/blink/renderer/bindings/BUILD.gn +++ b/chromium/third_party/blink/renderer/bindings/BUILD.gn @@ -138,12 +138,7 @@ action_with_pydeps("web_idl_database") { get_target_outputs(":web_idl_in_modules") + get_target_outputs(":web_idl_in_modules_for_testing") runtime_enabled_features_file = "../platform/runtime_enabled_features.json5" - runtime_enabled_features_test_file = - "${bindings_scripts_dir}/web_idl/runtime_enabled_features.json5" - inputs = input_data_files + [ - runtime_enabled_features_file, - runtime_enabled_features_test_file, - ] + inputs = input_data_files + [ runtime_enabled_features_file ] output_data_file = "${bindings_output_dir}/web_idl_database.pickle" outputs = [ output_data_file ] @@ -152,8 +147,6 @@ action_with_pydeps("web_idl_database") { rebase_path(output_data_file, root_build_dir), "--runtime_enabled_features", rebase_path(runtime_enabled_features_file, root_build_dir), - "--runtime_enabled_features", - rebase_path(runtime_enabled_features_test_file, root_build_dir), "--", ] + rebase_path(input_data_files, root_build_dir) diff --git a/chromium/third_party/blink/renderer/bindings/IDLExtendedAttributes.md b/chromium/third_party/blink/renderer/bindings/IDLExtendedAttributes.md index 1ed4cc30502..4ec693b8bf2 100644 --- a/chromium/third_party/blink/renderer/bindings/IDLExtendedAttributes.md +++ b/chromium/third_party/blink/renderer/bindings/IDLExtendedAttributes.md @@ -109,7 +109,9 @@ Extended attributes on partial interface members work as normal. However, only t * If a flag obviously applies to only one member of a single-member interface (i.e., it is named after that member), the extended attribute should be on the member. The remaining extended attribute, `[ImplementedAs]`, is mandatory. A partial -interface must have `[ImplementedAs]` extended attribute to specify a static-only C++ class. +interface must have `[ImplementedAs]` extended attribute to specify the C++ class that includes the required static methods. +This may be a static-only class, or for cases where a single static method is a simple getter for an object, that object's +class may implement the required static method. This is stored internally via `[PartialInterfaceImplementedAs]` (see below). ### interface mixins @@ -640,13 +642,13 @@ Usage: For methods all calls are logged, and by default for attributes all access (calls to getter or setter) are logged, but this can be restricted to just read (getter) or just write (setter). -### [CallWith] _(m, a)_, [SetterCallWith] _(a)_, [ConstructorCallWith] _(i)_ +### [CallWith] _(m, a)_, [GetterCallWith] _(a)_, [SetterCallWith] _(a)_, [ConstructorCallWith] _(i)_ Summary: `[CallWith]` indicates that the bindings code calls the Blink implementation with additional information. Each value changes the signature of the Blink methods by adding an additional parameter to the head of the parameter list, such as `ScriptState*` for `[CallWith=ScriptState]`. -`[SetterCallWith]` applies to attributes, and only affects the signature of the setter. +`[GetterCallWith]` and `[SetterCallWith]` apply to attributes, and only affects the signature of the getter and setter, respectively. #### [CallWith=ScriptState] _(m, a*)_ @@ -966,6 +968,13 @@ This attribute must be accompanied by either `[Measure]` or `[MeasureAs]`. [HighEntropy, Measure] const INTERESTING_CONSTANT = 1; ``` +Attributes labeled with `[HighEntropy=Direct]` are simple surfaces which can be expressed as a sequence of bytes without any need for additional parsing logic. +For now, this label is only supported for attribute getters, although the `[HighEntropy]` label is supported more broadly. + +```webidl +[HighEntropy=Direct, MeasureAs=SimpleNamedAttribute] attribute unsigned long simpleNamedAttribute; +``` + ### [DeprecateAs] _(m, a, c)_ Summary: Measures usage of a deprecated feature via UseCounter, and notifies developers about deprecation via a console warning. @@ -1562,7 +1571,7 @@ Marked functions are allowed to be nondeterministic, throw exceptions, force lay All DOM constructors are assumed to have side effects. However, an exception can be explicitly indicated when calling constructors using the V8 API method Function::NewInstanceWithSideEffectType(). -There is not yet support for marking SymbolKeyedMethodConfigurations as side-effect free. This requires additional support in V8 to whitelist Intrinsics. +There is not yet support for marking SymbolKeyedMethodConfigurations as side-effect free. This requires additional support in V8 to allow Intrinsics. Usage for attributes and operations: `[Affects=Nothing]` can be specified on an operation, or on an attribute to indicate that its getter callback is side effect free: diff --git a/chromium/third_party/blink/renderer/bindings/IDLExtendedAttributes.txt b/chromium/third_party/blink/renderer/bindings/IDLExtendedAttributes.txt index 5fe62ead835..e9bd064a9bb 100644 --- a/chromium/third_party/blink/renderer/bindings/IDLExtendedAttributes.txt +++ b/chromium/third_party/blink/renderer/bindings/IDLExtendedAttributes.txt @@ -58,8 +58,9 @@ EnforceRange Exposed=* FeaturePolicy=* FlexibleArrayBufferView +GetterCallWith=ScriptState Global=* -HighEntropy +HighEntropy=|Direct HTMLConstructor ImmutablePrototype ImplementedAs=* 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 349293eae18..3dffc0ddf8e 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 @@ -44,6 +44,7 @@ #include "third_party/blink/renderer/core/html/html_frame_element_base.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/instrumentation/use_counter.h" +#include "third_party/blink/renderer/platform/web_test_support.h" #include "third_party/blink/renderer/platform/weborigin/security_origin.h" namespace blink { @@ -53,8 +54,11 @@ namespace { // Documents that have the same WindowAgentFactory should be able to // share data with each other if they have the same Agent and are // SameOriginDomain. -bool IsSameWindowAgentFactory(Document* doc1, Document* doc2) { - return doc1->GetWindowAgentFactory() == doc2->GetWindowAgentFactory(); +bool IsSameWindowAgentFactory(const LocalDOMWindow* window1, + const LocalDOMWindow* window2) { + return window1->GetFrame() && window2->GetFrame() && + &window1->GetFrame()->window_agent_factory() == + &window2->GetFrame()->window_agent_factory(); } } // namespace @@ -148,8 +152,10 @@ bool CanAccessWindowInternal( kDomainNotRelevantAgentClusterMismatch) { // Assert that because the agent clusters are different than the // WindowAgentFactories must also be different. - SECURITY_CHECK(!IsSameWindowAgentFactory( - accessing_window->document(), local_target_window->document())); + SECURITY_CHECK( + !IsSameWindowAgentFactory(accessing_window, local_target_window) || + (WebTestSupport::IsRunningWebTest() && + local_target_window->GetFrame()->PagePopupOwner())); *cross_document_access = DOMWindow::CrossDocumentAccessPolicy::kDisallowed; @@ -481,8 +487,7 @@ void BindingSecurity::FailedAccessCheckFor(v8::Isolate* isolate, // instead of "cross-origin". DOMWindow::CrossDocumentAccessPolicy cross_document_access = (!target->ToLocalDOMWindow() || - IsSameWindowAgentFactory(local_dom_window->document(), - target->ToLocalDOMWindow()->document())) + IsSameWindowAgentFactory(local_dom_window, target->ToLocalDOMWindow())) ? DOMWindow::CrossDocumentAccessPolicy::kAllowed : DOMWindow::CrossDocumentAccessPolicy::kDisallowed; diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/boxed_v8_module.h b/chromium/third_party/blink/renderer/bindings/core/v8/boxed_v8_module.h index 886b4701c5d..d53d8230d90 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/boxed_v8_module.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/boxed_v8_module.h @@ -24,7 +24,7 @@ class CORE_EXPORT BoxedV8Module final : public GarbageCollected<BoxedV8Module> { : record_(isolate, module), identity_hash_(static_cast<unsigned>(module->GetIdentityHash())) {} - void Trace(Visitor* visitor) { + void Trace(Visitor* visitor) const { // TODO(keishi): Remove UnsafeCast. visitor->Trace(record_.UnsafeCast<v8::Value>()); } diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_custom_xpath_ns_resolver.cc b/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_custom_xpath_ns_resolver.cc index a071d23d646..8090bf839b4 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_custom_xpath_ns_resolver.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_custom_xpath_ns_resolver.cc @@ -94,7 +94,7 @@ AtomicString V8CustomXPathNSResolver::lookupNamespaceURI(const String& prefix) { return return_string; } -void V8CustomXPathNSResolver::Trace(Visitor* visitor) { +void V8CustomXPathNSResolver::Trace(Visitor* visitor) const { visitor->Trace(script_state_); XPathNSResolver::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_custom_xpath_ns_resolver.h b/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_custom_xpath_ns_resolver.h index ea35df084e1..84b5919e64f 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_custom_xpath_ns_resolver.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_custom_xpath_ns_resolver.h @@ -48,7 +48,7 @@ class V8CustomXPathNSResolver final : public XPathNSResolver { AtomicString lookupNamespaceURI(const String& prefix) override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: Member<ScriptState> script_state_; 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 b25053ac80d..0f2b88f4c50 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 @@ -153,9 +153,8 @@ void V8DevToolsHost::ShowContextMenuAtPointMethodCustom( if (info.Length() >= 4 && info[3]->IsObject()) { document = V8HTMLDocument::ToImplWithTypeCheck(isolate, info[3]); } else { - DOMWindow* window = V8Window::ToImplWithTypeCheck( - isolate, isolate->GetEnteredOrMicrotaskContext()->Global()); - document = window ? To<LocalDOMWindow>(window)->document() : nullptr; + LocalDOMWindow* window = EnteredDOMWindow(isolate); + document = window ? window->document() : nullptr; } if (!document || !document->GetFrame()) return; diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_html_plugin_element_custom.cc b/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_html_plugin_element_custom.cc index 8d14ddb729d..99dfb4e551a 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_html_plugin_element_custom.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_html_plugin_element_custom.cc @@ -74,6 +74,8 @@ void GetScriptableObjectProperty( return; } + UseCounter::Count(CurrentExecutionContext(info.GetIsolate()), + WebFeature::kPluginInstanceAccessSuccessful); V8SetReturnValue(info, 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 00aacbd8a1d..e5abc0a4a91 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 @@ -100,42 +100,6 @@ void V8Window::LocationAttributeGetterCustom( V8SetReturnValue(info, wrapper); } -void V8Window::EventAttributeGetterCustom( - const v8::FunctionCallbackInfo<v8::Value>& info) { - LocalDOMWindow* impl = To<LocalDOMWindow>(V8Window::ToImpl(info.Holder())); - v8::Isolate* isolate = info.GetIsolate(); - ExceptionState exception_state(isolate, ExceptionState::kGetterContext, - "Window", "event"); - if (!BindingSecurity::ShouldAllowAccessTo(CurrentDOMWindow(isolate), impl, - exception_state)) { - return; - } - - v8::Local<v8::Value> js_event; - if (!V8PrivateProperty::GetSymbol(isolate, kPrivatePropertyGlobalEvent) - .GetOrUndefined(info.Holder()) - .ToLocal(&js_event)) { - return; - } - - // Track usage of window.event when the event's target is inside V0 shadow - // tree. - // TODO(yukishiino): Make window.event [Replaceable] and simplify the - // following IsWrapper/ToImplWithTypeCheck hack. - if (V8DOMWrapper::IsWrapper(isolate, js_event)) { - if (Event* event = V8Event::ToImplWithTypeCheck(isolate, js_event)) { - if (event->target()) { - Node* target_node = event->target()->ToNode(); - if (target_node && target_node->IsInV0ShadowTree()) { - UseCounter::Count(CurrentExecutionContext(isolate), - WebFeature::kWindowEventInV0ShadowTree); - } - } - } - } - V8SetReturnValue(info, js_event); -} - void V8Window::FrameElementAttributeGetterCustom( const v8::FunctionCallbackInfo<v8::Value>& info) { LocalDOMWindow* impl = To<LocalDOMWindow>(V8Window::ToImpl(info.Holder())); diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/custom_wrappable_adapter.h b/chromium/third_party/blink/renderer/bindings/core/v8/custom_wrappable_adapter.h index 74507081f74..6a3c57a1e3e 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/custom_wrappable_adapter.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/custom_wrappable_adapter.h @@ -49,7 +49,7 @@ class CORE_EXPORT CustomWrappableAdapter : public CustomWrappable { ~CustomWrappableAdapter() override = default; - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(wrapper_); CustomWrappable::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/generated.gni b/chromium/third_party/blink/renderer/bindings/core/v8/generated.gni index 30bccc9aa05..c7044b7b1bd 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/generated.gni +++ b/chromium/third_party/blink/renderer/bindings/core/v8/generated.gni @@ -12,10 +12,10 @@ bindings_core_generated_union_type_files = [ "$bindings_core_v8_output_dir/add_event_listener_options_or_boolean.h", "$bindings_core_v8_output_dir/array_buffer_or_array_buffer_view.cc", "$bindings_core_v8_output_dir/array_buffer_or_array_buffer_view.h", - "$bindings_core_v8_output_dir/array_buffer_or_array_buffer_view_or_blob_or_document_or_string_or_form_data_or_url_search_params.cc", - "$bindings_core_v8_output_dir/array_buffer_or_array_buffer_view_or_blob_or_document_or_string_or_form_data_or_url_search_params.h", "$bindings_core_v8_output_dir/array_buffer_or_array_buffer_view_or_blob_or_usv_string.cc", "$bindings_core_v8_output_dir/array_buffer_or_array_buffer_view_or_blob_or_usv_string.h", + "$bindings_core_v8_output_dir/blob_or_array_buffer_or_array_buffer_view_or_form_data_or_url_search_params_or_usv_string.cc", + "$bindings_core_v8_output_dir/blob_or_array_buffer_or_array_buffer_view_or_form_data_or_url_search_params_or_usv_string.h", "$bindings_core_v8_output_dir/boolean_or_byte_string_byte_string_record.cc", "$bindings_core_v8_output_dir/boolean_or_byte_string_byte_string_record.h", "$bindings_core_v8_output_dir/byte_string_sequence_sequence_or_byte_string_byte_string_record.cc", @@ -24,6 +24,8 @@ bindings_core_generated_union_type_files = [ "$bindings_core_v8_output_dir/composite_operation_or_auto_or_composite_operation_or_auto_sequence.h", "$bindings_core_v8_output_dir/css_style_value_or_string.cc", "$bindings_core_v8_output_dir/css_style_value_or_string.h", + "$bindings_core_v8_output_dir/document_or_xml_http_request_body_init.cc", + "$bindings_core_v8_output_dir/document_or_xml_http_request_body_init.h", "$bindings_core_v8_output_dir/double_or_auto_keyword.cc", "$bindings_core_v8_output_dir/double_or_auto_keyword.h", "$bindings_core_v8_output_dir/double_or_css_numeric_value.cc", @@ -94,6 +96,8 @@ bindings_core_generated_union_type_files = [ "$bindings_core_v8_output_dir/string_or_trusted_html_or_trusted_script_or_trusted_script_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", + "$bindings_core_v8_output_dir/string_or_trusted_script_url.h", "$bindings_core_v8_output_dir/string_or_unrestricted_double_sequence.cc", "$bindings_core_v8_output_dir/string_or_unrestricted_double_sequence.h", "$bindings_core_v8_output_dir/string_or_worker_options.cc", 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 2bcef096d60..d0ce4013a26 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 @@ -13,6 +13,7 @@ #include "third_party/blink/renderer/core/frame/local_dom_window.h" #include "third_party/blink/renderer/core/html/custom/ce_reactions_scope.h" #include "third_party/blink/renderer/core/html/custom/v0_custom_element_processing_stack.h" +#include "third_party/blink/renderer/core/inspector/console_message.h" #include "third_party/blink/renderer/core/xml/dom_parser.h" #include "third_party/blink/renderer/platform/bindings/v8_per_context_data.h" @@ -131,7 +132,7 @@ void V8SetReflectedDOMStringAttribute( CEReactionsScope ce_reactions_scope; // Prepare the value to be set. - V8StringResource<> cpp_value = info[0]; + V8StringResource<> cpp_value{info[0]}; if (!cpp_value.Prepare()) return; @@ -147,7 +148,7 @@ void V8SetReflectedNullableDOMStringAttribute( CEReactionsScope ce_reactions_scope; // Prepare the value to be set. - V8StringResource<kTreatNullAndUndefinedAsNullString> cpp_value = info[0]; + V8StringResource<kTreatNullAndUndefinedAsNullString> cpp_value{info[0]}; if (!cpp_value.Prepare()) return; @@ -188,6 +189,25 @@ base::Optional<size_t> FindIndexInEnumStringTable( return base::nullopt; } +void ReportInvalidEnumSetToAttribute(v8::Isolate* isolate, + const String& value, + const String& enum_type_name, + ExceptionState& exception_state) { + ScriptState* script_state = ScriptState::From(isolate->GetCurrentContext()); + ExecutionContext* execution_context = ExecutionContext::From(script_state); + + exception_state.ThrowTypeError("The provided value '" + value + + "' is not a valid enum value of type " + + enum_type_name + "."); + String message = exception_state.Message(); + exception_state.ClearException(); + + execution_context->AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>( + mojom::blink::ConsoleMessageSource::kJavaScript, + mojom::blink::ConsoleMessageLevel::kWarning, message, + SourceLocation::Capture(execution_context))); +} + bool IsEsIterableObject(v8::Isolate* isolate, v8::Local<v8::Value> value, ExceptionState& exception_state) { 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 34c95176339..ed827e9c740 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 @@ -13,6 +13,7 @@ #include "third_party/blink/renderer/bindings/core/v8/script_promise.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/dom/events/event_target.h" +#include "third_party/blink/renderer/platform/bindings/exception_messages.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/v8_binding.h" #include "v8/include/v8.h" @@ -143,6 +144,12 @@ CORE_EXPORT base::Optional<size_t> FindIndexInEnumStringTable( const String& str_value, base::span<const char* const> enum_value_table); +CORE_EXPORT void ReportInvalidEnumSetToAttribute( + v8::Isolate* isolate, + const String& value, + const String& enum_type_name, + ExceptionState& exception_state); + CORE_EXPORT bool IsEsIterableObject(v8::Isolate* isolate, v8::Local<v8::Value> value, ExceptionState& exception_state); @@ -178,6 +185,49 @@ CORE_EXPORT v8::Local<v8::Array> EnumerateIndexedProperties( v8::Isolate* isolate, uint32_t length); +// Performs the ES value to IDL value conversion of IDL dictionary member. +// Sets a dictionary member |value| and |presence| to the resulting values. +// Returns true on success, otherwise returns false and throws an exception. +// +// |try_block| must be the innermost v8::TryCatch and it's used to internally +// capture an exception, which is rethrown in |exception_state|. +template <typename NVTTag, bool is_required, typename T> +bool ConvertDictionaryMember(v8::Isolate* isolate, + v8::Local<v8::Context> current_context, + v8::Local<v8::Object> v8_dictionary, + v8::Local<v8::Name> v8_member_name, + const char* dictionary_name, + const char* member_name, + T& value, + bool& presence, + v8::TryCatch& try_block, + ExceptionState& exception_state) { + v8::Local<v8::Value> v8_value; + if (!v8_dictionary->Get(current_context, v8_member_name).ToLocal(&v8_value)) { + exception_state.RethrowV8Exception(try_block.Exception()); + try_block.Reset(); + return false; + } + + if (v8_value->IsUndefined()) { + if (is_required) { + exception_state.ThrowTypeError(ExceptionMessages::FailedToGet( + member_name, dictionary_name, "Required member is undefined.")); + return false; + } + presence = false; + return true; + } + + value = NativeValueTraits<NVTTag>::NativeValue(isolate, v8_value, + exception_state); + if (exception_state.HadException()) { + return false; + } + presence = true; + return true; +} + } // namespace bindings } // namespace blink diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/idl_dictionary_base.cc b/chromium/third_party/blink/renderer/bindings/core/v8/idl_dictionary_base.cc index d2634225fc6..11b7f0da4b3 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/idl_dictionary_base.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/idl_dictionary_base.cc @@ -12,6 +12,6 @@ v8::Local<v8::Value> IDLDictionaryBase::ToV8Impl(v8::Local<v8::Object>, return v8::Local<v8::Value>(); } -void IDLDictionaryBase::Trace(Visitor* visitor) {} +void IDLDictionaryBase::Trace(Visitor* visitor) const {} } // namespace blink 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 fb924d34f26..616c95a322a 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 @@ -23,7 +23,7 @@ class CORE_EXPORT IDLDictionaryBase virtual v8::Local<v8::Value> ToV8Impl(v8::Local<v8::Object> creation_context, v8::Isolate*) const; - virtual void Trace(Visitor*); + virtual void Trace(Visitor*) const; protected: IDLDictionaryBase() = default; diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/isolated_world_csp.cc b/chromium/third_party/blink/renderer/bindings/core/v8/isolated_world_csp.cc index e0218d34a3c..8d4dcc1317c 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/isolated_world_csp.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/isolated_world_csp.cc @@ -9,8 +9,8 @@ #include "base/check.h" #include "third_party/blink/public/mojom/security_context/insecure_request_policy.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/script_controller.h" -#include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h" +#include "third_party/blink/renderer/core/frame/local_dom_window.h" #include "third_party/blink/renderer/core/probe/core_probes.h" #include "third_party/blink/renderer/platform/bindings/dom_wrapper_world.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" @@ -31,19 +31,19 @@ class IsolatedWorldCSPDelegate final USING_GARBAGE_COLLECTED_MIXIN(IsolatedWorldCSPDelegate); public: - IsolatedWorldCSPDelegate(Document& document, + IsolatedWorldCSPDelegate(LocalDOMWindow& window, scoped_refptr<SecurityOrigin> security_origin, int32_t world_id, bool apply_policy) - : document_(&document), + : window_(&window), security_origin_(std::move(security_origin)), world_id_(world_id), apply_policy_(apply_policy) { DCHECK(security_origin_); } - void Trace(Visitor* visitor) override { - visitor->Trace(document_); + void Trace(Visitor* visitor) const override { + visitor->Trace(window_); ContentSecurityPolicyDelegate::Trace(visitor); } @@ -90,19 +90,19 @@ class IsolatedWorldCSPDelegate final } void Count(WebFeature feature) override { - // Log the features used by isolated world CSPs on the underlying Document. - UseCounter::Count(document_, feature); + // Log the features used by isolated world CSPs on the underlying window. + UseCounter::Count(window_, feature); } void AddConsoleMessage(ConsoleMessage* console_message) override { - // Add console messages on the underlying Document. - document_->AddConsoleMessage(console_message); + // Add console messages on the underlying window. + window_->AddConsoleMessage(console_message); } void DisableEval(const String& error_message) override { - if (!document_->GetFrame()) + if (!window_->GetFrame()) return; - document_->GetFrame()->GetScriptController().DisableEvalForIsolatedWorld( + window_->GetFrame()->GetScriptController().DisableEvalForIsolatedWorld( world_id_, error_message); } @@ -110,15 +110,14 @@ class IsolatedWorldCSPDelegate final const String& directive_text) override { // This allows users to set breakpoints in the Devtools for the case when // script execution is blocked by CSP. - probe::ScriptExecutionBlockedByCSP(document_->GetExecutionContext(), - directive_text); + probe::ScriptExecutionBlockedByCSP(window_.Get(), directive_text); } void DidAddContentSecurityPolicies( WTF::Vector<network::mojom::blink::ContentSecurityPolicyPtr>) override {} private: - const Member<Document> document_; + const Member<LocalDOMWindow> window_; const scoped_refptr<SecurityOrigin> security_origin_; const int32_t world_id_; @@ -164,7 +163,7 @@ bool IsolatedWorldCSP::HasContentSecurityPolicy(int32_t world_id) const { } ContentSecurityPolicy* IsolatedWorldCSP::CreateIsolatedWorldCSP( - Document& document, + LocalDOMWindow& window, int32_t world_id) { DCHECK(IsMainThread()); DCHECK(DOMWrapperWorld::IsIsolatedWorldId(world_id)); @@ -182,7 +181,7 @@ ContentSecurityPolicy* IsolatedWorldCSP::CreateIsolatedWorldCSP( IsolatedWorldCSPDelegate* delegate = MakeGarbageCollected<IsolatedWorldCSPDelegate>( - document, std::move(self_origin), world_id, apply_policy); + window, std::move(self_origin), world_id, apply_policy); csp->BindToDelegate(*delegate); if (apply_policy) { diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/isolated_world_csp.h b/chromium/third_party/blink/renderer/bindings/core/v8/isolated_world_csp.h index 316bf550745..bd3545f3db2 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/isolated_world_csp.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/isolated_world_csp.h @@ -15,7 +15,7 @@ namespace blink { class ContentSecurityPolicy; -class Document; +class LocalDOMWindow; // A singleton storing content security policy for each isolated world. class CORE_EXPORT IsolatedWorldCSP { @@ -40,9 +40,9 @@ class CORE_EXPORT IsolatedWorldCSP { bool HasContentSecurityPolicy(int32_t world_id) const; // Creates a ContentSecurityPolicy instance for the given isolated |world_id| - // and |document|. Returns null if no ContentSecurityPolicy is defined for the + // and |window|. Returns null if no ContentSecurityPolicy is defined for the // given isolated |world_id|. - ContentSecurityPolicy* CreateIsolatedWorldCSP(Document& document, + ContentSecurityPolicy* CreateIsolatedWorldCSP(LocalDOMWindow& window, int32_t world_id); private: diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/iterable.h b/chromium/third_party/blink/renderer/bindings/core/v8/iterable.h index fd1a59d3e0e..34f6975b598 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/iterable.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/iterable.h @@ -97,7 +97,7 @@ class Iterable { // false. Otherwise: set |key| and |value| and return true. virtual bool Next(ScriptState*, KeyType&, ValueType&, ExceptionState&) = 0; - virtual void Trace(Visitor* visitor) {} + virtual void Trace(Visitor* visitor) const {} }; private: @@ -160,7 +160,7 @@ class Iterable { return next(script_state, exception_state); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(source_); Iterator::Trace(visitor); } 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 index 54a3b76f319..412bad667ca 100644 --- 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 @@ -16,9 +16,6 @@ namespace blink { -// extern -const V8PrivateProperty::SymbolKey kPrivatePropertyGlobalEvent; - JSBasedEventListener::JSBasedEventListener() { if (IsMainThread()) { InstanceCounters::IncrementCounter( @@ -123,25 +120,23 @@ void JSBasedEventListener::Invoke( // 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::GetSymbol(isolate, kPrivatePropertyGlobalEvent); - 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. + LocalDOMWindow* window = + ToLocalDOMWindow(script_state_of_listener->GetContext()); + + // Step 7: Let |current_event| be undefined. + Event* current_event = nullptr; + + // Step 8: If |global| is a Window object, then: + if (window) { + // Step 8-1: Set |current_event| to |global|’s current event. + current_event = window->CurrentEvent(); + + // Step 8-2: If |struct|’s invocation-target-in-shadow-tree is false (i.e., + // event's target is in a V1 shadow tree), then set |global|’s current + // event to event. Node* target_node = event->target()->ToNode(); if (!(target_node && target_node->IsInV1ShadowTree())) - event_symbol.Set(global, js_event); + window->SetCurrentEvent(event); } { @@ -158,17 +153,12 @@ void JSBasedEventListener::Invoke( // 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); + if (window) + window->SetCurrentEvent(current_event); } std::unique_ptr<SourceLocation> JSBasedEventListener::GetSourceLocation( 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 index be8a0a05d23..326c6dc5964 100644 --- 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 @@ -91,8 +91,6 @@ struct DowncastTraits<JSBasedEventListener> { } }; -extern const V8PrivateProperty::SymbolKey kPrivatePropertyGlobalEvent; - } // 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 index 4c4d331451b..06b0c845a46 100644 --- 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 @@ -193,7 +193,7 @@ void JSEventHandler::InvokeInternal(EventTarget& event_target, } } -void JSEventHandler::Trace(Visitor* visitor) { +void JSEventHandler::Trace(Visitor* visitor) const { visitor->Trace(event_handler_); JSBasedEventListener::Trace(visitor); } 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 index 20095badae2..fb46e24bfc0 100644 --- 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 @@ -42,7 +42,7 @@ class CORE_EXPORT JSEventHandler : public JSBasedEventListener { : event_handler_(event_handler), type_(type) {} // blink::CustomWrappable overrides: - void Trace(Visitor* visitor) override; + void Trace(Visitor* visitor) const override; // blink::EventListener overrides: bool IsEventHandler() const final { return true; } 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 index 0a123db8bc5..4c3ca16d470 100644 --- 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 @@ -59,7 +59,7 @@ void JSEventListener::InvokeInternal(EventTarget&, ALLOW_UNUSED_LOCAL(maybe_result); } -void JSEventListener::Trace(Visitor* visitor) { +void JSEventListener::Trace(Visitor* visitor) const { visitor->Trace(event_listener_); JSBasedEventListener::Trace(visitor); } 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 index d4b17bf990a..7c8bc2eada0 100644 --- 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 @@ -22,7 +22,7 @@ class CORE_EXPORT JSEventListener final : public JSBasedEventListener { : event_listener_(listener) {} // blink::CustomWrappable overrides: - void Trace(Visitor*) override; + void Trace(Visitor*) const override; // blink::EventListener overrides: // diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc b/chromium/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc index cd6850e3d61..5ac9a7ed3d0 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/local_window_proxy.cc @@ -74,7 +74,7 @@ constexpr char kGlobalProxyLabel[] = "WindowProxy::global_proxy_"; } // namespace -void LocalWindowProxy::Trace(Visitor* visitor) { +void LocalWindowProxy::Trace(Visitor* visitor) const { visitor->Trace(script_state_); WindowProxy::Trace(visitor); } @@ -175,7 +175,7 @@ void LocalWindowProxy::Initialize() { IsolatedWorldCSP::Get().HasContentSecurityPolicy(world_->GetWorldId())); if (evaluate_csp_for_eval) { ContentSecurityPolicy* csp = - GetFrame()->GetDocument()->GetContentSecurityPolicyForWorld(); + GetFrame()->DomWindow()->GetContentSecurityPolicyForWorld(); context->AllowCodeGenerationFromStrings(!csp->ShouldCheckEval()); context->SetErrorMessageForCodeGenerationFromStrings( V8String(GetIsolate(), csp->EvalDisabledErrorMessage())); diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/local_window_proxy.h b/chromium/third_party/blink/renderer/bindings/core/v8/local_window_proxy.h index 4aabac58f11..fabf0b56460 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/local_window_proxy.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/local_window_proxy.h @@ -50,7 +50,7 @@ class SecurityOrigin; class LocalWindowProxy final : public WindowProxy { public: LocalWindowProxy(v8::Isolate*, LocalFrame&, scoped_refptr<DOMWrapperWorld>); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; v8::Local<v8::Context> ContextIfInitialized() const { return script_state_ ? script_state_->GetContext() diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/module_record.cc b/chromium/third_party/blink/renderer/bindings/core/v8/module_record.cc index 3806816f898..d38ece04e5c 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/module_record.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/module_record.cc @@ -80,7 +80,7 @@ ModuleRecordProduceCacheData::ModuleRecordProduceCacheData( } } -void ModuleRecordProduceCacheData::Trace(Visitor* visitor) { +void ModuleRecordProduceCacheData::Trace(Visitor* visitor) const { visitor->Trace(cache_handler_); visitor->Trace(unbound_script_.UnsafeCast<v8::Value>()); } @@ -114,10 +114,11 @@ v8::Local<v8::Module> ModuleRecord::Compile( V8CodeCache::GetCompileOptions(v8_cache_options, cache_handler, source.length(), source_location_type); - if (!V8ScriptRunner::CompileModule(isolate, source, cache_handler, source_url, - text_position, compile_options, - no_cache_reason, - ReferrerScriptInfo(base_url, options)) + if (!V8ScriptRunner::CompileModule( + isolate, source, cache_handler, source_url, text_position, + compile_options, no_cache_reason, + ReferrerScriptInfo(base_url, options, + ReferrerScriptInfo::BaseUrlSource::kOther)) .ToLocal(&module)) { DCHECK(try_catch.HasCaught()); exception_state.RethrowV8Exception(try_catch.Exception()); diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/module_record.h b/chromium/third_party/blink/renderer/bindings/core/v8/module_record.h index 8d522b99335..4a1ed78025f 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/module_record.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/module_record.h @@ -76,7 +76,7 @@ class CORE_EXPORT ModuleRecordProduceCacheData final V8CodeCache::ProduceCacheOptions, v8::Local<v8::Module>); - void Trace(Visitor*); + void Trace(Visitor*) const; SingleCachedMetadataHandler* CacheHandler() const { return cache_handler_; } V8CodeCache::ProduceCacheOptions GetProduceCacheOptions() const { diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/module_record_test.cc b/chromium/third_party/blink/renderer/bindings/core/v8/module_record_test.cc index ec75452c4ed..4ddc165c2a7 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/module_record_test.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/module_record_test.cc @@ -34,7 +34,7 @@ class TestModuleRecordResolver final : public ModuleRecordResolver { MakeGarbageCollected<BoxedV8Module>(isolate_, module)); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(module_records_); ModuleRecordResolver::Trace(visitor); } @@ -68,7 +68,7 @@ class ModuleRecordTestModulator final : public DummyModulator { ModuleRecordTestModulator(v8::Isolate* isolate); ~ModuleRecordTestModulator() override = default; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; TestModuleRecordResolver* GetTestModuleRecordResolver() { return resolver_.Get(); @@ -87,7 +87,7 @@ class ModuleRecordTestModulator final : public DummyModulator { ModuleRecordTestModulator::ModuleRecordTestModulator(v8::Isolate* isolate) : resolver_(MakeGarbageCollected<TestModuleRecordResolver>(isolate)) {} -void ModuleRecordTestModulator::Trace(Visitor* visitor) { +void ModuleRecordTestModulator::Trace(Visitor* visitor) const { visitor->Trace(resolver_); DummyModulator::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/profiler_trace_builder.cc b/chromium/third_party/blink/renderer/bindings/core/v8/profiler_trace_builder.cc index fbf3ff83006..3fd86fb875a 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/profiler_trace_builder.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/profiler_trace_builder.cc @@ -43,7 +43,7 @@ ProfilerTraceBuilder::ProfilerTraceBuilder(ScriptState* script_state, allowed_origin_(allowed_origin), time_origin_(time_origin) {} -void ProfilerTraceBuilder::Trace(Visitor* visitor) { +void ProfilerTraceBuilder::Trace(Visitor* visitor) const { visitor->Trace(script_state_); visitor->Trace(frames_); visitor->Trace(stacks_); diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/profiler_trace_builder.h b/chromium/third_party/blink/renderer/bindings/core/v8/profiler_trace_builder.h index 2f02b90ba82..baab1ffe2af 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/profiler_trace_builder.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/profiler_trace_builder.h @@ -80,7 +80,7 @@ class ProfilerTraceBuilder final const SecurityOrigin* allowed_origin, base::TimeTicks time_origin); - void Trace(Visitor*); + void Trace(Visitor*) const; private: // Adds a stack sample from V8 to the trace, performing necessary filtering diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/referrer_script_info.cc b/chromium/third_party/blink/renderer/bindings/core/v8/referrer_script_info.cc index 0dce491aec2..4a3b3807462 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/referrer_script_info.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/referrer_script_info.cc @@ -18,6 +18,7 @@ enum HostDefinedOptionsIndex : size_t { kNonce, kParserState, kReferrerPolicy, + kBaseUrlSource, kLength }; @@ -66,8 +67,14 @@ ReferrerScriptInfo ReferrerScriptInfo::FromV8HostDefinedOptions( referrer_policy_int32) .value_or(network::mojom::ReferrerPolicy::kDefault); + v8::Local<v8::Primitive> base_url_source_value = + host_defined_options->Get(isolate, kBaseUrlSource); + SECURITY_CHECK(base_url_source_value->IsUint32()); + BaseUrlSource base_url_source = static_cast<BaseUrlSource>( + base_url_source_value->IntegerValue(context).ToChecked()); + return ReferrerScriptInfo(base_url, credentials_mode, nonce, parser_state, - referrer_policy); + referrer_policy, base_url_source); } v8::Local<v8::PrimitiveArray> ReferrerScriptInfo::ToV8HostDefinedOptions( @@ -103,6 +110,11 @@ v8::Local<v8::PrimitiveArray> ReferrerScriptInfo::ToV8HostDefinedOptions( host_defined_options->Set(isolate, HostDefinedOptionsIndex::kReferrerPolicy, referrer_policy_value); + v8::Local<v8::Primitive> base_url_source_value = v8::Integer::NewFromUnsigned( + isolate, static_cast<uint32_t>(base_url_source_)); + host_defined_options->Set(isolate, HostDefinedOptionsIndex::kBaseUrlSource, + base_url_source_value); + return host_defined_options; } diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/referrer_script_info.h b/chromium/third_party/blink/renderer/bindings/core/v8/referrer_script_info.h index 84ed3667786..279ac3ab4a0 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/referrer_script_info.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/referrer_script_info.h @@ -23,23 +23,33 @@ class CORE_EXPORT ReferrerScriptInfo { STACK_ALLOCATED(); public: + enum class BaseUrlSource { + kClassicScriptCORSSameOrigin, + kClassicScriptCORSCrossOrigin, + kOther + }; ReferrerScriptInfo() {} ReferrerScriptInfo(const KURL& base_url, network::mojom::CredentialsMode credentials_mode, const String& nonce, ParserDisposition parser_state, - network::mojom::ReferrerPolicy referrer_policy) + network::mojom::ReferrerPolicy referrer_policy, + BaseUrlSource base_url_source) : base_url_(base_url), credentials_mode_(credentials_mode), nonce_(nonce), parser_state_(parser_state), - referrer_policy_(referrer_policy) {} - ReferrerScriptInfo(const KURL& base_url, const ScriptFetchOptions& options) + referrer_policy_(referrer_policy), + base_url_source_(base_url_source) {} + ReferrerScriptInfo(const KURL& base_url, + const ScriptFetchOptions& options, + BaseUrlSource base_url_source) : ReferrerScriptInfo(base_url, options.CredentialsMode(), options.Nonce(), options.ParserState(), - options.GetReferrerPolicy()) {} + options.GetReferrerPolicy(), + base_url_source) {} static ReferrerScriptInfo FromV8HostDefinedOptions( v8::Local<v8::Context>, @@ -55,11 +65,13 @@ class CORE_EXPORT ReferrerScriptInfo { network::mojom::ReferrerPolicy GetReferrerPolicy() const { return referrer_policy_; } + BaseUrlSource GetBaseUrlSource() const { return base_url_source_; } bool IsDefaultValue() const { return base_url_.IsNull() && credentials_mode_ == network::mojom::CredentialsMode::kSameOrigin && - nonce_.IsEmpty() && parser_state_ == kNotParserInserted; + nonce_.IsEmpty() && parser_state_ == kNotParserInserted && + base_url_source_ == BaseUrlSource::kOther; } private: @@ -90,6 +102,9 @@ class CORE_EXPORT ReferrerScriptInfo { // https://html.spec.whatwg.org/C/#default-classic-script-fetch-options const network::mojom::ReferrerPolicy referrer_policy_ = network::mojom::ReferrerPolicy::kDefault; + + // Temporary flag to collect UMA for crbug.com/1082086. + const BaseUrlSource base_url_source_ = BaseUrlSource::kOther; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/referrer_script_info_test.cc b/chromium/third_party/blink/renderer/bindings/core/v8/referrer_script_info_test.cc index 3387eb16097..bf4c59b8bf9 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/referrer_script_info_test.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/referrer_script_info_test.cc @@ -15,7 +15,8 @@ TEST(ReferrerScriptInfo, IsDefaultValue) { EXPECT_FALSE(ReferrerScriptInfo(KURL("http://example.com"), network::mojom::CredentialsMode::kInclude, "", kNotParserInserted, - network::mojom::ReferrerPolicy::kDefault) + network::mojom::ReferrerPolicy::kDefault, + ReferrerScriptInfo::BaseUrlSource::kOther) .IsDefaultValue()); } @@ -27,9 +28,10 @@ TEST(ReferrerScriptInfo, ToFromV8) { .ToV8HostDefinedOptions(scope.GetIsolate()) .IsEmpty()); - ReferrerScriptInfo info(url, network::mojom::CredentialsMode::kInclude, - "foobar", kNotParserInserted, - network::mojom::ReferrerPolicy::kOrigin); + ReferrerScriptInfo info( + url, network::mojom::CredentialsMode::kInclude, "foobar", + kNotParserInserted, network::mojom::ReferrerPolicy::kOrigin, + ReferrerScriptInfo::BaseUrlSource::kClassicScriptCORSCrossOrigin); v8::Local<v8::PrimitiveArray> v8_info = info.ToV8HostDefinedOptions(scope.GetIsolate()); @@ -42,6 +44,8 @@ TEST(ReferrerScriptInfo, ToFromV8) { EXPECT_EQ(kNotParserInserted, decoded.ParserState()); EXPECT_EQ(network::mojom::ReferrerPolicy::kOrigin, decoded.GetReferrerPolicy()); + EXPECT_EQ(ReferrerScriptInfo::BaseUrlSource::kClassicScriptCORSCrossOrigin, + decoded.GetBaseUrlSource()); } } // namespace blink 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 31fe75f0aef..88a639c6697 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 @@ -208,8 +208,10 @@ void RejectedPromises::HandlerAdded(v8::PromiseRejectMessage data) { std::unique_ptr<Message>& message = reported_as_errors_.at(i); if (!message->IsCollected() && message->HasPromise(data.GetPromise())) { message->MakePromiseStrong(); - message->GetContext() - ->GetTaskRunner(TaskType::kDOMManipulation) + // Since we move out of `message` below, we need to pull `context` out in + // a separate statement. + ExecutionContext* context = message->GetContext(); + context->GetTaskRunner(TaskType::kDOMManipulation) ->PostTask(FROM_HERE, WTF::Bind(&RejectedPromises::RevokeNow, scoped_refptr<RejectedPromises>(this), WTF::Passed(std::move(message)))); 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 9ac8029e801..19d8cc383f4 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 @@ -138,7 +138,7 @@ void ScheduledAction::Execute(ExecutionContext* context) { } } -void ScheduledAction::Trace(Visitor* visitor) { +void ScheduledAction::Trace(Visitor* visitor) const { visitor->Trace(script_state_); visitor->Trace(function_); visitor->Trace(arguments_); diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/scheduled_action.h b/chromium/third_party/blink/renderer/bindings/core/v8/scheduled_action.h index 4f81e0c3800..c8d7a4c913c 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/scheduled_action.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/scheduled_action.h @@ -66,7 +66,7 @@ class ScheduledAction final : public GarbageCollected<ScheduledAction>, void Execute(ExecutionContext*); - void Trace(Visitor*); + void Trace(Visitor*) const; const char* NameInHeapSnapshot() const override { return "ScheduledAction"; } 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 b04bfa17836..b4936ceb9ba 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 @@ -73,7 +73,7 @@ namespace blink { -void ScriptController::Trace(Visitor* visitor) { +void ScriptController::Trace(Visitor* visitor) const { visitor->Trace(frame_); visitor->Trace(window_proxy_manager_); } @@ -115,7 +115,27 @@ v8::Local<v8::Value> ScriptController::ExecuteScriptAndReturnValue( // Note: This improves chance of getting into a fast path in // ReferrerScriptInfo::ToV8HostDefinedOptions. KURL stored_base_url = (base_url == source.Url()) ? KURL() : base_url; - const ReferrerScriptInfo referrer_info(stored_base_url, fetch_options); + + // TODO(hiroshige): Remove this code and related use counters once the + // measurement is done. + ReferrerScriptInfo::BaseUrlSource base_url_source = + ReferrerScriptInfo::BaseUrlSource::kOther; + if (source.SourceLocationType() == + ScriptSourceLocationType::kExternalFile && + !base_url.IsNull()) { + switch (sanitize_script_errors) { + case SanitizeScriptErrors::kDoNotSanitize: + base_url_source = + ReferrerScriptInfo::BaseUrlSource::kClassicScriptCORSSameOrigin; + break; + case SanitizeScriptErrors::kSanitize: + base_url_source = + ReferrerScriptInfo::BaseUrlSource::kClassicScriptCORSCrossOrigin; + break; + } + } + const ReferrerScriptInfo referrer_info(stored_base_url, fetch_options, + base_url_source); v8::Local<v8::Script> script; @@ -290,8 +310,14 @@ void ScriptController::ExecuteJavaScriptURL( // If a navigation begins during the javascript: url's execution, ignore // the return value of the script. Otherwise, replacing the document with a // string result would cancel the navigation. - if (!had_navigation_before && GetFrame()->Loader().HasProvisionalNavigation()) + // TODO(crbug.com/1085514): Consider making HasProvisionalNavigation return + // true when a form submission is pending instead of having a separate check + // for form submissions here. + if (!had_navigation_before && + (GetFrame()->Loader().HasProvisionalNavigation() || + GetFrame()->IsFormSubmissionPending())) { return; + } if (v8_result.IsEmpty() || !v8_result->IsString()) return; @@ -347,7 +373,7 @@ v8::Local<v8::Value> ScriptController::EvaluateScriptInMainWorld( const ScriptFetchOptions& fetch_options, ExecuteScriptPolicy policy) { if (policy == kDoNotExecuteScriptWhenScriptsDisabled && - !GetFrame()->GetDocument()->CanExecuteScripts(kAboutToExecuteScript)) + !GetFrame()->DomWindow()->CanExecuteScripts(kAboutToExecuteScript)) return v8::Local<v8::Value>(); // |context| should be initialized already due to the MainWorldProxy() call. 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 f0c8208e089..de262d4ab80 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 @@ -69,7 +69,7 @@ class CORE_EXPORT ScriptController final ScriptController(LocalFrame& frame, LocalWindowProxyManager& window_proxy_manager) : frame_(&frame), window_proxy_manager_(&window_proxy_manager) {} - void Trace(Visitor*); + void Trace(Visitor*) const; // This returns an initialized window proxy. (If the window proxy is not // yet initialized, it's implicitly initialized at the first access.) 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 402e5370fd8..763fdc7e82a 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 @@ -106,7 +106,7 @@ ScriptCustomElementDefinition::ScriptCustomElementDefinition( .ToChecked()); } -void ScriptCustomElementDefinition::Trace(Visitor* visitor) { +void ScriptCustomElementDefinition::Trace(Visitor* visitor) const { visitor->Trace(script_state_); visitor->Trace(constructor_); visitor->Trace(connected_callback_); 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 ef5cbe9819f..839c21348d6 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 @@ -39,7 +39,7 @@ class CORE_EXPORT ScriptCustomElementDefinition final CustomElementDefinition::Id); ~ScriptCustomElementDefinition() override = default; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; v8::Local<v8::Object> Constructor() const; 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 6dc7a124e09..eda95fd988c 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 @@ -35,6 +35,7 @@ #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/qualified_name.h" +#include "third_party/blink/renderer/core/frame/local_dom_window.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "v8/include/v8.h" @@ -47,7 +48,7 @@ EventListener* CreateAttributeEventListener(Node* node, const AtomicString& value, JSEventHandler::HandlerType type) { DCHECK(node); - if (value.IsNull()) + if (value.IsNull() || !node->GetExecutionContext()) return nullptr; // FIXME: Very strange: we initialize zero-based number with '1'. @@ -55,11 +56,9 @@ EventListener* CreateAttributeEventListener(Node* node, OrdinalNumber::First()); String source_url; - v8::Isolate* isolate = node->GetDocument().GetIsolate(); - if (LocalFrame* frame = node->GetDocument().GetFrame()) { ScriptController& script_controller = frame->GetScriptController(); - if (!node->GetDocument().CanExecuteScripts(kAboutToExecuteScript)) + if (!node->GetExecutionContext()->CanExecuteScripts(kAboutToExecuteScript)) return nullptr; position = script_controller.EventHandlerPosition(); source_url = node->GetDocument().Url().GetString(); @@ -72,6 +71,7 @@ EventListener* CreateAttributeEventListener(Node* node, // of the isolated world for the content script by design. DOMWrapperWorld& world = DOMWrapperWorld::MainWorld(); + v8::Isolate* isolate = node->GetExecutionContext()->GetIsolate(); return MakeGarbageCollected<JSEventHandlerForContentAttribute>( isolate, world, name.LocalName(), value, source_url, position, type); } @@ -86,7 +86,7 @@ EventListener* CreateAttributeEventListener(LocalFrame* frame, if (value.IsNull()) return nullptr; - if (!frame->GetDocument()->CanExecuteScripts(kAboutToExecuteScript)) + if (!frame->DomWindow()->CanExecuteScripts(kAboutToExecuteScript)) return nullptr; TextPosition position = frame->GetScriptController().EventHandlerPosition(); diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_function.cc b/chromium/third_party/blink/renderer/bindings/core/v8/script_function.cc index 94f862354d0..2cb44fb0034 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/script_function.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_function.cc @@ -9,7 +9,7 @@ namespace blink { -void ScriptFunction::Trace(Visitor* visitor) { +void ScriptFunction::Trace(Visitor* visitor) const { visitor->Trace(script_state_); CustomWrappableAdapter::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_function.h b/chromium/third_party/blink/renderer/bindings/core/v8/script_function.h index ed38826808e..91b186a0844 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/script_function.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_function.h @@ -54,7 +54,7 @@ class CORE_EXPORT ScriptFunction : public CustomWrappableAdapter { public: ~ScriptFunction() override = default; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; const char* NameInHeapSnapshot() const override { return "ScriptFunction"; } 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 f98cf313e7a..4bc39c11009 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 @@ -64,7 +64,7 @@ class PromiseAllHandler final : public GarbageCollected<PromiseAllHandler> { } } - virtual void Trace(Visitor* visitor) { + virtual void Trace(Visitor* visitor) const { visitor->Trace(resolver_); visitor->Trace(values_); } @@ -95,7 +95,7 @@ class PromiseAllHandler final : public GarbageCollected<PromiseAllHandler> { index_(index), handler_(handler) {} - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(handler_); ScriptFunction::Trace(visitor); } 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 6d317926d95..37385c2267a 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 @@ -124,7 +124,7 @@ class CORE_EXPORT ScriptPromise final { static ScriptPromise All(ScriptState*, const HeapVector<ScriptPromise>& promises); - void Trace(Visitor* visitor) { + void Trace(Visitor* visitor) const { visitor->Trace(promise_); visitor->Trace(script_state_); } @@ -142,7 +142,7 @@ class CORE_EXPORT ScriptPromise final { void Reject(v8::Local<v8::Value>); void Clear() { resolver_.Clear(); } ScriptState* GetScriptState() const { return script_state_; } - void Trace(Visitor* visitor) { + void Trace(Visitor* visitor) const { visitor->Trace(script_state_); visitor->Trace(resolver_); } diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_property.h b/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_property.h index 49ec9edc0d8..7a7174306b8 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_property.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_property.h @@ -160,7 +160,7 @@ class ScriptPromiseProperty final } } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { TraceIfNeeded<ResolvedType>::Trace(visitor, resolved_); TraceIfNeeded<RejectedType>::Trace(visitor, rejected_); visitor->Trace(resolvers_); 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 ecbc62a5549..56567fc475b 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 @@ -87,7 +87,7 @@ class GarbageCollectedHolder final : public GarbageCollectedScriptWrappable { return this; } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(property_); GarbageCollectedScriptWrappable::Trace(visitor); } @@ -111,7 +111,7 @@ class ScriptPromisePropertyResetter : public ScriptFunction { ScriptPromisePropertyResetter(ScriptState* script_state, Property* property) : ScriptFunction(script_state), property_(property) {} - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(property_); ScriptFunction::Trace(visitor); } diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_resolver.cc b/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_resolver.cc index eaadad2287b..e170073772d 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_resolver.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_resolver.cc @@ -116,7 +116,7 @@ void ScriptPromiseResolver::ResolveOrRejectDeferred() { ResolveOrRejectImmediately(); } -void ScriptPromiseResolver::Trace(Visitor* visitor) { +void ScriptPromiseResolver::Trace(Visitor* visitor) const { visitor->Trace(script_state_); visitor->Trace(resolver_); visitor->Trace(value_); diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h b/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h index e9f6431d8b1..ff66b4cf2c2 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h @@ -97,7 +97,7 @@ class CORE_EXPORT ScriptPromiseResolver // promise is pending and the associated ExecutionContext isn't stopped. void KeepAliveWhilePending(); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: typedef ScriptPromise::InternalResolver Resolver; 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 47e74683c9f..926840df7ae 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 @@ -310,7 +310,7 @@ TEST_F(ScriptPromiseResolverTest, suspend) { BlinkGC::kNoHeapPointersOnStack); ASSERT_TRUE(ScriptPromiseResolverKeepAlive::IsAlive()); - GetExecutionContext()->SetLifecycleState(mojom::FrameLifecycleState::kFrozen); + page_holder_->GetPage().SetPaused(true); resolver->Resolve("hello"); ThreadState::Current()->CollectAllGarbageForTesting( BlinkGC::kNoHeapPointersOnStack); diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_tester.cc b/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_tester.cc index c9f005bd171..41600d39f94 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_tester.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_tester.cc @@ -74,7 +74,7 @@ ScriptValue ScriptPromiseTester::Value() const { return value_; } -void ScriptPromiseTester::Trace(Visitor* visitor) { +void ScriptPromiseTester::Trace(Visitor* visitor) const { visitor->Trace(script_state_); visitor->Trace(value_); } diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_tester.h b/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_tester.h index 63a52f1673e..ee5315a0ae8 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_tester.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_tester.h @@ -40,7 +40,7 @@ class ScriptPromiseTester final { // The value the promise fulfilled or rejected with. ScriptValue Value() const; - void Trace(Visitor*); + void Trace(Visitor*) const; private: class ThenFunction; diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_source_code.cc b/chromium/third_party/blink/renderer/bindings/core/v8/script_source_code.cc index 38d117601d6..ab15d685078 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/script_source_code.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_source_code.cc @@ -66,7 +66,7 @@ ScriptSourceCode::ScriptSourceCode( const TextPosition& start_position) : source_(TreatNullSourceAsEmpty(source)), cache_handler_(cache_handler), - not_streaming_reason_(ScriptStreamer::kInlineScript), + not_streaming_reason_(ScriptStreamer::NotStreamingReason::kInlineScript), url_(StripFragmentIdentifier(url)), start_position_(start_position), source_location_type_(source_location_type) { @@ -107,14 +107,15 @@ ScriptSourceCode::ScriptSourceCode(const String& source, const KURL& url) : source_(TreatNullSourceAsEmpty(ParkableString(source.Impl()))), cache_handler_(cache_handler), - not_streaming_reason_(ScriptStreamer::kWorkerTopLevelScript), + not_streaming_reason_( + ScriptStreamer::NotStreamingReason::kWorkerTopLevelScript), url_(url), start_position_(TextPosition::MinimumPosition()), source_location_type_(ScriptSourceLocationType::kUnknown) {} ScriptSourceCode::~ScriptSourceCode() = default; -void ScriptSourceCode::Trace(Visitor* visitor) { +void ScriptSourceCode::Trace(Visitor* visitor) const { visitor->Trace(cache_handler_); visitor->Trace(streamer_); } 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 f7e38a00d20..e8582e35350 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 @@ -93,7 +93,7 @@ class CORE_EXPORT ScriptSourceCode final { const KURL&); ~ScriptSourceCode(); - void Trace(Visitor*); + void Trace(Visitor*) const; const ParkableString& Source() const { return source_; } SingleCachedMetadataHandler* CacheHandler() const { return cache_handler_; } 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 248d559730e..2d8b732dfc5 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 @@ -50,13 +50,12 @@ class SourceStream : public v8::ScriptCompiler::ExternalSourceStream { DCHECK(!IsMainThread()); CHECK(ready_to_run_.IsSet()); - if (finished_) { + if (load_state_ != ScriptStreamer::LoadingState::kLoading) { return 0; } if (cancelled_.IsSet()) { - SendLoadingFinishedCallback( - &ResponseBodyLoaderClient::DidCancelLoadingBody); + SetFinished(ScriptStreamer::LoadingState::kCancelled); return 0; } @@ -137,15 +136,13 @@ class SourceStream : public v8::ScriptCompiler::ExternalSourceStream { if (result != MOJO_RESULT_OK) { // If the producer handle was closed, then treat as EOF. CHECK_EQ(result, MOJO_RESULT_FAILED_PRECONDITION); - SendLoadingFinishedCallback( - &ResponseBodyLoaderClient::DidFinishLoadingBody); + SetFinished(ScriptStreamer::LoadingState::kLoaded); return 0; } // We were blocked, so check for cancelation again. if (cancelled_.IsSet()) { - SendLoadingFinishedCallback( - &ResponseBodyLoaderClient::DidCancelLoadingBody); + SetFinished(ScriptStreamer::LoadingState::kCancelled); return 0; } @@ -155,14 +152,12 @@ class SourceStream : public v8::ScriptCompiler::ExternalSourceStream { case MOJO_RESULT_FAILED_PRECONDITION: // If the producer handle was closed, then treat as EOF. - SendLoadingFinishedCallback( - &ResponseBodyLoaderClient::DidFinishLoadingBody); + SetFinished(ScriptStreamer::LoadingState::kLoaded); return 0; default: // Some other error occurred. - SendLoadingFinishedCallback( - &ResponseBodyLoaderClient::DidFailLoadingBody); + SetFinished(ScriptStreamer::LoadingState::kFailed); return 0; } } @@ -170,13 +165,13 @@ class SourceStream : public v8::ScriptCompiler::ExternalSourceStream { void DrainRemainingDataWithoutStreaming() { DCHECK(!IsMainThread()); - if (!finished_) { + if (load_state_ == ScriptStreamer::LoadingState::kLoading) { // Keep reading data until we finish (returning 0). It won't be streaming // compiled any more, but it will continue being forwarded to the client. while (GetMoreData(nullptr) != 0) { } } - CHECK(finished_); + CHECK_NE(load_state_, ScriptStreamer::LoadingState::kLoading); } void Cancel() { @@ -231,31 +226,31 @@ class SourceStream : public v8::ScriptCompiler::ExternalSourceStream { ready_to_run_.Set(); } + ScriptStreamer::LoadingState LoadingState() const { return load_state_; } + private: static void NotifyClientDidReceiveData( ResponseBodyLoaderClient* response_body_loader_client, std::unique_ptr<char[]> data, uint32_t data_size) { + // The response_body_loader_client is held weakly, so it may be dead by the + // time this callback is called. If so, we can simply drop this chunk. + if (!response_body_loader_client) + return; + response_body_loader_client->DidReceiveData( base::make_span(data.get(), data_size)); } - void SendLoadingFinishedCallback( - void (ResponseBodyLoaderClient::*callback)()) { - DCHECK(!IsMainThread()); - CHECK(!finished_); - PostCrossThreadTask( - *loading_task_runner_, FROM_HERE, - CrossThreadBindOnce(callback, response_body_loader_client_)); - finished_ = true; - } + void SetFinished(ScriptStreamer::LoadingState state) { load_state_ = state; } // TODO(leszeks): Make this a DCHECK-only flag. base::AtomicFlag ready_to_run_; base::AtomicFlag cancelled_; // Only used by background thread - bool finished_ = false; + ScriptStreamer::LoadingState load_state_ = + ScriptStreamer::LoadingState::kLoading; // The initial data that was already on the Resource, rather than being read // directly from the data pipe. @@ -294,24 +289,47 @@ bool ScriptStreamer::ConvertEncoding( return false; } +bool ScriptStreamer::IsStreamingStarted() const { + DCHECK(IsMainThread()); + return !!stream_; +} + +bool ScriptStreamer::IsStreamingSuppressed() const { + DCHECK(IsMainThread()); + return suppressed_reason_ != NotStreamingReason::kInvalid; +} + +bool ScriptStreamer::IsLoaded() const { + DCHECK(IsMainThread()); + return loading_state_ != LoadingState::kLoading; +} + +bool ScriptStreamer::CanStartStreaming() const { + DCHECK(IsMainThread()); + return !IsStreamingStarted() && !IsStreamingSuppressed(); +} + bool ScriptStreamer::IsFinished() const { DCHECK(IsMainThread()); - return loading_finished_ && (parsing_finished_ || streaming_suppressed_); + // We are finished when we know that we won't start streaming later (either + // because we are streaming already or streaming was suppressed). + return IsLoaded() && !CanStartStreaming(); } -bool ScriptStreamer::IsStreamingFinished() const { +bool ScriptStreamer::IsClientDetached() const { DCHECK(IsMainThread()); - return parsing_finished_ || streaming_suppressed_; + return !response_body_loader_client_; } -void ScriptStreamer::StreamingCompleteOnBackgroundThread() { +void ScriptStreamer::StreamingCompleteOnBackgroundThread(LoadingState state) { DCHECK(!IsMainThread()); // notifyFinished might already be called, or it might be called in the // future (if the parsing finishes earlier because of a parse error). - PostCrossThreadTask(*loading_task_runner_, FROM_HERE, - CrossThreadBindOnce(&ScriptStreamer::StreamingComplete, - WrapCrossThreadPersistent(this))); + PostCrossThreadTask( + *loading_task_runner_, FROM_HERE, + CrossThreadBindOnce(&ScriptStreamer::StreamingComplete, + WrapCrossThreadPersistent(this), state)); // The task might be the only remaining reference to the ScriptStreamer, and // there's no way to guarantee that this function has returned before the task @@ -324,25 +342,21 @@ void ScriptStreamer::Cancel() { // still be ongoing. Tell SourceStream to try to cancel it whenever it gets // the control the next time. It can also be that V8 has already completed // its operations and streamingComplete will be called soon. - detached_ = true; + response_body_loader_client_.Release(); + script_resource_.Release(); if (stream_) stream_->Cancel(); + CHECK(IsClientDetached()); } void ScriptStreamer::SuppressStreaming(NotStreamingReason reason) { DCHECK(IsMainThread()); - DCHECK(!loading_finished_); - DCHECK_NE(reason, NotStreamingReason::kInvalid); - - // It can be that the parsing task has already finished (e.g., if there was - // a parse error). - streaming_suppressed_ = true; + CHECK_EQ(suppressed_reason_, NotStreamingReason::kInvalid); + CHECK_NE(reason, NotStreamingReason::kInvalid); suppressed_reason_ = reason; } -namespace { - -void RunScriptStreamingTask( +void ScriptStreamer::RunScriptStreamingTask( std::unique_ptr<v8::ScriptCompiler::ScriptStreamingTask> task, ScriptStreamer* streamer, SourceStream* stream) { @@ -369,7 +383,13 @@ void RunScriptStreamingTask( "v8,devtools.timeline," TRACE_DISABLED_BY_DEFAULT("v8.compile"), "v8.parseOnBackgroundParsing"); - streamer->StreamingCompleteOnBackgroundThread(); + // Send a single callback back to the streamer signifying that the streaming + // is complete, and how it completed (success/fail/cancelled). The streamer + // will forward the state to the client on the main thread. We don't send the + // success/fail/cancelled client callback in separate tasks, as they can kill + // the (context-specific) task runner, which would make this StreamingComplete + // afterward fail to post. + streamer->StreamingCompleteOnBackgroundThread(stream->LoadingState()); TRACE_EVENT_END0( "v8,devtools.timeline," TRACE_DISABLED_BY_DEFAULT("v8.compile"), @@ -382,8 +402,6 @@ void RunScriptStreamingTask( "v8.parseOnBackground2"); } -} // namespace - bool ScriptStreamer::HasEnoughDataForStreaming(size_t resource_buffer_size) { if (base::FeatureList::IsEnabled(features::kSmallScriptStreaming)) { return resource_buffer_size >= kMaximumLengthOfBOM; @@ -393,9 +411,9 @@ bool ScriptStreamer::HasEnoughDataForStreaming(size_t resource_buffer_size) { } } -// Try to start streaming the script from the given datapipe, taking ownership -// of the datapipe and weak ownership of the client. Returns true if streaming -// succeeded and false otherwise. +// Try to start a task streaming the script from the datapipe, with the task +// taking ownership of the datapipe and weak ownership of the client. Returns +// true if streaming succeeded and false otherwise. // // Streaming may fail to start because: // @@ -405,26 +423,21 @@ bool ScriptStreamer::HasEnoughDataForStreaming(size_t resource_buffer_size) { // * V8 failed to create a script streamer // // If this method returns true, the datapipe handle will be cleared and the -// streamer becomes responsible for draining the datapipe and forwarding data -// to the client. Otherwise, the caller should continue as if this were a no-op. -bool ScriptStreamer::TryStartStreaming( - mojo::ScopedDataPipeConsumerHandle* data_pipe, - ResponseBodyLoaderClient* response_body_loader_client) { +// streaming task becomes responsible for draining the datapipe and forwarding +// data to the client. Otherwise, we should continue as if this were a no-op. +bool ScriptStreamer::TryStartStreamingTask() { DCHECK(IsMainThread()); - if (streaming_suppressed_) - return false; - if (stream_) + if (!CanStartStreaming()) return false; - DCHECK(!have_enough_data_for_streaming_); - - // Even if the first data chunk is small, the script can still be big - // enough - wait until the next data chunk comes before deciding whether - // to start the streaming. - DCHECK(script_resource_->ResourceBuffer()); - if (!HasEnoughDataForStreaming(script_resource_->ResourceBuffer()->size())) + // Even if the first data chunk is small, the script can still be big enough - + // wait until the next data chunk comes before deciding whether to start the + // streaming. + if (!script_resource_->ResourceBuffer() || + !HasEnoughDataForStreaming(script_resource_->ResourceBuffer()->size())) { + CHECK(!IsLoaded()); return false; - have_enough_data_for_streaming_ = true; + } { // Check for BOM (byte order marks), because that might change our @@ -449,7 +462,7 @@ bool ScriptStreamer::TryStartStreaming( // Also note that have at least s_smallScriptThreshold worth of // data, which is more than enough for detecting a BOM. if (!ConvertEncoding(decoder->Encoding().GetName(), &encoding_)) { - SuppressStreaming(kEncodingNotSupported); + SuppressStreaming(NotStreamingReason::kEncodingNotSupported); return false; } } @@ -458,9 +471,9 @@ bool ScriptStreamer::TryStartStreaming( // The resource has a code cache entry, so it's unnecessary to stream // and parse the code. // TODO(leszeks): Can we even reach this code path with data pipes? - SuppressStreaming(ScriptStreamer::kHasCodeCache); stream_ = nullptr; source_.reset(); + SuppressStreaming(ScriptStreamer::NotStreamingReason::kHasCodeCache); return false; } @@ -480,9 +493,9 @@ bool ScriptStreamer::TryStartStreaming( compile_options_))); if (!script_streaming_task) { // V8 cannot stream the script. - SuppressStreaming(kV8CannotStream); stream_ = nullptr; source_.reset(); + SuppressStreaming(NotStreamingReason::kV8CannotStream); return false; } @@ -493,8 +506,11 @@ bool ScriptStreamer::TryStartStreaming( this->ScriptURLString())); stream_->TakeDataAndPipeOnMainThread( - script_resource_, this, std::move(*data_pipe), - response_body_loader_client, loading_task_runner_); + script_resource_, this, std::move(data_pipe_), + response_body_loader_client_.Get(), loading_task_runner_); + + // This reset will also cancel the watcher. + watcher_.reset(); // Script streaming tasks are high priority, as they can block the parser, // and they can (and probably will) block during their own execution as @@ -510,117 +526,228 @@ bool ScriptStreamer::TryStartStreaming( return true; } -void ScriptStreamer::NotifyFinished() { - DCHECK(IsMainThread()); - - // A special case: empty and small scripts. We didn't receive enough data to - // start the streaming before this notification. In that case, there won't - // be a "parsing complete" notification either, and we should not wait for - // it. - if (!have_enough_data_for_streaming_) { - SuppressStreaming(kScriptTooSmall); - } - - loading_finished_ = true; - - NotifyFinishedToClient(); -} - ScriptStreamer::ScriptStreamer( ScriptResource* script_resource, + mojo::ScopedDataPipeConsumerHandle data_pipe, + ResponseBodyLoaderClient* response_body_loader_client, v8::ScriptCompiler::CompileOptions compile_options, scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner) : script_resource_(script_resource), - detached_(false), - stream_(nullptr), - loading_finished_(false), - parsing_finished_(false), - have_enough_data_for_streaming_(false), - streaming_suppressed_(false), - suppressed_reason_(kInvalid), + response_body_loader_client_(response_body_loader_client), + data_pipe_(std::move(data_pipe)), compile_options_(compile_options), script_url_string_(script_resource->Url().Copy().GetString()), script_resource_identifier_(script_resource->InspectorId()), // Unfortunately there's no dummy encoding value in the enum; let's use // one we don't stream. encoding_(v8::ScriptCompiler::StreamedSource::TWO_BYTE), - loading_task_runner_(std::move(loading_task_runner)) {} + loading_task_runner_(std::move(loading_task_runner)) { + watcher_ = std::make_unique<mojo::SimpleWatcher>( + FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::MANUAL, + loading_task_runner_); + + watcher_->Watch(data_pipe_.get(), MOJO_HANDLE_SIGNAL_READABLE, + MOJO_TRIGGER_CONDITION_SIGNALS_SATISFIED, + WTF::BindRepeating(&ScriptStreamer::OnDataPipeReadable, + WrapWeakPersistent(this))); + + MojoResult ready_result; + mojo::HandleSignalsState ready_state; + MojoResult rv = watcher_->Arm(&ready_result, &ready_state); + if (rv == MOJO_RESULT_OK) + return; + + DCHECK_EQ(MOJO_RESULT_FAILED_PRECONDITION, rv); + OnDataPipeReadable(ready_result, ready_state); +} + +void ScriptStreamer::OnDataPipeReadable(MojoResult result, + const mojo::HandleSignalsState& state) { + if (IsClientDetached()) + return; + + switch (result) { + case MOJO_RESULT_OK: + // All good, so read the data that we were notified that we received. + break; + + case MOJO_RESULT_CANCELLED: + // The consumer handle got closed, which means this script is done + // loading, and did so without streaming (otherwise the watcher wouldn't + // have been armed, and the handle ownership would have passed to the + // streaming task. + watcher_.reset(); + LoadCompleteWithoutStreaming(LoadingState::kCancelled, + NotStreamingReason::kLoadingCancelled); + return; + + case MOJO_RESULT_FAILED_PRECONDITION: + // This means the producer finished and we never started streaming. This + // must be because we suppressed streaming earlier, or never got enough + // data to start streaming. + CHECK(IsStreamingSuppressed() || !script_resource_->ResourceBuffer() || + !HasEnoughDataForStreaming( + script_resource_->ResourceBuffer()->size())); + watcher_.reset(); + // Pass kScriptTooSmall for the !IsStreamingSuppressed() case, it won't + // override an existing streaming reason. + LoadCompleteWithoutStreaming(LoadingState::kLoaded, + NotStreamingReason::kScriptTooSmall); + return; + + case MOJO_RESULT_SHOULD_WAIT: + NOTREACHED(); + return; + + default: + // Some other error occurred. + watcher_.reset(); + LoadCompleteWithoutStreaming(LoadingState::kFailed, + NotStreamingReason::kErrorOccurred); + return; + } + CHECK(state.readable()); + CHECK(data_pipe_); + + const void* data; + uint32_t data_size; + MojoReadDataFlags flags_to_pass = MOJO_READ_DATA_FLAG_NONE; + MojoResult begin_read_result = + data_pipe_->BeginReadData(&data, &data_size, flags_to_pass); + // There should be data, so this read should succeed. + CHECK_EQ(begin_read_result, MOJO_RESULT_OK); + + response_body_loader_client_->DidReceiveData( + base::make_span(reinterpret_cast<const char*>(data), data_size)); + + MojoResult end_read_result = data_pipe_->EndReadData(data_size); + + CHECK_EQ(end_read_result, MOJO_RESULT_OK); + + if (TryStartStreamingTask()) { + return; + } + + // TODO(leszeks): Depending on how small the chunks are, we may want to + // loop until a certain number of bytes are synchronously read rather than + // going back to the scheduler. + watcher_->ArmOrNotify(); +} ScriptStreamer::~ScriptStreamer() = default; void ScriptStreamer::Prefinalize() { + // Reset and cancel the watcher. This has to be called in the prefinalizer, + // rather than relying on the destructor, as accesses by the watcher of the + // script resource between prefinalization and destruction are invalid. See + // https://crbug.com/905975#c34 for more details. + watcher_.reset(); + + // Cancel any on-going streaming. Cancel(); - prefinalizer_called_ = true; } -void ScriptStreamer::Trace(Visitor* visitor) { +void ScriptStreamer::Trace(Visitor* visitor) const { visitor->Trace(script_resource_); + visitor->Trace(response_body_loader_client_); } -void ScriptStreamer::StreamingComplete() { +void ScriptStreamer::StreamingComplete(LoadingState loading_state) { TRACE_EVENT_WITH_FLOW2( TRACE_DISABLED_BY_DEFAULT("v8.compile"), "v8.streamingCompile.complete", this, TRACE_EVENT_FLAG_FLOW_IN, "streaming_suppressed", - streaming_suppressed_, "data", + IsStreamingSuppressed(), "data", inspector_parse_script_event::Data(this->ScriptResourceIdentifier(), this->ScriptURLString())); // The background task is completed; do the necessary ramp-down in the main // thread. DCHECK(IsMainThread()); - parsing_finished_ = true; - - // It's possible that the corresponding Resource was deleted before V8 - // finished streaming. In that case, the data or the notification is not - // needed. In addition, if the streaming is suppressed, the non-streaming - // code path will resume after the resource has loaded, before the - // background task finishes. - if (detached_ || streaming_suppressed_) - return; - // We have now streamed the whole script to V8 and it has parsed the - // script. We're ready for the next step: compiling and executing the - // script. - NotifyFinishedToClient(); -} + AdvanceLoadingState(loading_state); -void ScriptStreamer::NotifyFinishedToClient() { - DCHECK(IsMainThread()); - // Usually, the loading will be finished first, and V8 will still need some - // time to catch up. But the other way is possible too: if V8 detects a - // parse error, the V8 side can complete before loading has finished. Send - // the notification after both loading and V8 side operations have + // Sending a finished notification to the client also indicates that streaming // completed. - if (!IsFinished()) - return; + SendClientLoadFinishedCallback(); +} - script_resource_->StreamingFinished(); +void ScriptStreamer::LoadCompleteWithoutStreaming( + LoadingState state, + NotStreamingReason no_streaming_reason) { + // We might have previously suppressed streaming, in which case we want to + // keep the previous reason and not re-suppress. + if (!IsStreamingSuppressed()) { + SuppressStreaming(no_streaming_reason); + } + AdvanceLoadingState(state); + SendClientLoadFinishedCallback(); } -ScriptStreamer* ScriptStreamer::Create( - ScriptResource* resource, - scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner, - NotStreamingReason* not_streaming_reason) { - DCHECK(IsMainThread()); - *not_streaming_reason = kInvalid; - if (!resource->Url().ProtocolIsInHTTPFamily()) { - *not_streaming_reason = kNotHTTP; - return nullptr; +void ScriptStreamer::SendClientLoadFinishedCallback() { + // Don't do anything if we're detached, there's no client to send signals to. + if (IsClientDetached()) + return; + + CHECK(IsFinished()); + + switch (loading_state_) { + case LoadingState::kLoading: + CHECK(false); + break; + case LoadingState::kCancelled: + response_body_loader_client_->DidCancelLoadingBody(); + break; + case LoadingState::kFailed: + response_body_loader_client_->DidFailLoadingBody(); + break; + case LoadingState::kLoaded: + response_body_loader_client_->DidFinishLoadingBody(); + break; } - if (resource->IsLoaded() && !resource->ResourceBuffer()) { - // This happens for already loaded resources, e.g. if resource - // validation fails. In that case, the loading subsystem will discard - // the resource buffer. - *not_streaming_reason = kNoResourceBuffer; - return nullptr; + + response_body_loader_client_.Release(); +} + +void ScriptStreamer::AdvanceLoadingState(LoadingState new_state) { + switch (loading_state_) { + case LoadingState::kLoading: + CHECK(new_state == LoadingState::kLoaded || + new_state == LoadingState::kFailed || + new_state == LoadingState::kCancelled); + break; + case LoadingState::kLoaded: + case LoadingState::kFailed: + case LoadingState::kCancelled: + CHECK(false); + break; } - // We cannot filter out short scripts, even if we wait for the HTTP headers - // to arrive: the Content-Length HTTP header is not sent for chunked - // downloads. - return MakeGarbageCollected<ScriptStreamer>( - resource, v8::ScriptCompiler::kNoCompileOptions, - std::move(loading_task_runner)); + loading_state_ = new_state; + CheckState(); +} + +void ScriptStreamer::CheckState() const { + switch (loading_state_) { + case LoadingState::kLoading: + // If we are still loading, we either + // 1) Are still waiting for enough data to come in to start streaming, + // 2) Have already started streaming, or + // 3) Have suppressed streaming. + // TODO(leszeks): This check, with the current implementation, always + // returns true. We should either try to check something stronger, or get + // rid of it. + CHECK(CanStartStreaming() || IsStreamingStarted() || + IsStreamingSuppressed()); + break; + case LoadingState::kLoaded: + case LoadingState::kFailed: + case LoadingState::kCancelled: + // Otherwise, if we aren't still loading, we either + // 1) Have already started streaming, or + // 2) Have suppressed streaming. + CHECK(IsStreamingStarted() || IsStreamingSuppressed()); + break; + } } } // namespace blink 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 3818d966729..bf042780c45 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 @@ -15,6 +15,10 @@ #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "v8/include/v8.h" +namespace mojo { +class SimpleWatcher; +} + namespace blink { class ScriptResource; @@ -22,12 +26,9 @@ class SourceStream; class ResponseBodyLoaderClient; // ScriptStreamer streams incomplete script data to V8 so that it can be parsed -// while it's loaded. ScriptResource holds a reference to ScriptStreamer. -// At the moment, ScriptStreamer is only used for parser blocking scripts; this -// means that the Document stays stable and no other scripts are executing -// while we're streaming. It is possible, though, that Document and the -// ClassicPendingScript are destroyed while the streaming is in progress, and -// ScriptStreamer handles it gracefully. +// while it's loaded. ScriptResource holds a reference to ScriptStreamer. If the +// Document and the ClassicPendingScript are destroyed while the streaming is in +// progress, and ScriptStreamer handles it gracefully. class CORE_EXPORT ScriptStreamer final : public GarbageCollected<ScriptStreamer> { USING_PRE_FINALIZER(ScriptStreamer, Prefinalize); @@ -36,7 +37,7 @@ class CORE_EXPORT ScriptStreamer final // For tracking why some scripts are not streamed. Not streaming is part of // normal operation (e.g., script already loaded, script too small) and // doesn't necessarily indicate a failure. - enum NotStreamingReason { + enum class NotStreamingReason { kAlreadyLoaded, // DEPRECATED kNotHTTP, kRevalidate, @@ -49,36 +50,39 @@ class CORE_EXPORT ScriptStreamer final kHasCodeCache, kStreamerNotReadyOnGetSource, // DEPRECATED kInlineScript, - kDidntTryToStartStreaming, + kDidntTryToStartStreaming, // DEPRECATED kErrorOccurred, kStreamingDisabled, kSecondScriptResourceUse, kWorkerTopLevelScript, kModuleScript, + kNoDataPipe, + kLoadingCancelled, + kDisabledByFeatureList, // Pseudo values that should never be seen in reported metrics - kCount, + kMaxValue = kDisabledByFeatureList, kInvalid = -1, }; - ScriptStreamer(ScriptResource*, - v8::ScriptCompiler::CompileOptions, - scoped_refptr<base::SingleThreadTaskRunner>); + ScriptStreamer( + ScriptResource* resource, + mojo::ScopedDataPipeConsumerHandle data_pipe, + ResponseBodyLoaderClient* response_body_loader_client, + v8::ScriptCompiler::CompileOptions compile_options, + scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner); ~ScriptStreamer(); - void Trace(Visitor*); - - // Create a script streamer which will stream the given ScriptResource into V8 - // as it loads. - static ScriptStreamer* Create(ScriptResource*, - scoped_refptr<base::SingleThreadTaskRunner>, - NotStreamingReason* not_streaming_reason); + void Trace(Visitor*) const; // Returns false if we cannot stream the given encoding. static bool ConvertEncoding(const char* encoding_name, v8::ScriptCompiler::StreamedSource::Encoding*); - bool IsFinished() const; // Has loading & streaming finished? - bool IsStreamingFinished() const; // Has streaming finished? + bool IsStreamingStarted() const; // Have we actually started streaming? + bool CanStartStreaming() const; // Can we still start streaming later? + bool IsLoaded() const; // Has loading finished? + bool IsFinished() const; // Has loading & streaming finished? + bool IsStreamingSuppressed() const; // Has streaming been suppressed? v8::ScriptCompiler::StreamedSource* Source() { return source_.get(); } @@ -88,36 +92,11 @@ class CORE_EXPORT ScriptStreamer final // deleting itself (after the V8 side has finished too). void Cancel(); - // When the streaming is suppressed, the data is not given to V8, but - // ScriptStreamer still watches the resource load and notifies the upper - // layers when loading is finished. It is used in situations when we have - // started streaming but then we detect we don't want to stream (e.g., when - // we have the code cache for the script) and we still want to parse and - // execute it when it has finished loading. - void SuppressStreaming(NotStreamingReason reason); - bool StreamingSuppressed() const { - DCHECK(!streaming_suppressed_ || suppressed_reason_ != kInvalid); - return streaming_suppressed_; - } NotStreamingReason StreamingSuppressedReason() const { - DCHECK(streaming_suppressed_ || suppressed_reason_ == kInvalid); + CheckState(); return suppressed_reason_; } - // Called by ScriptResource when data arrives from the network. - bool TryStartStreaming(mojo::ScopedDataPipeConsumerHandle* data_pipe, - ResponseBodyLoaderClient* response_body_loader_client); - - // Called by ScriptResource when loading has completed. - // - // Should not be called synchronously, as it can trigger script resource - // client callbacks. - void NotifyFinished(); - - // Called by ScriptStreamingTask when it has streamed all data to V8 and V8 - // has processed it. - void StreamingCompleteOnBackgroundThread(); - const String& ScriptURLString() const { return script_url_string_; } uint64_t ScriptResourceIdentifier() const { return script_resource_identifier_; @@ -128,39 +107,99 @@ class CORE_EXPORT ScriptStreamer final } private: + friend class SourceStream; + + // Valid loading state transitions: + // + // kLoading + // .--------|---------. + // | | | + // v v v + // kLoaded kFailed kCancelled + enum class LoadingState { kLoading, kLoaded, kFailed, kCancelled }; + + static const char* str(LoadingState state) { + switch (state) { + case LoadingState::kLoading: + return "Loading"; + case LoadingState::kLoaded: + return "Loaded"; + case LoadingState::kFailed: + return "Failed"; + case LoadingState::kCancelled: + return "Cancelled"; + } + } + // Scripts whose first data chunk is smaller than this constant won't be // streamed. Non-const for testing. static size_t small_script_threshold_; // Maximum size of the BOM marker. static constexpr size_t kMaximumLengthOfBOM = 4; + static void RunScriptStreamingTask( + std::unique_ptr<v8::ScriptCompiler::ScriptStreamingTask> task, + ScriptStreamer* streamer, + SourceStream* stream); + + void OnDataPipeReadable(MojoResult result, + const mojo::HandleSignalsState& state); + + // Given the data we have collected already, try to start an actual V8 + // streaming task. Returns true if the task was started. + bool TryStartStreamingTask(); + void Prefinalize(); - // Should not be called synchronously, as it can trigger script resource - // client callbacks. - void StreamingComplete(); - // Should not be called synchronously, as it can trigger script resource - // client callbacks. - void NotifyFinishedToClient(); + // When the streaming is suppressed, the data is not given to V8, but + // ScriptStreamer still watches the resource load and notifies the upper + // layers when loading is finished. It is used in situations when we have + // started streaming but then we detect we don't want to stream (e.g., when + // we have the code cache for the script) and we still want to parse and + // execute it when it has finished loading. + void SuppressStreaming(NotStreamingReason reason); + + // Called by ScriptStreamingTask when it has streamed all data to V8 and V8 + // has processed it. + void StreamingCompleteOnBackgroundThread(LoadingState loading_state); + + // The four methods below should not be called synchronously, as they can + // trigger script resource client callbacks. + + // Streaming completed with loading in the given |state|. + void StreamingComplete(LoadingState loading_state); + // Loading completed in the given state, without ever starting streaming. + void LoadCompleteWithoutStreaming(LoadingState loading_state, + NotStreamingReason no_streaming_reason); + // Helper for the above methods to notify the client that loading has + // completed in the given state. Streaming is guaranteed to either have + // completed or be suppressed. + void SendClientLoadFinishedCallback(); + bool HasEnoughDataForStreaming(size_t resource_buffer_size); + // Has the script streamer been detached from its client. If true, then we can + // safely abort loading and not output any more data. + bool IsClientDetached() const; + + void AdvanceLoadingState(LoadingState new_state); + void CheckState() const; + + LoadingState loading_state_ = LoadingState::kLoading; + Member<ScriptResource> script_resource_; - // Whether ScriptStreamer is detached from the Resource. In those cases, the - // script data is not needed any more, and the client won't get notified - // when the loading and streaming are done. - bool detached_; + Member<ResponseBodyLoaderClient> response_body_loader_client_; - SourceStream* stream_; + // Fields active during asynchronous (non-streaming) reads. + mojo::ScopedDataPipeConsumerHandle data_pipe_; + std::unique_ptr<mojo::SimpleWatcher> watcher_; + + // Fields active during streaming. + SourceStream* stream_ = nullptr; std::unique_ptr<v8::ScriptCompiler::StreamedSource> source_; - bool loading_finished_; // Whether loading from the network is done. - bool parsing_finished_; // Whether the V8 side processing is done. - // Whether we have received enough data to start the streaming. - bool have_enough_data_for_streaming_; - // Whether the script source code should be retrieved from the Resource - // instead of the ScriptStreamer. - bool streaming_suppressed_; - NotStreamingReason suppressed_reason_; + // The reason that streaming is disabled + NotStreamingReason suppressed_reason_ = NotStreamingReason::kInvalid; // What kind of cached data V8 produces during streaming. v8::ScriptCompiler::CompileOptions compile_options_; @@ -176,12 +215,6 @@ class CORE_EXPORT ScriptStreamer final 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; - DISALLOW_COPY_AND_ASSIGN(ScriptStreamer); }; 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 50588ef4dbb..8eec7e0125b 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 @@ -147,11 +147,12 @@ class ScriptStreamingTest : public testing::Test { ScriptSourceCode GetScriptSourceCode() const { ScriptStreamer* streamer = resource_->TakeStreamer(); if (streamer) { - if (streamer->StreamingSuppressed()) { + if (streamer->IsStreamingSuppressed()) { return ScriptSourceCode(nullptr, resource_, streamer->StreamingSuppressedReason()); } - return ScriptSourceCode(streamer, resource_, ScriptStreamer::kInvalid); + return ScriptSourceCode(streamer, resource_, + ScriptStreamer::NotStreamingReason::kInvalid); } return ScriptSourceCode(nullptr, resource_, resource_->NoStreamerReason()); } @@ -210,8 +211,6 @@ class ScriptStreamingTest : public testing::Test { TEST_F(ScriptStreamingTest, DISABLED_CompilingStreamedScript) { // Test that we can successfully compile a streamed script. V8TestingScope scope; - resource_->StartStreaming(loading_task_runner_); - resource_->SetClientIsWaitingForFinished(); AppendData("function foo() {"); AppendPadding(); @@ -248,8 +247,6 @@ TEST_F(ScriptStreamingTest, DISABLED_CompilingStreamedScriptWithParseError) { // Test that scripts with parse errors are handled properly. In those cases, // V8 stops reading the network stream: make sure we handle it gracefully. V8TestingScope scope; - resource_->StartStreaming(loading_task_runner_); - resource_->SetClientIsWaitingForFinished(); AppendData("function foo() {"); AppendData("this is the part which will be a parse error"); // V8 won't realize the parse error until it actually starts parsing the @@ -286,8 +283,6 @@ TEST_F(ScriptStreamingTest, DISABLED_CancellingStreaming) { // Test that the upper layers (PendingScript and up) can be ramped down // while streaming is ongoing, and ScriptStreamer handles it gracefully. V8TestingScope scope; - resource_->StartStreaming(loading_task_runner_); - resource_->SetClientIsWaitingForFinished(); AppendData("function foo() {"); // In general, we cannot control what the background thread is doing @@ -311,8 +306,6 @@ TEST_F(ScriptStreamingTest, DISABLED_DataAfterDisposingPendingScript) { // Test that the upper layers (PendingScript and up) can be ramped down // before streaming is started, and ScriptStreamer handles it gracefully. V8TestingScope scope; - resource_->StartStreaming(loading_task_runner_); - resource_->SetClientIsWaitingForFinished(); // 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 @@ -346,8 +339,6 @@ TEST_F(ScriptStreamingTest, DISABLED_SuppressingStreaming) { // upper layer (ScriptResourceClient) should get a notification when the // script is loaded. V8TestingScope scope; - resource_->StartStreaming(loading_task_runner_); - resource_->SetClientIsWaitingForFinished(); SingleCachedMetadataHandler* cache_handler = resource_->CacheHandler(); EXPECT_TRUE(cache_handler); @@ -375,8 +366,6 @@ TEST_F(ScriptStreamingTest, DISABLED_EmptyScripts) { // (ScriptResourceClient) should be notified when an empty script has been // loaded. V8TestingScope scope; - resource_->StartStreaming(loading_task_runner_); - resource_->SetClientIsWaitingForFinished(); // Finish the script without sending any data. Finish(); @@ -394,9 +383,6 @@ TEST_F(ScriptStreamingTest, DISABLED_SmallScripts) { V8TestingScope scope; ScriptStreamer::SetSmallScriptThresholdForTesting(100); - resource_->StartStreaming(loading_task_runner_); - resource_->SetClientIsWaitingForFinished(); - AppendData("function foo() { }"); Finish(); @@ -415,9 +401,6 @@ TEST_F(ScriptStreamingTest, DISABLED_ScriptsWithSmallFirstChunk) { V8TestingScope scope; ScriptStreamer::SetSmallScriptThresholdForTesting(100); - resource_->StartStreaming(loading_task_runner_); - resource_->SetClientIsWaitingForFinished(); - // This is the first data chunk which is small. AppendData("function foo() { }"); AppendPadding(); @@ -453,9 +436,6 @@ TEST_F(ScriptStreamingTest, DISABLED_EncodingChanges) { V8TestingScope scope; resource_->SetEncodingForTest("windows-1252"); - resource_->StartStreaming(loading_task_runner_); - resource_->SetClientIsWaitingForFinished(); - resource_->SetEncodingForTest("UTF-8"); // \xec\x92\x81 are the raw bytes for \uc481. AppendData( @@ -493,9 +473,6 @@ TEST_F(ScriptStreamingTest, DISABLED_EncodingFromBOM) { // This encoding is wrong on purpose. resource_->SetEncodingForTest("windows-1252"); - resource_->StartStreaming(loading_task_runner_); - resource_->SetClientIsWaitingForFinished(); - // \xef\xbb\xbf is the UTF-8 byte order mark. \xec\x92\x81 are the raw bytes // for \uc481. AppendData( @@ -527,9 +504,7 @@ TEST_F(ScriptStreamingTest, DISABLED_EncodingFromBOM) { // A test for crbug.com/711703. Should not crash. TEST_F(ScriptStreamingTest, DISABLED_GarbageCollectDuringStreaming) { V8TestingScope scope; - resource_->StartStreaming(loading_task_runner_); - resource_->SetClientIsWaitingForFinished(); EXPECT_FALSE(resource_client_->Finished()); resource_ = nullptr; @@ -541,9 +516,6 @@ TEST_F(ScriptStreamingTest, DISABLED_GarbageCollectDuringStreaming) { // currently unable to block and wait for the script streaming thread. TEST_F(ScriptStreamingTest, DISABLED_ResourceSetRevalidatingRequest) { V8TestingScope scope; - resource_->StartStreaming(loading_task_runner_); - - resource_->SetClientIsWaitingForFinished(); // Kick the streaming off. AppendData("function foo() {"); @@ -552,18 +524,18 @@ TEST_F(ScriptStreamingTest, DISABLED_ResourceSetRevalidatingRequest) { Finish(); ProcessTasksUntilStreamingComplete(); - // Second start streaming should fail. - resource_->StartStreaming(loading_task_runner_); + // Should be done streaming by now. + EXPECT_TRUE(resource_->HasStreamer()); EXPECT_FALSE(resource_->HasRunningStreamer()); ResourceRequest request(resource_->Url()); resource_->SetRevalidatingRequest(request); - // The next streaming should still fail, but the reason should be + // Now there shouldn't be a streamer at all, and the reason should be // "kRevalidate". - resource_->StartStreaming(loading_task_runner_); - EXPECT_FALSE(resource_->HasRunningStreamer()); - EXPECT_EQ(resource_->NoStreamerReason(), ScriptStreamer::kRevalidate); + EXPECT_FALSE(resource_->HasStreamer()); + EXPECT_EQ(resource_->NoStreamerReason(), + ScriptStreamer::NotStreamingReason::kRevalidate); } } // namespace 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 6b828e17ba1..86fa0b6c18b 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 @@ -153,7 +153,7 @@ class CORE_EXPORT ScriptValue final { static ScriptValue CreateNull(v8::Isolate*); - void Trace(Visitor* visitor) { visitor->Trace(value_); } + void Trace(Visitor* visitor) const { visitor->Trace(value_); } private: v8::Isolate* isolate_ = nullptr; diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_color_params.cc b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_color_params.cc index ce665a4a177..2eacec18fa6 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_color_params.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_color_params.cc @@ -19,9 +19,6 @@ SerializedColorParams::SerializedColorParams(CanvasColorParams color_params) { case CanvasColorSpace::kSRGB: color_space_ = SerializedColorSpace::kSRGB; break; - case CanvasColorSpace::kLinearRGB: - color_space_ = SerializedColorSpace::kLinearRGB; - break; case CanvasColorSpace::kRec2020: color_space_ = SerializedColorSpace::kRec2020; break; @@ -83,9 +80,6 @@ CanvasColorParams SerializedColorParams::GetCanvasColorParams() const { case SerializedColorSpace::kSRGB: color_space = CanvasColorSpace::kSRGB; break; - case SerializedColorSpace::kLinearRGB: - color_space = CanvasColorSpace::kLinearRGB; - break; case SerializedColorSpace::kRec2020: color_space = CanvasColorSpace::kRec2020; break; diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_color_params.h b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_color_params.h index 4c47c3af96a..512df80ae8e 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_color_params.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_color_params.h @@ -41,8 +41,7 @@ enum class SerializedColorSpace : uint32_t { kSRGB = 1, kRec2020 = 2, kP3 = 3, - kLinearRGB = 4, - kLast = kLinearRGB, + kLast = kP3, }; // This enumeration specifies the values used to serialize CanvasPixelFormat. diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/unpacked_serialized_script_value.cc b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/unpacked_serialized_script_value.cc index a565ca00aee..ce4ffc32e44 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/unpacked_serialized_script_value.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/unpacked_serialized_script_value.cc @@ -45,7 +45,7 @@ UnpackedSerializedScriptValue::UnpackedSerializedScriptValue( UnpackedSerializedScriptValue::~UnpackedSerializedScriptValue() = default; -void UnpackedSerializedScriptValue::Trace(Visitor* visitor) { +void UnpackedSerializedScriptValue::Trace(Visitor* visitor) const { visitor->Trace(array_buffers_); visitor->Trace(image_bitmaps_); } diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/unpacked_serialized_script_value.h b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/unpacked_serialized_script_value.h index 9037cde7088..45a0fce1b7d 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/unpacked_serialized_script_value.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/unpacked_serialized_script_value.h @@ -42,7 +42,7 @@ class CORE_EXPORT UnpackedSerializedScriptValue final explicit UnpackedSerializedScriptValue(scoped_refptr<SerializedScriptValue>); ~UnpackedSerializedScriptValue(); - void Trace(Visitor*); + void Trace(Visitor*) const; SerializedScriptValue* Value() { return value_.get(); } const SerializedScriptValue* Value() const { return value_.get(); } 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 a6418f7df03..c28b65cc49a 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 @@ -531,9 +531,7 @@ bool V8ScriptValueSerializer::WriteDOMObject(ScriptWrappable* wrappable, "because it was not transferred."); return false; } - if (stream->IsLocked(script_state_, exception_state).value_or(true)) { - if (exception_state.HadException()) - return false; + if (stream->IsLocked()) { exception_state.ThrowDOMException( DOMExceptionCode::kDataCloneError, "A ReadableStream could not be cloned because it was locked"); @@ -582,12 +580,7 @@ bool V8ScriptValueSerializer::WriteDOMObject(ScriptWrappable* wrappable, "because it was not transferred."); return false; } - if (stream->Readable() - ->IsLocked(script_state_, exception_state) - .value_or(true) || - stream->Writable()->locked()) { - if (exception_state.HadException()) - return false; + if (stream->Readable()->locked() || stream->Writable()->locked()) { exception_state.ThrowDOMException( DOMExceptionCode::kDataCloneError, "A TransformStream could not be cloned because it was locked"); 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 351a330fb94..0025284fdf6 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 @@ -1043,9 +1043,10 @@ TEST(V8ScriptValueSerializerTest, RoundTripImageBitmap) { TEST(V8ScriptValueSerializerTest, RoundTripImageBitmapWithColorSpaceInfo) { V8TestingScope scope; // Make a 10x7 red ImageBitmap in P3 color space. - SkImageInfo info = SkImageInfo::Make( - 10, 7, kRGBA_F16_SkColorType, kPremul_SkAlphaType, - SkColorSpace::MakeRGB(SkNamedTransferFn::kLinear, SkNamedGamut::kDCIP3)); + SkImageInfo info = + SkImageInfo::Make(10, 7, kRGBA_F16_SkColorType, kPremul_SkAlphaType, + SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, + SkNamedGamut::kDisplayP3)); sk_sp<SkSurface> surface = SkSurface::MakeRaster(info); surface->getCanvas()->clear(SK_ColorRED); auto* image_bitmap = MakeGarbageCollected<ImageBitmap>( @@ -1067,7 +1068,7 @@ TEST(V8ScriptValueSerializerTest, RoundTripImageBitmapWithColorSpaceInfo) { EXPECT_EQ(CanvasPixelFormat::kF16, color_params.PixelFormat()); // Check that the pixel at (3, 3) is red. We expect red in P3 to be - // {0x94, 0x3A, 0x3F, 0x28, 0x5F, 0x24, 0x00, 0x3C} when each color + // {0x57, 0x3B, 0x68, 0x32, 0x6E, 0x30, 0x00, 0x3C} when each color // component is presented as a half float in Skia. However, difference in // GPU hardware may result in small differences in lower significant byte in // Skia color conversion pipeline. Hence, we use a tolerance of 2 here. @@ -1076,7 +1077,7 @@ TEST(V8ScriptValueSerializerTest, RoundTripImageBitmapWithColorSpaceInfo) { ->PaintImageForCurrentFrame() .GetSkImage() ->readPixels(info.makeWH(1, 1), &pixel, 8, 3, 3)); - uint8_t p3_red[8] = {0x94, 0x3A, 0x3F, 0x28, 0x5F, 0x24, 0x00, 0x3C}; + uint8_t p3_red[8] = {0x57, 0x3B, 0x68, 0x32, 0x6E, 0x30, 0x00, 0x3C}; bool approximate_match = true; uint8_t tolerance = 2; for (int i = 0; i < 8; i++) { @@ -1149,9 +1150,10 @@ TEST(V8ScriptValueSerializerTest, DecodeImageBitmapV18) { // Check that the pixel at (1, 0) is red. uint8_t pixel[8] = {}; - SkImageInfo info = SkImageInfo::Make( - 1, 1, kRGBA_F16_SkColorType, kPremul_SkAlphaType, - SkColorSpace::MakeRGB(SkNamedTransferFn::kLinear, SkNamedGamut::kDCIP3)); + SkImageInfo info = + SkImageInfo::Make(1, 1, kRGBA_F16_SkColorType, kPremul_SkAlphaType, + SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, + SkNamedGamut::kDisplayP3)); ASSERT_TRUE(new_image_bitmap->BitmapImage() ->PaintImageForCurrentFrame() .GetSkImage() @@ -1900,8 +1902,8 @@ TEST(V8ScriptValueSerializerTest, RoundTripReadableStream) { ReadableStream* transferred = V8ReadableStream::ToImpl(result.As<v8::Object>()); EXPECT_NE(rs, transferred); - EXPECT_TRUE(rs->locked(script_state, ASSERT_NO_EXCEPTION)); - EXPECT_FALSE(transferred->locked(script_state, ASSERT_NO_EXCEPTION)); + EXPECT_TRUE(rs->locked()); + EXPECT_FALSE(transferred->locked()); } TEST(V8ScriptValueSerializerTest, RoundTripDOMException) { diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/to_v8_test.cc b/chromium/third_party/blink/renderer/bindings/core/v8/to_v8_test.cc index 924dfa2ba73..219ca42cf6f 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/to_v8_test.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/to_v8_test.cc @@ -49,7 +49,7 @@ class GarbageCollectedHolderForToV8Test GarbageCollectedScriptWrappable* script_wrappable) : script_wrappable_(script_wrappable) {} - void Trace(Visitor* visitor) { visitor->Trace(script_wrappable_); } + void Trace(Visitor* visitor) const { visitor->Trace(script_wrappable_); } // This should be public in order to access a Member<X> object. Member<GarbageCollectedScriptWrappable> script_wrappable_; diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/trace_wrapper_v8_reference_test.cc b/chromium/third_party/blink/renderer/bindings/core/v8/trace_wrapper_v8_reference_test.cc index 8521450c7ab..ca368f684ce 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/trace_wrapper_v8_reference_test.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/trace_wrapper_v8_reference_test.cc @@ -29,7 +29,7 @@ class TraceWrapperV8ReferenceHolder final TraceWrapperV8ReferenceHolder(const TraceWrapperV8ReferenceHolder& other) : value_(other.value_) {} - virtual void Trace(Visitor* visitor) { visitor->Trace(value_); } + virtual void Trace(Visitor* visitor) const { visitor->Trace(value_); } TraceWrapperV8Reference<v8::Value>* ref() { return &value_; } 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 c762c48b488..2d907ef0b22 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 @@ -327,6 +327,18 @@ void UseCounterCallback(v8::Isolate* isolate, blink_feature = WebFeature::kV8InvalidatedTypedArraySpeciesLookupChainProtector; break; + case v8::Isolate::kVarRedeclaredCatchBinding: + blink_feature = WebFeature::kV8VarRedeclaredCatchBinding; + break; + case v8::Isolate::kWasmRefTypes: + blink_feature = WebFeature::kV8WasmRefTypes; + break; + case v8::Isolate::kWasmBulkMemory: + blink_feature = WebFeature::kV8WasmBulkMemory; + break; + case v8::Isolate::kWasmMultiValue: + blink_feature = WebFeature::kV8WasmMultiValue; + break; default: // This can happen if V8 has added counters that this version of Blink diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_code_cache.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_code_cache.cc index a29ede17964..11d6e43cac5 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_code_cache.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_code_cache.cc @@ -278,7 +278,7 @@ void V8CodeCache::ProduceCache(v8::Isolate* isolate, source_url, source_start_position, false, "v8.compileModule", produce_cache_data->GetProduceCacheOptions(), - ScriptStreamer::kModuleScript); + ScriptStreamer::NotStreamingReason::kModuleScript); } uint32_t V8CodeCache::TagForCodeCache( @@ -360,7 +360,7 @@ scoped_refptr<CachedMetadata> V8CodeCache::GenerateFullCodeCache( cached_data ? cached_data->length : 0), base::Optional<inspector_compile_script_event::V8CacheResult:: ConsumeResult>()), - false, ScriptStreamer::kHasCodeCache)); + false, ScriptStreamer::NotStreamingReason::kHasCodeCache)); return cached_metadata; } 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 b11f42b632b..78cfd886edd 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 @@ -170,6 +170,7 @@ v8::Local<FunctionOrTemplate> CreateAccessorFunctionOrTemplate( v8::Local<v8::Signature>, const char* name, AccessorType, + V8DOMConfiguration::AccessCheckConfiguration access_check_configuration, v8::SideEffectType side_effect_type = v8::SideEffectType::kHasSideEffect); template <> @@ -182,6 +183,7 @@ CreateAccessorFunctionOrTemplate<v8::FunctionTemplate>( v8::Local<v8::Signature> signature, const char* name, AccessorType type, + V8DOMConfiguration::AccessCheckConfiguration access_check_configuration, v8::SideEffectType side_effect_type) { v8::Local<v8::FunctionTemplate> function_template; if (callback) { @@ -208,7 +210,8 @@ CreateAccessorFunctionOrTemplate<v8::FunctionTemplate>( if (!function_template.IsEmpty()) { function_template->RemovePrototype(); - function_template->SetAcceptAnyReceiver(false); + function_template->SetAcceptAnyReceiver( + access_check_configuration == V8DOMConfiguration::kDoNotCheckAccess); // https://heycam.github.io/webidl/#dfn-attribute-getter has: // @@ -245,6 +248,7 @@ v8::Local<v8::Function> CreateAccessorFunctionOrTemplate<v8::Function>( v8::Local<v8::Signature> signature, const char* name, AccessorType type, + V8DOMConfiguration::AccessCheckConfiguration access_check_configuration, v8::SideEffectType side_effect_type) { if (!callback) return v8::Local<v8::Function>(); @@ -252,7 +256,7 @@ v8::Local<v8::Function> CreateAccessorFunctionOrTemplate<v8::Function>( v8::Local<v8::FunctionTemplate> function_template = CreateAccessorFunctionOrTemplate<v8::FunctionTemplate>( isolate, callback, V8PrivateProperty::CachedAccessor::kNone, data, - signature, name, type, side_effect_type); + signature, name, type, access_check_configuration, side_effect_type); if (function_template.IsEmpty()) return v8::Local<v8::Function>(); @@ -293,7 +297,6 @@ void InstallAccessorInternal( DCHECK(!IsObjectAndEmpty(instance_or_template) || !IsObjectAndEmpty(prototype_or_template) || !IsObjectAndEmpty(interface_or_template)); - DCHECK_EQ(config.getter_behavior, V8DOMConfiguration::kAlwaysCallGetter); if (!WorldConfigurationApplies(config, world)) return; @@ -317,6 +320,13 @@ void InstallAccessorInternal( V8DOMConfiguration::kDoNotCheckHolder) signature = v8::Local<v8::Signature>(); + V8DOMConfiguration::AccessCheckConfiguration getter_access_check = + static_cast<V8DOMConfiguration::AccessCheckConfiguration>( + config.getter_access_check_configuration); + V8DOMConfiguration::AccessCheckConfiguration setter_access_check = + static_cast<V8DOMConfiguration::AccessCheckConfiguration>( + config.setter_access_check_configuration); + const unsigned location = config.property_location_configuration; v8::SideEffectType getter_side_effect_type = config.getter_side_effect_type == V8DOMConfiguration::kHasNoSideEffect @@ -329,12 +339,12 @@ void InstallAccessorInternal( CreateAccessorFunctionOrTemplate<FunctionOrTemplate>( isolate, getter_callback, cached_property_key, v8::Local<v8::Value>(), signature, config.name, - AccessorType::Getter, getter_side_effect_type); + AccessorType::Getter, getter_access_check, getter_side_effect_type); v8::Local<FunctionOrTemplate> setter = CreateAccessorFunctionOrTemplate<FunctionOrTemplate>( isolate, setter_callback, V8PrivateProperty::CachedAccessor::kNone, v8::Local<v8::Value>(), signature, config.name, - AccessorType::Setter); + AccessorType::Setter, setter_access_check); if (location & V8DOMConfiguration::kOnInstance && !IsObjectAndEmpty(instance_or_template)) { instance_or_template->SetAccessorProperty( @@ -357,12 +367,12 @@ void InstallAccessorInternal( CreateAccessorFunctionOrTemplate<FunctionOrTemplate>( isolate, getter_callback, V8PrivateProperty::CachedAccessor::kNone, v8::Local<v8::Value>(), v8::Local<v8::Signature>(), config.name, - AccessorType::Getter, getter_side_effect_type); + AccessorType::Getter, getter_access_check, getter_side_effect_type); v8::Local<FunctionOrTemplate> setter = CreateAccessorFunctionOrTemplate<FunctionOrTemplate>( isolate, setter_callback, V8PrivateProperty::CachedAccessor::kNone, v8::Local<v8::Value>(), v8::Local<v8::Signature>(), config.name, - AccessorType::Setter); + AccessorType::Setter, setter_access_check); interface_or_template->SetAccessorProperty( name, getter, setter, static_cast<v8::PropertyAttribute>(config.attribute)); @@ -480,8 +490,9 @@ void InstallMethodInternal(v8::Isolate* isolate, isolate, callback, v8::Local<v8::Value>(), signature, method.length, v8::ConstructorBehavior::kAllow, side_effect_type); function_template->RemovePrototype(); - if (method.access_check_configuration == V8DOMConfiguration::kCheckAccess) - function_template->SetAcceptAnyReceiver(false); + function_template->SetAcceptAnyReceiver( + method.access_check_configuration == + V8DOMConfiguration::kDoNotCheckAccess); if (method.property_location_configuration & V8DOMConfiguration::kOnInstance) { AddMethodToTemplate(isolate, instance_template, function_template, @@ -548,9 +559,9 @@ void InstallMethodInternal( isolate, callback, v8::Local<v8::Value>(), signature, config.length, v8::ConstructorBehavior::kAllow, side_effect_type); function_template->RemovePrototype(); - if (config.access_check_configuration == V8DOMConfiguration::kCheckAccess) { - function_template->SetAcceptAnyReceiver(false); - } + function_template->SetAcceptAnyReceiver( + config.access_check_configuration == + V8DOMConfiguration::kDoNotCheckAccess); v8::Local<v8::Function> function = function_template->GetFunction(isolate->GetCurrentContext()) .ToLocalChecked(); 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 cbfe522d05b..af6f5c59683 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 @@ -153,10 +153,11 @@ class CORE_EXPORT V8DOMConfiguration final { unsigned property_location_configuration : 3; // HolderCheckConfiguration unsigned holder_check_configuration : 1; + // AccessCheckConfiguration + unsigned getter_access_check_configuration : 1; + unsigned setter_access_check_configuration : 1; // SideEffectConfiguration unsigned getter_side_effect_type : 1; - // AttributeGetterBehavior (should always be kReplaceWithDataProperty) - unsigned getter_behavior : 1; // WorldConfiguration unsigned world_configuration : 2; }; diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_embedder_graph_builder.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_embedder_graph_builder.cc index 5f1ac751ab6..e3eff49b276 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_embedder_graph_builder.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_embedder_graph_builder.cc @@ -6,7 +6,7 @@ #include "third_party/blink/renderer/bindings/core/v8/active_script_wrappable.h" #include "third_party/blink/renderer/bindings/core/v8/v8_gc_controller.h" #include "third_party/blink/renderer/bindings/core/v8/v8_node.h" -#include "third_party/blink/renderer/core/dom/document.h" +#include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/platform/bindings/active_script_wrappable_manager.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h" @@ -24,11 +24,11 @@ using Graph = v8::EmbedderGraph; // Information about whether a node is attached to the main DOM tree // or not. It is computed as follows: -// 1) A Document with IsContextDestroyed() = true is detached. -// 2) A Document with IsContextDestroyed() = false is attached. -// 3) A Node that is not connected to any Document is detached. -// 4) A Node that is connected to a detached Document is detached. -// 5) A Node that is connected to an attached Document is attached. +// 1) A ExecutionContext with IsContextDestroyed() = true is detached. +// 2) A ExecutionContext with IsContextDestroyed() = false is attached. +// 3) A Node that is not connected to any ExecutionContext is detached. +// 4) A Node that is connected to a detached ExecutionContext is detached. +// 5) A Node that is connected to an attached ExecutionContext is attached. // 6) A ScriptWrappable that is reachable from an attached Node is // attached. // 7) A ScriptWrappable that is reachable from a detached Node is @@ -46,10 +46,8 @@ DomTreeState DomTreeStateFromWrapper(v8::Isolate* isolate, return DomTreeState::kUnknown; Node* node = V8Node::ToImpl(v8_value); Node* root = V8GCController::OpaqueRootForGC(isolate, node); - if (root->isConnected() && - !node->GetDocument().MasterDocument().IsContextDestroyed()) { + if (root->isConnected() && node->GetExecutionContext()) return DomTreeState::kAttached; - } return DomTreeState::kDetached; } 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 25c100ae493..9f666b417ad 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 @@ -61,7 +61,7 @@ namespace blink { Node* V8GCController::OpaqueRootForGC(v8::Isolate*, Node* node) { DCHECK(node); if (node->isConnected()) - return &node->GetDocument().MasterDocument(); + return &node->GetDocument().TreeRootDocument(); if (auto* attr = DynamicTo<Attr>(node)) { Node* owner_element = attr->ownerElement(); diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_intersection_observer_delegate.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_intersection_observer_delegate.cc index e60cc9a0986..115da7c7ad9 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_intersection_observer_delegate.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_intersection_observer_delegate.cc @@ -32,7 +32,7 @@ ExecutionContext* V8IntersectionObserverDelegate::GetExecutionContext() const { return ExecutionContextClient::GetExecutionContext(); } -void V8IntersectionObserverDelegate::Trace(Visitor* visitor) { +void V8IntersectionObserverDelegate::Trace(Visitor* visitor) const { visitor->Trace(callback_); IntersectionObserverDelegate::Trace(visitor); ExecutionContextClient::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_intersection_observer_delegate.h b/chromium/third_party/blink/renderer/bindings/core/v8/v8_intersection_observer_delegate.h index dc1faee0221..00ea286f2f0 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_intersection_observer_delegate.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_intersection_observer_delegate.h @@ -28,7 +28,7 @@ class V8IntersectionObserverDelegate final ExecutionContext* GetExecutionContext() const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; IntersectionObserver::DeliveryBehavior GetDeliveryBehavior() const override { return IntersectionObserver::kPostTaskToDeliver; 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 5e62b87b1ea..94dfa0ba5bd 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 @@ -118,7 +118,7 @@ v8::MaybeLocal<v8::Script> CompileScriptInternal( // Streaming compilation may involve use of code cache. // TODO(leszeks): Add compile timer to streaming compilation. DCHECK(streamer->IsFinished()); - DCHECK(!streamer->StreamingSuppressed()); + DCHECK(!streamer->IsStreamingSuppressed()); return v8::ScriptCompiler::Compile(isolate->GetCurrentContext(), streamer->Source(), code, origin); } @@ -310,7 +310,7 @@ v8::MaybeLocal<v8::Module> V8ScriptRunner::CompileModule( TRACE_EVENT_END1(kTraceEventCategoryGroup, "v8.compileModule", "data", inspector_compile_script_event::Data( file_name, start_position, cache_result, false, - ScriptStreamer::kModuleScript)); + ScriptStreamer::NotStreamingReason::kModuleScript)); return script; } 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 62ac47f1166..acfd0ccaf41 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 @@ -98,13 +98,11 @@ class V8ScriptRunnerTest : public testing::Test { ScriptResource* CreateEmptyResource() { ScriptResource* resource = ScriptResource::CreateForTest(NullURL(), UTF8Encoding()); - resource->SetClientIsWaitingForFinished(); return resource; } ScriptResource* CreateResource(const WTF::TextEncoding& encoding) { ScriptResource* resource = ScriptResource::CreateForTest(Url(), encoding); - resource->SetClientIsWaitingForFinished(); String code = Code(); ResourceResponse response(Url()); response.SetHttpStatusCode(200); @@ -172,8 +170,9 @@ TEST_F(V8ScriptRunnerTest, emptyResourceDoesNotHaveCacheHandler) { TEST_F(V8ScriptRunnerTest, codeOption) { V8TestingScope scope; - ScriptSourceCode source_code(nullptr, CreateResource(UTF8Encoding()), - ScriptStreamer::kScriptTooSmall); + ScriptSourceCode source_code( + nullptr, CreateResource(UTF8Encoding()), + ScriptStreamer::NotStreamingReason::kScriptTooSmall); SingleCachedMetadataHandler* cache_handler = source_code.CacheHandler(); SetCacheTimeStamp(cache_handler); @@ -192,8 +191,9 @@ TEST_F(V8ScriptRunnerTest, consumeCodeOptionWithoutDiscarding) { feature_list_.InitAndDisableFeature( blink::features::kDiscardCodeCacheAfterFirstUse); V8TestingScope scope; - ScriptSourceCode source_code(nullptr, CreateResource(UTF8Encoding()), - ScriptStreamer::kScriptTooSmall); + ScriptSourceCode source_code( + nullptr, CreateResource(UTF8Encoding()), + ScriptStreamer::NotStreamingReason::kScriptTooSmall); // Set timestamp to simulate a warm run. SingleCachedMetadataHandler* cache_handler = source_code.CacheHandler(); SetCacheTimeStamp(cache_handler); @@ -225,8 +225,9 @@ TEST_F(V8ScriptRunnerTest, consumeCodeOptionWithDiscarding) { feature_list_.InitAndEnableFeature( blink::features::kDiscardCodeCacheAfterFirstUse); V8TestingScope scope; - ScriptSourceCode source_code(nullptr, CreateResource(UTF8Encoding()), - ScriptStreamer::kScriptTooSmall); + ScriptSourceCode source_code( + nullptr, CreateResource(UTF8Encoding()), + ScriptStreamer::NotStreamingReason::kScriptTooSmall); // Set timestamp to simulate a warm run. SingleCachedMetadataHandler* cache_handler = source_code.CacheHandler(); SetCacheTimeStamp(cache_handler); @@ -267,8 +268,9 @@ TEST_F(V8ScriptRunnerTest, produceAndConsumeCodeOptionWithoutDiscarding) { feature_list_.InitAndDisableFeature( blink::features::kDiscardCodeCacheAfterFirstUse); V8TestingScope scope; - ScriptSourceCode source_code(nullptr, CreateResource(UTF8Encoding()), - ScriptStreamer::kScriptTooSmall); + ScriptSourceCode source_code( + nullptr, CreateResource(UTF8Encoding()), + ScriptStreamer::NotStreamingReason::kScriptTooSmall); SingleCachedMetadataHandler* cache_handler = source_code.CacheHandler(); // Cold run - should set the timestamp. @@ -303,8 +305,9 @@ TEST_F(V8ScriptRunnerTest, produceAndConsumeCodeOptionWithDiscarding) { feature_list_.InitAndEnableFeature( blink::features::kDiscardCodeCacheAfterFirstUse); V8TestingScope scope; - ScriptSourceCode source_code(nullptr, CreateResource(UTF8Encoding()), - ScriptStreamer::kScriptTooSmall); + ScriptSourceCode source_code( + nullptr, CreateResource(UTF8Encoding()), + ScriptStreamer::NotStreamingReason::kScriptTooSmall); SingleCachedMetadataHandler* cache_handler = source_code.CacheHandler(); // Cold run - should set the timestamp. @@ -340,8 +343,9 @@ TEST_F(V8ScriptRunnerTest, cacheRequestedBeforeProduced) { feature_list_.InitAndEnableFeature( blink::features::kDiscardCodeCacheAfterFirstUse); V8TestingScope scope; - ScriptSourceCode source_code(nullptr, CreateResource(UTF8Encoding()), - ScriptStreamer::kScriptTooSmall); + ScriptSourceCode source_code( + nullptr, CreateResource(UTF8Encoding()), + ScriptStreamer::NotStreamingReason::kScriptTooSmall); SingleCachedMetadataHandler* cache_handler = source_code.CacheHandler(); base::HistogramTester tester; HistogramCounter counter(tester); @@ -355,8 +359,9 @@ TEST_F(V8ScriptRunnerTest, cacheDataTypeMismatch) { feature_list_.InitAndEnableFeature( blink::features::kDiscardCodeCacheAfterFirstUse); V8TestingScope scope; - ScriptSourceCode source_code(nullptr, CreateResource(UTF8Encoding()), - ScriptStreamer::kScriptTooSmall); + ScriptSourceCode source_code( + nullptr, CreateResource(UTF8Encoding()), + ScriptStreamer::NotStreamingReason::kScriptTooSmall); SingleCachedMetadataHandler* cache_handler = source_code.CacheHandler(); EXPECT_FALSE( cache_handler->GetCachedMetadata(TagForTimeStamp(cache_handler))); diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_string_resource.h b/chromium/third_party/blink/renderer/bindings/core/v8/v8_string_resource.h index b775a207003..cbf0530131a 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_string_resource.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_string_resource.h @@ -30,6 +30,7 @@ #include "third_party/blink/renderer/platform/bindings/string_resource.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" #include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" +#include "third_party/blink/renderer/platform/wtf/text/string_view.h" #include "third_party/blink/renderer/platform/wtf/threading.h" #include "v8/include/v8.h" @@ -49,6 +50,9 @@ class V8StringResource { STACK_ALLOCATED(); public: + V8StringResource(const V8StringResource&) = delete; + V8StringResource& operator=(const V8StringResource&) = delete; + V8StringResource() : mode_(kExternalize) {} V8StringResource(v8::Local<v8::Value> object) @@ -80,9 +84,24 @@ class V8StringResource { PrepareSlow(v8::Isolate::GetCurrent(), exception_state); } + // Implicit conversions needed to make Blink bindings easier to use. + + // NOLINTNEXTLINE(google-explicit-constructor) operator String() const { return ToString<String>(); } + + // NOLINTNEXTLINE(google-explicit-constructor) operator AtomicString() const { return ToString<AtomicString>(); } + // NOLINTNEXTLINE(google-explicit-constructor) + operator StringView() const { + if (LIKELY(!v8_object_.IsEmpty())) { + return ToBlinkStringView(v8_object_.As<v8::String>(), backing_store_, + mode_); + } + + return g_null_atom; + } + private: bool PrepareFast() { if (v8_object_.IsEmpty()) @@ -126,9 +145,7 @@ class V8StringResource { template <class StringType> StringType ToString() const { if (LIKELY(!v8_object_.IsEmpty())) - return ToBlinkString<StringType>( - const_cast<v8::Local<v8::Value>*>(&v8_object_)->As<v8::String>(), - mode_); + return ToBlinkString<StringType>(v8_object_.As<v8::String>(), mode_); return StringType(string_); } @@ -136,6 +153,8 @@ class V8StringResource { v8::Local<v8::Value> v8_object_; ExternalMode mode_; String string_; + + mutable WTF::StringView::StackBackingStore backing_store_; }; template <> diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_v0_custom_element_lifecycle_callbacks.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_v0_custom_element_lifecycle_callbacks.cc index 0c1f83bf067..fb9ec7b35ca 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_v0_custom_element_lifecycle_callbacks.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_v0_custom_element_lifecycle_callbacks.cc @@ -235,7 +235,7 @@ void V8V0CustomElementLifecycleCallbacks::Call( receiver, 0, nullptr, isolate); } -void V8V0CustomElementLifecycleCallbacks::Trace(Visitor* visitor) { +void V8V0CustomElementLifecycleCallbacks::Trace(Visitor* visitor) const { visitor->Trace(script_state_); visitor->Trace(prototype_); visitor->Trace(created_); diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_v0_custom_element_lifecycle_callbacks.h b/chromium/third_party/blink/renderer/bindings/core/v8/v8_v0_custom_element_lifecycle_callbacks.h index aef5ac99fad..3376747456a 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_v0_custom_element_lifecycle_callbacks.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_v0_custom_element_lifecycle_callbacks.h @@ -60,7 +60,7 @@ class V8V0CustomElementLifecycleCallbacks final bool SetBinding(std::unique_ptr<V0CustomElementBinding>); - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: void Created(Element*) override; 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 10c93506fd8..1010b8be136 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 @@ -104,7 +104,7 @@ class FetchDataLoaderForWasmStreaming final : public FetchDataLoader, return AbortCompilation(); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(consumer_); visitor->Trace(client_); visitor->Trace(script_state_); @@ -170,7 +170,7 @@ class WasmDataLoaderClient final void DidFetchDataLoadFailed() override { NOTREACHED(); } void Abort() override { loader_->AbortFromClient(); } - void Trace(Visitor* visitor) override { + void Trace(Visitor* visitor) const override { visitor->Trace(loader_); FetchDataLoader::Client::Trace(visitor); } @@ -331,21 +331,12 @@ void StreamFromResponseCallback( return; } - Body::BodyLocked body_locked = response->IsBodyLocked(exception_state); - if (body_locked == Body::BodyLocked::kBroken) - return; - - if (body_locked == Body::BodyLocked::kLocked || - response->IsBodyUsed(exception_state) == Body::BodyUsed::kUsed) { - DCHECK(!exception_state.HadException()); + if (response->IsBodyLocked() || response->IsBodyUsed()) { exception_state.ThrowTypeError( "Cannot compile WebAssembly.Module from an already read Response"); return; } - if (exception_state.HadException()) - return; - if (!response->BodyBuffer()) { // Since the status is 2xx (ok), this must be status 204 (No Content), // status 205 (Reset Content) or a malformed status 200 (OK). diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/window_proxy.cc b/chromium/third_party/blink/renderer/bindings/core/v8/window_proxy.cc index 389dcd940e9..3139b74a464 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/window_proxy.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/window_proxy.cc @@ -48,7 +48,7 @@ WindowProxy::~WindowProxy() { DCHECK(lifecycle_ != Lifecycle::kContextIsInitialized); } -void WindowProxy::Trace(Visitor* visitor) { +void WindowProxy::Trace(Visitor* visitor) const { visitor->Trace(frame_); } diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/window_proxy.h b/chromium/third_party/blink/renderer/bindings/core/v8/window_proxy.h index ce6aac22126..33d85e22813 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/window_proxy.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/window_proxy.h @@ -144,7 +144,7 @@ class WindowProxy : public GarbageCollected<WindowProxy> { public: virtual ~WindowProxy(); - virtual void Trace(Visitor*); + virtual void Trace(Visitor*) const; void InitializeIfNeeded(); diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.cc b/chromium/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.cc index ba9845625ea..b302d33b3df 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.cc @@ -9,7 +9,7 @@ namespace blink { -void WindowProxyManager::Trace(Visitor* visitor) { +void WindowProxyManager::Trace(Visitor* visitor) const { visitor->Trace(frame_); visitor->Trace(window_proxy_); visitor->Trace(isolated_worlds_); diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.h b/chromium/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.h index 2022f70d723..6c190cbb96a 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/window_proxy_manager.h @@ -22,7 +22,7 @@ class SecurityOrigin; class WindowProxyManager : public GarbageCollected<WindowProxyManager> { public: - void Trace(Visitor*); + void Trace(Visitor*) const; v8::Isolate* GetIsolate() const { return isolate_; } 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 83db0d2cba8..d5e60500c21 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 @@ -491,7 +491,7 @@ void WorkerOrWorkletScriptController::RethrowExceptionFromImportedScript( error_event->error(script_state_).V8ValueFor(script_state_)); } -void WorkerOrWorkletScriptController::Trace(Visitor* visitor) { +void WorkerOrWorkletScriptController::Trace(Visitor* visitor) const { visitor->Trace(global_scope_); visitor->Trace(script_state_); } 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 cca5d53e0c4..4395290604c 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 @@ -97,7 +97,7 @@ class CORE_EXPORT WorkerOrWorkletScriptController final return rejected_promises_.get(); } - void Trace(Visitor*); + void Trace(Visitor*) const; bool IsContextInitialized() const { return script_state_ && !!script_state_->PerContextData(); diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/world_safe_v8_reference.h b/chromium/third_party/blink/renderer/bindings/core/v8/world_safe_v8_reference.h index 41ea8d61481..446a1358c41 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/world_safe_v8_reference.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/world_safe_v8_reference.h @@ -126,7 +126,7 @@ class WorldSafeV8Reference final { bool IsEmpty() const { return v8_reference_.IsEmpty(); } - void Trace(Visitor* visitor) { visitor->Trace(v8_reference_); } + void Trace(Visitor* visitor) const { visitor->Trace(v8_reference_); } WorldSafeV8Reference& operator=(const WorldSafeV8Reference<V8Type>& other) = default; diff --git a/chromium/third_party/blink/renderer/bindings/generated_in_core.gni b/chromium/third_party/blink/renderer/bindings/generated_in_core.gni index e9202507fac..bf8ab75881a 100644 --- a/chromium/third_party/blink/renderer/bindings/generated_in_core.gni +++ b/chromium/third_party/blink/renderer/bindings/generated_in_core.gni @@ -246,6 +246,8 @@ generated_interface_sources_in_core = [ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_rule_list.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_scale.cc", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_scale.h", + "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_scroll_timeline_rule.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_scroll_timeline_rule.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_skew.cc", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_skew.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_css_skew_x.cc", @@ -696,8 +698,6 @@ generated_interface_sources_in_core = [ "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_readable_stream_default_controller.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_readable_stream_default_reader.cc", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_readable_stream_default_reader.h", - "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_render_subtree_activation_event.cc", - "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_render_subtree_activation_event.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_report.cc", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_report.h", "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_report_body.cc", diff --git a/chromium/third_party/blink/renderer/bindings/generated_in_modules.gni b/chromium/third_party/blink/renderer/bindings/generated_in_modules.gni index cc26e828379..76c7f54cf17 100644 --- a/chromium/third_party/blink/renderer/bindings/generated_in_modules.gni +++ b/chromium/third_party/blink/renderer/bindings/generated_in_modules.gni @@ -217,6 +217,8 @@ generated_enumeration_sources_in_modules = [ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_presenter_type.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_public_key_credential_type.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_public_key_credential_type.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_purchase_type.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_purchase_type.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_push_encryption_key_name.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_push_encryption_key_name.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_push_permission_state.cc", @@ -520,6 +522,8 @@ generated_interface_sources_in_modules = [ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_device_motion_event_rotation_rate.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_device_orientation_event.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_device_orientation_event.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_digital_goods_service.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_digital_goods_service.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_directory_entry.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_directory_entry.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_directory_entry_sync.cc", @@ -542,8 +546,8 @@ generated_interface_sources_in_modules = [ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_element.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_encoded_video_chunk.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_encoded_video_chunk.h", - "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_enter_picture_in_picture_event.cc", - "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_enter_picture_in_picture_event.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_picture_in_picture_event.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_picture_in_picture_event.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_entry.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_entry.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_entry_sync.cc", @@ -600,8 +604,6 @@ generated_interface_sources_in_modules = [ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_file_system_handle.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_file_system_writable_file_stream.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_file_system_writable_file_stream.h", - "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_file_system_writer.cc", - "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_file_system_writer.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_file_writer.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_file_writer.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_file_writer_sync.cc", @@ -884,6 +886,8 @@ generated_interface_sources_in_modules = [ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_notification.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_notification_event.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_notification_event.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_oes_draw_buffers_indexed.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_oes_draw_buffers_indexed.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_oes_element_index_uint.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_oes_element_index_uint.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_oes_fbo_render_mipmap.cc", @@ -1198,8 +1202,8 @@ generated_interface_sources_in_modules = [ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_video_track_writer.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_virtual_keyboard.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_virtual_keyboard.h", - "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_virtual_keyboard_overlay_geometry_change_event.cc", - "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_virtual_keyboard_overlay_geometry_change_event.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_virtual_keyboard_geometry_change_event.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_virtual_keyboard_geometry_change_event.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_wake_lock.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_wake_lock.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_wake_lock_sentinel.cc", diff --git a/chromium/third_party/blink/renderer/bindings/idl_in_core.gni b/chromium/third_party/blink/renderer/bindings/idl_in_core.gni index f47f6c28699..2a569d92aeb 100644 --- a/chromium/third_party/blink/renderer/bindings/idl_in_core.gni +++ b/chromium/third_party/blink/renderer/bindings/idl_in_core.gni @@ -49,6 +49,7 @@ static_idl_files_in_core = get_path_info( "//third_party/blink/renderer/core/css/css_property_rule.idl", "//third_party/blink/renderer/core/css/css_rule.idl", "//third_party/blink/renderer/core/css/css_rule_list.idl", + "//third_party/blink/renderer/core/css/css_scroll_timeline_rule.idl", "//third_party/blink/renderer/core/css/css_style_declaration.idl", "//third_party/blink/renderer/core/css/css_style_rule.idl", "//third_party/blink/renderer/core/css/css_style_sheet.idl", @@ -102,7 +103,6 @@ static_idl_files_in_core = get_path_info( "//third_party/blink/renderer/core/css/style_media.idl", "//third_party/blink/renderer/core/css/style_sheet.idl", "//third_party/blink/renderer/core/css/style_sheet_list.idl", - "//third_party/blink/renderer/core/display_lock/render_subtree_activation_event.idl", "//third_party/blink/renderer/core/dom/abort_controller.idl", "//third_party/blink/renderer/core/dom/abort_signal.idl", "//third_party/blink/renderer/core/dom/accessibility_role.idl", diff --git a/chromium/third_party/blink/renderer/bindings/idl_in_modules.gni b/chromium/third_party/blink/renderer/bindings/idl_in_modules.gni index eb0c40b5117..87e82f56f8a 100644 --- a/chromium/third_party/blink/renderer/bindings/idl_in_modules.gni +++ b/chromium/third_party/blink/renderer/bindings/idl_in_modules.gni @@ -62,6 +62,7 @@ static_idl_files_in_modules = get_path_info( "//third_party/blink/renderer/modules/bluetooth/bluetooth_uuid.idl", "//third_party/blink/renderer/modules/bluetooth/navigator_bluetooth.idl", "//third_party/blink/renderer/modules/bluetooth/request_device_options.idl", + "//third_party/blink/renderer/modules/bluetooth/watch_advertisements_options.idl", "//third_party/blink/renderer/modules/broadcastchannel/broadcast_channel.idl", "//third_party/blink/renderer/modules/cache_storage/cache.idl", "//third_party/blink/renderer/modules/cache_storage/cache_query_options.idl", @@ -99,13 +100,12 @@ static_idl_files_in_modules = get_path_info( "//third_party/blink/renderer/modules/content_index/service_worker_registration_content_index.idl", "//third_party/blink/renderer/modules/cookie_store/cookie_change_event.idl", "//third_party/blink/renderer/modules/cookie_store/cookie_change_event_init.idl", + "//third_party/blink/renderer/modules/cookie_store/cookie_init.idl", "//third_party/blink/renderer/modules/cookie_store/cookie_list_item.idl", "//third_party/blink/renderer/modules/cookie_store/cookie_store.idl", "//third_party/blink/renderer/modules/cookie_store/cookie_store_delete_options.idl", "//third_party/blink/renderer/modules/cookie_store/cookie_store_get_options.idl", "//third_party/blink/renderer/modules/cookie_store/cookie_store_manager.idl", - "//third_party/blink/renderer/modules/cookie_store/cookie_store_set_extra_options.idl", - "//third_party/blink/renderer/modules/cookie_store/cookie_store_set_options.idl", "//third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event.idl", "//third_party/blink/renderer/modules/cookie_store/extendable_cookie_change_event_init.idl", "//third_party/blink/renderer/modules/cookie_store/service_worker_global_scope_cookie_store.idl", @@ -375,12 +375,17 @@ static_idl_files_in_modules = get_path_info( "//third_party/blink/renderer/modules/native_file_system/file_system_handle_permission_descriptor.idl", "//third_party/blink/renderer/modules/native_file_system/file_system_remove_options.idl", "//third_party/blink/renderer/modules/native_file_system/file_system_writable_file_stream.idl", - "//third_party/blink/renderer/modules/native_file_system/file_system_writer.idl", "//third_party/blink/renderer/modules/native_file_system/get_system_directory_options.idl", "//third_party/blink/renderer/modules/native_file_system/native_file_system_directory_iterator.idl", "//third_party/blink/renderer/modules/native_file_system/native_file_system_directory_iterator_entry.idl", "//third_party/blink/renderer/modules/native_file_system/window_native_file_system.idl", + "//third_party/blink/renderer/modules/native_file_system/worker_global_scope_native_file_system.idl", "//third_party/blink/renderer/modules/native_file_system/write_params.idl", + "//third_party/blink/renderer/modules/native_file_system/file_picker_accept_type.idl", + "//third_party/blink/renderer/modules/native_file_system/file_picker_options.idl", + "//third_party/blink/renderer/modules/native_file_system/open_file_picker_options.idl", + "//third_party/blink/renderer/modules/native_file_system/save_file_picker_options.idl", + "//third_party/blink/renderer/modules/native_file_system/directory_picker_options.idl", "//third_party/blink/renderer/modules/native_io/native_io_file.idl", "//third_party/blink/renderer/modules/native_io/native_io_file_sync.idl", "//third_party/blink/renderer/modules/native_io/native_io_manager.idl", @@ -417,6 +422,9 @@ static_idl_files_in_modules = get_path_info( "//third_party/blink/renderer/modules/payments/can_make_payment_event.idl", "//third_party/blink/renderer/modules/payments/can_make_payment_event_init.idl", "//third_party/blink/renderer/modules/payments/can_make_payment_response.idl", + "//third_party/blink/renderer/modules/payments/goods/digital_goods_service.idl", + "//third_party/blink/renderer/modules/payments/goods/dom_window_digital_goods.idl", + "//third_party/blink/renderer/modules/payments/goods/item_details.idl", "//third_party/blink/renderer/modules/payments/html_iframe_element_payments.idl", "//third_party/blink/renderer/modules/payments/image_object.idl", "//third_party/blink/renderer/modules/payments/merchant_validation_event.idl", @@ -460,7 +468,9 @@ static_idl_files_in_modules = get_path_info( "//third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.idl", "//third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event.idl", "//third_party/blink/renderer/modules/peerconnection/rtc_dtmf_tone_change_event_init.idl", + "//third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame.idl", "//third_party/blink/renderer/modules/peerconnection/rtc_encoded_audio_frame_metadata.idl", + "//third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame.idl", "//third_party/blink/renderer/modules/peerconnection/rtc_encoded_video_frame_metadata.idl", "//third_party/blink/renderer/modules/peerconnection/rtc_error.idl", "//third_party/blink/renderer/modules/peerconnection/rtc_error_event.idl", @@ -525,8 +535,8 @@ static_idl_files_in_modules = get_path_info( "//third_party/blink/renderer/modules/permissions/push_permission_descriptor.idl", "//third_party/blink/renderer/modules/permissions/worker_navigator_permissions.idl", "//third_party/blink/renderer/modules/picture_in_picture/document_picture_in_picture.idl", - "//third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event.idl", - "//third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event_init.idl", + "//third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_event.idl", + "//third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_event_init.idl", "//third_party/blink/renderer/modules/picture_in_picture/html_element_picture_in_picture.idl", "//third_party/blink/renderer/modules/picture_in_picture/html_video_element_picture_in_picture.idl", "//third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_options.idl", @@ -650,8 +660,8 @@ static_idl_files_in_modules = get_path_info( "//third_party/blink/renderer/modules/video_rvfc/video_frame_request_callback.idl", "//third_party/blink/renderer/modules/virtualkeyboard/navigator_virtual_keyboard.idl", "//third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard.idl", - "//third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_overlay_geometry_change_event.idl", - "//third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_overlay_geometry_change_event_init.idl", + "//third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_geometry_change_event.idl", + "//third_party/blink/renderer/modules/virtualkeyboard/virtual_keyboard_geometry_change_event_init.idl", "//third_party/blink/renderer/modules/wake_lock/navigator_wake_lock.idl", "//third_party/blink/renderer/modules/wake_lock/wake_lock.idl", "//third_party/blink/renderer/modules/wake_lock/wake_lock_sentinel.idl", @@ -727,14 +737,14 @@ static_idl_files_in_modules = get_path_info( "//third_party/blink/renderer/modules/webcodecs/image_frame.idl", "//third_party/blink/renderer/modules/webcodecs/video_decoder.idl", "//third_party/blink/renderer/modules/webcodecs/video_decoder_init.idl", - "//third_party/blink/renderer/modules/webcodecs/video_decoder_output_callback.idl", "//third_party/blink/renderer/modules/webcodecs/video_encoder.idl", + "//third_party/blink/renderer/modules/webcodecs/video_encoder_config.idl", "//third_party/blink/renderer/modules/webcodecs/video_encoder_encode_options.idl", "//third_party/blink/renderer/modules/webcodecs/video_encoder_init.idl", "//third_party/blink/renderer/modules/webcodecs/video_encoder_output_callback.idl", - "//third_party/blink/renderer/modules/webcodecs/video_encoder_tune_options.idl", "//third_party/blink/renderer/modules/webcodecs/video_frame.idl", "//third_party/blink/renderer/modules/webcodecs/video_frame_init.idl", + "//third_party/blink/renderer/modules/webcodecs/video_frame_output_callback.idl", "//third_party/blink/renderer/modules/webcodecs/video_track_reader.idl", "//third_party/blink/renderer/modules/webcodecs/video_track_writer.idl", "//third_party/blink/renderer/modules/webcodecs/video_track_writer_parameters.idl", @@ -764,6 +774,7 @@ static_idl_files_in_modules = get_path_info( "//third_party/blink/renderer/modules/webgl/ext_texture_filter_anisotropic.idl", "//third_party/blink/renderer/modules/webgl/ext_texture_norm_16.idl", "//third_party/blink/renderer/modules/webgl/khr_parallel_shader_compile.idl", + "//third_party/blink/renderer/modules/webgl/oes_draw_buffers_indexed.idl", "//third_party/blink/renderer/modules/webgl/oes_element_index_uint.idl", "//third_party/blink/renderer/modules/webgl/oes_fbo_render_mipmap.idl", "//third_party/blink/renderer/modules/webgl/oes_standard_derivatives.idl", @@ -880,6 +891,7 @@ static_idl_files_in_modules = get_path_info( "//third_party/blink/renderer/modules/webgpu/gpu_swap_chain_descriptor.idl", "//third_party/blink/renderer/modules/webgpu/gpu_texture.idl", "//third_party/blink/renderer/modules/webgpu/gpu_texture_copy_view.idl", + "//third_party/blink/renderer/modules/webgpu/gpu_texture_data_layout.idl", "//third_party/blink/renderer/modules/webgpu/gpu_texture_descriptor.idl", "//third_party/blink/renderer/modules/webgpu/gpu_texture_usage.idl", "//third_party/blink/renderer/modules/webgpu/gpu_texture_view.idl", @@ -915,6 +927,7 @@ static_idl_files_in_modules = get_path_info( "//third_party/blink/renderer/modules/websockets/websocket_stream_options.idl", "//third_party/blink/renderer/modules/webtransport/bidirectional_stream.idl", "//third_party/blink/renderer/modules/webtransport/quic_transport.idl", + "//third_party/blink/renderer/modules/webtransport/quic_transport_options.idl", "//third_party/blink/renderer/modules/webtransport/receive_stream.idl", "//third_party/blink/renderer/modules/webtransport/send_stream.idl", "//third_party/blink/renderer/modules/webtransport/stream_abort_info.idl", @@ -1006,6 +1019,7 @@ if (!is_android) { "//third_party/blink/renderer/modules/serial/serial_output_signals.idl", "//third_party/blink/renderer/modules/serial/serial_port.idl", "//third_party/blink/renderer/modules/serial/serial_port_filter.idl", + "//third_party/blink/renderer/modules/serial/serial_port_info.idl", "//third_party/blink/renderer/modules/serial/serial_port_request_options.idl", "//third_party/blink/renderer/modules/serial/worker_navigator_serial.idl", ], diff --git a/chromium/third_party/blink/renderer/bindings/modules/BUILD.gn b/chromium/third_party/blink/renderer/bindings/modules/BUILD.gn index 4d47a971b0e..2849943e241 100644 --- a/chromium/third_party/blink/renderer/bindings/modules/BUILD.gn +++ b/chromium/third_party/blink/renderer/bindings/modules/BUILD.gn @@ -53,7 +53,7 @@ generate_event_interfaces("modules_bindings_generated_event_interfaces") { "//third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event.idl", "//third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.idl", "//third_party/blink/renderer/modules/peerconnection/rtc_quic_stream_event.idl", - "//third_party/blink/renderer/modules/picture_in_picture/enter_picture_in_picture_event.idl", + "//third_party/blink/renderer/modules/picture_in_picture/picture_in_picture_event.idl", "//third_party/blink/renderer/modules/presentation/presentation_connection_available_event.idl", "//third_party/blink/renderer/modules/presentation/presentation_connection_close_event.idl", "//third_party/blink/renderer/modules/push_messaging/push_event.idl", diff --git a/chromium/third_party/blink/renderer/bindings/modules/v8/generated.gni b/chromium/third_party/blink/renderer/bindings/modules/v8/generated.gni index d715d4d0684..20a43b8eb18 100644 --- a/chromium/third_party/blink/renderer/bindings/modules/v8/generated.gni +++ b/chromium/third_party/blink/renderer/bindings/modules/v8/generated.gni @@ -33,6 +33,8 @@ bindings_modules_generated_union_type_files = [ "$bindings_modules_v8_output_dir/audio_context_latency_category_or_double.h", "$bindings_modules_v8_output_dir/boolean_or_constrain_boolean_parameters.cc", "$bindings_modules_v8_output_dir/boolean_or_constrain_boolean_parameters.h", + "$bindings_modules_v8_output_dir/boolean_or_double_or_constrain_double_range.cc", + "$bindings_modules_v8_output_dir/boolean_or_double_or_constrain_double_range.h", "$bindings_modules_v8_output_dir/boolean_or_media_track_constraints.cc", "$bindings_modules_v8_output_dir/boolean_or_media_track_constraints.h", "$bindings_modules_v8_output_dir/canvas_image_source.cc", @@ -97,8 +99,6 @@ bindings_modules_generated_union_type_files = [ "$bindings_modules_v8_output_dir/string_or_string_sequence_or_constrain_dom_string_parameters.h", "$bindings_modules_v8_output_dir/string_or_unsigned_long.cc", "$bindings_modules_v8_output_dir/string_or_unsigned_long.h", - "$bindings_modules_v8_output_dir/string_or_uint32_array.cc", - "$bindings_modules_v8_output_dir/string_or_uint32_array.h", "$bindings_modules_v8_output_dir/unsigned_long_or_unsigned_long_sequence.cc", "$bindings_modules_v8_output_dir/unsigned_long_or_unsigned_long_sequence.h", "$bindings_modules_v8_output_dir/unsigned_long_enforce_range_sequence_or_gpu_extent_3d_dict.cc", @@ -107,6 +107,8 @@ bindings_modules_generated_union_type_files = [ "$bindings_modules_v8_output_dir/unsigned_long_enforce_range_sequence_or_gpu_origin_2d_dict.h", "$bindings_modules_v8_output_dir/unsigned_long_enforce_range_sequence_or_gpu_origin_3d_dict.cc", "$bindings_modules_v8_output_dir/unsigned_long_enforce_range_sequence_or_gpu_origin_3d_dict.h", + "$bindings_modules_v8_output_dir/usv_string_or_uint32_array.cc", + "$bindings_modules_v8_output_dir/usv_string_or_uint32_array.h", "$bindings_modules_v8_output_dir/webgl_rendering_context_or_webgl2_rendering_context.cc", "$bindings_modules_v8_output_dir/webgl_rendering_context_or_webgl2_rendering_context.h", "$bindings_modules_v8_output_dir/worklet_animation_effect_or_worklet_group_effect.cc", @@ -164,10 +166,10 @@ generated_modules_callback_function_files = [ "$bindings_modules_v8_output_dir/v8_storage_quota_callback.h", "$bindings_modules_v8_output_dir/v8_storage_usage_callback.cc", "$bindings_modules_v8_output_dir/v8_storage_usage_callback.h", - "$bindings_modules_v8_output_dir/v8_video_decoder_output_callback.cc", - "$bindings_modules_v8_output_dir/v8_video_decoder_output_callback.h", "$bindings_modules_v8_output_dir/v8_video_encoder_output_callback.cc", "$bindings_modules_v8_output_dir/v8_video_encoder_output_callback.h", + "$bindings_modules_v8_output_dir/v8_video_frame_output_callback.cc", + "$bindings_modules_v8_output_dir/v8_video_frame_output_callback.h", "$bindings_modules_v8_output_dir/v8_video_frame_request_callback.cc", "$bindings_modules_v8_output_dir/v8_video_frame_request_callback.h", "$bindings_modules_v8_output_dir/v8_web_codecs_error_callback.cc", diff --git a/chromium/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.cc b/chromium/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.cc index 7b07f628307..bfe65244349 100644 --- a/chromium/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.cc +++ b/chromium/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_deserializer_for_modules.cc @@ -310,7 +310,7 @@ CryptoKey* V8ScriptValueDeserializerForModules::ReadCryptoKey() { NativeFileSystemHandle* V8ScriptValueDeserializerForModules::ReadNativeFileSystemHandle( SerializationTag tag) { - if (!RuntimeEnabledFeatures::CloneableNativeFileSystemHandlesEnabled( + if (!RuntimeEnabledFeatures::NativeFileSystemEnabled( ExecutionContext::From(GetScriptState()))) { return nullptr; } diff --git a/chromium/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules.cc b/chromium/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules.cc index 2e88d05de51..06cacfb98ab 100644 --- a/chromium/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules.cc +++ b/chromium/third_party/blink/renderer/bindings/modules/v8/serialization/v8_script_value_serializer_for_modules.cc @@ -59,14 +59,14 @@ bool V8ScriptValueSerializerForModules::WriteDOMObject( return true; } if (wrapper_type_info == V8FileSystemFileHandle::GetWrapperTypeInfo() && - RuntimeEnabledFeatures::CloneableNativeFileSystemHandlesEnabled( + RuntimeEnabledFeatures::NativeFileSystemEnabled( ExecutionContext::From(GetScriptState()))) { return WriteNativeFileSystemHandle( kNativeFileSystemFileHandleTag, wrappable->ToImpl<NativeFileSystemHandle>()); } if (wrapper_type_info == V8FileSystemDirectoryHandle::GetWrapperTypeInfo() && - RuntimeEnabledFeatures::CloneableNativeFileSystemHandlesEnabled( + RuntimeEnabledFeatures::NativeFileSystemEnabled( ExecutionContext::From(GetScriptState()))) { return WriteNativeFileSystemHandle( kNativeFileSystemDirectoryHandleTag, diff --git a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/__init__.py b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/__init__.py index 79a9bcb9094..15f1aa277f6 100644 --- a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/__init__.py +++ b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/__init__.py @@ -36,7 +36,7 @@ _setup_sys_path() from .dictionary import generate_dictionaries from .enumeration import generate_enumerations from .interface import generate_interfaces -from .union import generate_unions +from .task_queue import TaskQueue def init(root_src_dir, root_gen_dir, component_reldirs): diff --git a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/blink_v8_bridge.py b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/blink_v8_bridge.py index 255c4b04626..ee49eb59d51 100644 --- a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/blink_v8_bridge.py +++ b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/blink_v8_bridge.py @@ -286,21 +286,56 @@ def make_default_value_expr(idl_type, default_value): Returns a set of C++ expressions to be used for initialization with default values. The returned object has the following attributes. - initializer: Used as "Type var(|initializer|);". This is None if - "Type var;" sets an appropriate default value. + initializer_expr: Used as "Type var{|initializer_expr|};". This is None + if "Type var;" sets an appropriate default value. + initializer_deps: A list of symbol names that |initializer_expr| depends + on. + is_initialization_lightweight: True if a possibly-redundant initialization + will not be more expensive than assignment. See bellow for an + example. assignment_value: Used as "var = |assignment_value|;". + assignment_deps: A list of symbol names that |assignment_value| depends + on. + + + |is_initialization_lightweight| is True if + + Type var{${initializer_expr}}; + if (value_is_given) + var = value; + + is not more expensive than + + Type var; + if (value_is_given) + var = value; + else + var = ${assignment_value}; """ assert default_value.is_type_compatible_with(idl_type) class DefaultValueExpr: - def __init__(self, initializer, is_initializer_lightweight, - assignment_value): - assert initializer is None or isinstance(initializer, str) - assert isinstance(is_initializer_lightweight, bool) + _ALLOWED_SYMBOLS_IN_DEPS = ("isolate") + + def __init__(self, initializer_expr, initializer_deps, + is_initialization_lightweight, assignment_value, + assignment_deps): + assert initializer_expr is None or isinstance( + initializer_expr, str) + assert (isinstance(initializer_deps, (list, tuple)) and all( + dependency in DefaultValueExpr._ALLOWED_SYMBOLS_IN_DEPS + for dependency in initializer_deps)) + assert isinstance(is_initialization_lightweight, bool) assert isinstance(assignment_value, str) - self.initializer = initializer - self.is_initializer_lightweight = is_initializer_lightweight + assert (isinstance(assignment_deps, (list, tuple)) and all( + dependency in DefaultValueExpr._ALLOWED_SYMBOLS_IN_DEPS + for dependency in assignment_deps)) + + self.initializer_expr = initializer_expr + self.initializer_deps = initializer_deps + self.is_initialization_lightweight = is_initialization_lightweight self.assignment_value = assignment_value + self.assignment_deps = assignment_deps if idl_type.unwrap(typedef=True).is_union: union_type = idl_type.unwrap(typedef=True) @@ -315,60 +350,72 @@ def make_default_value_expr(idl_type, default_value): member_default_expr = make_default_value_expr(member_type, default_value) if default_value.idl_type.is_nullable: - initializer = None + initializer_expr = None assignment_value = _format("{}()", union_class_name) else: func_name = name_style.func("From", member_type.type_name) argument = member_default_expr.assignment_value - initializer = _format("{}::{}({})", union_class_name, func_name, - argument) - assignment_value = initializer + # TODO(peria): Remove this workaround when we support V8Enum types + # in Union. + if (member_type.is_sequence + and member_type.element_type.unwrap().is_enumeration): + argument = "{}" + initializer_expr = _format("{}::{}({})", union_class_name, + func_name, argument) + assignment_value = initializer_expr return DefaultValueExpr( - initializer=initializer, - is_initializer_lightweight=False, - assignment_value=assignment_value) + initializer_expr=initializer_expr, + initializer_deps=member_default_expr.initializer_deps, + is_initialization_lightweight=False, + assignment_value=assignment_value, + assignment_deps=member_default_expr.assignment_deps) type_info = blink_type_info(idl_type) - is_initializer_lightweight = False + is_initialization_lightweight = False + initializer_deps = [] + assignment_deps = [] if default_value.idl_type.is_nullable: - if idl_type.unwrap().type_definition_object is not None: - initializer = "nullptr" - is_initializer_lightweight = True + if not type_info.has_null_value: + initializer_expr = None # !base::Optional::has_value() by default + assignment_value = "base::nullopt" + elif idl_type.unwrap().type_definition_object is not None: + initializer_expr = "nullptr" + is_initialization_lightweight = True assignment_value = "nullptr" elif idl_type.unwrap().is_string: - initializer = None # String::IsNull() by default + initializer_expr = None # String::IsNull() by default assignment_value = "String()" elif idl_type.unwrap().is_buffer_source_type: - initializer = "nullptr" - is_initializer_lightweight = True + initializer_expr = "nullptr" + is_initialization_lightweight = True assignment_value = "nullptr" elif type_info.value_t == "ScriptValue": - initializer = "${isolate}, v8::Null(${isolate})" + initializer_expr = "${isolate}, v8::Null(${isolate})" + initializer_deps = ["isolate"] assignment_value = "ScriptValue::CreateNull(${isolate})" + assignment_deps = ["isolate"] elif idl_type.unwrap().is_union: - initializer = None # <union_type>::IsNull() by default + initializer_expr = None # <union_type>::IsNull() by default assignment_value = "{}()".format(type_info.value_t) else: - assert not type_info.has_null_value - initializer = None # !base::Optional::has_value() by default - assignment_value = "base::nullopt" + assert False elif default_value.idl_type.is_sequence: - initializer = None # VectorOf<T>::size() == 0 by default + initializer_expr = None # VectorOf<T>::size() == 0 by default assignment_value = "{}()".format(type_info.value_t) elif default_value.idl_type.is_object: dict_name = blink_class_name(idl_type.unwrap().type_definition_object) value = _format("{}::Create()", dict_name) - initializer = value + initializer_expr = value assignment_value = value elif default_value.idl_type.is_boolean: value = "true" if default_value.value else "false" - initializer = value - is_initializer_lightweight = True + initializer_expr = value + is_initialization_lightweight = True assignment_value = value elif default_value.idl_type.is_integer: - initializer = default_value.literal - is_initializer_lightweight = True + initializer_expr = default_value.literal + is_initialization_lightweight = True assignment_value = default_value.literal elif default_value.idl_type.is_floating_point_numeric: if default_value.value == float("NaN"): @@ -381,31 +428,34 @@ def make_default_value_expr(idl_type, default_value): value_fmt = "{value}" value = value_fmt.format( type=type_info.value_t, value=default_value.literal) - initializer = value - is_initializer_lightweight = True + initializer_expr = value + is_initialization_lightweight = True assignment_value = value elif default_value.idl_type.is_string: if idl_type.unwrap().is_string: value = "\"{}\"".format(default_value.value) - initializer = value + initializer_expr = value assignment_value = value elif idl_type.unwrap().is_enumeration: enum_class_name = blink_class_name( idl_type.unwrap().type_definition_object) enum_value_name = name_style.constant(default_value.value) - initializer = "{}::Enum::{}".format(enum_class_name, - enum_value_name) - is_initializer_lightweight = True - assignment_value = "{}({})".format(enum_class_name, initializer) + initializer_expr = "{}::Enum::{}".format(enum_class_name, + enum_value_name) + is_initialization_lightweight = True + assignment_value = "{}({})".format(enum_class_name, + initializer_expr) else: assert False else: assert False return DefaultValueExpr( - initializer=initializer, - is_initializer_lightweight=is_initializer_lightweight, - assignment_value=assignment_value) + initializer_expr=initializer_expr, + initializer_deps=initializer_deps, + is_initialization_lightweight=is_initialization_lightweight, + assignment_value=assignment_value, + assignment_deps=assignment_deps) def make_v8_to_blink_value(blink_var_name, @@ -457,10 +507,10 @@ def make_v8_to_blink_value(blink_var_name, nodes = [] type_info = blink_type_info(idl_type) default_expr = make_default_value_expr(idl_type, default_value) - if default_expr.is_initializer_lightweight: + if default_expr.is_initialization_lightweight: nodes.append( F("{} ${{{}}}{{{}}};", type_info.value_t, blink_var_name, - default_expr.initializer)) + default_expr.initializer_expr)) else: nodes.append(F("{} ${{{}}};", type_info.value_t, blink_var_name)) assignment = [ @@ -468,21 +518,20 @@ def make_v8_to_blink_value(blink_var_name, CxxUnlikelyIfNode( cond="${exception_state}.HadException()", body=T("return;")), ] - if (default_expr.initializer is None - or default_expr.is_initializer_lightweight): + if (default_expr.initializer_expr is None + or default_expr.is_initialization_lightweight): nodes.append( CxxLikelyIfNode( cond="!{}->IsUndefined()".format(v8_value_expr), body=assignment)) else: nodes.append( - CxxIfElseNode( - cond="{}->IsUndefined()".format(v8_value_expr), - then=F("${{{}}} = {};", blink_var_name, - default_expr.assignment_value), - then_likeliness=Likeliness.LIKELY, - else_=assignment, - else_likeliness=Likeliness.LIKELY)) + CxxIfElseNode(cond="{}->IsUndefined()".format(v8_value_expr), + then=F("${{{}}} = {};", blink_var_name, + default_expr.assignment_value), + then_likeliness=Likeliness.LIKELY, + else_=assignment, + else_likeliness=Likeliness.LIKELY)) return SymbolDefinitionNode(symbol_node, nodes) return SymbolNode(blink_var_name, definition_constructor=create_definition) diff --git a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/code_node_cxx.py b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/code_node_cxx.py index 5e6eca7581d..5b44f5b4302 100644 --- a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/code_node_cxx.py +++ b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/code_node_cxx.py @@ -249,6 +249,7 @@ class CxxFuncDeclNode(CompositeNode): default: True makes this have the default implementation. delete: True makes this function be deleted. """ + assert isinstance(name, str) assert isinstance(static, bool) assert isinstance(explicit, bool) assert isinstance(constexpr, bool) @@ -330,6 +331,7 @@ class CxxFuncDefNode(CompositeNode): override: True makes this an overriding function. member_initializer_list: List of member initializers. """ + assert isinstance(name, str) assert isinstance(static, bool) assert isinstance(inline, bool) assert isinstance(explicit, bool) @@ -372,6 +374,7 @@ class CxxFuncDefNode(CompositeNode): separator=", ", head=" : ") + self._function_name = name self._body_node = SymbolScopeNode() CompositeNode.__init__( @@ -393,6 +396,10 @@ class CxxFuncDefNode(CompositeNode): body=self._body_node) @property + def function_name(self): + return self._function_name + + @property def body(self): return self._body_node diff --git a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_accumulator.py b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_accumulator.py index f72e41a7421..2c822edf4c2 100644 --- a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_accumulator.py +++ b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_accumulator.py @@ -25,11 +25,8 @@ class CodeGenAccumulator(object): def include_headers(self): return self._include_headers - def add_include_header(self, header): - self._include_headers.add(header) - def add_include_headers(self, headers): - self._include_headers.update(headers) + self._include_headers.update(filter(None, headers)) @staticmethod def require_include_headers(headers): @@ -39,11 +36,8 @@ class CodeGenAccumulator(object): def class_decls(self): return self._class_decls - def add_class_decl(self, class_name): - self._class_decls.add(class_name) - def add_class_decls(self, class_names): - self._class_decls.update(class_names) + self._class_decls.update(filter(None, class_names)) @staticmethod def require_class_decls(class_names): @@ -53,11 +47,8 @@ class CodeGenAccumulator(object): def struct_decls(self): return self._struct_decls - def add_struct_decl(self, struct_name): - self._struct_decls.add(struct_name) - def add_struct_decls(self, struct_names): - self._struct_decls.update(struct_names) + self._struct_decls.update(filter(None, struct_names)) @staticmethod def require_struct_decls(struct_names): diff --git a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_expr.py b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_expr.py index c53ec63e3b5..fe953c4f6be 100644 --- a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_expr.py +++ b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_expr.py @@ -143,7 +143,9 @@ def expr_uniq(terms): return uniq_terms -def expr_from_exposure(exposure, global_names=None): +def expr_from_exposure(exposure, + global_names=None, + may_use_feature_selector=False): """ Returns an expression to determine whether this property should be exposed or not. @@ -152,30 +154,75 @@ def expr_from_exposure(exposure, global_names=None): exposure: web_idl.Exposure of the target construct. global_names: When specified, it's taken into account that the global object implements |global_names|. + may_use_feature_selector: True enables use of ${feature_selector} iff + the exposure is context dependent. """ assert isinstance(exposure, web_idl.Exposure) assert (global_names is None or (isinstance(global_names, (list, tuple)) and all(isinstance(name, str) for name in global_names))) + # The property exposures are categorized into three. + # - Unconditional: Always exposed. + # - Context-independent: Enabled per v8::Isolate. + # - Context-dependent: Enabled per v8::Context, e.g. origin trials. + # + # Context-dependent properties can be installed in two phases. + # - The first phase installs all the properties that are associated with the + # features enabled at the moment. This phase is represented by + # FeatureSelector as FeatureSelector.IsAll(). + # - The second phase installs the properties associated with the specified + # feature. This phase is represented as FeatureSelector.IsAny(feature). + # + # The exposure condition is represented as; + # (and feature_selector-independent-term + # (or + # feature_selector-1st-phase-term + # feature_selector-2nd-phase-term)) + # which can be represented in more details as: + # (and secure_context_term + # uncond_exposed_term + # (or + # (and feature_selector.IsAll() # 1st phase; all enabled + # cond_exposed_term + # feature_enabled_term) + # (or exposed_selector_term # 2nd phase; any selected + # feature_selector_term))) + # where + # secure_context_term represents [SecureContext=F1] + # uncond_exposed_term represents [Exposed=(G1, G2)] + # cond_exposed_term represents [Exposed(G1 F1, G2 F2)] + # feature_enabled_term represents [RuntimeEnabled=(F1, F2)] + # exposed_selector_term represents [Exposed(G1 F1, G2 F2)] + # feature_selector_term represents [RuntimeEnabled=(F1, F2)] + uncond_exposed_terms = [] + cond_exposed_terms = [] + feature_enabled_terms = [] + exposed_selector_terms = [] + feature_selector_names = [] # Will turn into feature_selector.IsAnyOf(...) + def ref_enabled(feature): arg = "${execution_context}" if feature.is_context_dependent else "" return _Expr("RuntimeEnabledFeatures::{}Enabled({})".format( feature, arg)) - top_terms = [_Expr(True)] + def ref_selected(features): + feature_tokens = map( + lambda feature: "OriginTrialFeature::k{}".format(feature), + features) + return _Expr("${{feature_selector}}.IsAnyOf({})".format( + ", ".join(feature_tokens))) # [SecureContext] if exposure.only_in_secure_contexts is True: - top_terms.append(_Expr("${is_in_secure_context}")) + secure_context_term = _Expr("${is_in_secure_context}") elif exposure.only_in_secure_contexts is False: - top_terms.append(_Expr(True)) + secure_context_term = _Expr(True) else: terms = map(ref_enabled, exposure.only_in_secure_contexts) - top_terms.append( - expr_or( - [_Expr("${is_in_secure_context}"), - expr_not(expr_and(terms))])) + secure_context_term = expr_or( + [_Expr("${is_in_secure_context}"), + expr_not(expr_and(terms))]) # [Exposed] GLOBAL_NAME_TO_EXECUTION_CONTEXT_TEST = { @@ -190,7 +237,6 @@ def expr_from_exposure(exposure, global_names=None): "Worker": "IsWorkerGlobalScope", "Worklet": "IsWorkletGlobalScope", } - exposed_terms = [] if global_names: matched_global_count = 0 for entry in exposure.global_names_and_features: @@ -198,39 +244,72 @@ def expr_from_exposure(exposure, global_names=None): continue matched_global_count += 1 if entry.feature: - exposed_terms.append(ref_enabled(entry.feature)) + cond_exposed_terms.append(ref_enabled(entry.feature)) + if entry.feature.is_context_dependent: + feature_selector_names.append(entry.feature) assert (not exposure.global_names_and_features or matched_global_count > 0) else: for entry in exposure.global_names_and_features: - terms = [] - pred = GLOBAL_NAME_TO_EXECUTION_CONTEXT_TEST[entry.global_name] - terms.append(_Expr("${{execution_context}}->{}()".format(pred))) - if entry.feature: - terms.append(ref_enabled(entry.feature)) - if terms: - exposed_terms.append(expr_and(terms)) - if exposed_terms: - top_terms.append(expr_or(exposed_terms)) + pred_term = _Expr("${{execution_context}}->{}()".format( + GLOBAL_NAME_TO_EXECUTION_CONTEXT_TEST[entry.global_name])) + if not entry.feature: + uncond_exposed_terms.append(pred_term) + else: + cond_exposed_terms.append( + expr_and([pred_term, ref_enabled(entry.feature)])) + if entry.feature.is_context_dependent: + exposed_selector_terms.append( + expr_and([pred_term, + ref_selected([entry.feature])])) # [RuntimeEnabled] if exposure.runtime_enabled_features: - terms = map(ref_enabled, exposure.runtime_enabled_features) - top_terms.append(expr_or(terms)) - - return expr_and(top_terms) - - -def expr_of_feature_selector(exposure): - """ - Returns an expression that tells whether this property is a target of the - feature selector or not. - - Args: - exposure: web_idl.Exposure of the target construct. - """ - assert isinstance(exposure, web_idl.Exposure) - - features = map(lambda feature: "OriginTrialFeature::k{}".format(feature), - exposure.context_dependent_runtime_enabled_features) - return _Expr("${{feature_selector}}.AnyOf({})".format(", ".join(features))) + feature_enabled_terms.extend( + map(ref_enabled, exposure.runtime_enabled_features)) + feature_selector_names.extend( + exposure.context_dependent_runtime_enabled_features) + + # [ContextEnabled] + if exposure.context_enabled_features: + terms = map( + lambda feature: _Expr( + "${{context_feature_settings}}->is{}Enabled()".format( + feature)), exposure.context_enabled_features) + feature_enabled_terms.append( + expr_and([_Expr("${context_feature_settings}"), + expr_or(terms)])) + + # Build an expression. + top_level_terms = [] + top_level_terms.append(secure_context_term) + if uncond_exposed_terms: + top_level_terms.append(expr_or(uncond_exposed_terms)) + + if not (may_use_feature_selector + and exposure.is_context_dependent(global_names)): + if cond_exposed_terms: + top_level_terms.append(expr_or(cond_exposed_terms)) + if feature_enabled_terms: + top_level_terms.append(expr_and(feature_enabled_terms)) + return expr_and(top_level_terms) + + all_enabled_terms = [_Expr("${feature_selector}.IsAll()")] + if cond_exposed_terms: + all_enabled_terms.append(expr_or(cond_exposed_terms)) + if feature_enabled_terms: + all_enabled_terms.append(expr_or(feature_enabled_terms)) + + selector_terms = [] + if exposed_selector_terms: + selector_terms.append(expr_or(exposed_selector_terms)) + if feature_selector_names: + selector_terms.append(ref_selected(feature_selector_names)) + + terms = [] + terms.append(expr_and(all_enabled_terms)) + if selector_terms: + terms.append(expr_or(selector_terms)) + top_level_terms.append(expr_or(terms)) + + return expr_and(top_level_terms) diff --git a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_utils.py b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_utils.py index 7021f1a618c..acf1a92b3ad 100644 --- a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_utils.py +++ b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/codegen_utils.py @@ -59,15 +59,21 @@ def make_header_include_directives(accumulator): return LiteralNode(HeaderIncludeDirectives(accumulator)) -def component_export(component): +def component_export(component, for_testing): assert isinstance(component, web_idl.Component) + assert isinstance(for_testing, bool) + if for_testing: + return "" return name_style.macro(component, "EXPORT") -def component_export_header(component): +def component_export_header(component, for_testing): assert isinstance(component, web_idl.Component) + assert isinstance(for_testing, bool) + if for_testing: + return None if component == "core": return "third_party/blink/renderer/core/core_export.h" elif component == "modules": @@ -90,59 +96,6 @@ def enclose_with_header_guard(code_node, header_guard): ]) -def collect_include_headers_of_idl_types(idl_types): - """ - Returns a set of header paths that are required by |idl_types|. - """ - header_paths = set() - - def add_header_path(idl_type): - assert isinstance(idl_type, web_idl.IdlType) - - if idl_type.is_numeric or idl_type.is_boolean or idl_type.is_typedef: - pass - elif idl_type.is_string: - header_paths.add( - "third_party/blink/renderer/platform/wtf/text/wtf_string.h") - elif idl_type.is_buffer_source_type: - header_paths.update([ - "third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h", - "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h", - "third_party/blink/renderer/platform/heap/handle.h", - ]) - elif idl_type.is_object or idl_type.is_any: - header_paths.add( - "third_party/blink/renderer/bindings/core/v8/script_value.h") - elif idl_type.type_definition_object: - type_def_obj = idl_type.type_definition_object - header_paths.update([ - PathManager(type_def_obj).api_path(ext="h"), - "third_party/blink/renderer/platform/heap/handle.h", - ]) - elif (idl_type.is_sequence or idl_type.is_frozen_array - or idl_type.is_variadic or idl_type.is_record): - header_paths.update([ - "third_party/blink/renderer/platform/wtf/vector.h", - "third_party/blink/renderer/platform/heap/heap_allocator.h", - ]) - elif idl_type.is_promise: - header_paths.add( - "third_party/blink/renderer/bindings/core/v8/script_promise.h") - elif idl_type.is_union: - union_def_obj = idl_type.union_definition_object - header_paths.add(PathManager(union_def_obj).api_path(ext="h")) - elif idl_type.is_nullable: - if not blink_type_info(idl_type.inner_type).has_null_value: - header_paths.add("base/optional.h") - else: - assert False, "Unknown type: {}".format(idl_type.syntactic_form) - - for idl_type in idl_types: - idl_type.apply_to_all_composing_elements(add_header_path) - - return header_paths - - def write_code_node_to_file(code_node, filepath): """Renders |code_node| and then write the result to |filepath|.""" assert isinstance(code_node, CodeNode) diff --git a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/dictionary.py b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/dictionary.py index 851d5eadc49..40a863115d4 100644 --- a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/dictionary.py +++ b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/dictionary.py @@ -2,10 +2,6 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import itertools -import multiprocessing -import os.path - import web_idl from . import name_style @@ -13,7 +9,7 @@ from .blink_v8_bridge import blink_class_name from .blink_v8_bridge import blink_type_info from .blink_v8_bridge import make_default_value_expr from .blink_v8_bridge import make_v8_to_blink_value -from .code_node import CodeNode +from .blink_v8_bridge import native_value_tag from .code_node import Likeliness from .code_node import ListNode from .code_node import SequenceNode @@ -30,7 +26,6 @@ from .codegen_accumulator import CodeGenAccumulator from .codegen_context import CodeGenContext from .codegen_expr import expr_from_exposure from .codegen_format import format_template as _format -from .codegen_utils import collect_include_headers_of_idl_types from .codegen_utils import component_export from .codegen_utils import component_export_header from .codegen_utils import enclose_with_header_guard @@ -39,8 +34,8 @@ from .codegen_utils import make_forward_declarations from .codegen_utils import make_header_include_directives from .codegen_utils import write_code_node_to_file from .mako_renderer import MakoRenderer -from .package_initializer import package_initializer from .path_manager import PathManager +from .task_queue import TaskQueue _DICT_MEMBER_PRESENCE_PREDICATES = { @@ -57,12 +52,17 @@ def _blink_member_name(member): blink_name = (member.code_generator_info.property_implemented_as or member.identifier) self.get_api = name_style.api_func(blink_name) + self.get_or_api = name_style.api_func(blink_name, "or") self.set_api = name_style.api_func("set", blink_name) self.has_api = name_style.api_func("has", blink_name) # C++ data member that shows the presence of the IDL member. self.presence_var = name_style.member_var("has", blink_name) # C++ data member that holds the value of the IDL member. self.value_var = name_style.member_var(blink_name) + # Migration Adapters + self.get_non_null_api = name_style.api_func(blink_name, "non_null") + self.has_non_null_api = name_style.api_func( + "has", blink_name, "non_null") return BlinkMemberName(member) @@ -120,6 +120,7 @@ def _make_include_headers(cg_context): assert isinstance(cg_context, CodeGenContext) dictionary = cg_context.dictionary + for_testing = dictionary.code_generator_info.for_testing header_includes = set() source_includes = set() @@ -132,7 +133,7 @@ def _make_include_headers(cg_context): "third_party/blink/renderer/platform/bindings/dictionary_base.h") header_includes.update([ - component_export_header(dictionary.components[0]), + component_export_header(dictionary.components[0], for_testing), "third_party/blink/renderer/bindings/core/v8/generated_code_helper.h", "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h", "v8/include/v8.h", @@ -144,9 +145,55 @@ def _make_include_headers(cg_context): "third_party/blink/renderer/platform/heap/visitor.h", ]) - header_includes.update( - collect_include_headers_of_idl_types( - [member.idl_type for member in dictionary.own_members])) + def add_include_headers(idl_type): + if idl_type.is_numeric or idl_type.is_boolean or idl_type.is_typedef: + pass + elif idl_type.is_string: + header_includes.add( + "third_party/blink/renderer/platform/wtf/text/wtf_string.h") + elif idl_type.is_buffer_source_type: + header_includes.update([ + "third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h", + "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h", + "third_party/blink/renderer/platform/heap/handle.h", + ]) + elif idl_type.is_object or idl_type.is_any: + header_includes.add( + "third_party/blink/renderer/bindings/core/v8/script_value.h") + elif idl_type.is_enumeration: + type_def_obj = idl_type.type_definition_object + header_includes.add(PathManager(type_def_obj).api_path(ext="h")) + elif idl_type.is_dictionary: + type_def_obj = idl_type.type_definition_object + header_includes.add( + "third_party/blink/renderer/platform/heap/handle.h") + source_includes.add(PathManager(type_def_obj).api_path(ext="h")) + elif idl_type.type_definition_object: + type_def_obj = idl_type.type_definition_object + header_includes.update([ + PathManager(type_def_obj).api_path(ext="h"), + "third_party/blink/renderer/platform/heap/handle.h", + ]) + elif (idl_type.is_sequence or idl_type.is_frozen_array + or idl_type.is_variadic or idl_type.is_record): + header_includes.update([ + "third_party/blink/renderer/platform/wtf/vector.h", + "third_party/blink/renderer/platform/heap/heap_allocator.h", + ]) + elif idl_type.is_promise: + header_includes.add( + "third_party/blink/renderer/bindings/core/v8/script_promise.h") + elif idl_type.is_union: + union_def_obj = idl_type.union_definition_object + header_includes.add(PathManager(union_def_obj).api_path(ext="h")) + elif idl_type.is_nullable: + if not blink_type_info(idl_type.inner_type).has_null_value: + header_includes.add("base/optional.h") + else: + assert False, "Unknown type: {}".format(idl_type.syntactic_form) + + for member in dictionary.own_members: + member.idl_type.apply_to_all_composing_elements(add_include_headers) return header_includes, source_includes @@ -165,10 +212,89 @@ def _make_forward_declarations(cg_context): source_class_fwd_decls = set() source_struct_fwd_decls = set() + def add_fwd_decls(idl_type): + if idl_type.is_dictionary: + header_class_fwd_decls.add( + blink_class_name(idl_type.type_definition_object)) + + for member in dictionary.own_members: + member.idl_type.apply_to_all_composing_elements(add_fwd_decls) + return (header_class_fwd_decls, header_struct_fwd_decls, source_class_fwd_decls, source_struct_fwd_decls) +def _is_default_ctor_available(dictionary): + for member in dictionary.members: + if member.default_value is None: + continue + default_expr = make_default_value_expr(member.idl_type, + member.default_value) + if default_expr.initializer_deps: + return False + return True + + +def make_create_dict_funcs(cg_context): + assert isinstance(cg_context, CodeGenContext) + + dictionary = cg_context.dictionary + name = "Create" + return_type = "${class_name}*" + + decls = ListNode() + defs = ListNode() + + if _is_default_ctor_available(dictionary): + func_def = CxxFuncDefNode(name=name, + arg_decls=[], + return_type=return_type, + static=True) + decls.append(func_def) + func_def.set_base_template_vars(cg_context.template_bindings()) + func_def.body.append( + TextNode("return MakeGarbageCollected<${class_name}>();")) + + func_def = CxxFuncDefNode(name=name, + arg_decls=["v8::Isolate* isolate"], + return_type=return_type, + static=True) + decls.append(func_def) + func_def.set_base_template_vars(cg_context.template_bindings()) + func_def.body.append( + TextNode("return MakeGarbageCollected<${class_name}>(isolate);")) + + arg_decls = [ + "v8::Isolate* isolate", + "v8::Local<v8::Value> v8_value", + "ExceptionState& exception_state", + ] + func_decl = CxxFuncDeclNode(name=name, + arg_decls=arg_decls, + return_type=return_type, + static=True) + decls.append(func_decl) + func_def = CxxFuncDefNode(name=name, + class_name=cg_context.class_name, + arg_decls=arg_decls, + return_type=return_type) + defs.append(func_def) + func_def.set_base_template_vars(cg_context.template_bindings()) + + func_def.body.append( + TextNode("""\ +DCHECK(!v8_value.IsEmpty()); + +${class_name}* dictionary = Create(isolate); +dictionary->FillMembers(isolate, v8_value, exception_state); +if (exception_state.HadException()) { + return nullptr; +} +return dictionary;""")) + + return decls, defs + + def make_dict_constructors(cg_context): decls = ListNode() defs = ListNode() @@ -176,11 +302,39 @@ def make_dict_constructors(cg_context): dictionary = cg_context.dictionary class_name = blink_class_name(dictionary) + if _is_default_ctor_available(dictionary): + ctor_decl = CxxFuncDeclNode(name=class_name, + arg_decls=[], + return_type="", + default=True) + decls.append(ctor_decl) + ctor_decl = CxxFuncDeclNode(name=class_name, - arg_decls=[], + arg_decls=["v8::Isolate* isolate"], return_type="", - default=True) + explicit=True) decls.append(ctor_decl) + ctor_decl.set_base_template_vars(cg_context.template_bindings()) + + member_initializer_list = ["BaseClass(${isolate})"] + for member in dictionary.own_members: + if member.default_value is None: + continue + default_expr = make_default_value_expr(member.idl_type, + member.default_value) + if default_expr.initializer_deps == ["isolate"]: + _1 = _blink_member_name(member).value_var + _2 = default_expr.initializer_expr + member_initializer_list.append(_format("{_1}({_2})", _1=_1, _2=_2)) + + ctor_def = CxxFuncDefNode(name=class_name, + class_name=class_name, + arg_decls=["v8::Isolate* isolate"], + return_type="", + member_initializer_list=member_initializer_list) + defs.append(ctor_def) + ctor_def.set_base_template_vars(cg_context.template_bindings()) + ctor_def.add_template_var("isolate", "isolate") return decls, defs @@ -192,15 +346,16 @@ def make_dict_member_get(cg_context): blink_member_name = _blink_member_name(member) name = blink_member_name.get_api blink_type = blink_type_info(member.idl_type) + const_ref_t = blink_type.const_ref_t + ref_t = blink_type.ref_t decls = ListNode() defs = ListNode() - func_def = CxxFuncDefNode( - name=name, - arg_decls=[], - return_type=blink_type.const_ref_t, - const=True) + func_def = CxxFuncDefNode(name=name, + arg_decls=[], + return_type=const_ref_t, + const=True) decls.append(func_def) func_def.set_base_template_vars(cg_context.template_bindings()) func_def.body.extend([ @@ -208,9 +363,8 @@ def make_dict_member_get(cg_context): TextNode(_format("return {};", blink_member_name.value_var)), ]) - if blink_type.ref_t != blink_type.const_ref_t: - func_def = CxxFuncDefNode( - name=name, arg_decls=[], return_type=blink_type.ref_t) + if ref_t != const_ref_t: + func_def = CxxFuncDefNode(name=name, arg_decls=[], return_type=ref_t) decls.append(func_def) func_def.set_base_template_vars(cg_context.template_bindings()) func_def.body.extend([ @@ -218,6 +372,24 @@ def make_dict_member_get(cg_context): TextNode(_format("return {};", blink_member_name.value_var)), ]) + if not _is_member_always_present(member): + func_def = CxxFuncDefNode( + name=blink_member_name.get_or_api, + arg_decls=[_format("{} fallback_value", blink_type.value_t)], + return_type=blink_type.value_t, + const=True) + decls.append(func_def) + func_def.set_base_template_vars(cg_context.template_bindings()) + body_node = TextNode( + _format("""\ +if ({has}()) {{ + return {get}(); +}} +return std::move(fallback_value);""", + has=blink_member_name.has_api, + get=blink_member_name.get_api)) + func_def.body.append(body_node) + return decls, defs @@ -315,9 +487,10 @@ def make_dict_member_vars(cg_context): if member.default_value: default_expr = make_default_value_expr(member.idl_type, member.default_value) - if default_expr.initializer is not None: + if (default_expr.initializer_expr is not None + and not default_expr.initializer_deps): default_value_initializer = _format("{{{}}}", - default_expr.initializer) + default_expr.initializer_expr) _1 = blink_type_info(member.idl_type).member_t _2 = _blink_member_name(member).value_var @@ -333,6 +506,77 @@ def make_dict_member_vars(cg_context): return value_var_def, presense_var_def +def make_dict_member_migration_adapters(cg_context): + assert isinstance(cg_context, CodeGenContext) + + member = cg_context.dict_member + blink_member_name = _blink_member_name(member) + idl_type = member.idl_type + blink_type = blink_type_info(idl_type) + real_type = idl_type.unwrap(typedef=True) + + if (not real_type.is_nullable + or blink_type_info(real_type.inner_type).has_null_value): + return None, None + + decls = ListNode([TextNode("// Migration Adapters")]) + defs = ListNode() + + # Accessors for non-null values, if the usual getter returns + # base::Optional<T>. + blink_inner_type = blink_type_info(real_type.inner_type) + get_api = blink_member_name.get_api + has_api = blink_member_name.has_api + get_non_null_api = blink_member_name.get_non_null_api + has_non_null_api = blink_member_name.has_non_null_api + + func_def = CxxFuncDefNode(name=get_non_null_api, + arg_decls=[], + return_type=blink_inner_type.const_ref_t, + const=True) + decls.extend([ + TextNode( + _format( + """\ +// Returns the value if this member has a non-null value. Call +// |{}| in advance to check the condition.""", has_non_null_api)), + func_def, + ]) + func_def.set_base_template_vars(cg_context.template_bindings()) + func_def.body.extend([ + TextNode(_format("DCHECK({}());", has_non_null_api)), + TextNode(_format("return {}().value();", get_api)), + ]) + + if blink_inner_type.ref_t != blink_inner_type.const_ref_t: + func_def = CxxFuncDefNode(name=get_non_null_api, + arg_decls=[], + return_type=blink_inner_type.ref_t) + decls.append(func_def) + func_def.set_base_template_vars(cg_context.template_bindings()) + func_def.body.extend([ + TextNode(_format("DCHECK({}());", has_non_null_api)), + TextNode(_format("return {}().value();", get_api)), + ]) + + func_def = CxxFuncDefNode(name=has_non_null_api, + arg_decls=[], + return_type="bool", + const=True) + decls.extend([ + TextNode("""\ +// Returns true iff this member has a non-null value. Returns false if the +// value is missing or the null value."""), + func_def, + ]) + func_def.set_base_template_vars(cg_context.template_bindings()) + func_def.body.append( + TextNode(_format("return {}() && {}().has_value();", has_api, + get_api))) + + return decls, defs + + def make_get_v8_dict_member_names_func(cg_context): assert isinstance(cg_context, CodeGenContext) @@ -352,7 +596,7 @@ def make_get_v8_dict_member_names_func(cg_context): body = func_def.body if dictionary.own_members: - pattern = "static const char* kKeyStrings[] = {{{_1}}};" + pattern = "static const char* const kKeyStrings[] = {{{_1}}};" _1 = ", ".join( _format("\"{}\"", member.identifier) for member in dictionary.own_members) @@ -412,8 +656,6 @@ if (!BaseClass::FillWithMembers(isolate, creation_context, v8_dictionary)) { def make_fill_with_own_dict_members_func(cg_context): assert isinstance(cg_context, CodeGenContext) - T = TextNode - dictionary = cg_context.dictionary own_members = dictionary.own_members name = "FillWithOwnMembers" @@ -437,23 +679,35 @@ def make_fill_with_own_dict_members_func(cg_context): body.add_template_var("isolate", "isolate") bind_member_iteration_local_vars(body) + def to_v8_expr(member): + get_api = _blink_member_name(member).get_api + member_type = member.idl_type.unwrap(typedef=True) + expr = _format("ToV8({}(), creation_context, isolate)", get_api) + if member_type.is_nullable and member_type.unwrap().is_string: + expr = _format( + "({get_api}().IsNull() ? v8::Null(isolate) : {to_v8})", + get_api=get_api, + to_v8=expr) + return expr + for key_index, member in enumerate(own_members): - _1 = _blink_member_name(member).has_api - _2 = key_index - _3 = _blink_member_name(member).get_api - pattern = ("""\ -if ({_1}()) {{ + pattern = """\ +if ({has_api}()) {{ if (!v8_dictionary ->CreateDataProperty( ${current_context}, - ${member_names}[{_2}].Get(isolate), - ToV8({_3}(), creation_context, isolate)) + ${member_names}[{index}].Get(isolate), + {to_v8_expr}) .ToChecked()) {{ return false; }} }}\ -""") - node = T(_format(pattern, _1=_1, _2=_2, _3=_3)) +""" + node = TextNode( + _format(pattern, + has_api=_blink_member_name(member).has_api, + index=key_index, + to_v8_expr=to_v8_expr(member))) conditional = expr_from_exposure(member.exposure) if not conditional.is_always_true: @@ -461,60 +715,11 @@ if ({_1}()) {{ body.append(node) - body.append(T("return true;")) + body.append(TextNode("return true;")) return func_decl, func_def -def make_dict_create_funcs(cg_context): - assert isinstance(cg_context, CodeGenContext) - - name = "Create" - arg_decls = [ - "v8::Isolate* isolate", - "v8::Local<v8::Value> v8_value", - "ExceptionState& exception_state", - ] - return_type = "${class_name}*" - - default_create_def = CxxFuncDefNode( - name=name, arg_decls=[], return_type=return_type, static=True) - default_create_def.set_base_template_vars(cg_context.template_bindings()) - - default_create_def.body.append( - TextNode("return MakeGarbageCollected<${class_name}>();")) - - create_decl = CxxFuncDeclNode( - name=name, arg_decls=arg_decls, return_type=return_type, static=True) - create_def = CxxFuncDefNode( - name=name, - class_name=cg_context.class_name, - arg_decls=arg_decls, - return_type=return_type) - create_def.set_base_template_vars(cg_context.template_bindings()) - - create_def.body.append( - TextNode("""\ -DCHECK(!v8_value.IsEmpty()); - -${class_name}* dictionary = MakeGarbageCollected<${class_name}>(); -dictionary->FillMembers(isolate, v8_value, exception_state); -if (exception_state.HadException()) { - return nullptr; -} -return dictionary;""")) - - decls = ListNode([ - default_create_def, - create_decl, - ]) - defs = ListNode([ - create_def, - ]) - - return decls, defs - - def make_fill_dict_members_func(cg_context): assert isinstance(cg_context, CodeGenContext) @@ -612,6 +817,7 @@ def make_fill_dict_members_internal_func(cg_context): body.register_code_symbols([ SymbolNode("try_block", "v8::TryCatch ${try_block}(${isolate});"), SymbolNode("v8_value", "v8::Local<v8::Value> ${v8_value};"), + SymbolNode("unused_presence_var", "bool ${unused_presence_var};"), ]) if dictionary.inherited: @@ -633,44 +839,32 @@ def make_fill_own_dict_member(key_index, member): assert isinstance(key_index, int) assert isinstance(member, web_idl.DictionaryMember) - T = TextNode - - pattern = """ -if (!<% try_block %>v8_dictionary->Get(${current_context}, ${member_names}[{_1}].Get(${isolate})) - .ToLocal(&${v8_value})) {{ - ${exception_state}.RethrowV8Exception(${try_block}.Exception()); + pattern = """\ +if (!bindings::ConvertDictionaryMember<{nvt_tag}, {is_required}>( + ${isolate}, + ${current_context}, + v8_dictionary, + ${member_names}[{key_index}].Get(${isolate}), + "${{dictionary.identifier}}", + "{member_name}", + {value_var}, + {presence_var}, + ${try_block}, + ${exception_state})) {{ return; }}""" - get_v8_value_node = T(_format(pattern, _1=key_index)) - - api_call_node = SymbolScopeNode() - api_call_node.register_code_symbol( - make_v8_to_blink_value("blink_value", "${v8_value}", member.idl_type)) - _1 = _blink_member_name(member).set_api - api_call_node.append(T(_format("{_1}(${blink_value});", _1=_1))) - - if member.is_required: - exception_pattern = """\ -${exception_state}.ThrowTypeError( - ExceptionMessages::FailedToGet( - "{}", "${{dictionary.identifier}}", - "Required member is undefined.")); -""" - - check_and_fill_node = CxxIfElseNode( - cond="!${v8_value}->IsUndefined()", - then=api_call_node, - then_likeliness=Likeliness.LIKELY, - else_=T(_format(exception_pattern, member.identifier)), - else_likeliness=Likeliness.UNLIKELY) + if _does_use_presence_flag(member): + presence_var = _blink_member_name(member).presence_var else: - check_and_fill_node = CxxLikelyIfNode( - cond="!${v8_value}->IsUndefined()", body=api_call_node) - - node = SequenceNode([ - get_v8_value_node, - check_and_fill_node, - ]) + presence_var = "${unused_presence_var}" + node = TextNode( + _format(pattern, + nvt_tag=native_value_tag(member.idl_type), + is_required="true" if member.is_required else "false", + key_index=key_index, + member_name=member.identifier, + value_var=_blink_member_name(member).value_var, + presence_var=presence_var)) conditional = expr_from_exposure(member.exposure) if not conditional.is_always_true: @@ -690,13 +884,16 @@ def make_dict_trace_func(cg_context): arg_decls = ["Visitor* visitor"] return_type = "void" - func_decl = CxxFuncDeclNode( - name=name, arg_decls=arg_decls, return_type=return_type, override=True) - func_def = CxxFuncDefNode( - name=name, - class_name=cg_context.class_name, - arg_decls=arg_decls, - return_type=return_type) + func_decl = CxxFuncDeclNode(name=name, + arg_decls=arg_decls, + return_type=return_type, + const=True, + override=True) + func_def = CxxFuncDefNode(name=name, + class_name=cg_context.class_name, + arg_decls=arg_decls, + return_type=return_type, + const=True) func_def.set_base_template_vars(cg_context.template_bindings()) body = func_def.body @@ -713,9 +910,12 @@ def make_dict_trace_func(cg_context): def generate_dictionary(dictionary): + assert isinstance(dictionary, web_idl.Dictionary) + assert len(dictionary.components) == 1, ( "We don't support partial dictionaries across components yet.") component = dictionary.components[0] + for_testing = dictionary.code_generator_info.for_testing path_manager = PathManager(dictionary) class_name = name_style.class_(blink_class_name(dictionary)) @@ -746,16 +946,16 @@ def generate_dictionary(dictionary): source_blink_ns = CxxNamespaceNode(name_style.namespace("blink")) # Class definitions - class_def = CxxClassDefNode( - cg_context.class_name, - base_class_names=[cg_context.base_class_name], - export=component_export(component)) + class_def = CxxClassDefNode(cg_context.class_name, + base_class_names=[cg_context.base_class_name], + export=component_export( + component, for_testing)) class_def.set_base_template_vars(cg_context.template_bindings()) class_def.top_section.append( TextNode("using BaseClass = ${base_class_name};")) # Create functions - create_decl, create_def = make_dict_create_funcs(cg_context) + create_decl, create_def = make_create_dict_funcs(cg_context) # Constructor and destructor constructor_decls, constructor_defs = make_dict_constructors(cg_context) @@ -789,17 +989,21 @@ def generate_dictionary(dictionary): has_decls, has_defs = make_dict_member_has(member_context) set_decls, set_defs = make_dict_member_set(member_context) value_var_def, presense_var_def = make_dict_member_vars(member_context) + (migration_adapter_decls, migration_adapter_defs + ) = make_dict_member_migration_adapters(member_context) member_accessor_decls.extend([ TextNode(""), get_decls, has_decls, set_decls, + migration_adapter_decls, ]) member_accessor_defs.extend([ TextNode(""), get_defs, has_defs, set_defs, + migration_adapter_defs, ]) member_value_var_defs.append(value_var_def) member_presense_var_defs.append(presense_var_def) @@ -896,31 +1100,9 @@ def generate_dictionary(dictionary): write_code_node_to_file(source_node, path_manager.gen_path_to(source_path)) -def run_multiprocessing_task(args): - dictionary, package_initializer = args - package_initializer.init() - generate_dictionary(dictionary) - - -def generate_dictionaries(web_idl_database): - # More processes do not mean better performance. The default size was - # chosen heuristically. - process_pool_size = 8 - cpu_count = multiprocessing.cpu_count() - process_pool_size = max(1, min(cpu_count / 2, process_pool_size)) - - pool = multiprocessing.Pool(process_pool_size) - # Prior to Python3, Pool.map doesn't support user interrupts (e.g. Ctrl-C), - # although Pool.map_async(...).get(...) does. - timeout_in_sec = 3600 # Just enough long time - pool.map_async( - run_multiprocessing_task, - map(lambda dictionary: (dictionary, package_initializer()), - web_idl_database.dictionaries)).get(timeout_in_sec) - - return +def generate_dictionaries(task_queue, web_idl_database): + assert isinstance(task_queue, TaskQueue) + assert isinstance(web_idl_database, web_idl.Database) - # When it is difficult to see errors in generator, use following loop - # instead of parallel runs above. for dictionary in web_idl_database.dictionaries: - generate_dictionary(dictionary) + task_queue.post_task(generate_dictionary, dictionary) diff --git a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/enumeration.py b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/enumeration.py index 4155e0ee91f..4e03be8e8d6 100644 --- a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/enumeration.py +++ b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/enumeration.py @@ -2,6 +2,8 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import web_idl + from . import name_style from .blink_v8_bridge import blink_class_name from .code_node import EmptyNode @@ -23,6 +25,7 @@ from .codegen_utils import make_header_include_directives from .codegen_utils import write_code_node_to_file from .mako_renderer import MakoRenderer from .path_manager import PathManager +from .task_queue import TaskQueue def make_factory_methods(cg_context): @@ -234,9 +237,12 @@ def make_enum_string_table(cg_context): def generate_enumeration(enumeration): + assert isinstance(enumeration, web_idl.Enumeration) + path_manager = PathManager(enumeration) assert path_manager.api_component == path_manager.impl_component api_component = path_manager.api_component + for_testing = enumeration.code_generator_info.for_testing # Class names class_name = blink_class_name(enumeration) @@ -263,11 +269,11 @@ def generate_enumeration(enumeration): source_blink_ns = CxxNamespaceNode(name_style.namespace("blink")) # Class definition - class_def = CxxClassDefNode( - cg_context.class_name, - base_class_names=["bindings::EnumerationBase"], - final=True, - export=component_export(api_component)) + class_def = CxxClassDefNode(cg_context.class_name, + base_class_names=["bindings::EnumerationBase"], + final=True, + export=component_export( + api_component, for_testing)) class_def.set_base_template_vars(cg_context.template_bindings()) # Implementation parts @@ -308,7 +314,7 @@ def generate_enumeration(enumeration): EmptyNode(), ]) header_node.accumulator.add_include_headers([ - component_export_header(api_component), + component_export_header(api_component, for_testing), "third_party/blink/renderer/bindings/core/v8/generated_code_helper.h", "third_party/blink/renderer/platform/bindings/enumeration_base.h", ]) @@ -355,6 +361,9 @@ def generate_enumeration(enumeration): write_code_node_to_file(source_node, path_manager.gen_path_to(source_path)) -def generate_enumerations(web_idl_database): +def generate_enumerations(task_queue, web_idl_database): + assert isinstance(task_queue, TaskQueue) + assert isinstance(web_idl_database, web_idl.Database) + for enumeration in web_idl_database.enumerations: - generate_enumeration(enumeration) + task_queue.post_task(generate_enumeration, enumeration) diff --git a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/interface.py b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/interface.py index b3fb8ff1a0e..43616ad11dd 100644 --- a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/interface.py +++ b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/interface.py @@ -3,8 +3,6 @@ # found in the LICENSE file. import itertools -import multiprocessing -import os.path import web_idl @@ -37,7 +35,6 @@ from .codegen_context import CodeGenContext from .codegen_expr import CodeGenExpr from .codegen_expr import expr_and from .codegen_expr import expr_from_exposure -from .codegen_expr import expr_of_feature_selector from .codegen_expr import expr_or from .codegen_format import format_template as _format from .codegen_utils import component_export @@ -48,8 +45,8 @@ from .codegen_utils import make_forward_declarations from .codegen_utils import make_header_include_directives from .codegen_utils import write_code_node_to_file from .mako_renderer import MakoRenderer -from .package_initializer import package_initializer from .path_manager import PathManager +from .task_queue import TaskQueue def _is_none_or_str(arg): @@ -222,13 +219,17 @@ if (${exception_state}.HadException()) // step 4.6.2. If S is not one of the enumeration's values, then return // undefined. const auto arg1_value_maybe_enum = {enum_type}::Create(arg1_value_string); -if (!arg1_value_maybe_enum) +if (!arg1_value_maybe_enum) {{ + bindings::ReportInvalidEnumSetToAttribute( + ${isolate}, arg1_value_string, "{enum_type_name}", ${exception_state}); return; // Return undefined. +}} const auto ${arg1_value} = arg1_value_maybe_enum.value(); """ - text = _format( - pattern, - enum_type=blink_class_name(real_type.type_definition_object)) + text = _format(pattern, + enum_type=blink_class_name( + real_type.type_definition_object), + enum_type_name=real_type.identifier) code_node.register_code_symbol(SymbolNode("arg1_value", text)) return @@ -573,6 +574,7 @@ def _make_blink_api_call(code_node, ext_attrs = cg_context.member_like.extended_attributes values = ext_attrs.values_of("CallWith") + ( + ext_attrs.values_of("GetterCallWith") if cg_context.attribute_get else ext_attrs.values_of("SetterCallWith") if cg_context.attribute_set else ()) if "Isolate" in values: @@ -1467,6 +1469,7 @@ def make_v8_set_return_value(cg_context): assert isinstance(cg_context, CodeGenContext) T = TextNode + F = lambda *args, **kwargs: T(_format(*args, **kwargs)) if cg_context.does_override_idl_return_type: return T("bindings::V8SetReturnValue(${info}, ${return_value});") @@ -1495,10 +1498,28 @@ def make_v8_set_return_value(cg_context): return_type = return_type.unwrap(typedef=True) return_type_body = return_type.unwrap() - V8_RETURN_VALUE_FAST_TYPES = ("boolean", "byte", "octet", "short", - "unsigned short", "long", "unsigned long") - if return_type.keyword_typename in V8_RETURN_VALUE_FAST_TYPES: - return T("bindings::V8SetReturnValue(${info}, ${return_value});") + PRIMITIVE_TYPE_TO_CXX_TYPE = { + "boolean": "bool", + "byte": "int8_t", + "octet": "uint8_t", + "short": "int16_t", + "unsigned short": "uint16_t", + "long": "int32_t", + "unsigned long": "uint32_t", + "long long": "int64_t", + "unsigned long long": "uint64_t", + "float": "float", + "unrestricted float": "float", + "double": "double", + "unrestricted double": "double", + } + cxx_type = PRIMITIVE_TYPE_TO_CXX_TYPE.get( + return_type_body.keyword_typename) + if cxx_type: + return F( + "bindings::V8SetReturnValue(${info}, ${return_value}, " + "bindings::V8ReturnValue::PrimitiveType<{cxx_type}>());", + cxx_type=cxx_type) # TODO(yukishiino): Remove |return_type_body.is_enumeration| below once # the migration from String to V8Enum type is done. @@ -3992,6 +4013,19 @@ def bind_installer_local_vars(code_node, cg_context): "${class_name}::GetWrapperTypeInfo();")), ]) + # context_feature_settings + node = S("context_feature_settings", + ("const ContextFeatureSettings* ${context_feature_settings} = " + "ContextFeatureSettings::From(" + "${execution_context}, " + "ContextFeatureSettings::CreationMode::kDontCreateIfNotExists" + ");")) + node.accumulate( + CodeGenAccumulator.require_include_headers([ + "third_party/blink/renderer/core/context_features/context_feature_settings.h" + ])) + local_vars.append(node) + # execution_context node = S("execution_context", ("ExecutionContext* ${execution_context} = " "ExecutionContext::From(${script_state});")) @@ -4103,6 +4137,24 @@ def _make_property_entry_check_receiver(property_): return "V8DOMConfiguration::kCheckHolder" +def _make_property_entry_check_cross_origin_access(property_, + is_get=False, + is_set=False): + constants = { + True: "V8DOMConfiguration::kDoNotCheckAccess", + False: "V8DOMConfiguration::kCheckAccess", + } + if "CrossOrigin" not in property_.extended_attributes: + return constants[False] + values = property_.extended_attributes.values_of("CrossOrigin") + if is_get: + return constants[not values or "Getter" in values] + elif is_set: + return constants["Setter" in values] + else: + return constants[True] + + def _make_property_entry_has_side_effect(property_): if property_.extended_attributes.value_of("Affects") == "Nothing": return "V8DOMConfiguration::kHasNoSideEffect" @@ -4155,8 +4207,9 @@ def _make_attribute_registration_table(table_name, attribute_entries): "{v8_property_attribute}, " "{on_which_object}, " "{check_receiver}, " + "{check_cross_origin_get_access}, " + "{check_cross_origin_set_access}, " "{has_side_effect}, " - "V8DOMConfiguration::kAlwaysCallGetter, " "{world}" "}},") text = _format( @@ -4172,6 +4225,12 @@ def _make_attribute_registration_table(table_name, attribute_entries): entry.property_), check_receiver=_make_property_entry_check_receiver( entry.property_), + check_cross_origin_get_access=( + _make_property_entry_check_cross_origin_access(entry.property_, + is_get=True)), + check_cross_origin_set_access=( + _make_property_entry_check_cross_origin_access(entry.property_, + is_set=True)), has_side_effect=_make_property_entry_has_side_effect( entry.property_), world=_make_property_entry_world(entry.world)) @@ -4304,7 +4363,7 @@ def _make_operation_registration_table(table_name, operation_entries): "{v8_property_attribute}, " "{on_which_object}, " "{check_receiver}, " - "V8DOMConfiguration::kDoNotCheckAccess, " + "{check_cross_origin_access}, " "{has_side_effect}, " "{world}" "}}, ") @@ -4319,6 +4378,9 @@ def _make_operation_registration_table(table_name, operation_entries): entry.property_), check_receiver=_make_property_entry_check_receiver( entry.property_), + check_cross_origin_access=( + _make_property_entry_check_cross_origin_access( + entry.property_)), has_side_effect=_make_property_entry_has_side_effect( entry.property_), world=_make_property_entry_world(entry.world)) @@ -4432,8 +4494,10 @@ def _make_property_entries_and_callback_defs( for member in members: is_context_dependent = member.exposure.is_context_dependent( global_names) - exposure_conditional = expr_from_exposure(member.exposure, - global_names) + exposure_conditional = expr_from_exposure( + member.exposure, + global_names=global_names, + may_use_feature_selector=True) if "PerWorldBindings" in member.extended_attributes: worlds = (CodeGenContext.MAIN_WORLD, @@ -4985,8 +5049,18 @@ ${prototype_template}->SetImmutableProto(); return func_decl, func_def, trampoline_def +class PropInstallMode(object): + class Mode(int): + pass + + UNCONDITIONAL = Mode(0) + CONTEXT_INDEPENDENT = Mode(1) + CONTEXT_DEPENDENT = Mode(2) + V8_CONTEXT_SNAPSHOT = Mode(3) + + def make_install_properties(cg_context, function_name, class_name, - trampoline_var_name, is_context_dependent, + prop_install_mode, trampoline_var_name, attribute_entries, constant_entries, exposed_construct_entries, operation_entries): """ @@ -5000,8 +5074,8 @@ def make_install_properties(cg_context, function_name, class_name, assert isinstance(cg_context, CodeGenContext) assert isinstance(function_name, str) assert _is_none_or_str(class_name) + assert isinstance(prop_install_mode, PropInstallMode.Mode) assert _is_none_or_str(trampoline_var_name) - assert isinstance(is_context_dependent, bool) assert isinstance(attribute_entries, (list, tuple)) assert all( isinstance(entry, _PropEntryAttribute) for entry in attribute_entries) @@ -5017,7 +5091,7 @@ def make_install_properties(cg_context, function_name, class_name, isinstance(entry, _PropEntryOperationGroup) for entry in operation_entries) - if is_context_dependent: + if prop_install_mode == PropInstallMode.CONTEXT_DEPENDENT: install_prototype_object_node = _make_install_prototype_object( cg_context) else: @@ -5025,9 +5099,26 @@ def make_install_properties(cg_context, function_name, class_name, if not (attribute_entries or constant_entries or exposed_construct_entries or operation_entries or install_prototype_object_node): - return None, None, None + if prop_install_mode != PropInstallMode.V8_CONTEXT_SNAPSHOT: + return None, None, None - if is_context_dependent: + if prop_install_mode in (PropInstallMode.UNCONDITIONAL, + PropInstallMode.CONTEXT_INDEPENDENT): + arg_decls = [ + "v8::Isolate* isolate", + "const DOMWrapperWorld& world", + "v8::Local<v8::ObjectTemplate> instance_template", + "v8::Local<v8::ObjectTemplate> prototype_template", + "v8::Local<v8::FunctionTemplate> interface_template", + ] + arg_names = [ + "isolate", + "world", + "instance_template", + "prototype_template", + "interface_template", + ] + elif prop_install_mode == PropInstallMode.CONTEXT_DEPENDENT: arg_decls = [ "v8::Local<v8::Context> context", "const DOMWrapperWorld& world", @@ -5046,23 +5137,29 @@ def make_install_properties(cg_context, function_name, class_name, "interface_template", "feature_selector", ] - else: + elif prop_install_mode == PropInstallMode.V8_CONTEXT_SNAPSHOT: arg_decls = [ - "v8::Isolate* isolate", + "v8::Local<v8::Context> context", "const DOMWrapperWorld& world", - "v8::Local<v8::ObjectTemplate> instance_template", - "v8::Local<v8::ObjectTemplate> prototype_template", + "v8::Local<v8::Object> instance_object", + "v8::Local<v8::Object> prototype_object", + "v8::Local<v8::Function> interface_object", "v8::Local<v8::FunctionTemplate> interface_template", ] arg_names = [ - "isolate", + "context", "world", - "instance_template", - "prototype_template", + "instance_object", + "prototype_object", + "interface_object", "interface_template", ] return_type = "void" + is_per_context_install = ( + prop_install_mode in (PropInstallMode.CONTEXT_DEPENDENT, + PropInstallMode.V8_CONTEXT_SNAPSHOT)) + if trampoline_var_name is None: trampoline_def = None else: @@ -5077,11 +5174,10 @@ def make_install_properties(cg_context, function_name, class_name, args=", ".join(arg_names)) trampoline_def.body.append(TextNode(text)) - func_decl = CxxFuncDeclNode( - name=function_name, - arg_decls=arg_decls, - return_type=return_type, - static=True) + func_decl = CxxFuncDeclNode(name=function_name, + arg_decls=arg_decls, + return_type=return_type, + static=bool(class_name)) func_def = CxxFuncDefNode( name=function_name, @@ -5098,11 +5194,10 @@ def make_install_properties(cg_context, function_name, class_name, body.add_template_var(arg_name, arg_name) bind_installer_local_vars(body, cg_context) - if is_context_dependent and install_prototype_object_node: + if install_prototype_object_node: body.extend([ - CxxLikelyIfNode( - cond="${feature_selector}.AnyOf()", - body=[install_prototype_object_node]), + CxxLikelyIfNode(cond="${feature_selector}.IsAll()", + body=[install_prototype_object_node]), EmptyNode(), ]) @@ -5110,7 +5205,6 @@ def make_install_properties(cg_context, function_name, class_name, unconditional_entries = [] conditional_to_entries = {} for entry in entries: - assert entry.is_context_dependent == is_context_dependent if entry.exposure_conditional.is_always_true: unconditional_entries.append(entry) else: @@ -5130,11 +5224,6 @@ def make_install_properties(cg_context, function_name, class_name, ])) body.append(EmptyNode()) for conditional, entries in conditional_to_entries.items(): - if is_context_dependent: - conditional = expr_and([ - expr_of_feature_selector(entries[0].property_.exposure), - conditional, - ]) body.append( CxxUnlikelyIfNode( cond=conditional, @@ -5145,7 +5234,7 @@ def make_install_properties(cg_context, function_name, class_name, body.append(EmptyNode()) table_name = "kAttributeTable" - if is_context_dependent: + if is_per_context_install: installer_call_text = ( "V8DOMConfiguration::InstallAccessors(${isolate}, ${world}, " "${instance_object}, ${prototype_object}, ${interface_object}, " @@ -5160,7 +5249,7 @@ def make_install_properties(cg_context, function_name, class_name, _make_attribute_registration_table, installer_call_text) table_name = "kConstantCallbackTable" - if is_context_dependent: + if is_per_context_install: installer_call_text = ( "V8DOMConfiguration::InstallConstants(${isolate}, " "${interface_object}, ${prototype_object}, " @@ -5177,7 +5266,7 @@ def make_install_properties(cg_context, function_name, class_name, installer_call_text) table_name = "kConstantValueTable" - if is_context_dependent: + if is_per_context_install: installer_call_text = ( "V8DOMConfiguration::InstallConstants(${isolate}, " "${interface_object}, ${prototype_object}, " @@ -5194,7 +5283,7 @@ def make_install_properties(cg_context, function_name, class_name, installer_call_text) table_name = "kExposedConstructTable" - if is_context_dependent: + if is_per_context_install: installer_call_text = ( "V8DOMConfiguration::InstallAttributes(${isolate}, ${world}, " "${instance_object}, ${prototype_object}, " @@ -5209,7 +5298,7 @@ def make_install_properties(cg_context, function_name, class_name, installer_call_text) table_name = "kOperationTable" - if is_context_dependent: + if is_per_context_install: installer_call_text = ( "V8DOMConfiguration::InstallMethods(${isolate}, ${world}, " "${instance_object}, ${prototype_object}, ${interface_object}, " @@ -5810,6 +5899,16 @@ static void InstallContextDependentPropertiesAdapter( wrapper_type_info_def.append( F(pattern, FN_INSTALL_CONTEXT_DEPENDENT_PROPS)) pattern = """\ +// Construction of WrapperTypeInfo may require non-trivial initialization due +// to cross-component address resolution in order to load the pointer to the +// parent interface's WrapperTypeInfo. We ignore this issue because the issue +// happens only on component builds and the official release builds +// (statically-linked builds) are never affected by this issue. +#if defined(COMPONENT_BUILD) && defined(WIN32) && defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wglobal-constructors" +#endif + const WrapperTypeInfo ${class_name}::wrapper_type_info_{{ gin::kEmbedderBlink, ${class_name}::DomTemplate, @@ -5820,6 +5919,10 @@ const WrapperTypeInfo ${class_name}::wrapper_type_info_{{ {wrapper_class_id}, {active_script_wrappable_inheritance}, }}; + +#if defined(COMPONENT_BUILD) && defined(WIN32) && defined(__clang__) +#pragma clang diagnostic pop +#endif """ class_like = cg_context.class_like if has_context_dependent_props: @@ -5888,6 +5991,140 @@ static_assert( # ---------------------------------------------------------------------------- +# V8 Context Snapshot +# ---------------------------------------------------------------------------- + + +def make_v8_context_snapshot_api(cg_context, attribute_entries, + constant_entries, constructor_entries, + exposed_construct_entries, operation_entries, + named_properties_object_callback_defs, + cross_origin_property_callback_defs): + derived_interfaces = cg_context.interface.deriveds + derived_names = map(lambda interface: interface.identifier, + derived_interfaces) + derived_names.append(cg_context.interface.identifier) + if not ("Window" in derived_names or "HTMLDocument" in derived_names): + return None, None + + header_ns = CxxNamespaceNode(name_style.namespace("v8_context_snapshot")) + source_ns = CxxNamespaceNode(name_style.namespace("v8_context_snapshot")) + + (func_decl, + func_def) = make_v8_context_snapshot_get_reference_table_function( + cg_context, name_style.func("GetRefTableOf", + cg_context.class_name), attribute_entries, + constant_entries, constructor_entries, exposed_construct_entries, + operation_entries, named_properties_object_callback_defs, + cross_origin_property_callback_defs) + header_ns.body.extend([ + func_decl, + EmptyNode(), + ]) + source_ns.body.extend([ + func_def, + EmptyNode(), + ]) + + (func_decl, + func_def) = make_v8_context_snapshot_install_properties_function( + cg_context, name_style.func("InstallPropsOf", + cg_context.class_name), attribute_entries, + constant_entries, exposed_construct_entries, operation_entries) + header_ns.body.extend([ + func_decl, + EmptyNode(), + ]) + source_ns.body.extend([ + func_def, + EmptyNode(), + ]) + + return header_ns, source_ns + + +def make_v8_context_snapshot_get_reference_table_function( + cg_context, function_name, attribute_entries, constant_entries, + constructor_entries, exposed_construct_entries, operation_entries, + named_properties_object_callback_defs, + cross_origin_property_callback_defs): + callback_names = [] + + for entry in attribute_entries: + if entry.exposure_conditional.is_always_true: + callback_names.append(entry.attr_get_callback_name) + callback_names.append(entry.attr_set_callback_name) + for entry in constant_entries: + if entry.exposure_conditional.is_always_true: + callback_names.append(entry.const_callback_name) + for entry in constructor_entries: + if entry.exposure_conditional.is_always_true: + callback_names.append(entry.ctor_callback_name) + for entry in exposed_construct_entries: + if entry.exposure_conditional.is_always_true: + callback_names.append(entry.prop_callback_name) + for entry in operation_entries: + if entry.exposure_conditional.is_always_true: + callback_names.append(entry.op_callback_name) + + def collect_callbacks(node): + if isinstance(node, CxxFuncDefNode): + callback_names.append(node.function_name) + elif isinstance(node, ListNode): + for child_node in node: + collect_callbacks(child_node) + + collect_callbacks(named_properties_object_callback_defs) + collect_callbacks(cross_origin_property_callback_defs) + + entry_nodes = map( + lambda name: TextNode("reinterpret_cast<intptr_t>({}),".format(name)), + filter(None, callback_names)) + table_node = ListNode([ + TextNode("static const intptr_t kReferenceTable[] = {"), + ListNode(entry_nodes), + TextNode("};"), + ]) + + func_decl = CxxFuncDeclNode(name=function_name, + arg_decls=[], + return_type="base::span<const intptr_t>") + + func_def = CxxFuncDefNode(name=function_name, + arg_decls=[], + return_type="base::span<const intptr_t>") + func_def.set_base_template_vars(cg_context.template_bindings()) + body = func_def.body + body.extend([table_node, TextNode("return kReferenceTable;")]) + + return func_decl, func_def + + +def make_v8_context_snapshot_install_properties_function( + cg_context, function_name, attribute_entries, constant_entries, + exposed_construct_entries, operation_entries): + def selector(entry): + if entry.exposure_conditional.is_always_true: + return False + if entry.is_context_dependent: + return False + return True + + func_decl, func_def, _ = make_install_properties( + cg_context, + function_name, + class_name=None, + prop_install_mode=PropInstallMode.V8_CONTEXT_SNAPSHOT, + trampoline_var_name=None, + attribute_entries=filter(selector, attribute_entries), + constant_entries=filter(selector, constant_entries), + exposed_construct_entries=filter(selector, exposed_construct_entries), + operation_entries=filter(selector, operation_entries)) + + return func_decl, func_def + + +# ---------------------------------------------------------------------------- # Main functions # ---------------------------------------------------------------------------- @@ -5958,6 +6195,7 @@ def generate_interface(interface): api_component = path_manager.api_component impl_component = path_manager.impl_component is_cross_components = path_manager.is_cross_components + for_testing = interface.code_generator_info.for_testing # Class names api_class_name = v8_bridge_class_name(interface) @@ -6011,24 +6249,15 @@ def generate_interface(interface): blink_class_name(interface)), ], final=True, - export=component_export(api_component)) + export=component_export(api_component, for_testing)) api_class_def.set_base_template_vars(cg_context.template_bindings()) api_class_def.bottom_section.append( TextNode("friend class {};".format(blink_class_name(interface)))) - api_base_class_def = CxxNamespaceNode( - name="bindings", - body=TextNode( - _format( - "template class {export} " - "V8InterfaceBridge<{class_name}, {blink_impl_class}>;", - export=component_export(api_component), - class_name=cg_context.class_name, - blink_impl_class=blink_class_name(interface)))) if is_cross_components: - impl_class_def = CxxClassDefNode( - impl_class_name, - final=True, - export=component_export(impl_component)) + impl_class_def = CxxClassDefNode(impl_class_name, + final=True, + export=component_export( + impl_component, for_testing)) impl_class_def.set_base_template_vars(cg_context.template_bindings()) api_class_def.public_section.extend([ TextNode("// Cross-component implementation class"), @@ -6098,7 +6327,7 @@ def generate_interface(interface): attribute_set=True, arg_decls=[ "v8::Local<v8::Value>", - "const v8::PropertyCallbackInfo<v8::Value>&", + "const v8::PropertyCallbackInfo<void>&", ]) for operation_group in interface.operation_groups: if "Custom" in operation_group.extended_attributes: @@ -6197,8 +6426,8 @@ def generate_interface(interface): cg_context, FN_INSTALL_UNCONDITIONAL_PROPS, class_name=impl_class_name, + prop_install_mode=PropInstallMode.UNCONDITIONAL, trampoline_var_name=tp_install_unconditional_props, - is_context_dependent=False, attribute_entries=filter(is_unconditional, attribute_entries), constant_entries=filter(is_unconditional, constant_entries), exposed_construct_entries=filter(is_unconditional, @@ -6210,8 +6439,8 @@ def generate_interface(interface): cg_context, FN_INSTALL_CONTEXT_INDEPENDENT_PROPS, class_name=impl_class_name, + prop_install_mode=PropInstallMode.CONTEXT_INDEPENDENT, trampoline_var_name=tp_install_context_independent_props, - is_context_dependent=False, attribute_entries=filter(is_context_independent, attribute_entries), constant_entries=filter(is_context_independent, constant_entries), exposed_construct_entries=filter(is_context_independent, @@ -6222,8 +6451,8 @@ def generate_interface(interface): cg_context, FN_INSTALL_CONTEXT_DEPENDENT_PROPS, class_name=impl_class_name, + prop_install_mode=PropInstallMode.CONTEXT_DEPENDENT, trampoline_var_name=tp_install_context_dependent_props, - is_context_dependent=True, attribute_entries=filter(is_context_dependent, attribute_entries), constant_entries=filter(is_context_dependent, constant_entries), exposed_construct_entries=filter(is_context_dependent, @@ -6286,6 +6515,14 @@ def generate_interface(interface): has_context_dependent_props=bool( install_context_dependent_props_decl)) + # V8 Context Snapshot + (header_v8_context_snapshot_ns, + source_v8_context_snapshot_ns) = make_v8_context_snapshot_api( + cg_context, attribute_entries, constant_entries, constructor_entries, + exposed_construct_entries, operation_entries, + named_properties_object_callback_defs, + cross_origin_property_callback_defs) + # Header part (copyright, include directives, and forward declarations) api_header_node.extend([ make_copyright_header(), @@ -6345,19 +6582,19 @@ def generate_interface(interface): ]) api_header_node.accumulator.add_include_headers([ interface.code_generator_info.blink_headers[0], - component_export_header(api_component), + component_export_header(api_component, for_testing), "third_party/blink/renderer/platform/bindings/v8_interface_bridge.h", ]) api_source_node.accumulator.add_include_headers([ "third_party/blink/renderer/bindings/core/v8/v8_dom_configuration.h", ]) if interface.inherited: - api_source_node.accumulator.add_include_header( - PathManager(interface.inherited).api_path(ext="h")) + api_source_node.accumulator.add_include_headers( + [PathManager(interface.inherited).api_path(ext="h")]) if is_cross_components: impl_header_node.accumulator.add_include_headers([ api_header_path, - component_export_header(impl_component), + component_export_header(impl_component, for_testing), ]) impl_source_node.accumulator.add_include_headers([ "third_party/blink/renderer/bindings/core/v8/native_value_traits_impl.h", @@ -6374,11 +6611,12 @@ def generate_interface(interface): api_header_blink_ns.body.extend([ api_class_def, EmptyNode(), - api_base_class_def, - EmptyNode(), ]) if is_cross_components: - impl_header_blink_ns.body.append(impl_class_def) + impl_header_blink_ns.body.extend([ + impl_class_def, + EmptyNode(), + ]) if constants_def: api_class_def.public_section.extend([ @@ -6451,6 +6689,18 @@ def generate_interface(interface): EmptyNode(), ]) + if header_v8_context_snapshot_ns: + impl_header_blink_ns.body.extend([ + CxxNamespaceNode(name=name_style.namespace("bindings"), + body=header_v8_context_snapshot_ns), + EmptyNode(), + ]) + impl_source_blink_ns.body.extend([ + CxxNamespaceNode(name=name_style.namespace("bindings"), + body=source_v8_context_snapshot_ns), + EmptyNode(), + ]) + # Write down to the files. write_code_node_to_file(api_header_node, path_manager.gen_path_to(api_header_path)) @@ -6523,7 +6773,7 @@ def generate_install_properties_per_feature(web_idl_database, return_type="void") # Assemble the parts. - header_node.accumulator.add_class_decl("ScriptState") + header_node.accumulator.add_class_decls(["ScriptState"]) header_node.accumulator.add_include_headers([ "third_party/blink/renderer/platform/runtime_enabled_features.h", ]) @@ -6547,6 +6797,8 @@ def generate_install_properties_per_feature(web_idl_database, EmptyNode(), TextNode("#include \"{}\"".format(header_path)), EmptyNode(), + TextNode("#include <algorithm>"), + EmptyNode(), make_header_include_directives(source_node.accumulator), EmptyNode(), source_blink_ns, @@ -6581,11 +6833,16 @@ using InstallFuncType = for member in itertools.chain(interface.attributes, interface.constants, - interface.operation_groups): - for feature in (member.exposure. - context_dependent_runtime_enabled_features): + interface.operation_groups, + interface.exposed_constructs): + features = list( + member.exposure.context_dependent_runtime_enabled_features) + for entry in member.exposure.global_names_and_features: + if entry.feature and entry.feature.is_context_dependent: + features.append(entry.feature) + for feature in features: feature_to_interfaces.setdefault(feature, set()).add(interface) - if member.exposure.context_dependent_runtime_enabled_features: + if features: set_of_interfaces.add(interface) switch_node = CxxSwitchNode(cond="${feature}") @@ -6631,31 +6888,66 @@ using InstallFuncType = for interface in set_of_interfaces: path_manager = PathManager(interface) - source_node.accumulator.add_include_header( - path_manager.api_path(ext="h")) + source_node.accumulator.add_include_headers( + [path_manager.api_path(ext="h")]) # The helper function + globals = filter(lambda x: "Global" in x.extended_attributes, + set_of_interfaces) + entries = [ + TextNode("{}::GetWrapperTypeInfo(), ".format( + v8_bridge_class_name(interface))) + for interface in sorted(globals, key=lambda x: x.identifier) + ] + has_globals = bool(entries) + if has_globals: + # TODO(yukishiino): Make WrapperTypeInfo have a bit flag to indicate + # whether an interface is a global interface or not. Then, we can + # simplify this implementation. + helper_func_def.body.extend([ + ListNode([ + TextNode("static const WrapperTypeInfo* globals_body[] = {"), + ListNode(entries), + TextNode("};"), + ]), + TextNode("const auto& globals = base::make_span(globals_body);"), + EmptyNode(), + ]) helper_func_def.body.append( TextNode("""\ V8PerContextData* per_context_data = script_state->PerContextData(); v8::Isolate* isolate = script_state->GetIsolate(); v8::Local<v8::Context> context = script_state->GetContext(); const DOMWrapperWorld& world = script_state->World(); -v8::Local<v8::Object> instance_object; -v8::Local<v8::Object> prototype_object; -v8::Local<v8::Function> interface_object; -v8::Local<v8::FunctionTemplate> interface_template; V8InterfaceBridgeBase::FeatureSelector feature_selector(feature); for (const auto& pair : wrapper_type_info_list) { const WrapperTypeInfo* wrapper_type_info = pair.first; InstallFuncType install_func = pair.second; - if (per_context_data->GetExistingConstructorAndPrototypeForType( + + v8::Local<v8::Object> instance_object; + v8::Local<v8::Object> prototype_object; + v8::Local<v8::Function> interface_object; + v8::Local<v8::FunctionTemplate> interface_template; + + if (!per_context_data->GetExistingConstructorAndPrototypeForType( wrapper_type_info, &prototype_object, &interface_object)) { - interface_template = wrapper_type_info->DomTemplate(isolate, world); - install_func(context, world, instance_object, prototype_object, - interface_object, interface_template, feature_selector); + continue; + } +""")) + if has_globals: + helper_func_def.body.append( + TextNode("""\ + if (std::find(globals.begin(), globals.end(), wrapper_type_info) + != globals.end()) { + instance_object = context->Global()->GetPrototype().As<v8::Object>(); } +""")) + helper_func_def.body.append( + TextNode("""\ + interface_template = wrapper_type_info->DomTemplate(isolate, world); + install_func(context, world, instance_object, prototype_object, + interface_object, interface_template, feature_selector); }\ """)) @@ -6736,8 +7028,8 @@ def generate_init_idl_interfaces(web_idl_database, path_manager = PathManager(interface) if path_manager.is_cross_components: - source_node.accumulator.add_include_header( - path_manager.impl_path(ext="h")) + source_node.accumulator.add_include_headers( + [path_manager.impl_path(ext="h")]) class_name = v8_bridge_class_name(interface) init_calls.append(_format("{}::Impl::Init();", class_name)) @@ -6749,42 +7041,25 @@ def generate_init_idl_interfaces(web_idl_database, write_code_node_to_file(source_node, path_manager.gen_path_to(source_path)) -def run_multiprocessing_task(args): - interface, package_initializer = args - package_initializer.init() - generate_interface(interface) - - -def generate_interfaces(web_idl_database): +def generate_interfaces(task_queue, web_idl_database): + assert isinstance(task_queue, TaskQueue) assert isinstance(web_idl_database, web_idl.Database) - generate_install_properties_per_feature( - web_idl_database, "InstallPropertiesPerFeature", - "properties_per_feature_installer") - generate_install_properties_per_feature( - web_idl_database, - "InstallPropertiesPerFeatureForTesting", - "properties_per_feature_installer_for_testing", - for_testing=True) - generate_init_idl_interfaces(web_idl_database, "InitIDLInterfaces", - "init_idl_interfaces") - generate_init_idl_interfaces( - web_idl_database, - "InitIDLInterfacesForTesting", - "init_idl_interfaces_for_testing", - for_testing=True) - - # More processes do not mean better performance. The default size was - # chosen heuristically. - process_pool_size = 8 - cpu_count = multiprocessing.cpu_count() - process_pool_size = max(1, min(cpu_count / 2, process_pool_size)) - - pool = multiprocessing.Pool(process_pool_size) - # Prior to Python3, Pool.map doesn't support user interrupts (e.g. Ctrl-C), - # although Pool.map_async(...).get(...) does. - timeout_in_sec = 3600 # Just enough long time - pool.map_async( - run_multiprocessing_task, - map(lambda interface: (interface, package_initializer()), - web_idl_database.interfaces)).get(timeout_in_sec) + for interface in web_idl_database.interfaces: + task_queue.post_task(generate_interface, interface) + + task_queue.post_task(generate_install_properties_per_feature, + web_idl_database, "InstallPropertiesPerFeature", + "properties_per_feature_installer") + task_queue.post_task(generate_install_properties_per_feature, + web_idl_database, + "InstallPropertiesPerFeatureForTesting", + "properties_per_feature_installer_for_testing", + for_testing=True) + task_queue.post_task(generate_init_idl_interfaces, web_idl_database, + "InitIDLInterfaces", "init_idl_interfaces") + task_queue.post_task(generate_init_idl_interfaces, + web_idl_database, + "InitIDLInterfacesForTesting", + "init_idl_interfaces_for_testing", + for_testing=True) diff --git a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/path_manager.py b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/path_manager.py index 47d6c08b8ee..e95b5b3a966 100644 --- a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/path_manager.py +++ b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/path_manager.py @@ -218,4 +218,7 @@ _BACKWARD_COMPATIBLE_UNION_FILEPATHS = { # modules/canvas/offscreencanvas/offscreen_canvas_module.idl "OffscreenCanvasRenderingContext2DOrWebGLRenderingContextOrWebGL2RenderingContextOrImageBitmapRenderingContext": "OffscreenRenderingContext", + # core/xmlhttprequest/xml_http_request.idl + "DocumentOrBlobOrArrayBufferOrArrayBufferViewOrFormDataOrURLSearchParamsOrUSVString": + "DocumentOrXMLHttpRequestBodyInit", } diff --git a/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/task_queue.py b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/task_queue.py new file mode 100644 index 00000000000..7143edeb8c8 --- /dev/null +++ b/chromium/third_party/blink/renderer/bindings/scripts/bind_gen/task_queue.py @@ -0,0 +1,91 @@ +# Copyright 2020 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. + +import multiprocessing + +from .package_initializer import package_initializer + + +class TaskQueue(object): + """ + Represents a task queue to run tasks with using a worker pool. Scheduled + tasks will be executed in parallel. + """ + + def __init__(self): + # More processes do not mean better performance. The pool size was + # chosen heuristically. + cpu_count = multiprocessing.cpu_count() + self._pool_size = max(2, cpu_count / 4) + self._pool = multiprocessing.Pool(self._pool_size, + package_initializer().init) + self._requested_tasks = [] # List of (func, args, kwargs) + self._worker_tasks = [] # List of multiprocessing.pool.AsyncResult + self._did_run = False + + def post_task(self, func, *args, **kwargs): + """ + Schedules a new task to be executed when |run| method is invoked. This + method does not kick any execution, only puts a new task in the queue. + """ + assert not self._did_run + self._requested_tasks.append((func, args, kwargs)) + + def run(self, report_progress=None): + """ + Executes all scheduled tasks. + + Args: + report_progress: A callable that takes two arguments, total number + of worker tasks and number of completed worker tasks. + Scheduled tasks are reorganized into worker tasks, so the + number of worker tasks may be different from the number of + scheduled tasks. + """ + assert report_progress is None or callable(report_progress) + assert not self._did_run + assert not self._worker_tasks + self._did_run = True + + num_of_requested_tasks = len(self._requested_tasks) + chunk_size = min(20, num_of_requested_tasks / (4 * self._pool_size)) + i = 0 + while i < num_of_requested_tasks: + tasks = self._requested_tasks[i:i + chunk_size] + i += chunk_size + self._worker_tasks.append( + self._pool.apply_async(_task_queue_run_tasks, [tasks])) + self._pool.close() + + timeout_in_sec = 2 + while True: + self._report_worker_task_progress(report_progress) + for worker_task in self._worker_tasks: + if not worker_task.ready(): + worker_task.wait(timeout_in_sec) + break + if not worker_task.successful(): + worker_task.get() # Let |get()| raise an exception. + assert False + else: + break + + self._pool.join() + + def _report_worker_task_progress(self, report_progress): + assert report_progress is None or callable(report_progress) + + if not report_progress: + return + + done_count = reduce( + lambda count, worker_task: count + bool(worker_task.ready()), + self._worker_tasks, 0) + report_progress(len(self._worker_tasks), done_count) + + +def _task_queue_run_tasks(tasks): + for task in tasks: + func, args, kwargs = task + apply(func, args, kwargs) diff --git a/chromium/third_party/blink/renderer/bindings/scripts/build_web_idl_database.pydeps b/chromium/third_party/blink/renderer/bindings/scripts/build_web_idl_database.pydeps index 77100622a5b..c37de46d3cc 100644 --- a/chromium/third_party/blink/renderer/bindings/scripts/build_web_idl_database.pydeps +++ b/chromium/third_party/blink/renderer/bindings/scripts/build_web_idl_database.pydeps @@ -1,11 +1,8 @@ # Generated by running: # build/print_python_deps.py --root third_party/blink/renderer/bindings/scripts --output third_party/blink/renderer/bindings/scripts/build_web_idl_database.pydeps third_party/blink/renderer/bindings/scripts/build_web_idl_database.py ../../../../pyjson5/src/json5/__init__.py -../../../../pyjson5/src/json5/arg_parser.py -../../../../pyjson5/src/json5/host.py ../../../../pyjson5/src/json5/lib.py ../../../../pyjson5/src/json5/parser.py -../../../../pyjson5/src/json5/tool.py ../../../../pyjson5/src/json5/version.py ../../build/scripts/blinkbuild/__init__.py ../../build/scripts/blinkbuild/name_style_converter.py diff --git a/chromium/third_party/blink/renderer/bindings/scripts/collect_idl_files.pydeps b/chromium/third_party/blink/renderer/bindings/scripts/collect_idl_files.pydeps index 8546f9e4066..6e4c70168ba 100644 --- a/chromium/third_party/blink/renderer/bindings/scripts/collect_idl_files.pydeps +++ b/chromium/third_party/blink/renderer/bindings/scripts/collect_idl_files.pydeps @@ -8,11 +8,8 @@ ../../../../ply/lex.py ../../../../ply/yacc.py ../../../../pyjson5/src/json5/__init__.py -../../../../pyjson5/src/json5/arg_parser.py -../../../../pyjson5/src/json5/host.py ../../../../pyjson5/src/json5/lib.py ../../../../pyjson5/src/json5/parser.py -../../../../pyjson5/src/json5/tool.py ../../../../pyjson5/src/json5/version.py ../../build/scripts/blinkbuild/__init__.py ../../build/scripts/blinkbuild/name_style_converter.py diff --git a/chromium/third_party/blink/renderer/bindings/scripts/generate_bindings.py b/chromium/third_party/blink/renderer/bindings/scripts/generate_bindings.py index 51c66c38c5e..a732672fb04 100644 --- a/chromium/third_party/blink/renderer/bindings/scripts/generate_bindings.py +++ b/chromium/third_party/blink/renderer/bindings/scripts/generate_bindings.py @@ -59,7 +59,6 @@ def main(): 'dictionary': bind_gen.generate_dictionaries, 'enumeration': bind_gen.generate_enumerations, 'interface': bind_gen.generate_interfaces, - 'union': bind_gen.generate_unions, } for task in tasks: @@ -72,14 +71,29 @@ def main(): web_idl.Component('core'): options.output_core_reldir, web_idl.Component('modules'): options.output_modules_reldir, } - bind_gen.init( root_src_dir=options.root_src_dir, root_gen_dir=options.root_gen_dir, component_reldirs=component_reldirs) + task_queue = bind_gen.TaskQueue() + for task in tasks: - dispatch_table[task](web_idl_database=web_idl_database) + dispatch_table[task](task_queue=task_queue, + web_idl_database=web_idl_database) + + def report_progress(total, done): + out = sys.stdout + if not out.isatty(): + return + if total == 0: + return + percentage = int(float(done) / float(total) * 100) + message = "Blink-V8 bindings generation: {}% done\r".format(percentage) + out.write(message) + out.flush() + + task_queue.run(report_progress) if __name__ == '__main__': diff --git a/chromium/third_party/blink/renderer/bindings/scripts/generate_bindings.pydeps b/chromium/third_party/blink/renderer/bindings/scripts/generate_bindings.pydeps index 1a7000a8e81..8f86db1d217 100644 --- a/chromium/third_party/blink/renderer/bindings/scripts/generate_bindings.pydeps +++ b/chromium/third_party/blink/renderer/bindings/scripts/generate_bindings.pydeps @@ -20,11 +20,8 @@ ../../../../markupsafe/_compat.py ../../../../markupsafe/_native.py ../../../../pyjson5/src/json5/__init__.py -../../../../pyjson5/src/json5/arg_parser.py -../../../../pyjson5/src/json5/host.py ../../../../pyjson5/src/json5/lib.py ../../../../pyjson5/src/json5/parser.py -../../../../pyjson5/src/json5/tool.py ../../../../pyjson5/src/json5/version.py ../../build/scripts/blinkbuild/__init__.py ../../build/scripts/blinkbuild/name_style_converter.py @@ -45,7 +42,7 @@ bind_gen/name_style.py bind_gen/package_initializer.py bind_gen/path_manager.py bind_gen/style_format.py -bind_gen/union.py +bind_gen/task_queue.py generate_bindings.py web_idl/__init__.py web_idl/argument.py diff --git a/chromium/third_party/blink/renderer/bindings/scripts/generate_high_entropy_list.pydeps b/chromium/third_party/blink/renderer/bindings/scripts/generate_high_entropy_list.pydeps index 1d9e7f3b75a..7e87841737b 100644 --- a/chromium/third_party/blink/renderer/bindings/scripts/generate_high_entropy_list.pydeps +++ b/chromium/third_party/blink/renderer/bindings/scripts/generate_high_entropy_list.pydeps @@ -1,11 +1,8 @@ # Generated by running: # build/print_python_deps.py --root third_party/blink/renderer/bindings/scripts --output third_party/blink/renderer/bindings/scripts/generate_high_entropy_list.pydeps third_party/blink/renderer/bindings/scripts/generate_high_entropy_list.py ../../../../pyjson5/src/json5/__init__.py -../../../../pyjson5/src/json5/arg_parser.py -../../../../pyjson5/src/json5/host.py ../../../../pyjson5/src/json5/lib.py ../../../../pyjson5/src/json5/parser.py -../../../../pyjson5/src/json5/tool.py ../../../../pyjson5/src/json5/version.py ../../build/scripts/blinkbuild/__init__.py ../../build/scripts/blinkbuild/name_style_converter.py diff --git a/chromium/third_party/blink/renderer/bindings/scripts/generate_origin_trial_features.py b/chromium/third_party/blink/renderer/bindings/scripts/generate_origin_trial_features.py index c2b40844ad1..64c6b5e4189 100755 --- a/chromium/third_party/blink/renderer/bindings/scripts/generate_origin_trial_features.py +++ b/chromium/third_party/blink/renderer/bindings/scripts/generate_origin_trial_features.py @@ -39,12 +39,20 @@ def get_install_functions(interfaces, feature_names): be installed on those interfaces. """ return [{ - 'condition': 'RuntimeEnabledFeatures::%sEnabled' % feature_name, - 'name': feature_name, - 'install_method': 'Install%s' % feature_name, - 'interface_is_global': interface_info.is_global, - 'v8_class': interface_info.v8_class, - 'v8_class_or_partial': interface_info.v8_class_or_partial + 'condition': + 'RuntimeEnabledFeatures::%sEnabled' % feature_name, + 'name': + feature_name, + 'install_method': + 'Install%s' % feature_name, + 'interface_is_global': + interface_info.is_global, + 'global_type_check_method': + interface_global_type_check_method(interface_info), + 'v8_class': + interface_info.v8_class, + 'v8_class_or_partial': + interface_info.v8_class_or_partial, } for feature_name in feature_names for interface_info in interfaces] @@ -69,7 +77,9 @@ def read_idl_file(reader, idl_filename): interfaces = definitions.interfaces includes = definitions.includes # There should only be a single interface defined in an IDL file. Return it. - assert len(interfaces) == 1 + assert len(interfaces) == 1, ( + "Expected one interface in file %r, found %d" % + (idl_filename, len(interfaces))) return (interfaces.values()[0], includes) @@ -77,6 +87,21 @@ def interface_is_global(interface): return 'Global' in interface.extended_attributes +def interface_global_type_check_method(interface_info): + """Generate the name of the method on ExecutionContext used to check if the + context matches the type of the interface, which is a global. + + Returns None for non-global interfaces. + """ + if not interface_info.is_global: + return None + + if interface_info.name == 'Window': + return 'IsDocument' + + return 'Is%s' % interface_info.name + + def origin_trial_features_info(info_provider, reader, idl_filenames, target_component): """Read a set of IDL files and compile the mapping between interfaces and @@ -108,7 +133,9 @@ def origin_trial_features_info(info_provider, reader, idl_filenames, # If this interface include another one, # it inherits any conditional features from it. for include in includes: - assert include.interface == interface.name + assert include.interface == interface.name, ( + "'includes' interface identifier %r in file %r should be %r" % + (include.interface, idl_filename, interface.name)) mixin, _ = read_idl_file( reader, info_provider.interfaces_info[include.mixin].get('full_path')) diff --git a/chromium/third_party/blink/renderer/bindings/scripts/idl_definitions.py b/chromium/third_party/blink/renderer/bindings/scripts/idl_definitions.py index 11f6846eef2..e102585bd6a 100644 --- a/chromium/third_party/blink/renderer/bindings/scripts/idl_definitions.py +++ b/chromium/third_party/blink/renderer/bindings/scripts/idl_definitions.py @@ -331,7 +331,7 @@ class IdlInterface(object): custom_constructor_operations = [] constructor_operations_extended_attributes = {} - def is_blacklisted_attribute_type(idl_type): + def is_invalid_attribute_type(idl_type): return idl_type.is_callback_function or \ idl_type.is_dictionary or \ idl_type.is_record_type or \ @@ -342,7 +342,7 @@ class IdlInterface(object): child_class = child.GetClass() if child_class == 'Attribute': attr = IdlAttribute(child) - if is_blacklisted_attribute_type(attr.idl_type): + if is_invalid_attribute_type(attr.idl_type): raise ValueError( 'Type "%s" cannot be used as an attribute.' % attr.idl_type) diff --git a/chromium/third_party/blink/renderer/bindings/scripts/utilities.py b/chromium/third_party/blink/renderer/bindings/scripts/utilities.py index 1dc06544585..afff090609c 100644 --- a/chromium/third_party/blink/renderer/bindings/scripts/utilities.py +++ b/chromium/third_party/blink/renderer/bindings/scripts/utilities.py @@ -499,6 +499,9 @@ def shorten_union_name(union_type): # modules/canvas/offscreencanvas/offscreen_canvas_module.idl 'OffscreenCanvasRenderingContext2DOrWebGLRenderingContextOrWebGL2RenderingContextOrImageBitmapRenderingContext': 'OffscreenRenderingContext', + # core/xmlhttprequest/xml_http_request.idl + 'DocumentOrBlobOrArrayBufferOrArrayBufferViewOrFormDataOrURLSearchParamsOrUSVString': + 'DocumentOrXMLHttpRequestBodyInit', } idl_type = union_type diff --git a/chromium/third_party/blink/renderer/bindings/scripts/v8_attributes.py b/chromium/third_party/blink/renderer/bindings/scripts/v8_attributes.py index 60351a54cd0..99d20da5ec4 100644 --- a/chromium/third_party/blink/renderer/bindings/scripts/v8_attributes.py +++ b/chromium/third_party/blink/renderer/bindings/scripts/v8_attributes.py @@ -408,7 +408,8 @@ def getter_context(interface, attribute, context): or 'CachedAttribute' in extended_attributes or 'ReflectOnly' in extended_attributes or context['is_keep_alive_for_gc'] - or context['is_getter_raises_exception']): + or context['is_getter_raises_exception'] + or context['high_entropy'] == 'Direct'): context['cpp_value_original'] = cpp_value cpp_value = 'cpp_value' @@ -442,6 +443,9 @@ def getter_context(interface, attribute, context): cpp_value=cpp_value, creation_context='holder', extended_attributes=extended_attributes), + 'is_getter_call_with_script_state': + has_extended_attribute_value(attribute, 'GetterCallWith', + 'ScriptState'), 'v8_set_return_value_for_main_world': v8_set_return_value_statement(for_main_world=True), 'v8_set_return_value': @@ -455,10 +459,9 @@ def getter_expression(interface, attribute, context): extra_arguments) getter_name = scoped_name(interface, attribute, this_getter_base_name) - arguments = [] - arguments.extend( - v8_utilities.call_with_arguments( - attribute.extended_attributes.get('CallWith'))) + arguments = v8_utilities.call_with_arguments( + attribute.extended_attributes.get('GetterCallWith') + or attribute.extended_attributes.get('CallWith')) # Members of IDL partial interface definitions are implemented in C++ as # static member functions, which for instance members (non-static members) # take *impl as their first argument diff --git a/chromium/third_party/blink/renderer/bindings/scripts/v8_dictionary.py b/chromium/third_party/blink/renderer/bindings/scripts/v8_dictionary.py index c799496ec88..81b0e6b99d8 100644 --- a/chromium/third_party/blink/renderer/bindings/scripts/v8_dictionary.py +++ b/chromium/third_party/blink/renderer/bindings/scripts/v8_dictionary.py @@ -33,6 +33,11 @@ def getter_name_for_dictionary_member(member): return NameStyleConverter(name).to_lower_camel_case() +def non_null_getter_name_for_dictionary_member(member): + name = v8_utilities.cpp_name(member) + return NameStyleConverter('{}_non_null'.format(name)).to_lower_camel_case() + + def setter_name_for_dictionary_member(member): name = 'set_{}'.format(v8_utilities.cpp_name(member)) return NameStyleConverter(name).to_lower_camel_case() @@ -50,6 +55,11 @@ def has_method_name_for_dictionary_member(member): return name.to_lower_camel_case() +def non_null_has_method_name_for_dictionary_member(member, for_non_null=False): + name = 'has_{}_non_null'.format(v8_utilities.cpp_name(member)) + return NameStyleConverter(name).to_lower_camel_case() + + def unwrap_nullable_if_needed(idl_type): if idl_type.is_nullable: return idl_type.inner_type @@ -343,20 +353,23 @@ def member_impl_context(member, interfaces_info, header_includes, 'has_method_name': has_method_name_for_dictionary_member(member), 'is_nullable': - idl_type.is_nullable, + member.idl_type.is_nullable, 'is_traceable': idl_type.is_traceable, 'member_cpp_type': - idl_type.cpp_type_args( - used_in_cpp_sequence=True, - extended_attributes=extended_attributes), + idl_type.cpp_type_args(used_in_cpp_sequence=True, + extended_attributes=extended_attributes), + 'non_null_getter_name': + non_null_getter_name_for_dictionary_member(member), + 'non_null_has_method_name': + non_null_has_method_name_for_dictionary_member(member), 'null_setter_name': null_setter_name_for_dictionary_member(member), 'nullable_indicator_name': nullable_indicator_name, 'rvalue_cpp_type': - idl_type.cpp_type_args( - used_as_rvalue_type=True, extended_attributes=extended_attributes), + idl_type.cpp_type_args(used_as_rvalue_type=True, + extended_attributes=extended_attributes), 'setter_inline': setter_inline, 'setter_name': diff --git a/chromium/third_party/blink/renderer/bindings/scripts/v8_interface.py b/chromium/third_party/blink/renderer/bindings/scripts/v8_interface.py index 65730ff17fd..7d95aee2fd7 100644 --- a/chromium/third_party/blink/renderer/bindings/scripts/v8_interface.py +++ b/chromium/third_party/blink/renderer/bindings/scripts/v8_interface.py @@ -1095,8 +1095,6 @@ def overloads_context(interface, overloads): method['overload_index'] = index # [RuntimeEnabled] - # TODO(iclelland): Allow origin trials on method overloads - # (crbug.com/621641) if any(method.get('origin_trial_feature_name') for method in overloads): raise Exception( '[RuntimeEnabled] for origin trial cannot be specified on ' diff --git a/chromium/third_party/blink/renderer/bindings/scripts/v8_types.py b/chromium/third_party/blink/renderer/bindings/scripts/v8_types.py index 642b122f26c..3ae15c35ac5 100644 --- a/chromium/third_party/blink/renderer/bindings/scripts/v8_types.py +++ b/chromium/third_party/blink/renderer/bindings/scripts/v8_types.py @@ -85,8 +85,8 @@ ARRAY_BUFFER_AND_VIEW_TYPES = TYPED_ARRAY_TYPES.union( 'SharedArrayBuffer', ])) # We have an unfortunate hack that treats types whose name ends with -# 'Constructor' as aliases to IDL interface object. This white list is used to -# disable the hack. +# 'Constructor' as aliases to IDL interface object. This list is used to disable +# the hack. _CALLBACK_CONSTRUCTORS = frozenset(( 'AnimatorConstructor', 'BlinkAudioWorkletProcessorConstructor', @@ -552,6 +552,11 @@ def impl_includes_for_type(idl_type, interfaces_info): base_idl_type = idl_type.base_type if idl_type.is_string_type: includes_for_type.add('platform/wtf/text/wtf_string.h') + if idl_type.is_record_type: + includes_for_type.update(impl_includes_for_type(idl_type.key_type, + interfaces_info)) + includes_for_type.update(impl_includes_for_type(idl_type.value_type, + interfaces_info)) if idl_type.is_callback_function: component = IdlType.callback_functions[base_idl_type]['component_dir'] return set([ diff --git a/chromium/third_party/blink/renderer/bindings/scripts/v8_utilities.py b/chromium/third_party/blink/renderer/bindings/scripts/v8_utilities.py index d6a53c6538a..7fe94fe28f0 100644 --- a/chromium/third_party/blink/renderer/bindings/scripts/v8_utilities.py +++ b/chromium/third_party/blink/renderer/bindings/scripts/v8_utilities.py @@ -453,6 +453,8 @@ def high_entropy(definition_or_member): raise Exception( '%s specified [HighEntropy], but does not include ' 'either [Measure] or [MeasureAs]' % definition_or_member.name) + if extended_attributes['HighEntropy'] == 'Direct': + return 'Direct' return True return False diff --git a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/runtime_enabled_features.json5 b/chromium/third_party/blink/renderer/bindings/scripts/web_idl/runtime_enabled_features.json5 deleted file mode 100644 index 151d8d0ff4f..00000000000 --- a/chromium/third_party/blink/renderer/bindings/scripts/web_idl/runtime_enabled_features.json5 +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - - -// This file is used only for testing purposes, and is never used for -// production. For production purposes, see the following file: -// //third_party/blink/renderer/platform/runtime_enabled_features.json5 -// -// This file is used to add runtime enabled features in order to test the Web -// IDL compiler and bindings code generator. - -{ - data: [ - { - name: "TestFeature1", - }, - { - name: "TestFeature2", - origin_trial_feature_name: "TestFeature2", - }, - ] -} diff --git a/chromium/third_party/blink/renderer/bindings/templates/attributes.cc.tmpl b/chromium/third_party/blink/renderer/bindings/templates/attributes.cc.tmpl index 47ce2f75275..c8ecb1c3758 100644 --- a/chromium/third_party/blink/renderer/bindings/templates/attributes.cc.tmpl +++ b/chromium/third_party/blink/renderer/bindings/templates/attributes.cc.tmpl @@ -114,7 +114,8 @@ const v8::FunctionCallbackInfo<v8::Value>& info } {% endif %} - {% if attribute.is_call_with_execution_context %} + {% if attribute.is_call_with_execution_context or + attribute.high_entropy == 'Direct' %} {% if attribute.is_static %} ExecutionContext* execution_context = ExecutionContext::ForCurrentRealm(info); {% else %} @@ -122,7 +123,8 @@ const v8::FunctionCallbackInfo<v8::Value>& info {% endif %} {% endif %} - {% if attribute.is_call_with_script_state %} + {% if attribute.is_call_with_script_state or + attribute.is_getter_call_with_script_state %} {% if attribute.is_static %} ScriptState* script_state = ScriptState::ForCurrentRealm(info); {% else %} @@ -138,6 +140,10 @@ const v8::FunctionCallbackInfo<v8::Value>& info {{attribute.cpp_type}} {{attribute.cpp_value}}({{attribute.cpp_value_original}}); {% endif %} + {% if attribute.high_entropy == 'Direct' %} + Dactyloscoper::RecordDirectSurface(execution_context, WebFeature::k{{attribute.measure_as('AttributeGetter')}}, {{attribute.cpp_value}}); + {% endif %} + {% if attribute.use_output_parameter_for_result %} {{attribute.cpp_type}} result; {{attribute.cpp_value}}; @@ -455,7 +461,7 @@ static void {{attribute.camel_case_name}}AttributeSetter{{world_suffix}}( {% endif %} {% if attribute.is_call_with_script_state or - attribute.is_setter_call_with_script_state %} + attribute.is_setter_call_with_script_state %} {% if attribute.is_static %} ScriptState* script_state = ScriptState::ForCurrentRealm(info); {% else %} @@ -573,7 +579,7 @@ void {{v8_class_or_partial}}::{{attribute.camel_case_name}}AttributeSetterCallba {% set setter_callback_for_main_world = '%sForMainWorld' % setter_callback if attribute.has_setter else 'nullptr' %} {% endif %} -{% set config_pre = { +{% set world_dependent_config = { 'main' : [ '"%s"' % attribute.name, getter_callback_for_main_world, @@ -585,26 +591,37 @@ void {{v8_class_or_partial}}::{{attribute.camel_case_name}}AttributeSetterCallba setter_callback, ], } %} -{% set accessor_only_fields = [] if config_type == 'attribute' else [cached_property_key] %} -{% set config_post = [ +{% if config_type == 'attribute' %} +{% set world_common_config = [ property_attribute, property_location(attribute), holder_check, getter_side_effect_type, getter_behavior, ] %} +{% else %}{# config_type == 'accessor' #} +{% set world_common_config = [ + cached_property_key, + property_attribute, + property_location(attribute), + holder_check, + 'V8DOMConfiguration::kCheckAccess', + 'V8DOMConfiguration::kCheckAccess', + getter_side_effect_type, +] %} +{% endif %} {% if attribute.is_per_world_bindings %} - {% set main_config_list = config_pre["main"] + accessor_only_fields + - config_post + ['V8DOMConfiguration::kMainWorld'] %} - {% set non_main_config_list = config_pre["non_main"] + accessor_only_fields + - config_post + ['V8DOMConfiguration::kNonMainWorlds'] %} + {% set main_config_list = world_dependent_config["main"] + + world_common_config + ['V8DOMConfiguration::kMainWorld'] %} + {% set non_main_config_list = world_dependent_config["non_main"] + + world_common_config + ['V8DOMConfiguration::kNonMainWorlds'] %} {# Emit for main world then non-main.#} { {{main_config_list | join(', ')}} }, { {{non_main_config_list | join(', ')}} } {%- else -%} - {% set all_worlds_config_list = config_pre["non_main"] + accessor_only_fields + - config_post + ['V8DOMConfiguration::kAllWorlds'] %} + {% set all_worlds_config_list = world_dependent_config["non_main"] + + world_common_config + ['V8DOMConfiguration::kAllWorlds'] %} {# Emit only for all worlds #} { {{all_worlds_config_list | join(', ')}} } {%- endif -%} diff --git a/chromium/third_party/blink/renderer/bindings/templates/dictionary_impl.cc.tmpl b/chromium/third_party/blink/renderer/bindings/templates/dictionary_impl.cc.tmpl index f533b68857a..14c6a2c66a5 100644 --- a/chromium/third_party/blink/renderer/bindings/templates/dictionary_impl.cc.tmpl +++ b/chromium/third_party/blink/renderer/bindings/templates/dictionary_impl.cc.tmpl @@ -27,7 +27,7 @@ namespace blink { {{dictionary_setter_impl(member)}} {% endfor %} -void {{cpp_class}}::Trace(Visitor* visitor) { +void {{cpp_class}}::Trace(Visitor* visitor) const { {% for member in members if member.is_traceable %} visitor->Trace({{member.cpp_name}}_); {% endfor %} diff --git a/chromium/third_party/blink/renderer/bindings/templates/dictionary_impl.h.tmpl b/chromium/third_party/blink/renderer/bindings/templates/dictionary_impl.h.tmpl index 465c2688d95..2571de7d264 100644 --- a/chromium/third_party/blink/renderer/bindings/templates/dictionary_impl.h.tmpl +++ b/chromium/third_party/blink/renderer/bindings/templates/dictionary_impl.h.tmpl @@ -38,10 +38,22 @@ class {{exported}}{{cpp_class}} : public {{parent_cpp_class}} { {% if member.null_setter_name %} {{member.setter_inline}}void {{member.null_setter_name}}(); {% endif %} + {% if member.is_nullable %} + // Migration adapters + // Returns true iff this member has a non-null value. Returns false if the + // value is missing or a null value. + bool {{member.non_null_has_method_name}}() const { return {{member.has_method_expression}}; } + // Returns the value if this member has a non-null value. Call + // |{{member.non_null_has_method_name}}| in advance to check the condition. + {{member.rvalue_cpp_type}} {{member.non_null_getter_name}}() const { + DCHECK({{member.non_null_has_method_name}}()); + return {{member.getter_expression}}; + } + {% endif %} {% endfor %} v8::Local<v8::Value> ToV8Impl(v8::Local<v8::Object>, v8::Isolate*) const override; - void Trace(Visitor*) override; + void Trace(Visitor*) const override; private: {% for member in members if member.nullable_indicator_name %} diff --git a/chromium/third_party/blink/renderer/bindings/templates/origin_trial_features_for_core.cc.tmpl b/chromium/third_party/blink/renderer/bindings/templates/origin_trial_features_for_core.cc.tmpl index ddb012a198b..57f28d7ffb7 100644 --- a/chromium/third_party/blink/renderer/bindings/templates/origin_trial_features_for_core.cc.tmpl +++ b/chromium/third_party/blink/renderer/bindings/templates/origin_trial_features_for_core.cc.tmpl @@ -72,14 +72,20 @@ void InstallPendingOriginTrialFeatureForCore(OriginTrialFeature feature, v8::Isolate* isolate = script_state->GetIsolate(); const DOMWrapperWorld& world = script_state->World(); V8PerContextData* context_data = script_state->PerContextData(); + v8::Local<v8::Context> current_context = script_state->GetContext(); + v8::Local<v8::Object> global_object = current_context->Global(); + ALLOW_UNUSED_LOCAL(global_object); + ExecutionContext* execution_context = ToExecutionContext(current_context); + ALLOW_UNUSED_LOCAL(execution_context); switch (feature) { {% for feature in installers_by_feature %} case {{feature.name_constant}}: { {% for installer in feature.installers %} {% if installer.interface_is_global %} - {{installer.v8_class_or_partial}}::{{installer.install_method}}( - isolate, world, script_state->GetContext()->Global(), - v8::Local<v8::Object>(), v8::Local<v8::Function>()); + if (execution_context && execution_context->{{installer.global_type_check_method}}()) { + {{installer.v8_class_or_partial}}::{{installer.install_method}}( + isolate, world, global_object, v8::Local<v8::Object>(), v8::Local<v8::Function>()); + } {% else %} if (context_data->GetExistingConstructorAndPrototypeForType( {{installer.v8_class}}::GetWrapperTypeInfo(), &prototype_object, &interface_object)) { diff --git a/chromium/third_party/blink/renderer/bindings/templates/origin_trial_features_for_modules.cc.tmpl b/chromium/third_party/blink/renderer/bindings/templates/origin_trial_features_for_modules.cc.tmpl index 9f4921b52de..e61bd0617eb 100644 --- a/chromium/third_party/blink/renderer/bindings/templates/origin_trial_features_for_modules.cc.tmpl +++ b/chromium/third_party/blink/renderer/bindings/templates/origin_trial_features_for_modules.cc.tmpl @@ -64,14 +64,20 @@ void InstallPendingOriginTrialFeatureForModules( v8::Isolate* isolate = script_state->GetIsolate(); const DOMWrapperWorld& world = script_state->World(); V8PerContextData* context_data = script_state->PerContextData(); + v8::Local<v8::Context> current_context = script_state->GetContext(); + v8::Local<v8::Object> global_object = current_context->Global(); + ALLOW_UNUSED_LOCAL(global_object); + ExecutionContext* execution_context = ToExecutionContext(current_context); + ALLOW_UNUSED_LOCAL(execution_context); switch (feature) { {% for feature in installers_by_feature %} case {{feature.name_constant}}: { {% for installer in feature.installers %} {% if installer.interface_is_global %} - {{installer.v8_class_or_partial}}::{{installer.install_method}}( - isolate, world, script_state->GetContext()->Global(), - v8::Local<v8::Object>(), v8::Local<v8::Function>()); + if (execution_context && execution_context->{{installer.global_type_check_method}}()) { + {{installer.v8_class_or_partial}}::{{installer.install_method}}( + isolate, world, global_object, v8::Local<v8::Object>(), v8::Local<v8::Function>()); + } {% else %} if (context_data->GetExistingConstructorAndPrototypeForType( {{installer.v8_class}}::GetWrapperTypeInfo(), &prototype_object, &interface_object)) { diff --git a/chromium/third_party/blink/renderer/bindings/templates/union_container.cc.tmpl b/chromium/third_party/blink/renderer/bindings/templates/union_container.cc.tmpl index 0599b20b16c..90e1e25f3f7 100644 --- a/chromium/third_party/blink/renderer/bindings/templates/union_container.cc.tmpl +++ b/chromium/third_party/blink/renderer/bindings/templates/union_container.cc.tmpl @@ -62,7 +62,7 @@ void {{cpp_class}}::Set{{member.type_name}}({{member.rvalue_cpp_type}} value) { {{cpp_class}}::~{{cpp_class}}() = default; {{cpp_class}}& {{cpp_class}}::operator=(const {{cpp_class}}&) = default; -void {{cpp_class}}::Trace(Visitor* visitor) { +void {{cpp_class}}::Trace(Visitor* visitor) const { {% for member in members if member.is_traceable %} visitor->Trace({{member.cpp_name}}_); {% endfor %} diff --git a/chromium/third_party/blink/renderer/bindings/templates/union_container.h.tmpl b/chromium/third_party/blink/renderer/bindings/templates/union_container.h.tmpl index f2463c68930..374868f4419 100644 --- a/chromium/third_party/blink/renderer/bindings/templates/union_container.h.tmpl +++ b/chromium/third_party/blink/renderer/bindings/templates/union_container.h.tmpl @@ -30,7 +30,7 @@ class {{exported}}{{cpp_class}} final { {{cpp_class}}(const {{cpp_class}}&); ~{{cpp_class}}(); {{cpp_class}}& operator=(const {{cpp_class}}&); - void Trace(Visitor*); + void Trace(Visitor*) const; private: enum class SpecificType { diff --git a/chromium/third_party/blink/renderer/bindings/templates/utilities.cc.tmpl b/chromium/third_party/blink/renderer/bindings/templates/utilities.cc.tmpl index 035dbf2cd80..1a81c99dd0f 100644 --- a/chromium/third_party/blink/renderer/bindings/templates/utilities.cc.tmpl +++ b/chromium/third_party/blink/renderer/bindings/templates/utilities.cc.tmpl @@ -11,7 +11,7 @@ {% else %} {% if item.declare_variable %} {% if item.assign_expression %} -{{item.cpp_type}} {{item.cpp_name}} = {{item.assign_expression}}; +{{item.cpp_type}} {{item.cpp_name}}{ {{item.assign_expression}} }; {% else %} {{item.cpp_type}} {{item.cpp_name}}; {% endif %} |