Commit c4bffcd5 authored by Yutaka Hirano's avatar Yutaka Hirano Committed by Commit Bot

Use ScriptOriginOptions with IsSharedCrossOrigin set for empty script

Currently, neither IsSharedCrossOrigin nor IsOpaque is set for an empty
script. Hence an exception thrown from it (e.g., an exception thrown
from native promise implementation) is treated as an error with
blink::kNotSharableCrossOrigin. On the other hand, as the script is
empty, there is no meaningful URL attached, which means the
ExecutionContext's URL is used as the script's name in
blink::SourceLocation::FromMessage. In other words, it works virtually
as same as blink::kSharableCrossOrigin corresponding to
ScriptOriginOptions with IsSharedCrossOrigin set and IsOpaque unset.

With this CL, a ScriptOriginOptions with IsSharedCrossOrigin is set
and IsOpaque is not set is attached to the empty script, as a
preliminary step to deprecate kNotSharableCrossOrigin.

Bug: chromium:875153,chromium:876248
Change-Id: I39279a43994337329b8bd9d28b6ca29f0ac30d9c
Cq-Include-Trybots: luci.chromium.try:linux_chromium_rel_ng
Reviewed-on: https://chromium-review.googlesource.com/1201689Reviewed-by: 's avatarAdam Klein <adamk@chromium.org>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Commit-Queue: Yutaka Hirano <yhirano@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55673}
parent 0074ecf5
...@@ -815,6 +815,9 @@ void Heap::CreateInitialObjects() { ...@@ -815,6 +815,9 @@ void Heap::CreateInitialObjects() {
// Allocate the empty script. // Allocate the empty script.
Handle<Script> script = factory->NewScript(factory->empty_string()); Handle<Script> script = factory->NewScript(factory->empty_string());
script->set_type(Script::TYPE_NATIVE); script->set_type(Script::TYPE_NATIVE);
// This is used for exceptions thrown with no stack frames. Such exceptions
// can be shared everywhere.
script->set_origin_options(ScriptOriginOptions(true, false));
set_empty_script(*script); set_empty_script(*script);
Handle<Cell> array_constructor_cell = factory->NewCell( Handle<Cell> array_constructor_cell = factory->NewCell(
......
...@@ -17914,6 +17914,7 @@ int promise_reject_msg_column_number = -1; ...@@ -17914,6 +17914,7 @@ int promise_reject_msg_column_number = -1;
int promise_reject_line_number = -1; int promise_reject_line_number = -1;
int promise_reject_column_number = -1; int promise_reject_column_number = -1;
int promise_reject_frame_count = -1; int promise_reject_frame_count = -1;
bool promise_reject_is_shared_cross_origin = false;
void PromiseRejectCallback(v8::PromiseRejectMessage reject_message) { void PromiseRejectCallback(v8::PromiseRejectMessage reject_message) {
v8::Local<v8::Object> global = CcTest::global(); v8::Local<v8::Object> global = CcTest::global();
...@@ -17935,6 +17936,8 @@ void PromiseRejectCallback(v8::PromiseRejectMessage reject_message) { ...@@ -17935,6 +17936,8 @@ void PromiseRejectCallback(v8::PromiseRejectMessage reject_message) {
message->GetLineNumber(context).FromJust(); message->GetLineNumber(context).FromJust();
promise_reject_msg_column_number = promise_reject_msg_column_number =
message->GetStartColumn(context).FromJust() + 1; message->GetStartColumn(context).FromJust() + 1;
promise_reject_is_shared_cross_origin =
message->IsSharedCrossOrigin();
if (!stack_trace.IsEmpty()) { if (!stack_trace.IsEmpty()) {
promise_reject_frame_count = stack_trace->GetFrameCount(); promise_reject_frame_count = stack_trace->GetFrameCount();
...@@ -18365,6 +18368,67 @@ TEST(PromiseRejectCallback) { ...@@ -18365,6 +18368,67 @@ TEST(PromiseRejectCallback) {
CHECK_EQ(7, promise_reject_msg_column_number); CHECK_EQ(7, promise_reject_msg_column_number);
} }
TEST(PromiseRejectIsSharedCrossOrigin) {
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope scope(isolate);
isolate->SetPromiseRejectCallback(PromiseRejectCallback);
ResetPromiseStates();
// Create promise p0.
CompileRun(
"var reject; \n"
"var p0 = new Promise( \n"
" function(res, rej) { \n"
" reject = rej; \n"
" } \n"
"); \n");
CHECK(!GetPromise("p0")->HasHandler());
CHECK_EQ(0, promise_reject_counter);
CHECK_EQ(0, promise_revoke_counter);
// Not set because it's not yet rejected.
CHECK(!promise_reject_is_shared_cross_origin);
// Reject p0.
CompileRun("reject('ppp');");
CHECK_EQ(1, promise_reject_counter);
CHECK_EQ(0, promise_revoke_counter);
// Not set because the ScriptOriginOptions is from the script.
CHECK(!promise_reject_is_shared_cross_origin);
ResetPromiseStates();
// Create promise p1
CompileRun(
"var reject; \n"
"var p1 = new Promise( \n"
" function(res, rej) { \n"
" reject = rej; \n"
" } \n"
"); \n");
CHECK(!GetPromise("p1")->HasHandler());
CHECK_EQ(0, promise_reject_counter);
CHECK_EQ(0, promise_revoke_counter);
// Not set because it's not yet rejected.
CHECK(!promise_reject_is_shared_cross_origin);
// Add resolve handler (and default reject handler) to p1.
CompileRun("var p2 = p1.then(function(){});");
CHECK(GetPromise("p1")->HasHandler());
CHECK(!GetPromise("p2")->HasHandler());
CHECK_EQ(0, promise_reject_counter);
CHECK_EQ(0, promise_revoke_counter);
// Reject p1.
CompileRun("reject('ppp');");
CHECK_EQ(1, promise_reject_counter);
CHECK_EQ(0, promise_revoke_counter);
// Set because the event is from an empty script.
CHECK(promise_reject_is_shared_cross_origin);
}
void PromiseRejectCallbackConstructError( void PromiseRejectCallbackConstructError(
v8::PromiseRejectMessage reject_message) { v8::PromiseRejectMessage reject_message) {
v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext(); v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment