diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-01-23 17:21:03 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-01-23 16:25:15 +0000 |
commit | c551f43206405019121bd2b2c93714319a0a3300 (patch) | |
tree | 1f48c30631c421fd4bbb3c36da20183c8a2ed7d7 /chromium/third_party/blink/renderer/bindings/core | |
parent | 7961cea6d1041e3e454dae6a1da660b453efd238 (diff) | |
download | qtwebengine-chromium-c551f43206405019121bd2b2c93714319a0a3300.tar.gz |
BASELINE: Update Chromium to 79.0.3945.139
Change-Id: I336b7182fab9bca80b709682489c07db112eaca5
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/third_party/blink/renderer/bindings/core')
78 files changed, 686 insertions, 756 deletions
diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/DEPS b/chromium/third_party/blink/renderer/bindings/core/v8/DEPS new file mode 100644 index 00000000000..c386e5e6f34 --- /dev/null +++ b/chromium/third_party/blink/renderer/bindings/core/v8/DEPS @@ -0,0 +1,5 @@ +specific_include_rules = { + "script_promise_resolver_test.cc": [ + "+base/run_loop.h", + ] +}
\ No newline at end of file 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 29ab49d8a63..f2c6c2ed25f 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 @@ -30,6 +30,7 @@ #include "third_party/blink/renderer/bindings/core/v8/binding_security.h" +#include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" #include "third_party/blink/renderer/bindings/core/v8/v8_location.h" #include "third_party/blink/renderer/bindings/core/v8/v8_window.h" 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 2daa9ac0eb0..e5d11a33924 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 @@ -18,8 +18,7 @@ namespace blink { // Hash of Member<BoxedV8Module> overrides HashTraits. // Therefore, BoxedV8Module can be a key/value type of WTF::HashMap, // HashSet,HashTable by using BoxedV8ModuleHash. -class CORE_EXPORT BoxedV8Module - : public GarbageCollectedFinalized<BoxedV8Module> { +class CORE_EXPORT BoxedV8Module final : public GarbageCollected<BoxedV8Module> { public: BoxedV8Module(v8::Isolate* isolate, v8::Local<v8::Module> module) : record_(isolate, module), diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_pop_state_event_custom.cc b/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_pop_state_event_custom.cc index 28c17d96664..5ac764eb377 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_pop_state_event_custom.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_pop_state_event_custom.cc @@ -37,12 +37,6 @@ namespace blink { -namespace { -// |kHistoryStateSymbolKey| is a key for a cached attribute for History.state. -// TODO(peria): Do not use this cached attribute directly. -constexpr char kHistoryStateSymbolKey[] = "History#State"; -} - // Save the state value to a hidden attribute in the V8PopStateEvent, and return // it, for convenience. static v8::Local<v8::Value> CacheState(ScriptState* script_state, @@ -94,7 +88,7 @@ void V8PopStateEvent::StateAttributeGetterCustom( bool is_same_state = history->IsSameAsCurrentState(event->SerializedState()); if (is_same_state) { V8PrivateProperty::Symbol history_state = - V8PrivateProperty::GetSymbol(isolate, kHistoryStateSymbolKey); + V8PrivateProperty::GetHistoryStateSymbol(info.GetIsolate()); v8::Local<v8::Value> v8_history_value = ToV8(history, info.Holder(), isolate); if (v8_history_value.IsEmpty()) diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_readable_stream_custom.cc b/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_readable_stream_custom.cc deleted file mode 100644 index d0e9fe48b4c..00000000000 --- a/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_readable_stream_custom.cc +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "third_party/blink/renderer/bindings/core/v8/v8_readable_stream.h" - -#include "third_party/blink/renderer/bindings/core/v8/script_value.h" -#include "third_party/blink/renderer/core/streams/readable_stream_native.h" -#include "third_party/blink/renderer/core/streams/readable_stream_wrapper.h" -#include "third_party/blink/renderer/platform/bindings/exception_state.h" -#include "third_party/blink/renderer/platform/bindings/script_state.h" -#include "third_party/blink/renderer/platform/bindings/v8_binding.h" -#include "third_party/blink/renderer/platform/runtime_enabled_features.h" -#include "v8/include/v8.h" - -namespace blink { - -void V8ReadableStream::ConstructorCustom( - const v8::FunctionCallbackInfo<v8::Value>& info) { - RUNTIME_CALL_TIMER_SCOPE_DISABLED_BY_DEFAULT( - info.GetIsolate(), "Blink_ReadableStream_ConstructorCallback"); - - ExceptionState exception_state(info.GetIsolate(), - ExceptionState::kConstructionContext, - "ReadableStream"); - ScriptState* script_state = - ScriptState::From(info.NewTarget().As<v8::Object>()->CreationContext()); - - ScriptValue underlying_source = - ScriptValue(ScriptState::Current(info.GetIsolate()), - v8::Undefined(info.GetIsolate())); - ScriptValue strategy = ScriptValue(ScriptState::Current(info.GetIsolate()), - v8::Undefined(info.GetIsolate())); - int num_args = info.Length(); - if (num_args >= 1) { - underlying_source = - ScriptValue(ScriptState::Current(info.GetIsolate()), info[0]); - } - if (num_args >= 2) - strategy = ScriptValue(ScriptState::Current(info.GetIsolate()), info[1]); - - v8::Local<v8::Object> wrapper = info.Holder(); - if (RuntimeEnabledFeatures::StreamsNativeEnabled()) { - auto* impl = MakeGarbageCollected<ReadableStreamNative>( - script_state, underlying_source, strategy, false, exception_state); - if (exception_state.HadException()) { - return; - } - wrapper = impl->AssociateWithWrapper( - info.GetIsolate(), V8ReadableStream::GetWrapperTypeInfo(), wrapper); - } else { - auto* impl = MakeGarbageCollected<ReadableStreamWrapper>(); - wrapper = impl->AssociateWithWrapper( - info.GetIsolate(), V8ReadableStream::GetWrapperTypeInfo(), wrapper); - - impl->Init(script_state, underlying_source, strategy, exception_state); - if (exception_state.HadException()) { - return; - } - } - V8SetReturnValue(info, wrapper); -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_writable_stream_custom.cc b/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_writable_stream_custom.cc deleted file mode 100644 index 2f67ed55f98..00000000000 --- a/chromium/third_party/blink/renderer/bindings/core/v8/custom/v8_writable_stream_custom.cc +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this sink code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "third_party/blink/renderer/bindings/core/v8/v8_writable_stream.h" - -#include "third_party/blink/renderer/bindings/core/v8/script_value.h" -#include "third_party/blink/renderer/core/streams/writable_stream_native.h" -#include "third_party/blink/renderer/core/streams/writable_stream_wrapper.h" -#include "third_party/blink/renderer/platform/bindings/exception_state.h" -#include "third_party/blink/renderer/platform/bindings/script_state.h" -#include "third_party/blink/renderer/platform/bindings/v8_binding.h" -#include "third_party/blink/renderer/platform/runtime_enabled_features.h" -#include "v8/include/v8.h" - -namespace blink { - -void V8WritableStream::ConstructorCustom( - const v8::FunctionCallbackInfo<v8::Value>& info) { - RUNTIME_CALL_TIMER_SCOPE_DISABLED_BY_DEFAULT( - info.GetIsolate(), "Blink_WritableStream_ConstructorCallback"); - - ExceptionState exception_state(info.GetIsolate(), - ExceptionState::kConstructionContext, - "WritableStream"); - ScriptState* script_state = - ScriptState::From(info.NewTarget().As<v8::Object>()->CreationContext()); - - ScriptValue underlying_sink = - ScriptValue(ScriptState::Current(info.GetIsolate()), - v8::Undefined(info.GetIsolate())); - ScriptValue strategy = ScriptValue(ScriptState::Current(info.GetIsolate()), - v8::Undefined(info.GetIsolate())); - int num_args = info.Length(); - if (num_args >= 1) { - underlying_sink = - ScriptValue(ScriptState::Current(info.GetIsolate()), info[0]); - } - if (num_args >= 2) - strategy = ScriptValue(ScriptState::Current(info.GetIsolate()), info[1]); - v8::Local<v8::Object> wrapper = info.Holder(); - - if (RuntimeEnabledFeatures::StreamsNativeEnabled()) { - auto* impl = MakeGarbageCollected<WritableStreamNative>( - script_state, underlying_sink, strategy, exception_state); - if (exception_state.HadException()) { - return; - } - wrapper = impl->AssociateWithWrapper( - info.GetIsolate(), V8WritableStream::GetWrapperTypeInfo(), wrapper); - } else { - auto* impl = MakeGarbageCollected<WritableStreamWrapper>(); - wrapper = impl->AssociateWithWrapper( - info.GetIsolate(), V8WritableStream::GetWrapperTypeInfo(), wrapper); - impl->Init(script_state, underlying_sink, strategy, exception_state); - if (exception_state.HadException()) { - return; - } - } - - V8SetReturnValue(info, wrapper); -} - -} // 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 a6bbfaf20dc..5e20c3cff75 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/idl_dictionary_base.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/idl_dictionary_base.h @@ -16,7 +16,7 @@ namespace blink { // by auto-generated IDL dictionary impl classes. toV8Impl() is used // in ToV8.h to provide a consistent API of ToV8(). class CORE_EXPORT IDLDictionaryBase - : public GarbageCollectedFinalized<IDLDictionaryBase> { + : public GarbageCollected<IDLDictionaryBase> { public: virtual ~IDLDictionaryBase() = default; diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/initialize_v8_extras_binding.cc b/chromium/third_party/blink/renderer/bindings/core/v8/initialize_v8_extras_binding.cc deleted file mode 100644 index fe15e880fe2..00000000000 --- a/chromium/third_party/blink/renderer/bindings/core/v8/initialize_v8_extras_binding.cc +++ /dev/null @@ -1,180 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "third_party/blink/renderer/bindings/core/v8/initialize_v8_extras_binding.h" - -#include <algorithm> -#include <iterator> - -#include "third_party/blink/renderer/bindings/core/v8/script_function.h" -#include "third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h" -#include "third_party/blink/renderer/core/execution_context/execution_context.h" -#include "third_party/blink/renderer/core/frame/web_feature.h" -#include "third_party/blink/renderer/platform/bindings/to_v8.h" -#include "third_party/blink/renderer/platform/bindings/v8_binding.h" -#include "third_party/blink/renderer/platform/bindings/v8_throw_exception.h" -#include "third_party/blink/renderer/platform/instrumentation/use_counter.h" -#include "third_party/blink/renderer/platform/runtime_enabled_features.h" -#include "v8/include/v8.h" - -namespace blink { - -namespace { - -// This macro avoids duplicating the name and hence prevents typos. -#define WEB_FEATURE_ID_NAME_LOOKUP_ENTRY(id) \ - { #id, WebFeature::k##id } - -struct WebFeatureIdNameLookupEntry { - const char* const name; - const WebFeature id; -}; - -// TODO(ricea): Replace with a more efficient data structure if the -// number of entries increases. -constexpr WebFeatureIdNameLookupEntry web_feature_id_name_lookup_table[] = { - WEB_FEATURE_ID_NAME_LOOKUP_ENTRY(ReadableStreamConstructor), - WEB_FEATURE_ID_NAME_LOOKUP_ENTRY(WritableStreamConstructor), - WEB_FEATURE_ID_NAME_LOOKUP_ENTRY(TransformStreamConstructor), -}; - -#undef WEB_FEATURE_ID_NAME_LOOKUP_ENTRY - -class CountUseForBindings : public ScriptFunction { - public: - static v8::Local<v8::Function> CreateFunction(ScriptState* script_state) { - auto* self = MakeGarbageCollected<CountUseForBindings>(script_state); - return self->BindToV8Function(); - } - - explicit CountUseForBindings(ScriptState* script_state) - : ScriptFunction(script_state) {} - - private: - ScriptValue Call(ScriptValue value) override { - String string_id; - if (!value.ToString(string_id)) { - V8ThrowException::ThrowTypeError(GetScriptState()->GetIsolate(), - "countUse requires a string argument"); - return ScriptValue(); - } - - auto* const it = - std::find_if(std::begin(web_feature_id_name_lookup_table), - std::end(web_feature_id_name_lookup_table), - [&string_id](const WebFeatureIdNameLookupEntry& entry) { - return string_id == entry.name; - }); - - if (it == std::end(web_feature_id_name_lookup_table)) { - V8ThrowException::ThrowTypeError(GetScriptState()->GetIsolate(), - "unknown use counter"); - return ScriptValue(); - } - - UseCounter::Count(ExecutionContext::From(GetScriptState()), it->id); - - return ScriptValue::From(GetScriptState(), ToV8UndefinedGenerator()); - } -}; - -void AddCountUse(ScriptState* script_state, v8::Local<v8::Object> binding) { - v8::Local<v8::Function> fn = - CountUseForBindings::CreateFunction(script_state); - v8::Local<v8::String> name = - V8AtomicString(script_state->GetIsolate(), "countUse"); - binding->Set(script_state->GetContext(), name, fn).ToChecked(); -} - -void AddOriginals(ScriptState* script_state, v8::Local<v8::Object> binding) { - // These values are only used when serialization is enabled. - if (!RuntimeEnabledFeatures::TransferableStreamsEnabled()) - return; - - v8::Local<v8::Object> global = script_state->GetContext()->Global(); - v8::Local<v8::Context> context = script_state->GetContext(); - v8::Isolate* isolate = script_state->GetIsolate(); - - const auto ObjectGet = [&context, &isolate](v8::Local<v8::Value> object, - const char* property) { - DCHECK(object->IsObject()); - return object.As<v8::Object>() - ->Get(context, V8AtomicString(isolate, property)) - .ToLocalChecked(); - }; - - const auto GetPrototype = [&ObjectGet](v8::Local<v8::Value> object) { - return ObjectGet(object, "prototype"); - }; - - const auto GetOwnPD = [&context, &isolate](v8::Local<v8::Value> object, - const char* property) { - DCHECK(object->IsObject()); - return object.As<v8::Object>() - ->GetOwnPropertyDescriptor(context, V8AtomicString(isolate, property)) - .ToLocalChecked(); - }; - - const auto GetOwnPDGet = [&ObjectGet, &GetOwnPD](v8::Local<v8::Value> object, - const char* property) { - return ObjectGet(GetOwnPD(object, property), "get"); - }; - - const auto Bind = [&context, &isolate, &binding](const char* name, - v8::Local<v8::Value> value) { - bool result = - binding - ->CreateDataProperty(context, V8AtomicString(isolate, name), value) - .ToChecked(); - DCHECK(result); - }; - - v8::Local<v8::Value> message_port = ObjectGet(global, "MessagePort"); - v8::Local<v8::Value> dom_exception = ObjectGet(global, "DOMException"); - - // Most Worklets don't have MessagePort. In this case, serialization will - // fail. AudioWorklet has MessagePort but no DOMException, so it can't use - // serialization for now. - if (message_port->IsUndefined() || dom_exception->IsUndefined()) { - // Allow V8 Extras JavaScript to safely detect that MessagePort is not - // available. Without this, lookups of MessagePort_postMessage will follow - // the prototype chain. - Bind("MessagePort_postMessage", v8::Undefined(isolate)); - return; - } - - v8::Local<v8::Value> event_target_prototype = - GetPrototype(ObjectGet(global, "EventTarget")); - Bind("EventTarget_addEventListener", - ObjectGet(event_target_prototype, "addEventListener")); - - v8::Local<v8::Value> message_port_prototype = GetPrototype(message_port); - Bind("MessagePort_postMessage", - ObjectGet(message_port_prototype, "postMessage")); - Bind("MessagePort_close", ObjectGet(message_port_prototype, "close")); - Bind("MessagePort_start", ObjectGet(message_port_prototype, "start")); - - v8::Local<v8::Value> message_event_prototype = - GetPrototype(ObjectGet(global, "MessageEvent")); - - Bind("MessageEvent_data_get", GetOwnPDGet(message_event_prototype, "data")); - - Bind("DOMException", dom_exception); - - v8::Local<v8::Value> dom_exception_prototype = GetPrototype(dom_exception); - Bind("DOMException_message_get", - GetOwnPDGet(dom_exception_prototype, "message")); - Bind("DOMException_name_get", GetOwnPDGet(dom_exception_prototype, "name")); -} - -} // namespace - -void InitializeV8ExtrasBinding(ScriptState* script_state) { - v8::Local<v8::Object> binding = - script_state->GetContext()->GetExtrasBindingObject(); - AddCountUse(script_state, binding); - AddOriginals(script_state, binding); -} - -} // namespace blink diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/initialize_v8_extras_binding.h b/chromium/third_party/blink/renderer/bindings/core/v8/initialize_v8_extras_binding.h deleted file mode 100644 index a0f066de265..00000000000 --- a/chromium/third_party/blink/renderer/bindings/core/v8/initialize_v8_extras_binding.h +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_INITIALIZE_V8_EXTRAS_BINDING_H_ -#define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_INITIALIZE_V8_EXTRAS_BINDING_H_ - -#include "third_party/blink/renderer/core/core_export.h" - -namespace blink { - -class ScriptState; - -// Add the JavaScript function countUse() to the "binding" object that is -// exposed to the JavaScript streams implementations. -// -// binding.countUse() takes a string and calls UseCounter::Count() on the -// matching ID. It only does anything the first time it is called in a -// particular execution context. The use of a string argument avoids duplicating -// the IDs in the JS files, but means that JS code should avoid calling it more -// than once to avoid unnecessary overhead. Only string IDs that this code -// specifically knows about will work. -// -// Also copy the original values of MessageChannel, MessagePort and MessageEvent -// methods and accessors to the binding object where they can be used for -// serialization by the streams code. -// -// This function must be called during initialisation of the V8 context. -// -// countUse() is not available during snapshot creation. -void CORE_EXPORT InitializeV8ExtrasBinding(ScriptState*); - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_INITIALIZE_V8_EXTRAS_BINDING_H_ diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/initialize_v8_extras_binding_test.cc b/chromium/third_party/blink/renderer/bindings/core/v8/initialize_v8_extras_binding_test.cc deleted file mode 100644 index c3a402f66d9..00000000000 --- a/chromium/third_party/blink/renderer/bindings/core/v8/initialize_v8_extras_binding_test.cc +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "third_party/blink/renderer/bindings/core/v8/initialize_v8_extras_binding.h" - -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/renderer/bindings/core/v8/script_value.h" -#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h" -#include "third_party/blink/renderer/bindings/core/v8/v8_extras_test_utils.h" -#include "third_party/blink/renderer/core/dom/document.h" -#include "third_party/blink/renderer/core/frame/web_feature.h" -#include "third_party/blink/renderer/core/page/page.h" -#include "third_party/blink/renderer/platform/bindings/v8_binding.h" -#include "third_party/blink/renderer/platform/instrumentation/use_counter.h" -#include "v8/include/v8.h" - -namespace blink { - -namespace { - -// Add "binding" to the global object. Production code should never do this; -// it would be a huge security hole. -void AddExtrasBindingToGlobal(V8TestingScope* scope) { - auto context = scope->GetContext(); - v8::Local<v8::Object> global = context->Global(); - v8::Local<v8::Object> binding = context->GetExtrasBindingObject(); - v8::Local<v8::String> key = V8AtomicString(scope->GetIsolate(), "binding"); - global->Set(context, key, binding).FromJust(); -} - -TEST(InitializeV8ExtrasBindingTest, SupportedId) { - V8TestingScope scope; - InitializeV8ExtrasBinding(scope.GetScriptState()); - AddExtrasBindingToGlobal(&scope); - Page::InsertOrdinaryPageForTesting(&scope.GetPage()); - - ScriptValue rv = EvalWithPrintingError( - &scope, "binding.countUse('TransformStreamConstructor');"); - EXPECT_TRUE(rv.IsUndefined()); - EXPECT_TRUE(scope.GetDocument().IsUseCounted( - WebFeature::kTransformStreamConstructor)); -} - -TEST(InitializeV8ExtrasBindingTest, UnsupportedId) { - V8TestingScope scope; - InitializeV8ExtrasBinding(scope.GetScriptState()); - AddExtrasBindingToGlobal(&scope); - - ScriptValue rv = EvalWithPrintingError(&scope, - "let result;" - "try {" - " binding.countUse('WindowEvent');" - " result = 'FAIL';" - "} catch (e) {" - " result = e.name;" - "}" - "result"); - String result; - EXPECT_TRUE(rv.ToString(result)); - EXPECT_EQ("TypeError", result); -} - -} // namespace - -} // namespace blink 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 91827731a70..efa7fbcdd02 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 @@ -25,7 +25,7 @@ namespace blink { namespace { class IsolatedWorldCSPDelegate final - : public GarbageCollectedFinalized<IsolatedWorldCSPDelegate>, + : public GarbageCollected<IsolatedWorldCSPDelegate>, public ContentSecurityPolicyDelegate { USING_GARBAGE_COLLECTED_MIXIN(IsolatedWorldCSPDelegate); 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 0d89cfa5e2e..8cf18c135ad 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/iterable.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/iterable.h @@ -79,8 +79,9 @@ class Iterable { if (callback ->Invoke(v8_callback_this_value, - ScriptValue(script_state, v8_value), - ScriptValue(script_state, v8_key), this_value) + ScriptValue(script_state->GetIsolate(), v8_value), + ScriptValue(script_state->GetIsolate(), v8_key), + this_value) .IsNothing()) { exception_state.RethrowV8Exception(try_catch.Exception()); return; @@ -88,7 +89,7 @@ class Iterable { } } - class IterationSource : public GarbageCollectedFinalized<IterationSource> { + class IterationSource : public GarbageCollected<IterationSource> { public: virtual ~IterationSource() = default; @@ -120,18 +121,18 @@ class Iterable { }; struct EntrySelector { STATIC_ONLY(EntrySelector); - static Vector<ScriptValue, 2> Select(ScriptState* script_state, - const KeyType& key, - const ValueType& value) { + static HeapVector<ScriptValue, 2> Select(ScriptState* script_state, + const KeyType& key, + const ValueType& value) { v8::Local<v8::Object> creation_context = script_state->GetContext()->Global(); v8::Isolate* isolate = script_state->GetIsolate(); - Vector<ScriptValue, 2> entry; + HeapVector<ScriptValue, 2> entry; entry.push_back( - ScriptValue(script_state, ToV8(key, creation_context, isolate))); + ScriptValue(isolate, ToV8(key, creation_context, isolate))); entry.push_back( - ScriptValue(script_state, ToV8(value, creation_context, isolate))); + ScriptValue(isolate, ToV8(value, creation_context, isolate))); return entry; } }; 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 6d8b70d607a..b5062cc0327 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 @@ -88,7 +88,7 @@ void JSEventHandler::InvokeInternal(EventTarget& event_target, // If an exception gets thrown by the callback, end these steps and allow // the exception to propagate. (It will propagate to the DOM event dispatch // logic, which will then report the exception.) - Vector<ScriptValue> arguments; + HeapVector<ScriptValue> arguments; ScriptState* script_state_of_listener = event_handler_->CallbackRelevantScriptState(); @@ -99,9 +99,10 @@ void JSEventHandler::InvokeInternal(EventTarget& event_target, // https://html.spec.whatwg.org/C/#runtime-script-errors-2 ScriptValue error_attribute = error_event->error(script_state_of_listener); if (error_attribute.IsEmpty() || - error_event->target()->InterfaceName() == event_target_names::kWorker) - error_attribute = ScriptValue::CreateNull(script_state_of_listener); - + error_event->target()->InterfaceName() == event_target_names::kWorker) { + error_attribute = + ScriptValue::CreateNull(script_state_of_listener->GetIsolate()); + } arguments = { ScriptValue::From(script_state_of_listener, error_event->message()), ScriptValue::From(script_state_of_listener, error_event->filename()), 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 c0ec993ca6d..4eb7d11483b 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 @@ -30,7 +30,6 @@ #include "third_party/blink/renderer/bindings/core/v8/local_window_proxy.h" -#include "third_party/blink/renderer/bindings/core/v8/initialize_v8_extras_binding.h" #include "third_party/blink/renderer/bindings/core/v8/isolated_world_csp.h" #include "third_party/blink/renderer/bindings/core/v8/script_controller.h" #include "third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h" @@ -182,9 +181,15 @@ void LocalWindowProxy::Initialize() { if (evaluate_csp_for_eval) { ContentSecurityPolicy* csp = GetFrame()->GetDocument()->GetContentSecurityPolicyForWorld(); - context->AllowCodeGenerationFromStrings(csp->AllowEval( - nullptr, SecurityViolationReportingPolicy::kSuppressReporting, - ContentSecurityPolicy::kWillNotThrowException, g_empty_string)); + // CSP has two mechanisms for controlling eval, script-src and Trusted + // Types, and we need to check both. + // TODO(vogelheim): Provide a simple(e) API for this use case. + bool allow_code_generation = + csp->AllowEval(SecurityViolationReportingPolicy::kSuppressReporting, + ContentSecurityPolicy::kWillNotThrowException, + g_empty_string) && + !csp->IsRequireTrustedTypes(); + context->AllowCodeGenerationFromStrings(allow_code_generation); context->SetErrorMessageForCodeGenerationFromStrings( V8String(GetIsolate(), csp->EvalDisabledErrorMessage())); } @@ -210,9 +215,6 @@ void LocalWindowProxy::Initialize() { InstallConditionalFeatures(); - // This needs to go after everything else since it accesses the window object. - InitializeV8ExtrasBinding(script_state_); - if (World().IsMainWorld()) { GetFrame()->Loader().DispatchDidClearWindowObjectInMainWorld(); } diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/maplike.h b/chromium/third_party/blink/renderer/bindings/core/v8/maplike.h index a7ca7bfb287..f22fa7559dc 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/maplike.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/maplike.h @@ -26,10 +26,11 @@ class Maplike : public PairIterable<KeyType, ValueType> { ExceptionState& exception_state) { ValueType value; if (GetMapEntry(script_state, key, value, exception_state)) - return ScriptValue(script_state, + return ScriptValue(script_state->GetIsolate(), ToV8(value, script_state->GetContext()->Global(), script_state->GetIsolate())); - return ScriptValue(script_state, v8::Undefined(script_state->GetIsolate())); + return ScriptValue(script_state->GetIsolate(), + v8::Undefined(script_state->GetIsolate())); } private: 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 b1278954fb2..31f20815c6a 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 @@ -107,7 +107,7 @@ ScriptValue ModuleRecord::Instantiate(ScriptState* script_state, .To(&success) || !success) { DCHECK(try_catch.HasCaught()); - return ScriptValue(script_state, try_catch.Exception()); + return ScriptValue(isolate, try_catch.Exception()); } DCHECK(!try_catch.HasCaught()); return ScriptValue(); @@ -133,7 +133,7 @@ ScriptValue ModuleRecord::Evaluate(ScriptState* script_state, script_state->GetContext()) .ToLocal(&result)) { DCHECK(try_catch.HasCaught()); - return ScriptValue(script_state, try_catch.Exception()); + return ScriptValue(isolate, try_catch.Exception()); } return ScriptValue(); 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 83d9e8894fc..fac8fdacfd1 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 @@ -8,7 +8,6 @@ #include "third_party/blink/renderer/bindings/core/v8/script_source_location_type.h" #include "third_party/blink/renderer/bindings/core/v8/v8_code_cache.h" #include "third_party/blink/renderer/core/core_export.h" -#include "third_party/blink/renderer/platform/bindings/shared_persistent.h" #include "third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h" #include "third_party/blink/renderer/platform/loader/fetch/cached_metadata_handler.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" @@ -28,7 +27,7 @@ class ScriptValue; // ModuleRecordProduceCacheData is a parameter object for // ModuleRecord::ProduceCache(). class CORE_EXPORT ModuleRecordProduceCacheData final - : public GarbageCollectedFinalized<ModuleRecordProduceCacheData> { + : public GarbageCollected<ModuleRecordProduceCacheData> { public: ModuleRecordProduceCacheData(v8::Isolate*, SingleCachedMetadataHandler*, diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl_test.cc b/chromium/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl_test.cc index 4004a722cbe..7ea955c253d 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl_test.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/native_value_traits_impl_test.cc @@ -259,7 +259,7 @@ TEST(NativeValueTraitsImplTest, IDLSequence) { EvaluateScriptForArray(scope, "['Vini, vidi, vici.', 65535, 0.125]"); NonThrowableExceptionState exception_state; - Vector<ScriptValue> script_value_vector = + HeapVector<ScriptValue> script_value_vector = NativeValueTraits<IDLSequence<ScriptValue>>::NativeValue( scope.GetIsolate(), v8_array, exception_state); EXPECT_EQ(3U, script_value_vector.size()); 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 48ccf8594e2..ca5975ade93 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 @@ -68,8 +68,8 @@ struct ProfilerNodeFrameHash { // // The trace format is described at: // https://wicg.github.io/js-self-profiling/#the-profilertrace-dictionary -class ProfilerTraceBuilder - : public GarbageCollectedFinalized<ProfilerTraceBuilder> { +class ProfilerTraceBuilder final + : public GarbageCollected<ProfilerTraceBuilder> { public: static ProfilerTrace* FromProfile(ScriptState*, const v8::CpuProfile* profile, 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 4875efec8a8..0dce491aec2 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 @@ -4,6 +4,7 @@ #include "third_party/blink/renderer/bindings/core/v8/referrer_script_info.h" +#include "mojo/public/cpp/bindings/enum_utils.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" #include "v8/include/v8.h" @@ -58,9 +59,12 @@ ReferrerScriptInfo ReferrerScriptInfo::FromV8HostDefinedOptions( v8::Local<v8::Primitive> referrer_policy_value = host_defined_options->Get(isolate, kReferrerPolicy); SECURITY_CHECK(referrer_policy_value->IsUint32()); + int32_t referrer_policy_int32 = base::saturated_cast<int32_t>( + referrer_policy_value->IntegerValue(context).ToChecked()); network::mojom::ReferrerPolicy referrer_policy = - static_cast<network::mojom::ReferrerPolicy>( - referrer_policy_value->IntegerValue(context).ToChecked()); + mojo::ConvertIntToMojoEnum<network::mojom::ReferrerPolicy>( + referrer_policy_int32) + .value_or(network::mojom::ReferrerPolicy::kDefault); return ReferrerScriptInfo(base_url, credentials_mode, nonce, parser_state, referrer_policy); 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 cb6ba97fcb1..9f459d22d1c 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 @@ -75,7 +75,7 @@ class RejectedPromises::Message final { sanitize_script_errors_ == SanitizeScriptErrors::kDoNotSanitize) { PromiseRejectionEventInit* init = PromiseRejectionEventInit::Create(); init->setPromise(ScriptPromise(script_state_, value)); - init->setReason(ScriptValue(script_state_, reason)); + init->setReason(ScriptValue(script_state_->GetIsolate(), reason)); init->setCancelable(true); PromiseRejectionEvent* event = PromiseRejectionEvent::Create( script_state_, event_type_names::kUnhandledrejection, init); @@ -115,7 +115,7 @@ class RejectedPromises::Message final { sanitize_script_errors_ == SanitizeScriptErrors::kDoNotSanitize) { PromiseRejectionEventInit* init = PromiseRejectionEventInit::Create(); init->setPromise(ScriptPromise(script_state_, value)); - init->setReason(ScriptValue(script_state_, reason)); + init->setReason(ScriptValue(script_state_->GetIsolate(), reason)); PromiseRejectionEvent* event = PromiseRejectionEvent::Create( script_state_, event_type_names::kRejectionhandled, init); target->DispatchEvent(*event); 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 cb096bd269e..843cb14c3c2 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 @@ -51,10 +51,11 @@ namespace blink { -ScheduledAction* ScheduledAction::Create(ScriptState* script_state, - ExecutionContext* target, - V8Function* handler, - const Vector<ScriptValue>& arguments) { +ScheduledAction* ScheduledAction::Create( + ScriptState* script_state, + ExecutionContext* target, + V8Function* handler, + const HeapVector<ScriptValue>& arguments) { if (!script_state->World().IsWorkerWorld()) { if (!BindingSecurity::ShouldAllowAccessToFrame( EnteredDOMWindow(script_state->GetIsolate()), @@ -85,7 +86,7 @@ ScheduledAction* ScheduledAction::Create(ScriptState* script_state, ScheduledAction::ScheduledAction(ScriptState* script_state, V8Function* function, - const Vector<ScriptValue>& arguments) + const HeapVector<ScriptValue>& arguments) : script_state_( MakeGarbageCollected<ScriptStateProtectingContext>(script_state)), function_(function), @@ -157,6 +158,7 @@ void ScheduledAction::Execute(ExecutionContext* context) { void ScheduledAction::Trace(blink::Visitor* visitor) { visitor->Trace(script_state_); visitor->Trace(function_); + visitor->Trace(arguments_); } void ScheduledAction::Execute(LocalFrame* frame) { 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 5c6de14a14c..888c1c91ed0 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 @@ -47,7 +47,7 @@ class ScriptValue; class V8Function; class WorkerGlobalScope; -class ScheduledAction final : public GarbageCollectedFinalized<ScheduledAction>, +class ScheduledAction final : public GarbageCollected<ScheduledAction>, public NameClient { DISALLOW_COPY_AND_ASSIGN(ScheduledAction); @@ -55,14 +55,14 @@ class ScheduledAction final : public GarbageCollectedFinalized<ScheduledAction>, static ScheduledAction* Create(ScriptState*, ExecutionContext* target, V8Function* handler, - const Vector<ScriptValue>& arguments); + const HeapVector<ScriptValue>& arguments); static ScheduledAction* Create(ScriptState*, ExecutionContext* target, const String& handler); explicit ScheduledAction(ScriptState*, V8Function* handler, - const Vector<ScriptValue>& arguments); + const HeapVector<ScriptValue>& arguments); explicit ScheduledAction(ScriptState*, const String& handler); // Creates an empty ScheduledAction. explicit ScheduledAction(ScriptState*); @@ -83,7 +83,7 @@ class ScheduledAction final : public GarbageCollectedFinalized<ScheduledAction>, Member<ScriptStateProtectingContext> script_state_; Member<V8Function> function_; - Vector<ScriptValue> arguments_; + HeapVector<ScriptValue> arguments_; String code_; }; 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 53dac106484..e2cc2813646 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 @@ -39,7 +39,6 @@ #include "third_party/blink/renderer/bindings/core/v8/window_proxy_manager.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" -#include "third_party/blink/renderer/platform/bindings/shared_persistent.h" #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h" #include "third_party/blink/renderer/platform/loader/fetch/script_fetch_options.h" 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 dfbfed1ca13..aae5dbeba44 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 @@ -262,7 +262,7 @@ v8::Local<v8::Object> ScriptCustomElementDefinition::Constructor() const { // CustomElementDefinition ScriptValue ScriptCustomElementDefinition::GetConstructorForScript() { - return ScriptValue(script_state_, Constructor()); + return ScriptValue(script_state_->GetIsolate(), Constructor()); } bool ScriptCustomElementDefinition::HasConnectedCallback() const { 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 3657116ff81..849ba6405ae 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 @@ -34,7 +34,8 @@ ScriptValue ScriptFunction::Call(ScriptValue) { } void ScriptFunction::CallRaw(const v8::FunctionCallbackInfo<v8::Value>& args) { - ScriptValue result = Call(ScriptValue(GetScriptState(), args[0])); + ScriptValue result = + Call(ScriptValue(GetScriptState()->GetIsolate(), args[0])); V8SetReturnValue(args, result.V8Value()); } 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 b031ff084e5..25ec59b272e 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 @@ -36,18 +36,16 @@ #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/v8_throw_exception.h" -#include "third_party/blink/renderer/platform/instrumentation/instance_counters.h" #include "v8/include/v8.h" namespace blink { namespace { -class PromiseAllHandler final - : public GarbageCollectedFinalized<PromiseAllHandler> { +class PromiseAllHandler final : public GarbageCollected<PromiseAllHandler> { public: static ScriptPromise All(ScriptState* script_state, - const Vector<ScriptPromise>& promises) { + const HeapVector<ScriptPromise>& promises) { if (promises.IsEmpty()) return ScriptPromise::Cast(script_state, v8::Array::New(script_state->GetIsolate())); @@ -55,7 +53,8 @@ class PromiseAllHandler final ->resolver_.Promise(); } - PromiseAllHandler(ScriptState* script_state, Vector<ScriptPromise> promises) + PromiseAllHandler(ScriptState* script_state, + HeapVector<ScriptPromise> promises) : number_of_pending_promises_(promises.size()), resolver_(script_state) { DCHECK(!promises.IsEmpty()); values_.resize(promises.size()); @@ -65,7 +64,10 @@ class PromiseAllHandler final } } - virtual void Trace(blink::Visitor* visitor) { visitor->Trace(resolver_); } + virtual void Trace(blink::Visitor* visitor) { + visitor->Trace(resolver_); + visitor->Trace(values_); + } private: class AdapterFunction : public ScriptFunction { @@ -157,7 +159,7 @@ class PromiseAllHandler final // This is cleared when owners of this handler, that is, given promises are // settled. - Vector<ScriptValue> values_; + HeapVector<ScriptValue> values_; DISALLOW_COPY_AND_ASSIGN(PromiseAllHandler); }; @@ -166,7 +168,7 @@ class PromiseAllHandler final ScriptPromise::InternalResolver::InternalResolver(ScriptState* script_state) : script_state_(script_state), - resolver_(script_state, + resolver_(script_state->GetIsolate(), v8::Promise::Resolver::New(script_state->GetContext())) { // |resolver| can be empty when the thread is being terminated. We ignore such // errors. @@ -210,38 +212,26 @@ void ScriptPromise::InternalResolver::Reject(v8::Local<v8::Value> value) { Clear(); } -ScriptPromise::ScriptPromise() { - IncreaseInstanceCount(); -} - ScriptPromise::ScriptPromise(ScriptState* script_state, v8::Local<v8::Value> value) : script_state_(script_state) { - IncreaseInstanceCount(); - if (value.IsEmpty()) return; if (!value->IsPromise()) { - promise_ = ScriptValue(script_state, v8::Local<v8::Value>()); + promise_ = ScriptValue(); V8ThrowException::ThrowTypeError(script_state->GetIsolate(), "the given value is not a Promise"); return; } - promise_ = ScriptValue(script_state, value); + promise_ = ScriptValue(script_state->GetIsolate(), value); } ScriptPromise::ScriptPromise(const ScriptPromise& other) { - IncreaseInstanceCount(); - this->script_state_ = other.script_state_; this->promise_ = other.promise_; } -ScriptPromise::~ScriptPromise() { - DecreaseInstanceCount(); -} - ScriptPromise ScriptPromise::Then(v8::Local<v8::Function> on_fulfilled, v8::Local<v8::Function> on_rejected) { if (promise_.IsEmpty()) @@ -350,16 +340,8 @@ void ScriptPromise::MarkAsHandled() { } ScriptPromise ScriptPromise::All(ScriptState* script_state, - const Vector<ScriptPromise>& promises) { + const HeapVector<ScriptPromise>& promises) { return PromiseAllHandler::All(script_state, promises); } -void ScriptPromise::IncreaseInstanceCount() { - InstanceCounters::IncrementCounter(InstanceCounters::kScriptPromiseCounter); -} - -void ScriptPromise::DecreaseInstanceCount() { - InstanceCounters::DecrementCounter(InstanceCounters::kScriptPromiseCounter); -} - } // namespace blink 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 555de6a7c09..fde92c9aeb2 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 @@ -57,7 +57,7 @@ class CORE_EXPORT ScriptPromise final { public: // Constructs an empty promise. - ScriptPromise(); + ScriptPromise() = default; // Constructs a ScriptPromise from |promise|. // If |promise| is not a Promise object, throws a v8 TypeError. @@ -65,7 +65,7 @@ class CORE_EXPORT ScriptPromise final { ScriptPromise(const ScriptPromise&); - ~ScriptPromise(); + ~ScriptPromise() = default; ScriptPromise Then(v8::Local<v8::Function> on_fulfilled, v8::Local<v8::Function> on_rejected = {}); @@ -121,7 +121,13 @@ class CORE_EXPORT ScriptPromise final { // Constructs and returns a ScriptPromise to be resolved when all |promises| // are resolved. If one of |promises| is rejected, the returned // ScriptPromise is rejected. - static ScriptPromise All(ScriptState*, const Vector<ScriptPromise>& promises); + static ScriptPromise All(ScriptState*, + const HeapVector<ScriptPromise>& promises); + + void Trace(Visitor* visitor) { + visitor->Trace(promise_); + visitor->Trace(script_state_); + } // This is a utility class intended to be used internally. // ScriptPromiseResolver is for general purpose. @@ -136,7 +142,10 @@ class CORE_EXPORT ScriptPromise final { void Reject(v8::Local<v8::Value>); void Clear() { resolver_.Clear(); } ScriptState* GetScriptState() const { return script_state_; } - void Trace(blink::Visitor* visitor) { visitor->Trace(script_state_); } + void Trace(blink::Visitor* visitor) { + visitor->Trace(script_state_); + visitor->Trace(resolver_); + } private: Member<ScriptState> script_state_; @@ -147,12 +156,21 @@ class CORE_EXPORT ScriptPromise final { static void IncreaseInstanceCount(); static void DecreaseInstanceCount(); - // TODO(peria): Move ScriptPromise to Oilpan heap. - GC_PLUGIN_IGNORE("813731") - Persistent<ScriptState> script_state_; + Member<ScriptState> script_state_; ScriptValue promise_; }; } // namespace blink +namespace WTF { + +template <> +struct VectorTraits<blink::ScriptPromise> + : VectorTraitsBase<blink::ScriptPromise> { + STATIC_ONLY(VectorTraits); + static constexpr bool kCanClearUnusedSlotsWithMemset = true; +}; + +} // namespace WTF + #endif // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_SCRIPT_PROMISE_H_ diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_property_base.h b/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_property_base.h index cf1785b4cce..11cb4eef85d 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_property_base.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_property_base.h @@ -25,7 +25,7 @@ class ScriptState; // TODO(yhirano): Remove NOINLINE once we find the cause of crashes. class CORE_EXPORT ScriptPromisePropertyBase - : public GarbageCollectedFinalized<ScriptPromisePropertyBase>, + : public GarbageCollected<ScriptPromisePropertyBase>, public ContextClient { USING_GARBAGE_COLLECTED_MIXIN(ScriptPromisePropertyBase); 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 5ab7eba37e6..a64d5000304 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 @@ -154,7 +154,7 @@ class ScriptPromisePropertyTestBase { ScriptState::From(ToV8Context(&GetDocument(), world)); ScriptState::Scope scope(script_state); return ScriptValue( - script_state, + GetIsolate(), ToV8(value, script_state->GetContext()->Global(), GetIsolate())); } 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 8b8ff3a6472..835b86b9c93 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 @@ -121,6 +121,7 @@ void ScriptPromiseResolver::ResolveOrRejectDeferred() { void ScriptPromiseResolver::Trace(blink::Visitor* visitor) { visitor->Trace(script_state_); visitor->Trace(resolver_); + visitor->Trace(value_); ContextLifecycleObserver::Trace(visitor); } 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 934967b1c01..929535af650 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 @@ -36,7 +36,7 @@ namespace blink { // There are cases where promises cannot work (e.g., where the thread is being // terminated). In such cases operations will silently fail. class CORE_EXPORT ScriptPromiseResolver - : public GarbageCollectedFinalized<ScriptPromiseResolver>, + : public GarbageCollected<ScriptPromiseResolver>, public ContextLifecycleObserver { USING_GARBAGE_COLLECTED_MIXIN(ScriptPromiseResolver); USING_PRE_FINALIZER(ScriptPromiseResolver, Dispose); @@ -148,7 +148,7 @@ class CORE_EXPORT ScriptPromiseResolver const Member<ScriptState> script_state_; TaskHandle deferred_resolve_task_; Resolver resolver_; - ScopedPersistent<v8::Value> value_; + TraceWrapperV8Reference<v8::Value> value_; // To support keepAliveWhilePending(), this object needs to keep itself // alive while in that state. 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 0243503c357..7d92626c7d8 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 @@ -6,6 +6,7 @@ #include <memory> +#include "base/run_loop.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/renderer/bindings/core/v8/script_function.h" #include "third_party/blink/renderer/bindings/core/v8/script_value.h" diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_test.cc b/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_test.cc index 49e6343f0bf..0e4aa4195a8 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_test.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_test.cc @@ -283,8 +283,8 @@ TEST(ScriptPromiseTest, CastNonPromise) { V8TestingScope scope; ScriptValue on_fulfilled1, on_fulfilled2, on_rejected1, on_rejected2; - ScriptValue value = ScriptValue(scope.GetScriptState(), - V8String(scope.GetIsolate(), "hello")); + ScriptValue value = + ScriptValue(scope.GetIsolate(), V8String(scope.GetIsolate(), "hello")); ScriptPromise promise1 = ScriptPromise::Cast(scope.GetScriptState(), ScriptValue(value)); ScriptPromise promise2 = @@ -322,8 +322,8 @@ TEST(ScriptPromiseTest, Reject) { V8TestingScope scope; ScriptValue on_fulfilled, on_rejected; - ScriptValue value = ScriptValue(scope.GetScriptState(), - V8String(scope.GetIsolate(), "hello")); + ScriptValue value = + ScriptValue(scope.GetIsolate(), V8String(scope.GetIsolate(), "hello")); ScriptPromise promise = ScriptPromise::Reject(scope.GetScriptState(), ScriptValue(value)); promise.Then(FunctionForScriptPromiseTest::CreateFunction( @@ -371,7 +371,7 @@ TEST(ScriptPromiseTest, AllWithEmptyPromises) { ScriptValue on_fulfilled, on_rejected; ScriptPromise promise = - ScriptPromise::All(scope.GetScriptState(), Vector<ScriptPromise>()); + ScriptPromise::All(scope.GetScriptState(), HeapVector<ScriptPromise>()); ASSERT_FALSE(promise.IsEmpty()); promise.Then(FunctionForScriptPromiseTest::CreateFunction( @@ -393,7 +393,7 @@ TEST(ScriptPromiseTest, AllWithResolvedPromises) { V8TestingScope scope; ScriptValue on_fulfilled, on_rejected; - Vector<ScriptPromise> promises; + HeapVector<ScriptPromise> promises; promises.push_back(ScriptPromise::Cast( scope.GetScriptState(), V8String(scope.GetIsolate(), "hello"))); promises.push_back(ScriptPromise::Cast( @@ -423,7 +423,7 @@ TEST(ScriptPromiseTest, AllWithRejectedPromise) { V8TestingScope scope; ScriptValue on_fulfilled, on_rejected; - Vector<ScriptPromise> promises; + HeapVector<ScriptPromise> promises; promises.push_back(ScriptPromise::Cast( scope.GetScriptState(), V8String(scope.GetIsolate(), "hello"))); promises.push_back(ScriptPromise::Reject( 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 new file mode 100644 index 00000000000..c9f005bd171 --- /dev/null +++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_tester.cc @@ -0,0 +1,82 @@ +// 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. + +#include "third_party/blink/renderer/bindings/core/v8/script_promise_tester.h" + +#include <utility> + +#include "third_party/blink/renderer/bindings/core/v8/script_function.h" +#include "third_party/blink/renderer/bindings/core/v8/script_promise.h" +#include "third_party/blink/renderer/platform/bindings/script_state.h" +#include "third_party/blink/renderer/platform/heap/heap.h" +#include "third_party/blink/renderer/platform/heap/visitor.h" +#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" +#include "v8/include/v8.h" + +namespace blink { + +class ScriptPromiseTester::ThenFunction : public ScriptFunction { + public: + static v8::Local<v8::Function> CreateFunction( + ScriptState* script_state, + base::WeakPtr<ScriptPromiseTester> owner, + ScriptPromiseTester::State target_state) { + ThenFunction* self = MakeGarbageCollected<ThenFunction>( + script_state, std::move(owner), target_state); + return self->BindToV8Function(); + } + + ThenFunction(ScriptState* script_state, + base::WeakPtr<ScriptPromiseTester> owner, + ScriptPromiseTester::State target_state) + : ScriptFunction(script_state), + owner_(std::move(owner)), + target_state_(target_state) {} + + ScriptValue Call(ScriptValue value) override { + if (!owner_) + return value; + + DCHECK_EQ(owner_->state_, State::kNotSettled); + owner_->state_ = target_state_; + + DCHECK(owner_->value_.IsEmpty()); + owner_->value_ = value; + return value; + } + + private: + base::WeakPtr<ScriptPromiseTester> owner_; + State target_state_; +}; + +ScriptPromiseTester::ScriptPromiseTester(ScriptState* script_state, + ScriptPromise script_promise) + : script_state_(script_state) { + DCHECK(script_state); + script_promise.Then( + ThenFunction::CreateFunction(script_state, weak_factory_.GetWeakPtr(), + State::kFulfilled), + ThenFunction::CreateFunction(script_state, weak_factory_.GetWeakPtr(), + State::kRejected)); +} + +void ScriptPromiseTester::WaitUntilSettled() { + auto* isolate = script_state_->GetIsolate(); + while (state_ == State::kNotSettled) { + v8::MicrotasksScope::PerformCheckpoint(isolate); + test::RunPendingTasks(); + } +} + +ScriptValue ScriptPromiseTester::Value() const { + return value_; +} + +void ScriptPromiseTester::Trace(Visitor* visitor) { + visitor->Trace(script_state_); + visitor->Trace(value_); +} + +} // namespace blink 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 new file mode 100644 index 00000000000..63a52f1673e --- /dev/null +++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_promise_tester.h @@ -0,0 +1,61 @@ +// 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. + +#ifndef THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_SCRIPT_PROMISE_TESTER_H_ +#define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_SCRIPT_PROMISE_TESTER_H_ + +#include "base/memory/weak_ptr.h" +#include "third_party/blink/renderer/bindings/core/v8/script_value.h" +#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" + +namespace blink { + +class ScriptState; +class ScriptPromise; +class Visitor; + +// Utility for writing unit tests involving promises. +// Typical usage: +// ScriptPromiseTester tester(script_state, script_promise); +// tester.WaitUntilSettled(); // Runs a nested event loop. +// EXPECT_TRUE(tester.IsFulfilled()); +// EXPECT_TRUE(tester.Value().IsUndefined()); +class ScriptPromiseTester final { + DISALLOW_NEW(); + + public: + ScriptPromiseTester(ScriptState*, ScriptPromise); + + // Run microtasks and tasks until the promise is either fulfilled or rejected. + // If the promise never settles this will busy loop until the test times out. + void WaitUntilSettled(); + + // Did the promise fulfill? + bool IsFulfilled() const { return state_ == State::kFulfilled; } + + // Did the promise reject? + bool IsRejected() const { return state_ == State::kRejected; } + + // The value the promise fulfilled or rejected with. + ScriptValue Value() const; + + void Trace(Visitor*); + + private: + class ThenFunction; + + enum class State { kNotSettled, kFulfilled, kRejected }; + + Member<ScriptState> script_state_; + State state_ = State::kNotSettled; + ScriptValue value_; + + base::WeakPtrFactory<ScriptPromiseTester> weak_factory_{this}; + + DISALLOW_COPY_AND_ASSIGN(ScriptPromiseTester); +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_SCRIPT_PROMISE_TESTER_H_ 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 2993ffb7c08..afd83f83ae7 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 @@ -5,6 +5,7 @@ #include "third_party/blink/renderer/bindings/core/v8/script_source_code.h" #include "third_party/blink/renderer/core/loader/resource/script_resource.h" +#include "third_party/blink/renderer/platform/loader/fetch/cached_metadata_handler.h" 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 43f3998a6ba..685112d599d 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 @@ -29,7 +29,7 @@ class ResponseBodyLoaderClient; // ClassicPendingScript are destroyed while the streaming is in progress, and // ScriptStreamer handles it gracefully. class CORE_EXPORT ScriptStreamer final - : public GarbageCollectedFinalized<ScriptStreamer> { + : public GarbageCollected<ScriptStreamer> { USING_PRE_FINALIZER(ScriptStreamer, Prefinalize); public: 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 1cd0bdcc1c1..93db3b70169 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 @@ -43,9 +43,8 @@ namespace blink { namespace { -class TestResourceClient final - : public GarbageCollectedFinalized<TestResourceClient>, - public ResourceClient { +class TestResourceClient final : public GarbageCollected<TestResourceClient>, + public ResourceClient { USING_GARBAGE_COLLECTED_MIXIN(TestResourceClient); public: diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/script_value.cc b/chromium/third_party/blink/renderer/bindings/core/v8/script_value.cc index 4df0baeb46e..ed52b29b0f2 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/script_value.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/script_value.cc @@ -35,43 +35,13 @@ #include "third_party/blink/renderer/platform/bindings/script_state.h" namespace blink { -namespace { - -v8::Local<v8::Value> ToWorldSafeValue(ScriptState* target_script_state, - v8::Local<v8::Value> value) { - if (value.IsEmpty() || !value->IsObject()) - return value; - - v8::Local<v8::Context> creation_context = - value.As<v8::Object>()->CreationContext(); - v8::Isolate* isolate = target_script_state->GetIsolate(); - if (&ScriptState::From(creation_context)->World() == - &target_script_state->World()) { - return value; - } - - v8::Context::Scope target_context_scope(target_script_state->GetContext()); - scoped_refptr<SerializedScriptValue> serialized = - SerializedScriptValue::SerializeAndSwallowExceptions(isolate, value); - return serialized->Deserialize(isolate); -} - -} // namespace v8::Local<v8::Value> ScriptValue::V8Value() const { if (IsEmpty()) return v8::Local<v8::Value>(); DCHECK(GetIsolate()->InContext()); - - // This is a check to validate that you don't return a ScriptValue to a world - // different from the world that created the ScriptValue. - // Probably this could be: - // if (&script_state_->world() == &DOMWrapperWorld::current(isolate())) - // return v8::Local<v8::Value>(); - // instead of triggering CHECK. - CHECK_EQ(&script_state_->World(), &DOMWrapperWorld::Current(GetIsolate())); - return value_->NewLocal(GetIsolate()); + return value_->Get(ScriptState::From(isolate_->GetCurrentContext())); } v8::Local<v8::Value> ScriptValue::V8ValueFor( @@ -79,15 +49,13 @@ v8::Local<v8::Value> ScriptValue::V8ValueFor( if (IsEmpty()) return v8::Local<v8::Value>(); - return ToWorldSafeValue(target_script_state, - value_->NewLocal(target_script_state->GetIsolate())); + return value_->GetAcrossWorld(target_script_state); } bool ScriptValue::ToString(String& result) const { if (IsEmpty()) return false; - ScriptState::Scope scope(script_state_); v8::Local<v8::Value> string = V8Value(); if (string.IsEmpty() || !string->IsString()) return false; @@ -95,8 +63,8 @@ bool ScriptValue::ToString(String& result) const { return true; } -ScriptValue ScriptValue::CreateNull(ScriptState* script_state) { - return ScriptValue(script_state, v8::Null(script_state->GetIsolate())); +ScriptValue ScriptValue::CreateNull(v8::Isolate* isolate) { + return ScriptValue(isolate, v8::Null(isolate)); } } // namespace blink 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 3027b1c9877..791d6556280 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 @@ -33,9 +33,10 @@ #include "base/memory/scoped_refptr.h" #include "third_party/blink/renderer/bindings/core/v8/native_value_traits.h" +#include "third_party/blink/renderer/bindings/core/v8/world_safe_v8_reference.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/platform/bindings/script_state.h" -#include "third_party/blink/renderer/platform/bindings/shared_persistent.h" +#include "third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "v8/include/v8.h" @@ -69,44 +70,34 @@ class CORE_EXPORT ScriptValue final { ScriptValue() = default; - ScriptValue(ScriptState* script_state, v8::Local<v8::Value> value) - : script_state_(script_state), - value_(value.IsEmpty() ? nullptr - : SharedPersistent<v8::Value>::Create( - value, - script_state->GetIsolate())) { - DCHECK(IsEmpty() || script_state_); + ScriptValue(v8::Isolate* isolate, v8::Local<v8::Value> value) + : isolate_(isolate), + value_( + MakeGarbageCollected<WorldSafeV8ReferenceWrapper>(isolate, value)) { + DCHECK(isolate_); } template <typename T> - ScriptValue(ScriptState* script_state, v8::MaybeLocal<T> value) - : script_state_(script_state), - value_(value.IsEmpty() ? nullptr - : SharedPersistent<v8::Value>::Create( - value.ToLocalChecked(), - script_state->GetIsolate())) { - DCHECK(IsEmpty() || script_state_); + ScriptValue(v8::Isolate* isolate, v8::MaybeLocal<T> value) + : isolate_(isolate), + value_(value.IsEmpty() + ? MakeGarbageCollected<WorldSafeV8ReferenceWrapper>() + : MakeGarbageCollected<WorldSafeV8ReferenceWrapper>( + isolate, + value.ToLocalChecked())) { + DCHECK(isolate_); } - ScriptValue(const ScriptValue& value) - : script_state_(value.script_state_), value_(value.value_) { - DCHECK(IsEmpty() || script_state_); - } - - ScriptState* GetScriptState() const { return script_state_; } + ScriptValue(const ScriptValue& value) = default; + // TODO(riakf): Use this GetIsolate() only when doing DCHECK inside + // ScriptValue. v8::Isolate* GetIsolate() const { - return script_state_ ? script_state_->GetIsolate() - : v8::Isolate::GetCurrent(); + DCHECK(isolate_); + return isolate_; } - ScriptValue& operator=(const ScriptValue& value) { - if (this != &value) { - script_state_ = value.script_state_; - value_ = value.value_; - } - return *this; - } + ScriptValue& operator=(const ScriptValue& value) = default; bool operator==(const ScriptValue& value) const { if (IsEmpty()) @@ -150,9 +141,12 @@ class CORE_EXPORT ScriptValue final { return !value.IsEmpty() && value->IsObject(); } - bool IsEmpty() const { return !value_.get() || value_->IsEmpty(); } + bool IsEmpty() const { return !value_ || value_->IsEmpty(); } - void Clear() { value_ = nullptr; } + void Clear() { + isolate_ = nullptr; + value_.Clear(); + } v8::Local<v8::Value> V8Value() const; // Returns v8Value() if a given ScriptState is the same as the @@ -162,13 +156,46 @@ class CORE_EXPORT ScriptValue final { bool ToString(String&) const; - static ScriptValue CreateNull(ScriptState*); + static ScriptValue CreateNull(v8::Isolate*); + + void Trace(Visitor* visitor) { visitor->Trace(value_); } private: - // TODO(peria): Move ScriptValue to Oilpan heap. - GC_PLUGIN_IGNORE("813731") - Persistent<ScriptState> script_state_; - scoped_refptr<SharedPersistent<v8::Value>> value_; + // WorldSafeV8ReferenceWrapper wraps a WorldSafeV8Reference so that it can be + // used on both the stack and heaps. WorldSafeV8Reference cannot be used on + // the stack because the conservative scanning does not know how to trace + // TraceWrapperV8Reference. + class CORE_EXPORT WorldSafeV8ReferenceWrapper + : public GarbageCollected<WorldSafeV8ReferenceWrapper> { + public: + WorldSafeV8ReferenceWrapper() = default; + WorldSafeV8ReferenceWrapper(v8::Isolate* isolate, + v8::Local<v8::Value> value) + : value_(isolate, value) {} + + virtual ~WorldSafeV8ReferenceWrapper() = default; + void Trace(blink::Visitor* visitor) { visitor->Trace(value_); } + + v8::Local<v8::Value> Get(ScriptState* script_state) const { + return value_.Get(script_state); + } + + v8::Local<v8::Value> GetAcrossWorld(ScriptState* script_state) const { + return value_.GetAcrossWorld(script_state); + } + + bool IsEmpty() const { return value_.IsEmpty(); } + + bool operator==(const WorldSafeV8ReferenceWrapper& other) const { + return value_ == other.value_; + } + + private: + WorldSafeV8Reference<v8::Value> value_; + }; + + v8::Isolate* isolate_ = nullptr; + Member<WorldSafeV8ReferenceWrapper> value_; }; template <> @@ -177,10 +204,20 @@ struct NativeValueTraits<ScriptValue> static inline ScriptValue NativeValue(v8::Isolate* isolate, v8::Local<v8::Value> value, ExceptionState& exception_state) { - return ScriptValue(ScriptState::Current(isolate), value); + return ScriptValue(isolate, value); } }; } // namespace blink +namespace WTF { + +template <> +struct VectorTraits<blink::ScriptValue> : VectorTraitsBase<blink::ScriptValue> { + STATIC_ONLY(VectorTraits); + static constexpr bool kCanClearUnusedSlotsWithMemset = true; +}; + +} // namespace WTF + #endif // THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_SCRIPT_VALUE_H_ diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.cc b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.cc index 33320193204..0bad9aae85c 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.cc @@ -4,6 +4,7 @@ #include "third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.h" +#include "third_party/blink/public/mojom/messaging/user_activation_snapshot.mojom-blink.h" #include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h" #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/frame/frame.h" diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.h b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.h index 2edf1d69a5f..0dce019e0c6 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/post_message_helper.h @@ -6,7 +6,7 @@ #define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_SERIALIZATION_POST_MESSAGE_HELPER_H_ #include "base/memory/scoped_refptr.h" -#include "third_party/blink/public/mojom/messaging/user_activation_snapshot.mojom-blink.h" +#include "third_party/blink/public/mojom/messaging/user_activation_snapshot.mojom-blink-forward.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" #include "v8/include/v8.h" diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.cc b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.cc index 6a926077a78..f4e1d24b263 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.cc @@ -67,7 +67,6 @@ #include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" -#include "third_party/blink/renderer/platform/wtf/dtoa/utils.h" #include "third_party/blink/renderer/platform/wtf/shared_buffer.h" #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" #include "third_party/blink/renderer/platform/wtf/text/string_buffer.h" @@ -518,7 +517,7 @@ bool SerializedScriptValue::ExtractTransferables( if (value.IsEmpty() || value->IsUndefined()) return true; - const Vector<ScriptValue>& transferable_array = + const HeapVector<ScriptValue>& transferable_array = NativeValueTraits<IDLSequence<ScriptValue>>::NativeValue(isolate, value, exception_state); if (exception_state.HadException()) @@ -530,7 +529,7 @@ bool SerializedScriptValue::ExtractTransferables( bool SerializedScriptValue::ExtractTransferables( v8::Isolate* isolate, - const Vector<ScriptValue>& object_sequence, + const HeapVector<ScriptValue>& object_sequence, Transferables& transferables, ExceptionState& exception_state) { // Validate the passed array of transferables. @@ -705,6 +704,16 @@ SerializedScriptValue::TransferArrayBufferContents( contents.Grow(array_buffers.size()); HeapHashSet<Member<DOMArrayBufferBase>> visited; + // The scope object to promptly free the backing store to avoid memory + // regressions. + // TODO(bikineev): Revisit after young generation is there. + struct PromptlyFreeSet { + // The void* is to avoid blink-gc-plugin error. + void* buffer; + ~PromptlyFreeSet() { + static_cast<HeapHashSet<Member<DOMArrayBufferBase>>*>(buffer)->clear(); + } + } promptly_free_array_buffers{&visited}; for (auto* it = array_buffers.begin(); it != array_buffers.end(); ++it) { DOMArrayBufferBase* array_buffer_base = *it; if (visited.Contains(array_buffer_base)) diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h index d1edfe780db..52d1f2aea4e 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h @@ -74,8 +74,7 @@ class CORE_EXPORT SerializedScriptValue using ArrayBufferContentsArray = Vector<WTF::ArrayBufferContents, 1>; using SharedArrayBufferContentsArray = Vector<WTF::ArrayBufferContents, 1>; using ImageBitmapContentsArray = Vector<scoped_refptr<StaticBitmapImage>, 1>; - using TransferredWasmModulesArray = - WTF::Vector<v8::WasmModuleObject::TransferrableModule>; + using TransferredWasmModulesArray = WTF::Vector<v8::CompiledWasmModule>; using MessagePortChannelArray = Vector<MessagePortChannel>; // Increment this for each incompatible change to the wire format. @@ -205,7 +204,7 @@ class CORE_EXPORT SerializedScriptValue Transferables&, ExceptionState&); static bool ExtractTransferables(v8::Isolate*, - const Vector<ScriptValue>&, + const HeapVector<ScriptValue>&, Transferables&, ExceptionState&); diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/transferables.cc b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/transferables.cc new file mode 100644 index 00000000000..f3929db0f1f --- /dev/null +++ b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/transferables.cc @@ -0,0 +1,32 @@ +// 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. + +#include "third_party/blink/renderer/bindings/core/v8/serialization/transferables.h" + +#include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h" +#include "third_party/blink/renderer/core/messaging/message_port.h" +#include "third_party/blink/renderer/core/mojo/mojo_handle.h" +#include "third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.h" +#include "third_party/blink/renderer/core/streams/readable_stream.h" +#include "third_party/blink/renderer/core/streams/transform_stream.h" +#include "third_party/blink/renderer/core/streams/writable_stream.h" +#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer_base.h" + +namespace blink { + +Transferables::~Transferables() { + // Explicitly free all backing stores for containers to avoid memory + // regressions. + // TODO(bikineev): Revisit after young generation is there. + array_buffers.clear(); + image_bitmaps.clear(); + offscreen_canvases.clear(); + message_ports.clear(); + mojo_handles.clear(); + readable_streams.clear(); + writable_streams.clear(); + transform_streams.clear(); +} + +} // namespace blink diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/transferables.h b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/transferables.h index 4883b80b8be..e813ef37d87 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/transferables.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/transferables.h @@ -35,6 +35,7 @@ class CORE_EXPORT Transferables final { public: Transferables() = default; + ~Transferables(); ArrayBufferArray array_buffers; ImageBitmapArray 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 6d93d2feac9..cb97edb5ea9 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 @@ -35,8 +35,8 @@ class ImageBitmap; // but (for security reasons) separate JavaScript wrappers must exist. For this // reason, a SerializedScriptValue can only be unpacked once, but thereafter it // can be deserialized multiple times. -class CORE_EXPORT UnpackedSerializedScriptValue - : public GarbageCollectedFinalized<UnpackedSerializedScriptValue> { +class CORE_EXPORT UnpackedSerializedScriptValue final + : public GarbageCollected<UnpackedSerializedScriptValue> { public: // Callers should use SerializedScriptValue::Unpack. explicit UnpackedSerializedScriptValue(scoped_refptr<SerializedScriptValue>); diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.cc b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.cc index 0b0da0ca5bf..042a35881ed 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_deserializer.cc @@ -325,8 +325,9 @@ ScriptWrappable* V8ScriptValueDeserializer::ReadDOMObject( if (!ReadUint32(&is_premultiplied) || is_premultiplied > 1) return nullptr; break; - default: - NOTREACHED(); + case ImageSerializationTag::kImageDataStorageFormatTag: + // Does not apply to ImageBitmap. + return nullptr; } } while (!is_done); } else if (!ReadUint32(&origin_clean) || origin_clean > 1 || @@ -384,8 +385,12 @@ ScriptWrappable* V8ScriptValueDeserializer::ReadDOMObject( &image_data_storage_format)) return nullptr; break; - default: - NOTREACHED(); + case ImageSerializationTag::kCanvasPixelFormatTag: + case ImageSerializationTag::kOriginCleanTag: + case ImageSerializationTag::kIsPremultipliedTag: + case ImageSerializationTag::kCanvasOpacityModeTag: + // Does not apply to ImageData. + return nullptr; } } while (!is_done); } @@ -509,7 +514,8 @@ ScriptWrappable* V8ScriptValueDeserializer::ReadDOMObject( !ReadUint32(&canvas_id) || !ReadUint32(&client_id) || !ReadUint32(&sink_id)) return nullptr; - OffscreenCanvas* canvas = OffscreenCanvas::Create(width, height); + OffscreenCanvas* canvas = OffscreenCanvas::Create( + ExecutionContext::From(GetScriptState()), width, height); canvas->SetPlaceholderCanvasId(canvas_id); canvas->SetFrameSinkId(client_id, sink_id); return canvas; @@ -692,7 +698,7 @@ v8::MaybeLocal<v8::WasmModuleObject> V8ScriptValueDeserializer::GetWasmModuleFromId(v8::Isolate* isolate, uint32_t id) { if (id < serialized_script_value_->WasmModules().size()) { - return v8::WasmModuleObject::FromTransferrableModule( + return v8::WasmModuleObject::FromCompiledModule( isolate, serialized_script_value_->WasmModules()[id]); } CHECK(serialized_script_value_->WasmModules().IsEmpty()); 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 90821da650b..5c6173a1cae 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 @@ -5,6 +5,7 @@ #include "third_party/blink/renderer/bindings/core/v8/serialization/v8_script_value_serializer.h" #include "base/auto_reset.h" +#include "third_party/blink/public/mojom/web_feature/web_feature.mojom-blink.h" #include "third_party/blink/public/platform/web_blob_info.h" #include "third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h" #include "third_party/blink/renderer/bindings/core/v8/v8_blob.h" @@ -28,6 +29,7 @@ #include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h" #include "third_party/blink/renderer/bindings/core/v8/v8_transform_stream.h" #include "third_party/blink/renderer/bindings/core/v8/v8_writable_stream.h" +#include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/geometry/dom_matrix.h" #include "third_party/blink/renderer/core/geometry/dom_matrix_read_only.h" #include "third_party/blink/renderer/core/geometry/dom_point.h" @@ -42,6 +44,7 @@ #include "third_party/blink/renderer/core/streams/writable_stream.h" #include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer_base.h" #include "third_party/blink/renderer/platform/file_metadata.h" +#include "third_party/blink/renderer/platform/instrumentation/use_counter.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/wtf/allocator/partitions.h" #include "third_party/blink/renderer/platform/wtf/date_math.h" @@ -151,6 +154,16 @@ void V8ScriptValueSerializer::FinalizeTransfer( v8::Isolate* isolate = script_state_->GetIsolate(); ArrayBufferArray array_buffers; + // The scope object to promptly free the backing store to avoid memory + // regressions. + // TODO(bikineev): Revisit after young generation is there. + struct PromptlyFreeArrayBuffers { + // The void* is to avoid blink-gc-plugin error. + void* buffer; + ~PromptlyFreeArrayBuffers() { + static_cast<ArrayBufferArray*>(buffer)->clear(); + } + } promptly_free_array_buffers{&array_buffers}; if (transferables_) array_buffers.AppendVector(transferables_->array_buffers); @@ -248,11 +261,20 @@ bool V8ScriptValueSerializer::WriteDOMObject(ScriptWrappable* wrappable, return false; } + auto* execution_context = ExecutionContext::From(script_state_.Get()); // If this ImageBitmap was transferred, it can be serialized by index. size_t index = kNotFound; if (transferables_) index = transferables_->image_bitmaps.Find(image_bitmap); if (index != kNotFound) { + if (image_bitmap->OriginClean()) { + execution_context->CountUse( + mojom::WebFeature::kOriginCleanImageBitmapTransfer); + } else { + execution_context->CountUse( + mojom::WebFeature::kNonOriginCleanImageBitmapTransfer); + } + DCHECK_LE(index, std::numeric_limits<uint32_t>::max()); WriteTag(kImageBitmapTransferTag); WriteUint32(static_cast<uint32_t>(index)); @@ -260,6 +282,13 @@ bool V8ScriptValueSerializer::WriteDOMObject(ScriptWrappable* wrappable, } // Otherwise, it must be fully serialized. + if (image_bitmap->OriginClean()) { + execution_context->CountUse( + mojom::WebFeature::kOriginCleanImageBitmapSerialization); + } else { + execution_context->CountUse( + mojom::WebFeature::kNonOriginCleanImageBitmapSerialization); + } WriteTag(kImageBitmapTag); SerializedColorParams color_params(image_bitmap->GetCanvasColorParams()); WriteUint32Enum(ImageSerializationTag::kCanvasColorSpaceTag); @@ -275,9 +304,17 @@ bool V8ScriptValueSerializer::WriteDOMObject(ScriptWrappable* wrappable, WriteUint32Enum(ImageSerializationTag::kEndTag); WriteUint32(image_bitmap->width()); WriteUint32(image_bitmap->height()); - scoped_refptr<Uint8Array> pixels = image_bitmap->CopyBitmapData(); - WriteUint32(pixels->length()); - WriteRawBytes(pixels->Data(), pixels->length()); + Vector<uint8_t> pixels = image_bitmap->CopyBitmapData(); + // Check if we succeeded to copy the BitmapData. + if (image_bitmap->width() != 0 && image_bitmap->height() != 0 && + pixels.size() == 0) { + exception_state.ThrowDOMException( + DOMExceptionCode::kDataCloneError, + "An ImageBitmap could not be read successfully."); + return false; + } + WriteUint32(pixels.size()); + WriteRawBytes(pixels.data(), pixels.size()); return true; } if (wrapper_type_info == V8ImageData::GetWrapperTypeInfo()) { @@ -725,7 +762,7 @@ v8::Maybe<uint32_t> V8ScriptValueSerializer::GetWasmModuleTransferId( // around. Most likely, we'll have one module. The vector approach is // simple and should perform sufficiently well under these expectations. serialized_script_value_->WasmModules().push_back( - module->GetTransferrableModule()); + module->GetCompiledModule()); uint32_t size = static_cast<uint32_t>(serialized_script_value_->WasmModules().size()); DCHECK_GE(size, 1u); 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 de2d7f680ec..981efb4bf1e 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 @@ -855,6 +855,19 @@ TEST(V8ScriptValueSerializerTest, DecodeImageDataV18) { new_image_data->BufferBase()->Data())[0]); } +TEST(V8ScriptValueSerializerTest, InvalidImageDataDecodeV18) { + V8TestingScope scope; + ScriptState* script_state = scope.GetScriptState(); + { + // Nonsense image serialization tag (kOriginCleanTag). + scoped_refptr<SerializedScriptValue> input = + SerializedValue({0xff, 0x12, 0xff, 0x0d, 0x5c, 0x23, 0x02, 0x00, 0x00, + 0x01, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00}); + EXPECT_TRUE( + V8ScriptValueDeserializer(script_state, input).Deserialize()->IsNull()); + } +} + MessagePort* MakeMessagePort(ExecutionContext* execution_context, ::MojoHandle* unowned_handle_out = nullptr) { auto* port = MakeGarbageCollected<MessagePort>(*execution_context); @@ -1252,6 +1265,14 @@ TEST(V8ScriptValueSerializerTest, InvalidImageBitmapDecodeV18) { EXPECT_TRUE( V8ScriptValueDeserializer(script_state, input).Deserialize()->IsNull()); } + { + // Nonsense image serialization tag (kImageDataStorageFormatTag). + scoped_refptr<SerializedScriptValue> input = + SerializedValue({0xff, 0x12, 0xff, 0x0d, 0x5c, 0x67, 0x03, 0x00, 0x00, + 0x01, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00}); + EXPECT_TRUE( + V8ScriptValueDeserializer(script_state, input).Deserialize()->IsNull()); + } } TEST(V8ScriptValueSerializerTest, TransferImageBitmap) { @@ -1293,7 +1314,8 @@ TEST(V8ScriptValueSerializerTest, TransferImageBitmap) { TEST(V8ScriptValueSerializerTest, TransferOffscreenCanvas) { // More exhaustive tests in web_tests/. This is a sanity check. V8TestingScope scope; - OffscreenCanvas* canvas = OffscreenCanvas::Create(10, 7); + OffscreenCanvas* canvas = + OffscreenCanvas::Create(scope.GetExecutionContext(), 10, 7); canvas->SetPlaceholderCanvasId(519); v8::Local<v8::Value> wrapper = ToV8(canvas, scope.GetScriptState()); Transferables transferables; @@ -1850,7 +1872,7 @@ TEST(V8ScriptValueSerializerTest, RoundTripReadableStream) { auto* rs = ReadableStream::Create(script_state, ASSERT_NO_EXCEPTION); v8::Local<v8::Value> wrapper = ToV8(rs, script_state); - Vector<ScriptValue> transferable_array = {ScriptValue(script_state, wrapper)}; + HeapVector<ScriptValue> transferable_array = {ScriptValue(isolate, wrapper)}; Transferables transferables; ASSERT_TRUE(SerializedScriptValue::ExtractTransferables( isolate, transferable_array, transferables, ASSERT_NO_EXCEPTION)); diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/to_v8_for_core.cc b/chromium/third_party/blink/renderer/bindings/core/v8/to_v8_for_core.cc index 51ba025d2a3..5e5ec0d9b34 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/to_v8_for_core.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/to_v8_for_core.cc @@ -6,6 +6,7 @@ #include "third_party/blink/renderer/bindings/core/v8/window_proxy.h" #include "third_party/blink/renderer/core/dom/events/event_target.h" +#include "third_party/blink/renderer/core/dom/node.h" #include "third_party/blink/renderer/core/frame/dom_window.h" #include "third_party/blink/renderer/core/frame/frame.h" #include "third_party/blink/renderer/platform/bindings/runtime_call_stats.h" @@ -49,4 +50,10 @@ v8::Local<v8::Value> ToV8(EventTarget* impl, return ToV8(static_cast<ScriptWrappable*>(impl), creation_context, isolate); } +v8::Local<v8::Value> ToV8(Node* node, + v8::Local<v8::Object> creation_context, + v8::Isolate* isolate) { + return ToV8(static_cast<ScriptWrappable*>(node), creation_context, isolate); +} + } // namespace blink diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h b/chromium/third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h index d27e786867d..544815c302a 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/to_v8_for_core.h @@ -10,9 +10,9 @@ #include "third_party/blink/renderer/bindings/core/v8/idl_dictionary_base.h" #include "third_party/blink/renderer/bindings/core/v8/script_value.h" -#include "third_party/blink/renderer/core/dom/node.h" #include "third_party/blink/renderer/core/typed_arrays/array_buffer_view_helpers.h" #include "third_party/blink/renderer/platform/bindings/to_v8.h" +#include "third_party/blink/renderer/platform/heap/disallow_new_wrapper.h" #include "v8/include/v8.h" namespace blink { @@ -27,11 +27,9 @@ CORE_EXPORT v8::Local<v8::Value> ToV8(DOMWindow*, CORE_EXPORT v8::Local<v8::Value> ToV8(EventTarget*, v8::Local<v8::Object> creation_context, v8::Isolate*); -inline v8::Local<v8::Value> ToV8(Node* node, - v8::Local<v8::Object> creation_context, - v8::Isolate* isolate) { - return ToV8(static_cast<ScriptWrappable*>(node), creation_context, isolate); -} +CORE_EXPORT v8::Local<v8::Value> ToV8(Node* node, + v8::Local<v8::Object> creation_context, + v8::Isolate* isolate); inline v8::Local<v8::Value> ToV8(const Dictionary& value, v8::Local<v8::Object> creation_context, @@ -67,11 +65,22 @@ inline v8::Local<v8::Value> ToV8(const ScriptValue& value, return value.V8Value(); } +inline v8::Local<v8::Value> ToV8(const DisallowNewWrapper<ScriptValue>* value, + v8::Local<v8::Object> creation_context, + v8::Isolate* isolate) { + if (value->Value().IsEmpty()) + return v8::Undefined(isolate); + return value->Value().V8Value(); +} + // Cannot define in ScriptValue because of the circular dependency between toV8 // and ScriptValue template <typename T> inline ScriptValue ScriptValue::From(ScriptState* script_state, T&& value) { - return ScriptValue(script_state, ToV8(std::forward<T>(value), script_state)); + v8::Local<v8::Value> v8_value = ToV8(std::forward<T>(value), script_state); + if (v8_value.IsEmpty()) + return ScriptValue(); + return ScriptValue(script_state->GetIsolate(), v8_value); } } // namespace blink 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 b71fa3f818a..ed09cf5afbe 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 @@ -152,7 +152,7 @@ TEST(ToV8Test, undefinedType) { TEST(ToV8Test, scriptValue) { V8TestingScope scope; - ScriptValue value(scope.GetScriptState(), + ScriptValue value(scope.GetIsolate(), v8::Number::New(scope.GetIsolate(), 1234)); TEST_TOV8("1234", value); @@ -300,7 +300,7 @@ TEST(ToV8Test, heapVector) { TEST(ToV8Test, withScriptState) { V8TestingScope scope; - ScriptValue value(scope.GetScriptState(), + ScriptValue value(scope.GetIsolate(), v8::Number::New(scope.GetIsolate(), 1234.0)); v8::Local<v8::Value> actual = ToV8(value, scope.GetScriptState()); 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 fd91a6bee39..d8425c4a58b 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 @@ -14,7 +14,7 @@ namespace { using TraceWrapperV8ReferenceTest = BindingTestSupportingGC; -class TraceWrapperV8ReferenceHolder +class TraceWrapperV8ReferenceHolder final : public GarbageCollected<TraceWrapperV8ReferenceHolder> { public: TraceWrapperV8ReferenceHolder() = default; 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 a381af0a56d..46acbdc2541 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 @@ -234,9 +234,6 @@ void UseCounterCallback(v8::Isolate* isolate, case v8::Isolate::kCallSiteAPIGetThisSloppyCall: blink_feature = WebFeature::kV8CallSiteAPIGetThisSloppyCall; break; - case v8::Isolate::kRegExpMatchAllWithNonGlobalRegExp: - blink_feature = WebFeature::kV8RegExpMatchAllWithNonGlobalRegExp; - break; default: // This can happen if V8 has added counters that this version of Blink // does not know about. It's harmless. diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v0_custom_element_constructor_builder.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v0_custom_element_constructor_builder.cc index e07a189ccb7..b8f95c90ea6 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/v0_custom_element_constructor_builder.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/v0_custom_element_constructor_builder.cc @@ -318,7 +318,7 @@ bool V0CustomElementConstructorBuilder::DidRegisterDefinition() const { } ScriptValue V0CustomElementConstructorBuilder::BindingsReturnValue() const { - return ScriptValue(script_state_, constructor_); + return ScriptValue(script_state_->GetIsolate(), constructor_); } bool V0CustomElementConstructorBuilder::HasValidPrototypeChainFor( diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.cc index 647f70e18f2..22f10d19ee7 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.cc @@ -783,7 +783,7 @@ ScriptState* ToScriptStateForMainWorld(LocalFrame* frame) { } bool IsValidEnum(const String& value, - const char** valid_values, + const char* const* valid_values, size_t length, const String& enum_name, ExceptionState& exception_state) { @@ -799,7 +799,7 @@ bool IsValidEnum(const String& value, } bool IsValidEnum(const Vector<String>& values, - const char** valid_values, + const char* const* valid_values, size_t length, const String& enum_name, ExceptionState& exception_state) { diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h b/chromium/third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h index a03407398c6..c69e169d739 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h @@ -502,12 +502,12 @@ CORE_EXPORT void ToFlexibleArrayBufferView(v8::Isolate*, void* storage = nullptr); CORE_EXPORT bool IsValidEnum(const String& value, - const char** valid_values, + const char* const* valid_values, size_t length, const String& enum_name, ExceptionState&); CORE_EXPORT bool IsValidEnum(const Vector<String>& values, - const char** valid_values, + const char* const* valid_values, size_t length, const String& enum_name, ExceptionState&); diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.cc index 0f2accba4e3..8d3b1b24c3a 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.cc @@ -12,9 +12,8 @@ namespace blink { -namespace { - -std::unique_ptr<DummyPageHolder> CreateDummyPageHolder(const KURL& url) { +std::unique_ptr<DummyPageHolder> V8TestingScope::CreateDummyPageHolder( + const KURL& url) { std::unique_ptr<DummyPageHolder> holder = std::make_unique<DummyPageHolder>(); if (url.IsValid()) { holder->GetFrame().Loader().CommitNavigation( @@ -25,8 +24,6 @@ std::unique_ptr<DummyPageHolder> CreateDummyPageHolder(const KURL& url) { return holder; } -} // namespace - V8TestingScope::V8TestingScope(const KURL& url) : holder_(CreateDummyPageHolder(url)), handle_scope_(GetIsolate()), diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h b/chromium/third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h index d22214d67fc..ba8125b9159 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h @@ -27,6 +27,9 @@ class V8TestingScope { STACK_ALLOCATED(); public: + // TODO(keishi): Define CreateDummyPageHolder in DummyPageHolder. + static std::unique_ptr<DummyPageHolder> CreateDummyPageHolder( + const KURL& url); explicit V8TestingScope(const KURL& url = KURL()); ScriptState* GetScriptState() const; ExecutionContext* GetExecutionContext() const; 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 794d58df642..4187057454c 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 @@ -173,8 +173,9 @@ class GC_PLUGIN_IGNORE( uint16_t class_id) override; // v8::EmbedderHeapTracer::TracedGlobalHandleVisitor override. - void VisitTracedGlobalHandle( - const v8::TracedGlobal<v8::Value>& value) override; + void VisitTracedReference( + const v8::TracedReference<v8::Value>& value) override; + void VisitTracedGlobalHandle(const v8::TracedGlobal<v8::Value>&) override; // Visitor overrides. void VisitRoot(void*, TraceDescriptor, const base::Location&) final; @@ -508,8 +509,8 @@ void V8EmbedderGraphBuilder::VisitPersistentHandleInternal( } } -void V8EmbedderGraphBuilder::VisitTracedGlobalHandle( - const v8::TracedGlobal<v8::Value>& value) { +void V8EmbedderGraphBuilder::VisitTracedReference( + const v8::TracedReference<v8::Value>& value) { const uint16_t class_id = value.WrapperClassId(); if (class_id != WrapperTypeInfo::kNodeClassId && class_id != WrapperTypeInfo::kObjectClassId) @@ -517,6 +518,11 @@ void V8EmbedderGraphBuilder::VisitTracedGlobalHandle( VisitPersistentHandleInternal(value.As<v8::Object>().Get(isolate_), class_id); } +void V8EmbedderGraphBuilder::VisitTracedGlobalHandle( + const v8::TracedGlobal<v8::Value>&) { + CHECK(false) << "Blink does not use v8::TracedGlobal."; +} + void V8EmbedderGraphBuilder::VisitPersistentHandle( v8::Persistent<v8::Value>* value, uint16_t class_id) { @@ -637,7 +643,7 @@ void V8EmbedderGraphBuilder::VisitBlinkRoots() { std::unique_ptr<Graph::Node>(new EmbedderRootNode("Blink roots")))); EnsureRootState(root); ParentScope parent(this, root); - ThreadState::Current()->GetPersistentRegion()->TracePersistentNodes(this); + ThreadState::Current()->GetPersistentRegion()->TraceNodes(this); } { EmbedderNode* root = @@ -646,7 +652,7 @@ void V8EmbedderGraphBuilder::VisitBlinkRoots() { EnsureRootState(root); ParentScope parent(this, root); MutexLocker persistent_lock(ProcessHeap::CrossThreadPersistentMutex()); - ProcessHeap::GetCrossThreadPersistentRegion().TracePersistentNodes(this); + ProcessHeap::GetCrossThreadPersistentRegion().TraceNodes(this); } } diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_extras_test_utils.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_extras_test_utils.cc index 7623ed70b80..16a021bdf2a 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_extras_test_utils.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_extras_test_utils.cc @@ -33,7 +33,7 @@ ScriptValue Eval(V8TestingScope* scope, const char* script_as_string) { ADD_FAILURE() << "Compilation fails"; return ScriptValue(); } - return ScriptValue(scope->GetScriptState(), script->Run(scope->GetContext())); + return ScriptValue(scope->GetIsolate(), script->Run(scope->GetContext())); } ScriptValue EvalWithPrintingError(V8TestingScope* scope, const char* script) { 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 bf045ffc632..de328132d2f 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 @@ -176,18 +176,10 @@ void V8GCController::GcEpilogue(v8::Isolate* isolate, case v8::kGCTypeScavenge: TRACE_EVENT_END1("devtools.timeline,v8", "MinorGC", "usedHeapSizeAfter", UsedHeapSize(isolate)); - // Scavenger might have dropped nodes. - if (ThreadState::Current()) { - ThreadState::Current()->ScheduleV8FollowupGCIfNeeded( - BlinkGC::kV8MinorGC); - } break; case v8::kGCTypeMarkSweepCompact: TRACE_EVENT_END1("devtools.timeline,v8", "MajorGC", "usedHeapSizeAfter", UsedHeapSize(isolate)); - if (ThreadState::Current()) - ThreadState::Current()->ScheduleV8FollowupGCIfNeeded( - BlinkGC::kV8MajorGC); break; case v8::kGCTypeIncrementalMarking: TRACE_EVENT_END1("devtools.timeline,v8", "MajorGC", "usedHeapSizeAfter", @@ -260,7 +252,11 @@ class DOMWrapperForwardingVisitor final VisitHandle(value, class_id); } - void VisitTracedGlobalHandle(const v8::TracedGlobal<v8::Value>& value) final { + void VisitTracedGlobalHandle(const v8::TracedGlobal<v8::Value>&) final { + CHECK(false) << "Blink does not use v8::TracedGlobal."; + } + + void VisitTracedReference(const v8::TracedReference<v8::Value>& value) final { VisitHandle(&value, value.WrapperClassId()); } diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc index 3eeafca490b..3b1ced15de4 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_initializer.cc @@ -374,9 +374,9 @@ static bool ContentSecurityPolicyCodeGenerationCheck( static_cast<size_t>(source_str.length())); memcpy(snippet, *source_str, len * sizeof(UChar)); snippet[len] = 0; - return policy->AllowEval( - ScriptState::From(context), SecurityViolationReportingPolicy::kReport, - ContentSecurityPolicy::kWillThrowException, snippet); + return policy->AllowEval(SecurityViolationReportingPolicy::kReport, + ContentSecurityPolicy::kWillThrowException, + snippet); } } return false; @@ -450,12 +450,10 @@ static bool WasmCodeGenerationCheckCallbackInMainThread( // Wasm code generation is allowed if we have either the wasm-eval // directive or the unsafe-eval directive. However, we only recognize // wasm-eval for certain schemes - return policy->AllowWasmEval(ScriptState::From(context), - SecurityViolationReportingPolicy::kReport, + return policy->AllowWasmEval(SecurityViolationReportingPolicy::kReport, ContentSecurityPolicy::kWillThrowException, snippet) || - policy->AllowEval(ScriptState::From(context), - SecurityViolationReportingPolicy::kReport, + policy->AllowEval(SecurityViolationReportingPolicy::kReport, ContentSecurityPolicy::kWillThrowException, snippet); } diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_iterator_result_value.h b/chromium/third_party/blink/renderer/bindings/core/v8/v8_iterator_result_value.h index 6d37648968d..0af30777d9b 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_iterator_result_value.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_iterator_result_value.h @@ -27,7 +27,7 @@ V8UnpackIteratorResult(ScriptState*, v8::Local<v8::Object> result, bool* done); template <typename T> inline ScriptValue V8IteratorResult(ScriptState* script_state, const T& value) { return ScriptValue( - script_state, + script_state->GetIsolate(), V8IteratorResultValue(script_state, false, ToV8(value, script_state->GetContext()->Global(), script_state->GetIsolate()))); @@ -35,7 +35,7 @@ inline ScriptValue V8IteratorResult(ScriptState* script_state, const T& value) { inline ScriptValue V8IteratorResultDone(ScriptState* script_state) { return ScriptValue( - script_state, + script_state->GetIsolate(), V8IteratorResultValue(script_state, true, v8::Undefined(script_state->GetIsolate()))); } diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_object_builder.cc b/chromium/third_party/blink/renderer/bindings/core/v8/v8_object_builder.cc index c448406ca4b..6abb611983a 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_object_builder.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_object_builder.cc @@ -53,7 +53,7 @@ V8ObjectBuilder& V8ObjectBuilder::AddStringOrNull(const StringView& name, } ScriptValue V8ObjectBuilder::GetScriptValue() const { - return ScriptValue(script_state_, object_); + return ScriptValue(script_state_->GetIsolate(), object_); } void V8ObjectBuilder::AddInternal(const StringView& name, 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 4aca5e28650..94ce5a11791 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 @@ -44,6 +44,7 @@ #include "third_party/blink/renderer/platform/instrumentation/histogram.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" #include "third_party/blink/renderer/platform/loader/fetch/cached_metadata.h" +#include "third_party/blink/renderer/platform/loader/fetch/cached_metadata_handler.h" #include "third_party/blink/renderer/platform/scheduler/public/event_loop.h" #include "third_party/blink/renderer/platform/wtf/assertions.h" #include "third_party/blink/renderer/platform/wtf/text/text_encoding.h" @@ -524,22 +525,4 @@ void V8ScriptRunner::ReportException(v8::Isolate* isolate, V8Initializer::MessageHandlerInWorker(message, exception); } -v8::MaybeLocal<v8::Value> V8ScriptRunner::CallExtraHelper( - ScriptState* script_state, - const char* name, - uint32_t num_args, - v8::Local<v8::Value>* args) { - v8::Isolate* isolate = script_state->GetIsolate(); - v8::Local<v8::Value> function_value; - v8::Local<v8::Context> context = script_state->GetContext(); - if (!context->GetExtrasBindingObject() - ->Get(context, V8AtomicString(isolate, name)) - .ToLocal(&function_value)) - return v8::MaybeLocal<v8::Value>(); - v8::Local<v8::Function> function = function_value.As<v8::Function>(); - return V8ScriptRunner::CallInternalFunction( - isolate, ToMicrotaskQueue(script_state), function, v8::Undefined(isolate), - num_args, args); -} - } // namespace blink diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/v8_script_runner.h b/chromium/third_party/blink/renderer/bindings/core/v8/v8_script_runner.h index 002f4ce7c30..fb0ad51edf9 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/v8_script_runner.h +++ b/chromium/third_party/blink/renderer/bindings/core/v8/v8_script_runner.h @@ -103,26 +103,12 @@ class CORE_EXPORT V8ScriptRunner final { const String& file_name, const WTF::TextPosition&); - // Calls a function on the V8 extras binding object. - template <uint32_t N> - static v8::MaybeLocal<v8::Value> CallExtra(ScriptState* script_state, - const char* name, - v8::Local<v8::Value> (&args)[N]) { - return CallExtraHelper(script_state, name, N, args); - } - // Reports an exception to the message handler, as if it were an uncaught // exception. Can only be called on the main thread. // // TODO(adamk): This should live on V8ThrowException, but it depends on // V8Initializer and so can't trivially move to platform/bindings. static void ReportException(v8::Isolate*, v8::Local<v8::Value> exception); - - private: - static v8::MaybeLocal<v8::Value> CallExtraHelper(ScriptState*, - const char* name, - uint32_t num_args, - v8::Local<v8::Value>* args); }; } // namespace blink 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 fe0426952bc..00a872a9953 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 @@ -106,19 +106,15 @@ V8V0CustomElementLifecycleCallbacks::V8V0CustomElementLifecycleCallbacks( : V0CustomElementLifecycleCallbacks( FlagSet(attached, detached, attribute_changed)), script_state_(script_state), - prototype_(script_state->GetIsolate(), prototype), - created_(script_state->GetIsolate(), created), - attached_(script_state->GetIsolate(), attached), - detached_(script_state->GetIsolate(), detached), - attribute_changed_(script_state->GetIsolate(), attribute_changed) { - prototype_.SetPhantom(); - -#define MAKE_WEAK(Var, Ignored) \ - if (!Var##_.IsEmpty()) \ - Var##_.SetPhantom(); - - CALLBACK_LIST(MAKE_WEAK) -#undef MAKE_WEAK + prototype_(script_state->GetIsolate(), prototype){ + v8::Isolate* isolate = script_state->GetIsolate(); + v8::Local<v8::Function> function; +#define SET_FIELD(maybe, ignored) \ + if (maybe.ToLocal(&function)) \ + maybe##_.Set(isolate, function); + + CALLBACK_LIST(SET_FIELD) +#undef SET_FIELD } V8PerContextData* V8V0CustomElementLifecycleCallbacks::CreationContextData() { @@ -228,7 +224,7 @@ void V8V0CustomElementLifecycleCallbacks::AttributeChanged( } void V8V0CustomElementLifecycleCallbacks::Call( - const ScopedPersistent<v8::Function>& weak_callback, + const TraceWrapperV8Reference<v8::Function>& callback_reference, Element* element) { // FIXME: callbacks while paused should be queued up for execution to // continue then be delivered in order rather than delivered immediately. @@ -238,7 +234,7 @@ void V8V0CustomElementLifecycleCallbacks::Call( ScriptState::Scope scope(script_state_); v8::Isolate* isolate = script_state_->GetIsolate(); v8::Local<v8::Context> context = script_state_->GetContext(); - v8::Local<v8::Function> callback = weak_callback.NewLocal(isolate); + v8::Local<v8::Function> callback = callback_reference.NewLocal(isolate); if (callback.IsEmpty()) return; @@ -254,6 +250,11 @@ void V8V0CustomElementLifecycleCallbacks::Call( void V8V0CustomElementLifecycleCallbacks::Trace(blink::Visitor* visitor) { visitor->Trace(script_state_); + visitor->Trace(prototype_); + visitor->Trace(created_); + visitor->Trace(attached_); + visitor->Trace(detached_); + visitor->Trace(attribute_changed_); V0CustomElementLifecycleCallbacks::Trace(visitor); } 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 c37f7880552..f295bfbb236 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 @@ -35,8 +35,8 @@ #include "base/memory/scoped_refptr.h" #include "third_party/blink/renderer/core/html/custom/v0_custom_element_lifecycle_callbacks.h" -#include "third_party/blink/renderer/platform/bindings/scoped_persistent.h" #include "third_party/blink/renderer/platform/bindings/script_state.h" +#include "third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h" #include "v8/include/v8.h" namespace blink { @@ -79,16 +79,17 @@ class V8V0CustomElementLifecycleCallbacks final const AtomicString& old_value, const AtomicString& new_value) override; - void Call(const ScopedPersistent<v8::Function>& weak_callback, Element*); + void Call(const TraceWrapperV8Reference<v8::Function>& callback_reference, + Element*); V8PerContextData* CreationContextData(); Member<ScriptState> script_state_; - ScopedPersistent<v8::Object> prototype_; - ScopedPersistent<v8::Function> created_; - ScopedPersistent<v8::Function> attached_; - ScopedPersistent<v8::Function> detached_; - ScopedPersistent<v8::Function> attribute_changed_; + TraceWrapperV8Reference<v8::Object> prototype_; + TraceWrapperV8Reference<v8::Function> created_; + TraceWrapperV8Reference<v8::Function> attached_; + TraceWrapperV8Reference<v8::Function> detached_; + TraceWrapperV8Reference<v8::Function> attribute_changed_; }; } // namespace blink 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 8bf3935efb2..1be10f4d468 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 @@ -159,7 +159,7 @@ class FetchDataLoaderForWasmStreaming final : public FetchDataLoader, // argument to BodyStreamBuffer::startLoading, however, it fulfills // a very small role. Consider refactoring to avoid it. class WasmDataLoaderClient final - : public GarbageCollectedFinalized<WasmDataLoaderClient>, + : public GarbageCollected<WasmDataLoaderClient>, public FetchDataLoader::Client { USING_GARBAGE_COLLECTED_MIXIN(WasmDataLoaderClient); @@ -234,24 +234,15 @@ RawResource* GetRawResource(ScriptState* script_state, class WasmStreamingClient : public v8::WasmStreaming::Client { public: WasmStreamingClient(const String& response_url, - const base::Time& response_time, - v8::Isolate* isolate, - v8::Local<v8::Context> context) + const base::Time& response_time) : response_url_(response_url.IsolatedCopy()), - response_time_(response_time), - context_(isolate, context) { - context_.SetWeak(); - } + response_time_(response_time) {} void OnModuleCompiled(v8::CompiledWasmModule compiled_module) override { TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), "v8.wasm.compiledModule", TRACE_EVENT_SCOPE_THREAD, "url", response_url_.Utf8()); - // Don't cache if Context has been destroyed. - if (context_.IsEmpty()) - return; - // Our heuristic for whether it's worthwhile to cache is that the module // was fully compiled and it is "large". Wire bytes size is likely to be // highly correlated with compiled module size so we use it to avoid the @@ -292,7 +283,6 @@ class WasmStreamingClient : public v8::WasmStreaming::Client { private: String response_url_; base::Time response_time_; - v8::Global<v8::Context> context_; scoped_refptr<CachedMetadata> cached_module_; DISALLOW_COPY_AND_ASSIGN(WasmStreamingClient); @@ -365,8 +355,7 @@ void StreamFromResponseCallback( raw_resource->ScriptCacheHandler(); if (cache_handler) { auto client = std::make_shared<WasmStreamingClient>( - url, raw_resource->GetResponse().ResponseTime(), args.GetIsolate(), - script_state->GetContext()); + url, raw_resource->GetResponse().ResponseTime()); streaming->SetClient(client); scoped_refptr<CachedMetadata> cached_module = cache_handler->GetCachedMetadata(kWasmModuleTag); 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 44a70bdf501..060b4a3b6b6 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 @@ -141,7 +141,7 @@ struct WrapperTypeInfo; // ====== References ====== // https://wiki.mozilla.org/Gecko:SplitWindow // https://whatwg.org/C/browsers.html#the-windowproxy-exotic-object -class WindowProxy : public GarbageCollectedFinalized<WindowProxy> { +class WindowProxy : public GarbageCollected<WindowProxy> { public: virtual ~WindowProxy(); 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 7a2c63f5439..1463b2baaf9 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 @@ -33,7 +33,6 @@ #include <memory> #include "third_party/blink/public/platform/platform.h" -#include "third_party/blink/renderer/bindings/core/v8/initialize_v8_extras_binding.h" #include "third_party/blink/renderer/bindings/core/v8/referrer_script_info.h" #include "third_party/blink/renderer/bindings/core/v8/script_controller.h" #include "third_party/blink/renderer/bindings/core/v8/script_source_code.h" @@ -115,9 +114,8 @@ void WorkerOrWorkletScriptController::Dispose() { rejected_promises_->Dispose(); rejected_promises_ = nullptr; - world_->Dispose(); - DisposeContextIfNeeded(); + world_->Dispose(); } void WorkerOrWorkletScriptController::DisposeContextIfNeeded() { @@ -133,9 +131,23 @@ void WorkerOrWorkletScriptController::DisposeContextIfNeeded() { { ScriptState::Scope scope(script_state_); + v8::Local<v8::Context> context = script_state_->GetContext(); + // After disposing the world, all Blink->V8 references are gone. Blink + // stand-alone GCs may collect the WorkerOrWorkletGlobalScope because there + // are no more roots (V8->Blink references that are actually found by + // iterating Blink->V8 references). Clear the back pointers to avoid + // referring to cleared memory on the next GC in case the JS wrapper objects + // survived. + v8::Local<v8::Object> global_proxy_object = context->Global(); + v8::Local<v8::Object> global_object = + global_proxy_object->GetPrototype().As<v8::Object>(); + DCHECK(!global_object.IsEmpty()); + V8DOMWrapper::ClearNativeInfo(isolate_, global_object); + V8DOMWrapper::ClearNativeInfo(isolate_, global_proxy_object); + // This detaches v8::MicrotaskQueue pointer from v8::Context, so that we can // destroy EventLoop safely. - script_state_->GetContext()->DetachGlobal(); + context->DetachGlobal(); } script_state_->DisposePerContextData(); @@ -308,10 +320,6 @@ void WorkerOrWorkletScriptController::PrepareForEvaluation() { wrapper_type_info->InstallConditionalFeatures( context, *world_, global_object, v8::Local<v8::Object>(), v8::Local<v8::Function>(), global_interface_template); - - // This can only be called after the global object is fully initialised, as it - // reads values from it. - InitializeV8ExtrasBinding(script_state_); } void WorkerOrWorkletScriptController::DisableEvalInternal( @@ -372,7 +380,8 @@ ScriptValue WorkerOrWorkletScriptController::EvaluateInternal( execution_state_->error_message = ToCoreString(message->Get()); execution_state_->location_ = SourceLocation::FromMessage( isolate_, message, ExecutionContext::From(script_state_)); - execution_state_->exception = ScriptValue(script_state_, block.Exception()); + execution_state_->exception = + ScriptValue(script_state_->GetIsolate(), block.Exception()); block.Reset(); } else { execution_state_->had_exception = false; @@ -382,7 +391,7 @@ ScriptValue WorkerOrWorkletScriptController::EvaluateInternal( if (!maybe_result.ToLocal(&result) || result->IsUndefined()) return ScriptValue(); - return ScriptValue(script_state_, result); + return ScriptValue(script_state_->GetIsolate(), result); } bool WorkerOrWorkletScriptController::Evaluate( 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 3b9faadbe69..b4d37783935 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 @@ -50,7 +50,7 @@ class ScriptSourceCode; class WorkerOrWorkletGlobalScope; class CORE_EXPORT WorkerOrWorkletScriptController final - : public GarbageCollectedFinalized<WorkerOrWorkletScriptController> { + : public GarbageCollected<WorkerOrWorkletScriptController> { public: WorkerOrWorkletScriptController(WorkerOrWorkletGlobalScope*, v8::Isolate*); virtual ~WorkerOrWorkletScriptController(); diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/world_safe_v8_reference.cc b/chromium/third_party/blink/renderer/bindings/core/v8/world_safe_v8_reference.cc index 7ee67ac88a7..8ee18890b38 100644 --- a/chromium/third_party/blink/renderer/bindings/core/v8/world_safe_v8_reference.cc +++ b/chromium/third_party/blink/renderer/bindings/core/v8/world_safe_v8_reference.cc @@ -41,8 +41,12 @@ void WorldSafeV8ReferenceInternal::MaybeCheckCreationContextWorld( if (!value->IsObject()) return; - ScriptState* script_state = - ScriptState::From(value.As<v8::Object>()->CreationContext()); + v8::Local<v8::Context> context = value.As<v8::Object>()->CreationContext(); + // Creation context is null if the value is a remote object. + if (context.IsEmpty()) + return; + + ScriptState* script_state = ScriptState::From(context); CHECK_EQ(&world, &script_state->World()); } 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 85b3e322567..20b5677af71 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 @@ -47,40 +47,58 @@ class CORE_EXPORT WorldSafeV8ReferenceInternal final { // provides accessors that check whether the value is accessed in the same world // or not, also provides an accessor that clones the value when accessed across // worlds. +// +// TODO(crbug.com/1008765): Allow WorldSafeV8Reference created/set not in +// context. template <typename V8Type> class WorldSafeV8Reference final { DISALLOW_NEW(); public: WorldSafeV8Reference() = default; + explicit WorldSafeV8Reference(v8::Isolate* isolate, v8::Local<V8Type> value) - : v8_reference_(isolate, value), - world_(&DOMWrapperWorld::Current(isolate)) { - WorldSafeV8ReferenceInternal::MaybeCheckCreationContextWorld(*world_.get(), - value); + : v8_reference_(isolate, value) { + DCHECK(!value.IsEmpty()); + // Basically, |world_| is a world when this V8 reference is created. + // However, when this V8 reference isn't created in context and value is + // object, we set |world_| to a value's creation cotext's world. + if (isolate->InContext()) { + world_ = &DOMWrapperWorld::Current(isolate); + WorldSafeV8ReferenceInternal::MaybeCheckCreationContextWorld( + *world_.get(), value); + } else if (value->IsObject()) { + ScriptState* script_state = + ScriptState::From(value.template As<v8::Object>()->CreationContext()); + world_ = &script_state->World(); + } } ~WorldSafeV8Reference() = default; - // Returns the V8 reference. Crashes if |target_script_state|'s world is - // different from this V8 reference's world. + // Returns the V8 reference. Crashes if |world_| is set and it is + // different from |target_script_state|'s world. v8::Local<V8Type> Get(ScriptState* target_script_state) const { DCHECK(!v8_reference_.IsEmpty()); - CHECK_EQ(world_.get(), &target_script_state->World()); + if (world_) { + CHECK_EQ(world_.get(), &target_script_state->World()); + } return v8_reference_.NewLocal(target_script_state->GetIsolate()); } // Returns a V8 reference that is safe to access in |target_script_state|. // The return value may be a cloned object. v8::Local<V8Type> GetAcrossWorld(ScriptState* target_script_state) const { + CHECK(world_); return WorldSafeV8ReferenceInternal::ToWorldSafeValue( target_script_state, v8_reference_, *world_.get()) .template As<V8Type>(); } - // Sets a new V8 reference. Crashes if |new_value|'s world is different from - // this V8 reference's world. + // Sets a new V8 reference. Crashes if |world_| is set and it is + // different from |new_value|'s world. void Set(v8::Isolate* isolate, v8::Local<V8Type> new_value) { DCHECK(!new_value.IsEmpty()); + CHECK(isolate->InContext()); const DOMWrapperWorld& new_world = DOMWrapperWorld::Current(isolate); WorldSafeV8ReferenceInternal::MaybeCheckCreationContextWorld(new_world, new_value); @@ -93,6 +111,7 @@ class WorldSafeV8Reference final { // world of this V8 reference will be |new_value|'s world. void SetAcrossWorld(v8::Isolate* isolate, v8::Local<V8Type> new_value) { DCHECK(!new_value.IsEmpty()); + CHECK(isolate->InContext()); const DOMWrapperWorld& new_world = DOMWrapperWorld::Current(isolate); v8_reference_.Set(isolate, new_value); world_ = WrapRefCounted(&new_world); @@ -107,14 +126,19 @@ class WorldSafeV8Reference final { void Trace(blink::Visitor* visitor) { visitor->Trace(v8_reference_); } + WorldSafeV8Reference& operator=(const WorldSafeV8Reference<V8Type>& other) = + default; + + bool operator==(const WorldSafeV8Reference<V8Type>& other) const { + return v8_reference_ == other.v8_reference_; + } + private: TraceWrapperV8Reference<V8Type> v8_reference_; // The world of the current context at the time when |v8_reference_| was set. // It's guaranteed that, if |v8_reference_| is a v8::Object, the world of the // creation context of |v8_reference_| is the same as |world_|. scoped_refptr<const DOMWrapperWorld> world_; - - DISALLOW_COPY_AND_ASSIGN(WorldSafeV8Reference); }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/bindings/core/v8/world_safe_v8_reference_test.cc b/chromium/third_party/blink/renderer/bindings/core/v8/world_safe_v8_reference_test.cc new file mode 100644 index 00000000000..8f166748c69 --- /dev/null +++ b/chromium/third_party/blink/renderer/bindings/core/v8/world_safe_v8_reference_test.cc @@ -0,0 +1,63 @@ +// 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. + +#include "third_party/blink/renderer/bindings/core/v8/world_safe_v8_reference.h" + +#include "testing/gmock/include/gmock/gmock-matchers.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h" +#include "third_party/blink/renderer/core/frame/settings.h" +#include "third_party/blink/renderer/core/testing/dummy_page_holder.h" +#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" +#include "third_party/blink/renderer/platform/weborigin/kurl.h" +#include "v8/include/v8.h" + +namespace blink { + +class DummyPageHolder; +class KURL; + +namespace { + +class IsolateOnlyV8TestingScope { + STACK_ALLOCATED(); + + public: + IsolateOnlyV8TestingScope(const KURL& url = KURL()) + : holder_(V8TestingScope::CreateDummyPageHolder(url)), + handle_scope_(GetIsolate()) {} + + v8::Isolate* GetIsolate() const { + return ToScriptStateForMainWorld(holder_->GetDocument().GetFrame()) + ->GetIsolate(); + } + + private: + std::unique_ptr<DummyPageHolder> holder_; + v8::HandleScope handle_scope_; +}; + +// http://crbug.com/1007504, http://crbug.com/1008425 +TEST(WorldSafeV8ReferenceTest, CreatedWhenNotInContext) { + WorldSafeV8Reference<v8::Value> v8_reference; + v8::Local<v8::Value> value; + { + IsolateOnlyV8TestingScope scope1; + v8::Isolate* isolate = scope1.GetIsolate(); + CHECK(isolate); + CHECK(!isolate->InContext()); + + value = v8::Null(isolate); + v8_reference = WorldSafeV8Reference<v8::Value>(isolate, value); + EXPECT_FALSE(v8_reference.IsEmpty()); + } + V8TestingScope scope2; + ScriptState* script_state = scope2.GetScriptState(); + EXPECT_EQ(v8_reference.Get(script_state), value); +} + +} // namespace + +} // namespace blink |