summaryrefslogtreecommitdiff
path: root/chromium/gin
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2017-07-17 13:57:45 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2017-07-19 13:44:40 +0000
commit6ec7b8da05d21a3878bd21c691b41e675d74bb1c (patch)
treeb87f250bc19413750b9bb9cdbf2da20ef5014820 /chromium/gin
parentec02ee4181c49b61fce1c8fb99292dbb8139cc90 (diff)
downloadqtwebengine-chromium-6ec7b8da05d21a3878bd21c691b41e675d74bb1c.tar.gz
BASELINE: Update Chromium to 60.0.3112.70
Change-Id: I9911c2280a014d4632f254857876a395d4baed2d Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/gin')
-rw-r--r--chromium/gin/BUILD.gn6
-rw-r--r--chromium/gin/OWNERS3
-rw-r--r--chromium/gin/README.md (renamed from chromium/gin/README)8
-rw-r--r--chromium/gin/arguments.cc13
-rw-r--r--chromium/gin/arguments.h5
-rw-r--r--chromium/gin/arguments_unittest.cc63
-rw-r--r--chromium/gin/data_object_builder.cc14
-rw-r--r--chromium/gin/data_object_builder.h69
-rw-r--r--chromium/gin/data_object_builder_unittest.cc119
-rw-r--r--chromium/gin/isolate_holder.cc1
-rw-r--r--chromium/gin/modules/module_registry.cc3
-rw-r--r--chromium/gin/modules/timer.cc9
-rw-r--r--chromium/gin/modules/timer_unittest.cc30
-rw-r--r--chromium/gin/shell/gin_main.cc52
-rw-r--r--chromium/gin/shell_runner_unittest.cc4
-rw-r--r--chromium/gin/v8_platform.cc27
16 files changed, 362 insertions, 64 deletions
diff --git a/chromium/gin/BUILD.gn b/chromium/gin/BUILD.gn
index 427d2a03f8c..f386fb6b222 100644
--- a/chromium/gin/BUILD.gn
+++ b/chromium/gin/BUILD.gn
@@ -32,6 +32,8 @@ component("gin") {
"context_holder.cc",
"converter.cc",
"converter.h",
+ "data_object_builder.cc",
+ "data_object_builder.h",
"debug_impl.cc",
"debug_impl.h",
"dictionary.cc",
@@ -120,7 +122,7 @@ executable("gin_shell") {
":gin",
"//base",
"//base:i18n",
- "//build/config/sanitizers:deps",
+ "//build/config:exe_and_shlib_deps",
"//build/win:default_exe_manifest",
"//v8",
]
@@ -151,6 +153,7 @@ source_set("gin_test") {
"//testing/gtest",
]
deps = [
+ "//base/test:test_support",
"//v8",
]
@@ -161,6 +164,7 @@ test("gin_unittests") {
sources = [
"arguments_unittest.cc",
"converter_unittest.cc",
+ "data_object_builder_unittest.cc",
"interceptor_unittest.cc",
"modules/module_registry_unittest.cc",
"modules/timer_unittest.cc",
diff --git a/chromium/gin/OWNERS b/chromium/gin/OWNERS
index d691287b2d5..ae52483ef1c 100644
--- a/chromium/gin/OWNERS
+++ b/chromium/gin/OWNERS
@@ -1 +1,4 @@
jochen@chromium.org
+
+# TEAM: blink-reviews-bindings@chromium.org
+# COMPONENT: Blink>Bindings
diff --git a/chromium/gin/README b/chromium/gin/README.md
index fc2d92e0f78..99a7a35fa54 100644
--- a/chromium/gin/README
+++ b/chromium/gin/README.md
@@ -5,13 +5,13 @@ This directory contains Gin, a set of utilities to make working with V8 easier.
Here are some of the key bits:
-* converter.h: Templatized JS<->C++ conversion routines for many common C++
+* converter.h: Templatized JS &harr; C++ conversion routines for many common C++
types. You can define your own by specializing Converter.
-* function_template.h: Create JavaScript functions that dispatch to any C++
+* function\_template.h: Create JavaScript functions that dispatch to any C++
function, member function pointer, or base::Callback.
-* object_template_builder.h: A handy utility for creation of v8::ObjectTemplate.
+* object\_template\_builder.h: A handy utility for creation of v8::ObjectTemplate.
* wrappable.h: Base class for C++ classes that want to be owned by the V8 GC.
Wrappable objects are automatically deleted when GC discovers that nothing in
@@ -20,5 +20,5 @@ Here are some of the key bits:
* runner.h: Create script contexts and run code in them.
-* module_runner_delegate.h: A delegate for runner that implements a subset of
+* module\_runner\_delegate.h: A delegate for runner that implements a subset of
the AMD module specification. Also see modules/ with some example modules.
diff --git a/chromium/gin/arguments.cc b/chromium/gin/arguments.cc
index 600a811f848..4d01c0e44d9 100644
--- a/chromium/gin/arguments.cc
+++ b/chromium/gin/arguments.cc
@@ -32,6 +32,19 @@ v8::Local<v8::Value> Arguments::PeekNext() const {
return (*info_)[next_];
}
+std::vector<v8::Local<v8::Value>> Arguments::GetAll() const {
+ std::vector<v8::Local<v8::Value>> result;
+ int length = info_->Length();
+ if (length == 0)
+ return result;
+
+ result.reserve(length);
+ for (int i = 0; i < length; ++i)
+ result.push_back((*info_)[i]);
+
+ return result;
+}
+
v8::Local<v8::Context> Arguments::GetHolderCreationContext() {
return info_->Holder()->CreationContext();
}
diff --git a/chromium/gin/arguments.h b/chromium/gin/arguments.h
index 99a5d16db21..c0a7bc2171d 100644
--- a/chromium/gin/arguments.h
+++ b/chromium/gin/arguments.h
@@ -81,6 +81,11 @@ class GIN_EXPORT Arguments {
// dereferencing the handle.
v8::Local<v8::Value> PeekNext() const;
+ // Returns all arguments. Since this doesn't require any conversion, it
+ // cannot fail. This does not rely on or modify the current position in the
+ // array used by Get/PeekNext().
+ std::vector<v8::Local<v8::Value>> GetAll() const;
+
void ThrowError() const;
void ThrowTypeError(const std::string& message) const;
diff --git a/chromium/gin/arguments_unittest.cc b/chromium/gin/arguments_unittest.cc
index d2b51361995..3a262c7818d 100644
--- a/chromium/gin/arguments_unittest.cc
+++ b/chromium/gin/arguments_unittest.cc
@@ -64,4 +64,67 @@ TEST_F(ArgumentsTest, TestArgumentsHolderCreationContext) {
}
}
+TEST_F(ArgumentsTest, TestGetAll) {
+ v8::Isolate* isolate = instance_->isolate();
+ v8::HandleScope handle_scope(isolate);
+ v8::Local<v8::Context> context = context_.Get(instance_->isolate());
+
+ using V8List = std::vector<v8::Local<v8::Value>>;
+
+ V8List list1 = {
+ gin::ConvertToV8(isolate, 1), gin::StringToV8(isolate, "some string"),
+ gin::ConvertToV8(context, std::vector<double>({2.0, 3.0}))
+ .ToLocalChecked(),
+ };
+ bool called1 = false;
+
+ V8List list2 = {
+ gin::StringToV8(isolate, "some other string"),
+ gin::ConvertToV8(isolate, 42),
+ };
+ bool called2 = false;
+
+ V8List list3; // Empty list.
+ bool called3 = false;
+
+ auto check_arguments = [](V8List* expected, bool* called,
+ gin::Arguments* arguments) {
+ *called = true;
+ V8List actual = arguments->GetAll();
+ ASSERT_EQ(expected->size(), actual.size());
+ for (size_t i = 0; i < expected->size(); ++i)
+ EXPECT_EQ(expected->at(i), actual[i]) << i;
+ };
+
+ // Create an object that will compare GetHolderCreationContext() with
+ // |creation_context|.
+ v8::Local<v8::ObjectTemplate> object_template =
+ ObjectTemplateBuilder(isolate)
+ .SetMethod("check1", base::Bind(check_arguments, &list1, &called1))
+ .SetMethod("check2", base::Bind(check_arguments, &list2, &called2))
+ .SetMethod("check3", base::Bind(check_arguments, &list3, &called3))
+ .Build();
+
+ v8::Local<v8::Object> object =
+ object_template->NewInstance(context).ToLocalChecked();
+
+ auto do_check = [object, context](V8List& args, base::StringPiece key) {
+ v8::Local<v8::Value> val;
+ ASSERT_TRUE(
+ object->Get(context, gin::StringToSymbol(context->GetIsolate(), key))
+ .ToLocal(&val));
+ ASSERT_TRUE(val->IsFunction());
+ val.As<v8::Function>()
+ ->Call(context, object, static_cast<int>(args.size()), args.data())
+ .ToLocalChecked();
+ };
+
+ do_check(list1, "check1");
+ EXPECT_TRUE(called1);
+ do_check(list2, "check2");
+ EXPECT_TRUE(called2);
+ do_check(list3, "check3");
+ EXPECT_TRUE(called3);
+}
+
} // namespace gin
diff --git a/chromium/gin/data_object_builder.cc b/chromium/gin/data_object_builder.cc
new file mode 100644
index 00000000000..243c7efc5ff
--- /dev/null
+++ b/chromium/gin/data_object_builder.cc
@@ -0,0 +1,14 @@
+// Copyright 2017 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 "gin/data_object_builder.h"
+
+namespace gin {
+
+DataObjectBuilder::DataObjectBuilder(v8::Isolate* isolate)
+ : isolate_(isolate),
+ context_(isolate->GetCurrentContext()),
+ object_(v8::Object::New(isolate)) {}
+
+} // namespace gin
diff --git a/chromium/gin/data_object_builder.h b/chromium/gin/data_object_builder.h
new file mode 100644
index 00000000000..8d75dfd2356
--- /dev/null
+++ b/chromium/gin/data_object_builder.h
@@ -0,0 +1,69 @@
+// Copyright 2017 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 GIN_DATA_OBJECT_BUILDER_H_
+#define GIN_DATA_OBJECT_BUILDER_H_
+
+#include <utility>
+
+#include "base/logging.h"
+#include "base/macros.h"
+#include "base/strings/string_piece.h"
+#include "gin/converter.h"
+#include "gin/gin_export.h"
+#include "v8/include/v8.h"
+
+namespace gin {
+
+// Constructs a JavaScript object with a series of data properties.
+// (As with default data properties in JavaScript, these properties are
+// configurable, writable and enumerable.)
+//
+// Values are automatically converted using gin::Converter, though if
+// using a type where the conversion may fail, callers must convert ahead of
+// time.
+//
+// This class avoids the pitfall of using v8::Object::Set, which may invoke
+// setters on the object prototype.
+//
+// Expected usage:
+// v8::Local<v8::Object> object = gin::DataObjectBuilder(isolate)
+// .Set("boolean", true)
+// .Set("integer", 42)
+// .Build();
+//
+// Because this builder class contains local handles, callers must ensure it
+// does not outlive the scope in which it is created.
+class GIN_EXPORT DataObjectBuilder {
+ public:
+ explicit DataObjectBuilder(v8::Isolate* isolate);
+
+ template <typename T>
+ DataObjectBuilder& Set(base::StringPiece key, T&& value) {
+ DCHECK(!object_.IsEmpty());
+ v8::Local<v8::String> v8_key = StringToSymbol(isolate_, key);
+ v8::Local<v8::Value> v8_value =
+ ConvertToV8(isolate_, std::forward<T>(value));
+ CHECK(object_->CreateDataProperty(context_, v8_key, v8_value).ToChecked());
+ return *this;
+ }
+
+ v8::Local<v8::Object> Build() {
+ DCHECK(!object_.IsEmpty());
+ v8::Local<v8::Object> result = object_;
+ object_.Clear();
+ return result;
+ }
+
+ private:
+ v8::Isolate* isolate_;
+ v8::Local<v8::Context> context_;
+ v8::Local<v8::Object> object_;
+
+ DISALLOW_COPY_AND_ASSIGN(DataObjectBuilder);
+};
+
+} // namespace gin
+
+#endif // GIN_DATA_OBJECT_BUILDER_H_
diff --git a/chromium/gin/data_object_builder_unittest.cc b/chromium/gin/data_object_builder_unittest.cc
new file mode 100644
index 00000000000..1629cdf596d
--- /dev/null
+++ b/chromium/gin/data_object_builder_unittest.cc
@@ -0,0 +1,119 @@
+// Copyright 2017 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 "gin/data_object_builder.h"
+
+#include "base/bind.h"
+#include "gin/dictionary.h"
+#include "gin/public/isolate_holder.h"
+#include "gin/test/v8_test.h"
+
+namespace gin {
+namespace {
+
+using DataObjectBuilderTest = V8Test;
+
+// It should create ordinary data properties.
+TEST_F(DataObjectBuilderTest, CreatesDataProperties) {
+ v8::Isolate* isolate = instance_->isolate();
+ v8::HandleScope handle_scope(isolate);
+ v8::Local<v8::Context> context = context_.Get(isolate);
+
+ v8::Local<v8::Object> object =
+ DataObjectBuilder(isolate).Set("key", 42).Build();
+ ASSERT_TRUE(object->HasOwnProperty(context, StringToSymbol(isolate, "key"))
+ .ToChecked());
+
+ v8::Local<v8::Value> descriptor_object;
+ ASSERT_TRUE(
+ object->GetOwnPropertyDescriptor(context, StringToSymbol(isolate, "key"))
+ .ToLocal(&descriptor_object));
+ gin::Dictionary descriptor(isolate, descriptor_object.As<v8::Object>());
+
+ int32_t value = 0;
+ ASSERT_TRUE(descriptor.Get("value", &value));
+ EXPECT_EQ(42, value);
+
+ bool writable = false;
+ ASSERT_TRUE(descriptor.Get("writable", &writable));
+ EXPECT_TRUE(writable);
+
+ bool enumerable = false;
+ ASSERT_TRUE(descriptor.Get("enumerable", &enumerable));
+ EXPECT_TRUE(enumerable);
+
+ bool configurable = false;
+ ASSERT_TRUE(descriptor.Get("configurable", &configurable));
+ EXPECT_TRUE(configurable);
+}
+
+// It should not invoke setters on the prototype chain.
+TEST_F(DataObjectBuilderTest, DoesNotInvokeSetters) {
+ v8::Isolate* isolate = instance_->isolate();
+ v8::HandleScope handle_scope(isolate);
+ v8::Local<v8::Context> context = context_.Get(isolate);
+
+ // Install a setter on the object prototype.
+ v8::Local<v8::Value> object_constructor;
+ ASSERT_TRUE(context->Global()
+ ->Get(context, StringToSymbol(isolate, "Object"))
+ .ToLocal(&object_constructor));
+ v8::Local<v8::Value> object_prototype;
+ ASSERT_TRUE(object_constructor.As<v8::Function>()
+ ->Get(context, StringToSymbol(isolate, "prototype"))
+ .ToLocal(&object_prototype));
+ ASSERT_TRUE(
+ object_prototype.As<v8::Object>()
+ ->SetAccessor(context, StringToSymbol(isolate, "key"),
+ [](v8::Local<v8::Name>,
+ const v8::PropertyCallbackInfo<v8::Value>&) {},
+ [](v8::Local<v8::Name>, v8::Local<v8::Value>,
+ const v8::PropertyCallbackInfo<void>&) {
+ ADD_FAILURE() << "setter should not be invoked";
+ })
+ .ToChecked());
+
+ // Create an object.
+ DataObjectBuilder(isolate).Set("key", 42).Build();
+}
+
+// The internal handle is cleared when the builder is finished.
+// This makes the class harder to abuse, so that its methods cannot be used
+// after something may have modified the object in unexpected ways.
+#if DCHECK_IS_ON()
+TEST_F(DataObjectBuilderTest, UnusableAfterBuild) {
+ v8::Isolate* isolate = instance_->isolate();
+ v8::HandleScope handle_scope(isolate);
+
+ DataObjectBuilder builder(isolate);
+ EXPECT_FALSE(builder.Build().IsEmpty());
+
+ bool has_dcheck_failure = false;
+ logging::ScopedLogAssertHandler handler(base::Bind(
+ [](bool* flag, const char* file, int line, base::StringPiece message,
+ base::StringPiece stack_trace) { *flag = true; },
+ base::Unretained(&has_dcheck_failure)));
+ builder.Build();
+ EXPECT_TRUE(has_dcheck_failure);
+}
+#endif // DCHECK_IS_ON()
+
+// As is the normal behaviour of CreateDataProperty, new data properties should
+// replace existing ones. Since no non-configurable ones are present, nor should
+// the object be non-extensible, this should work.
+TEST_F(DataObjectBuilderTest, ReplacesExistingProperties) {
+ v8::Isolate* isolate = instance_->isolate();
+ v8::HandleScope handle_scope(isolate);
+
+ v8::Local<v8::Object> object =
+ DataObjectBuilder(isolate).Set("value", 42).Set("value", 55).Build();
+
+ gin::Dictionary dictionary(isolate, object);
+ int32_t value;
+ ASSERT_TRUE(dictionary.Get("value", &value));
+ EXPECT_EQ(55, value);
+}
+
+} // namespace
+} // namespace gin
diff --git a/chromium/gin/isolate_holder.cc b/chromium/gin/isolate_holder.cc
index caea27e7a56..2e707359ca7 100644
--- a/chromium/gin/isolate_holder.cc
+++ b/chromium/gin/isolate_holder.cc
@@ -13,6 +13,7 @@
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
+#include "base/single_thread_task_runner.h"
#include "base/sys_info.h"
#include "gin/debug_impl.h"
#include "gin/function_template.h"
diff --git a/chromium/gin/modules/module_registry.cc b/chromium/gin/modules/module_registry.cc
index 3e8b4759760..99783d37920 100644
--- a/chromium/gin/modules/module_registry.cc
+++ b/chromium/gin/modules/module_registry.cc
@@ -11,6 +11,7 @@
#include <vector>
#include "base/logging.h"
+#include "base/memory/ptr_util.h"
#include "gin/arguments.h"
#include "gin/converter.h"
#include "gin/modules/module_registry_observer.h"
@@ -139,7 +140,7 @@ ModuleRegistry* ModuleRegistry::From(v8::Local<Context> context) {
// PerContextData takes ownership of ModuleRegistryData.
registry_data = new ModuleRegistryData;
registry_data->registry.reset(new ModuleRegistry(context->GetIsolate()));
- data->SetUserData(kModuleRegistryKey, registry_data);
+ data->SetUserData(kModuleRegistryKey, base::WrapUnique(registry_data));
}
return registry_data->registry.get();
}
diff --git a/chromium/gin/modules/timer.cc b/chromium/gin/modules/timer.cc
index 9e5a26c8ea9..e1deeaad8f5 100644
--- a/chromium/gin/modules/timer.cc
+++ b/chromium/gin/modules/timer.cc
@@ -67,9 +67,14 @@ void Timer::OnTimerFired() {
Runner::Scope scope(runner_.get());
v8::Isolate* isolate = runner_->GetContextHolder()->isolate();
+
+ v8::Local<v8::Object> wrapper;
+ if (!GetWrapper(isolate).ToLocal(&wrapper)) {
+ return;
+ }
+
v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast(
- GetWrapper(isolate)
- .ToLocalChecked()
+ wrapper
->GetPrivate(runner_->GetContextHolder()->context(),
GetHiddenPropertyName(isolate))
.ToLocalChecked());
diff --git a/chromium/gin/modules/timer_unittest.cc b/chromium/gin/modules/timer_unittest.cc
index bd4b3450f0a..665ea4e788d 100644
--- a/chromium/gin/modules/timer_unittest.cc
+++ b/chromium/gin/modules/timer_unittest.cc
@@ -67,12 +67,6 @@ struct TestHelper {
result->GetWrapper(isolate).ToLocalChecked());
}
- void QuitSoon(base::MessageLoop* message_loop) {
- message_loop->task_runner()->PostDelayedTask(
- FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(),
- base::TimeDelta::FromMilliseconds(0));
- }
-
ShellRunnerDelegate delegate;
std::unique_ptr<ShellRunner> runner;
Runner::Scope scope;
@@ -94,8 +88,7 @@ TEST_F(TimerUnittest, OneShot) {
helper.runner->Run(source, "script");
EXPECT_EQ(0, helper.result->count());
- helper.QuitSoon(&message_loop_);
- base::RunLoop().Run();
+ base::RunLoop().RunUntilIdle();
EXPECT_EQ(1, helper.result->count());
}
@@ -110,8 +103,7 @@ TEST_F(TimerUnittest, OneShotCancel) {
helper.runner->Run(source, "script");
EXPECT_EQ(0, helper.result->count());
- helper.QuitSoon(&message_loop_);
- base::RunLoop().Run();
+ base::RunLoop().RunUntilIdle();
EXPECT_EQ(0, helper.result->count());
}
@@ -121,12 +113,15 @@ TEST_F(TimerUnittest, Repeating) {
// TODO(aa): Cannot do: if (++result.count == 3) because of v8 bug. Create
// test case and report.
std::string source =
- "timer.createRepeating(0, function() {"
- " result.count++;"
- " if (result.count == 3) {"
- " result.quit();"
- " }"
- "});";
+ "var t = timer.createRepeating(0, function() {"
+ " result.count++;"
+ " if (result.count == 3) {"
+ " /* Cancel the timer to prevent a hang when ScopedTaskEnvironment "
+ " flushes main thread tasks. */"
+ " t.cancel();"
+ " result.quit();"
+ " }"
+ "});";
helper.runner->Run(source, "script");
EXPECT_EQ(0, helper.result->count());
@@ -146,9 +141,8 @@ TEST_F(TimerUnittest, TimerCallbackToDestroyedRunner) {
EXPECT_EQ(0, helper.result->count());
// Destroy runner, which should destroy the timer object we created.
- helper.QuitSoon(&message_loop_);
helper.runner.reset(NULL);
- base::RunLoop().Run();
+ base::RunLoop().RunUntilIdle();
// Timer should not have run because it was deleted.
EXPECT_EQ(0, helper.result->count());
diff --git a/chromium/gin/shell/gin_main.cc b/chromium/gin/shell/gin_main.cc
index c7cf598756d..0b8f8b8597e 100644
--- a/chromium/gin/shell/gin_main.cc
+++ b/chromium/gin/shell/gin_main.cc
@@ -14,6 +14,7 @@
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
+#include "base/task_scheduler/task_scheduler.h"
#include "base/threading/thread_task_runner_handle.h"
#include "gin/array_buffer.h"
#include "gin/modules/console.h"
@@ -73,34 +74,43 @@ int main(int argc, char** argv) {
#endif
base::MessageLoop message_loop;
+ base::TaskScheduler::CreateAndStartWithDefaultParams("gin");
// Initialize the base::FeatureList since IsolateHolder can depend on it.
base::FeatureList::SetInstance(base::WrapUnique(new base::FeatureList));
- gin::IsolateHolder::Initialize(gin::IsolateHolder::kStrictMode,
- gin::IsolateHolder::kStableV8Extras,
- gin::ArrayBufferAllocator::SharedInstance());
- gin::IsolateHolder instance(base::ThreadTaskRunnerHandle::Get());
-
- gin::GinShellRunnerDelegate delegate;
- gin::ShellRunner runner(&delegate, instance.isolate());
-
{
- gin::Runner::Scope scope(&runner);
- runner.GetContextHolder()
- ->isolate()
- ->SetCaptureStackTraceForUncaughtExceptions(true);
+ gin::IsolateHolder::Initialize(gin::IsolateHolder::kStrictMode,
+ gin::IsolateHolder::kStableV8Extras,
+ gin::ArrayBufferAllocator::SharedInstance());
+ gin::IsolateHolder instance(base::ThreadTaskRunnerHandle::Get());
+
+ gin::GinShellRunnerDelegate delegate;
+ gin::ShellRunner runner(&delegate, instance.isolate());
+
+ {
+ gin::Runner::Scope scope(&runner);
+ runner.GetContextHolder()
+ ->isolate()
+ ->SetCaptureStackTraceForUncaughtExceptions(true);
+ }
+
+ base::CommandLine::StringVector args =
+ base::CommandLine::ForCurrentProcess()->GetArgs();
+ for (base::CommandLine::StringVector::const_iterator it = args.begin();
+ it != args.end(); ++it) {
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::Bind(gin::Run, runner.GetWeakPtr(), base::FilePath(*it)));
+ }
+
+ base::RunLoop().RunUntilIdle();
}
- base::CommandLine::StringVector args =
- base::CommandLine::ForCurrentProcess()->GetArgs();
- for (base::CommandLine::StringVector::const_iterator it = args.begin();
- it != args.end(); ++it) {
- base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE,
- base::Bind(gin::Run, runner.GetWeakPtr(), base::FilePath(*it)));
- }
+ // gin::IsolateHolder waits for tasks running in TaskScheduler in its
+ // destructor and thus must be destroyed before TaskScheduler starts skipping
+ // CONTINUE_ON_SHUTDOWN tasks.
+ base::TaskScheduler::GetInstance()->Shutdown();
- base::RunLoop().RunUntilIdle();
return 0;
}
diff --git a/chromium/gin/shell_runner_unittest.cc b/chromium/gin/shell_runner_unittest.cc
index 0743ededb62..02e6835abcf 100644
--- a/chromium/gin/shell_runner_unittest.cc
+++ b/chromium/gin/shell_runner_unittest.cc
@@ -5,7 +5,7 @@
#include "gin/shell_runner.h"
#include "base/compiler_specific.h"
-#include "base/message_loop/message_loop.h"
+#include "base/test/scoped_task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
#include "gin/array_buffer.h"
#include "gin/converter.h"
@@ -25,7 +25,7 @@ using v8::String;
namespace gin {
TEST(RunnerTest, Run) {
- base::MessageLoop message_loop;
+ base::test::ScopedTaskEnvironment scoped_task_environment;
std::string source = "this.result = 'PASS';\n";
#ifdef V8_USE_EXTERNAL_STARTUP_DATA
diff --git a/chromium/gin/v8_platform.cc b/chromium/gin/v8_platform.cc
index dc887c43c3e..1bfa2f66e8e 100644
--- a/chromium/gin/v8_platform.cc
+++ b/chromium/gin/v8_platform.cc
@@ -4,11 +4,14 @@
#include "gin/public/v8_platform.h"
+#include <algorithm>
+
#include "base/bind.h"
#include "base/debug/stack_trace.h"
#include "base/location.h"
#include "base/sys_info.h"
-#include "base/threading/worker_pool.h"
+#include "base/task_scheduler/post_task.h"
+#include "base/task_scheduler/task_scheduler.h"
#include "base/trace_event/trace_event.h"
#include "gin/per_isolate_data.h"
@@ -16,6 +19,9 @@ namespace gin {
namespace {
+constexpr base::TaskTraits kBackgroundThreadTaskTraits = {
+ base::TaskPriority::USER_VISIBLE};
+
base::LazyInstance<V8Platform>::Leaky g_v8_platform = LAZY_INSTANCE_INITIALIZER;
void RunWithLocker(v8::Isolate* isolate, v8::Task* task) {
@@ -58,25 +64,16 @@ V8Platform::V8Platform() {}
V8Platform::~V8Platform() {}
size_t V8Platform::NumberOfAvailableBackgroundThreads() {
- // WorkerPool will currently always create additional threads for posted
- // background tasks, unless there are threads sitting idle (on posix).
- // Indicate that V8 should create no more than the number of cores available,
- // reserving one core for the main thread.
- const size_t available_cores =
- static_cast<size_t>(base::SysInfo::NumberOfProcessors());
- if (available_cores > 1) {
- return available_cores - 1;
- }
- return 1;
+ return std::max(1, base::TaskScheduler::GetInstance()
+ ->GetMaxConcurrentTasksWithTraitsDeprecated(
+ kBackgroundThreadTaskTraits));
}
void V8Platform::CallOnBackgroundThread(
v8::Task* task,
v8::Platform::ExpectedRuntime expected_runtime) {
- base::WorkerPool::PostTask(
- FROM_HERE,
- base::Bind(&v8::Task::Run, base::Owned(task)),
- expected_runtime == v8::Platform::kLongRunningTask);
+ base::PostTaskWithTraits(FROM_HERE, kBackgroundThreadTaskTraits,
+ base::Bind(&v8::Task::Run, base::Owned(task)));
}
void V8Platform::CallOnForegroundThread(v8::Isolate* isolate, v8::Task* task) {