Skip to content
This repository was archived by the owner on Jul 18, 2018. It is now read-only.

Commit 505cc74

Browse files
nyaxtCommit Bot
authored and
Commit Bot
committed
[ES6 modules] Update #creating-a-module-script to record its compilation error
This CL updates Blink's impl of #creating-a-module-script to match recent spec change: whatwg/html#2595 . Before this CL, ModuleScript::Create, the Blink's impl of #creating-a-module-script reported the compilation error to console. After this CL, ModuleScript::Create records module script compilation error to ModuleScript::error_, and stops reporting the error to console. Tests: external/wpt/html/semantics/scripting-1/the-script-element/module/compilation-error-*.html Bug: 727299, 594639 Change-Id: Iad166780aa93db491abe1c5185fb2da07b61b8f0 Reviewed-on: https://chromium-review.googlesource.com/526555 Commit-Queue: Kouhei Ueno <kouhei@chromium.org> Reviewed-by: Yutaka Hirano <yhirano@chromium.org> Cr-Commit-Position: refs/heads/master@{#478207}
1 parent 29997a9 commit 505cc74

14 files changed

+117
-72
lines changed

Diff for: third_party/WebKit/LayoutTests/TestExpectations

-2
Original file line numberDiff line numberDiff line change
@@ -1796,8 +1796,6 @@ crbug.com/694958 virtual/stable/http/tests/navigation/same-and-different-back.ht
17961796

17971797
# Failing because of module-related implementation/test issues.
17981798
crbug.com/594639 external/wpt/html/semantics/scripting-1/the-script-element/module/errorhandling.html [ Failure ]
1799-
crbug.com/594639 external/wpt/html/semantics/scripting-1/the-script-element/module/compilation-error-1.html [ Failure ]
1800-
crbug.com/594639 external/wpt/html/semantics/scripting-1/the-script-element/module/compilation-error-2.html [ Failure ]
18011799
crbug.com/594639 external/wpt/html/semantics/scripting-1/the-script-element/module/evaluation-error-1.html [ Failure ]
18021800
crbug.com/594639 external/wpt/html/semantics/scripting-1/the-script-element/module/evaluation-error-2.html [ Failure ]
18031801
crbug.com/594639 external/wpt/html/semantics/scripting-1/the-script-element/module/evaluation-error-3.html [ Failure ]

Diff for: third_party/WebKit/Source/bindings/core/v8/ScriptModule.cpp

+4-6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include "bindings/core/v8/ScriptModule.h"
66

7+
#include "bindings/core/v8/ExceptionState.h"
78
#include "bindings/core/v8/V8BindingForCore.h"
89
#include "core/dom/Modulator.h"
910
#include "core/dom/ScriptModuleResolver.h"
@@ -40,22 +41,19 @@ ScriptModule ScriptModule::Compile(v8::Isolate* isolate,
4041
const String& source,
4142
const String& file_name,
4243
AccessControlStatus access_control_status,
43-
const TextPosition& start_position) {
44+
const TextPosition& start_position,
45+
ExceptionState& exception_state) {
4446
// We ensure module-related code is not executed without the flag.
4547
// https://crbug.com/715376
4648
CHECK(RuntimeEnabledFeatures::ModuleScriptsEnabled());
4749

4850
v8::TryCatch try_catch(isolate);
49-
try_catch.SetVerbose(true);
5051
v8::Local<v8::Module> module;
5152
if (!V8ScriptRunner::CompileModule(isolate, source, file_name,
5253
access_control_status, start_position)
5354
.ToLocal(&module)) {
54-
// Compilation error is not used in Blink implementaion logic.
55-
// Note: Error message is delivered to user (e.g. console) by message
56-
// listeners set on v8::Isolate. See V8Initializer::initalizeMainThread().
57-
// TODO(nhiroki): Revisit this when supporting modules on worker threads.
5855
DCHECK(try_catch.HasCaught());
56+
exception_state.RethrowV8Exception(try_catch.Exception());
5957
return ScriptModule();
6058
}
6159
DCHECK(!try_catch.HasCaught());

Diff for: third_party/WebKit/Source/bindings/core/v8/ScriptModule.h

+8-6
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
namespace blink {
1919

20+
class ExceptionState;
21+
2022
// ScriptModule wraps a handle to a v8::Module for use in core.
2123
//
2224
// Using ScriptModules needs a ScriptState and its scope to operate in. You
@@ -28,12 +30,12 @@ class CORE_EXPORT ScriptModule final {
2830
DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
2931

3032
public:
31-
static ScriptModule Compile(
32-
v8::Isolate*,
33-
const String& source,
34-
const String& file_name,
35-
AccessControlStatus,
36-
const TextPosition& start_position = TextPosition::MinimumPosition());
33+
static ScriptModule Compile(v8::Isolate*,
34+
const String& source,
35+
const String& file_name,
36+
AccessControlStatus,
37+
const TextPosition& start_position,
38+
ExceptionState&);
3739

3840
// TODO(kouhei): Remove copy ctor
3941
ScriptModule();

Diff for: third_party/WebKit/Source/bindings/core/v8/ScriptModuleTest.cpp

+32-23
Original file line numberDiff line numberDiff line change
@@ -78,30 +78,33 @@ DEFINE_TRACE(ScriptModuleTestModulator) {
7878

7979
TEST(ScriptModuleTest, compileSuccess) {
8080
V8TestingScope scope;
81-
ScriptModule module =
82-
ScriptModule::Compile(scope.GetIsolate(), "export const a = 42;",
83-
"foo.js", kSharableCrossOrigin);
81+
ScriptModule module = ScriptModule::Compile(
82+
scope.GetIsolate(), "export const a = 42;", "foo.js",
83+
kSharableCrossOrigin, TextPosition::MinimumPosition(),
84+
ASSERT_NO_EXCEPTION);
8485
ASSERT_FALSE(module.IsNull());
8586
}
8687

8788
TEST(ScriptModuleTest, compileFail) {
8889
V8TestingScope scope;
89-
ScriptModule module = ScriptModule::Compile(scope.GetIsolate(), "123 = 456",
90-
"foo.js", kSharableCrossOrigin);
90+
ScriptModule module = ScriptModule::Compile(
91+
scope.GetIsolate(), "123 = 456", "foo.js", kSharableCrossOrigin,
92+
TextPosition::MinimumPosition(), scope.GetExceptionState());
9193
ASSERT_TRUE(module.IsNull());
94+
EXPECT_TRUE(scope.GetExceptionState().HadException());
9295
}
9396

9497
TEST(ScriptModuleTest, equalAndHash) {
9598
V8TestingScope scope;
9699

97100
ScriptModule module_null;
98-
ScriptModule module_a =
99-
ScriptModule::Compile(scope.GetIsolate(), "export const a = 'a';", "a.js",
100-
kSharableCrossOrigin);
101+
ScriptModule module_a = ScriptModule::Compile(
102+
scope.GetIsolate(), "export const a = 'a';", "a.js", kSharableCrossOrigin,
103+
TextPosition::MinimumPosition(), ASSERT_NO_EXCEPTION);
101104
ASSERT_FALSE(module_a.IsNull());
102-
ScriptModule module_b =
103-
ScriptModule::Compile(scope.GetIsolate(), "export const b = 'b';", "b.js",
104-
kSharableCrossOrigin);
105+
ScriptModule module_b = ScriptModule::Compile(
106+
scope.GetIsolate(), "export const b = 'b';", "b.js", kSharableCrossOrigin,
107+
TextPosition::MinimumPosition(), ASSERT_NO_EXCEPTION);
105108
ASSERT_FALSE(module_b.IsNull());
106109
Vector<char> module_deleted_buffer(sizeof(ScriptModule));
107110
ScriptModule& module_deleted =
@@ -141,7 +144,8 @@ TEST(ScriptModuleTest, moduleRequests) {
141144
V8TestingScope scope;
142145
ScriptModule module = ScriptModule::Compile(
143146
scope.GetIsolate(), "import 'a'; import 'b'; export const c = 'c';",
144-
"foo.js", kSharableCrossOrigin);
147+
"foo.js", kSharableCrossOrigin, TextPosition::MinimumPosition(),
148+
ASSERT_NO_EXCEPTION);
145149
ASSERT_FALSE(module.IsNull());
146150

147151
auto requests = module.ModuleRequests(scope.GetScriptState());
@@ -156,9 +160,10 @@ TEST(ScriptModuleTest, instantiateNoDeps) {
156160

157161
Modulator::SetModulator(scope.GetScriptState(), modulator);
158162

159-
ScriptModule module =
160-
ScriptModule::Compile(scope.GetIsolate(), "export const a = 42;",
161-
"foo.js", kSharableCrossOrigin);
163+
ScriptModule module = ScriptModule::Compile(
164+
scope.GetIsolate(), "export const a = 42;", "foo.js",
165+
kSharableCrossOrigin, TextPosition::MinimumPosition(),
166+
ASSERT_NO_EXCEPTION);
162167
ASSERT_FALSE(module.IsNull());
163168
ScriptValue exception = module.Instantiate(scope.GetScriptState());
164169
ASSERT_TRUE(exception.IsEmpty());
@@ -174,21 +179,24 @@ TEST(ScriptModuleTest, instantiateWithDeps) {
174179

175180
Modulator::SetModulator(scope.GetScriptState(), modulator);
176181

177-
ScriptModule module_a =
178-
ScriptModule::Compile(scope.GetIsolate(), "export const a = 'a';",
179-
"foo.js", kSharableCrossOrigin);
182+
ScriptModule module_a = ScriptModule::Compile(
183+
scope.GetIsolate(), "export const a = 'a';", "foo.js",
184+
kSharableCrossOrigin, TextPosition::MinimumPosition(),
185+
ASSERT_NO_EXCEPTION);
180186
ASSERT_FALSE(module_a.IsNull());
181187
resolver->PushScriptModule(module_a);
182188

183-
ScriptModule module_b =
184-
ScriptModule::Compile(scope.GetIsolate(), "export const b = 'b';",
185-
"foo.js", kSharableCrossOrigin);
189+
ScriptModule module_b = ScriptModule::Compile(
190+
scope.GetIsolate(), "export const b = 'b';", "foo.js",
191+
kSharableCrossOrigin, TextPosition::MinimumPosition(),
192+
ASSERT_NO_EXCEPTION);
186193
ASSERT_FALSE(module_b.IsNull());
187194
resolver->PushScriptModule(module_b);
188195

189196
ScriptModule module = ScriptModule::Compile(
190197
scope.GetIsolate(), "import 'a'; import 'b'; export const c = 123;",
191-
"c.js", kSharableCrossOrigin);
198+
"c.js", kSharableCrossOrigin, TextPosition::MinimumPosition(),
199+
ASSERT_NO_EXCEPTION);
192200
ASSERT_FALSE(module.IsNull());
193201
ScriptValue exception = module.Instantiate(scope.GetScriptState());
194202
ASSERT_TRUE(exception.IsEmpty());
@@ -206,7 +214,8 @@ TEST(ScriptModuleTest, Evaluate) {
206214

207215
ScriptModule module = ScriptModule::Compile(
208216
scope.GetIsolate(), "export const a = 42; window.foo = 'bar';", "foo.js",
209-
kSharableCrossOrigin);
217+
kSharableCrossOrigin, TextPosition::MinimumPosition(),
218+
ASSERT_NO_EXCEPTION);
210219
ASSERT_FALSE(module.IsNull());
211220
ScriptValue exception = module.Instantiate(scope.GetScriptState());
212221
ASSERT_TRUE(exception.IsEmpty());

Diff for: third_party/WebKit/Source/core/dom/Modulator.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
namespace blink {
2020

21+
class ExceptionState;
2122
class ModuleScript;
2223
class ModuleScriptFetchRequest;
2324
class ModuleScriptLoaderClient;
@@ -107,7 +108,8 @@ class CORE_EXPORT Modulator : public GarbageCollectedFinalized<Modulator>,
107108
virtual ScriptModule CompileModule(const String& script,
108109
const String& url_str,
109110
AccessControlStatus,
110-
const TextPosition&) = 0;
111+
const TextPosition&,
112+
ExceptionState&) = 0;
111113

112114
virtual ScriptValue InstantiateModule(ScriptModule) = 0;
113115

Diff for: third_party/WebKit/Source/core/dom/ModulatorImpl.cpp

+5-6
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,9 @@ ScriptModule ModulatorImpl::CompileModule(
121121
const String& provided_source,
122122
const String& url_str,
123123
AccessControlStatus access_control_status,
124-
const TextPosition& position) {
125-
// Implements Steps 3-6 of
124+
const TextPosition& position,
125+
ExceptionState& exception_state) {
126+
// Implements Steps 3-5 of
126127
// https://html.spec.whatwg.org/multipage/webappapis.html#creating-a-module-script
127128

128129
// Step 3. Let realm be the provided environment settings object's Realm.
@@ -136,12 +137,10 @@ ScriptModule ModulatorImpl::CompileModule(
136137
script_source = provided_source;
137138

138139
// Step 5. Let result be ParseModule(script source, realm, script).
139-
// Step 6. If result is a List of errors, report the exception given by the
140-
// first element of result for script, return null, and abort these steps.
141-
// Note: reporting is routed via V8Initializer::messageHandlerInMainThread.
142140
ScriptState::Scope scope(script_state_.Get());
143141
return ScriptModule::Compile(script_state_->GetIsolate(), script_source,
144-
url_str, access_control_status, position);
142+
url_str, access_control_status, position,
143+
exception_state);
145144
}
146145

147146
ScriptValue ModulatorImpl::InstantiateModule(ScriptModule script_module) {

Diff for: third_party/WebKit/Source/core/dom/ModulatorImpl.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ class ModulatorImpl final : public Modulator {
6363
ScriptModule CompileModule(const String& script,
6464
const String& url_str,
6565
AccessControlStatus,
66-
const TextPosition&) override;
66+
const TextPosition&,
67+
ExceptionState&) override;
6768
ScriptValue InstantiateModule(ScriptModule) override;
6869
ScriptValue GetError(const ModuleScript*) override;
6970
Vector<String> ModuleRequestsFromScriptModule(ScriptModule) override;

Diff for: third_party/WebKit/Source/core/dom/ModuleScript.cpp

+39-13
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,40 @@ ModuleScript* ModuleScript::Create(
2727
// provided.
2828
// Note: "script's settings object" will be "modulator".
2929

30-
// Delegate to Modulator::compileModule to process Steps 3-6.
30+
v8::HandleScope scope(modulator->GetScriptState()->GetIsolate());
31+
ExceptionState exception_state(modulator->GetScriptState()->GetIsolate(),
32+
ExceptionState::kExecutionContext,
33+
"ModuleScript", "Create");
34+
35+
// Delegate to Modulator::CompileModule to process Steps 3-5.
3136
ScriptModule result = modulator->CompileModule(
32-
source_text, base_url.GetString(), access_control_status, start_position);
33-
// Step 6: "...return null, and abort these steps."
34-
if (result.IsNull())
35-
return nullptr;
37+
source_text, base_url.GetString(), access_control_status, start_position,
38+
exception_state);
39+
40+
// CreateInternal processes Steps 7-13.
41+
// [nospec] We initialize the other ModuleScript members anyway by running
42+
// Steps 7-13 before Step 6. In a case that compile failed, we will
43+
// immediately turn the script into errored state. Thus the members will not
44+
// be used for the speced algorithms, but may be used from inspector.
45+
ModuleScript* script =
46+
CreateInternal(source_text, modulator, result, base_url, nonce,
47+
parser_state, credentials_mode, start_position);
48+
49+
// Step 6. If result is a List of errors, then:
50+
if (exception_state.HadException()) {
51+
DCHECK(result.IsNull());
52+
53+
// Step 6.1. Error script with errors[0].
54+
v8::Local<v8::Value> error = exception_state.GetException();
55+
exception_state.ClearException();
56+
script->SetErrorAndClearRecord(
57+
ScriptValue(modulator->GetScriptState(), error));
58+
59+
// Step 6.2. Return script.
60+
return script;
61+
}
3662

37-
return CreateInternal(source_text, modulator, result, base_url, nonce,
38-
parser_state, credentials_mode, start_position);
63+
return script;
3964
}
4065

4166
ModuleScript* ModuleScript::CreateForTest(
@@ -61,13 +86,14 @@ ModuleScript* ModuleScript::CreateInternal(
6186
WebURLRequest::FetchCredentialsMode credentials_mode,
6287
const TextPosition& start_position) {
6388
// https://html.spec.whatwg.org/#creating-a-module-script
64-
// Step 7. Set script's module record to result.
65-
// Step 8. Set script's base URL to the script base URL provided.
66-
// Step 9. Set script's cryptographic nonce to the cryptographic nonce
89+
// Step 7. Set script's state to "uninstantiated".
90+
// Step 8. Set script's module record to result.
91+
// Step 9. Set script's base URL to the script base URL provided.
92+
// Step 10. Set script's cryptographic nonce to the cryptographic nonce
6793
// provided.
68-
// Step 10. Set script's parser state to the parser state.
69-
// Step 11. Set script's credentials mode to the credentials mode provided.
70-
// Step 12. Return script.
94+
// Step 11. Set script's parser state to the parser state.
95+
// Step 12. Set script's credentials mode to the credentials mode provided.
96+
// Step 13. Return script.
7197
// [not specced] |source_text| is saved for CSP checks.
7298
ModuleScript* module_script =
7399
new ModuleScript(modulator, result, base_url, nonce, parser_state,

Diff for: third_party/WebKit/Source/core/dom/ScriptModuleResolverImpl.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,15 @@ namespace blink {
1212

1313
void ScriptModuleResolverImpl::RegisterModuleScript(
1414
ModuleScript* module_script) {
15+
DCHECK(module_script);
16+
if (module_script->Record().IsNull())
17+
return;
18+
1519
DVLOG(1) << "ScriptModuleResolverImpl::registerModuleScript(url=\""
1620
<< module_script->BaseURL().GetString()
1721
<< "\", hash=" << ScriptModuleHash::GetHash(module_script->Record())
1822
<< ")";
1923

20-
DCHECK(module_script);
21-
DCHECK(!module_script->Record().IsNull());
2224
auto result =
2325
record_to_module_script_map_.Set(module_script->Record(), module_script);
2426
DCHECK(result.is_new_entry);

Diff for: third_party/WebKit/Source/core/dom/ScriptModuleResolverImplTest.cpp

+6-4
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@ ModuleScript* CreateReferrerModuleScript(Modulator* modulator,
7474
V8TestingScope& scope) {
7575
ScriptModule referrer_record = ScriptModule::Compile(
7676
scope.GetIsolate(), "import './target.js'; export const a = 42;",
77-
"referrer.js", kSharableCrossOrigin);
77+
"referrer.js", kSharableCrossOrigin, TextPosition::MinimumPosition(),
78+
ASSERT_NO_EXCEPTION);
7879
KURL referrer_url(kParsedURLString, "https://example.com/referrer.js");
7980
ModuleScript* referrer_module_script = ModuleScript::CreateForTest(
8081
modulator, referrer_record, referrer_url, "", kParserInserted,
@@ -87,9 +88,10 @@ ModuleScript* CreateTargetModuleScript(
8788
Modulator* modulator,
8889
V8TestingScope& scope,
8990
ModuleInstantiationState state = ModuleInstantiationState::kInstantiated) {
90-
ScriptModule record =
91-
ScriptModule::Compile(scope.GetIsolate(), "export const pi = 3.14;",
92-
"target.js", kSharableCrossOrigin);
91+
ScriptModule record = ScriptModule::Compile(
92+
scope.GetIsolate(), "export const pi = 3.14;", "target.js",
93+
kSharableCrossOrigin, TextPosition::MinimumPosition(),
94+
ASSERT_NO_EXCEPTION);
9395
KURL url(kParsedURLString, "https://example.com/target.js");
9496
ModuleScript* module_script =
9597
ModuleScript::CreateForTest(modulator, record, url, "", kParserInserted,

Diff for: third_party/WebKit/Source/core/loader/modulescript/ModuleScriptLoaderTest.cpp

+6-4
Original file line numberDiff line numberDiff line change
@@ -69,11 +69,13 @@ class ModuleScriptLoaderTestModulator final : public DummyModulator {
6969
ScriptModule CompileModule(const String& script,
7070
const String& url_str,
7171
AccessControlStatus access_control_status,
72-
const TextPosition& position) override {
72+
const TextPosition& position,
73+
ExceptionState& exception_state) override {
7374
ScriptState::Scope scope(script_state_.Get());
74-
return ScriptModule::Compile(script_state_->GetIsolate(),
75-
"export default 'foo';", "",
76-
access_control_status);
75+
return ScriptModule::Compile(
76+
script_state_->GetIsolate(), "export default 'foo';", "",
77+
access_control_status, TextPosition::MinimumPosition(),
78+
exception_state);
7779
}
7880

7981
DECLARE_TRACE();

Diff for: third_party/WebKit/Source/core/loader/modulescript/ModuleTreeLinkerTest.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ class ModuleTreeLinkerTestModulator final : public DummyModulator {
7878

7979
ScriptModule script_module = ScriptModule::Compile(
8080
script_state_->GetIsolate(), source_text.ToString(), url.GetString(),
81-
kSharableCrossOrigin);
81+
kSharableCrossOrigin, TextPosition::MinimumPosition(),
82+
ASSERT_NO_EXCEPTION);
8283
ModuleScript* module_script = ModuleScript::CreateForTest(
8384
this, script_module, url, "", kParserInserted,
8485
WebURLRequest::kFetchCredentialsModeOmit);
@@ -131,7 +132,8 @@ class ModuleTreeLinkerTestModulator final : public DummyModulator {
131132

132133
ScriptModule script_module = ScriptModule::Compile(
133134
script_state_->GetIsolate(), "export default 'pineapples';",
134-
url.GetString(), kSharableCrossOrigin);
135+
url.GetString(), kSharableCrossOrigin, TextPosition::MinimumPosition(),
136+
ASSERT_NO_EXCEPTION);
135137
ModuleScript* module_script = ModuleScript::CreateForTest(
136138
this, script_module, url, "", kParserInserted,
137139
WebURLRequest::kFetchCredentialsModeOmit);

Diff for: third_party/WebKit/Source/core/testing/DummyModulator.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,8 @@ bool DummyModulator::HasValidContext() {
103103
ScriptModule DummyModulator::CompileModule(const String& script,
104104
const String& url_str,
105105
AccessControlStatus,
106-
const TextPosition&) {
106+
const TextPosition&,
107+
ExceptionState&) {
107108
NOTREACHED();
108109
return ScriptModule();
109110
}

0 commit comments

Comments
 (0)