[ES6] Implement ES6 Module loader hook stubs in WebCore
authorutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 27 Sep 2015 22:24:18 +0000 (22:24 +0000)
committerutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 27 Sep 2015 22:24:18 +0000 (22:24 +0000)
https://bugs.webkit.org/show_bug.cgi?id=149574

Reviewed by Ryosuke Niwa.

In this patch, we implement the loader hooks in the WebCore side.
Since the fetcher and actual evaluation code are separated from
this patch, they become empty.

Here, WebCore implements 3 loader hooks.

1. resolve hook

    Takes the module name and resolve it to the unique module key.
    In WebCore, we use URL as a module key.
    And for the inlined module tag (e.g. <script type="module">import ...</script>),
    we use the ES6 symbol as a module key.
    In WebCore, we take the module name like "./hello.js" and resolve it by using
    the URL of the importer module.
    This functionality is implemented in this patch.

2. fetch hook

    Fetches the resource specified by the module key. In WebCore, the module key is
    URL. We use CachedResource loading system to load the resource of the modules.
    The actual code of the fetch hook will be implemented in the subsequent patch.

3. evaluate hook

    This is additional hook to instrument the module's execution for the inspector.
    The actual code of the evaluate hook will be implemented in the subsequent patch.

In addition to that, we added required JSC forward headers for the module loader
implementation.

* CMakeLists.txt:
* ForwardingHeaders/runtime/JSInternalPromise.h: Added.
* ForwardingHeaders/runtime/JSInternalPromiseDeferred.h: Added.
* ForwardingHeaders/runtime/JSModuleRecord.h: Added.
* ForwardingHeaders/runtime/Symbol.h: Added.
* WebCore.vcxproj/WebCore.vcxproj:
* WebCore.vcxproj/WebCore.vcxproj.filters:
* WebCore.xcodeproj/project.pbxproj:
* bindings/js/JSBindingsAllInOne.cpp:
* bindings/js/JSDOMWindowBase.cpp:
(WebCore::JSDOMWindowBase::moduleLoaderResolve):
(WebCore::JSDOMWindowBase::moduleLoaderFetch):
(WebCore::JSDOMWindowBase::moduleLoaderEvaluate):
* bindings/js/JSDOMWindowBase.h:
* bindings/js/JSModuleLoader.cpp: Added.
(WebCore::JSModuleLoader::JSModuleLoader):
(WebCore::JSModuleLoader::resolve):
(WebCore::JSModuleLoader::fetch):
(WebCore::JSModuleLoader::evaluate):
* bindings/js/JSModuleLoader.h: Added.
(WebCore::JSModuleLoader::document):
* dom/Document.cpp:
(WebCore::Document::Document):
(WebCore::Document::~Document):
* dom/Document.h:
(WebCore::Document::moduleLoader):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@190272 268f45cc-cd09-0410-ab3c-d52691b4dbfc

16 files changed:
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/ForwardingHeaders/runtime/JSInternalPromise.h [new file with mode: 0644]
Source/WebCore/ForwardingHeaders/runtime/JSInternalPromiseDeferred.h [new file with mode: 0644]
Source/WebCore/ForwardingHeaders/runtime/JSModuleRecord.h [new file with mode: 0644]
Source/WebCore/ForwardingHeaders/runtime/Symbol.h [new file with mode: 0644]
Source/WebCore/WebCore.vcxproj/WebCore.vcxproj
Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/bindings/js/JSBindingsAllInOne.cpp
Source/WebCore/bindings/js/JSDOMWindowBase.cpp
Source/WebCore/bindings/js/JSDOMWindowBase.h
Source/WebCore/bindings/js/JSModuleLoader.cpp [new file with mode: 0644]
Source/WebCore/bindings/js/JSModuleLoader.h [new file with mode: 0644]
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Document.h

index 131f644..7a821ee 100644 (file)
@@ -1177,6 +1177,7 @@ set(WebCore_SOURCES
     bindings/js/JSMessageChannelCustom.cpp
     bindings/js/JSMessageEventCustom.cpp
     bindings/js/JSMessagePortCustom.cpp
+    bindings/js/JSModuleLoader.cpp
     bindings/js/JSMutationCallback.cpp
     bindings/js/JSMutationObserverCustom.cpp
     bindings/js/JSNamedNodeMapCustom.cpp
index ecf19c3..54322e9 100644 (file)
@@ -1,3 +1,67 @@
+2015-09-27  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [ES6] Implement ES6 Module loader hook stubs in WebCore
+        https://bugs.webkit.org/show_bug.cgi?id=149574
+
+        Reviewed by Ryosuke Niwa.
+
+        In this patch, we implement the loader hooks in the WebCore side.
+        Since the fetcher and actual evaluation code are separated from
+        this patch, they become empty.
+
+        Here, WebCore implements 3 loader hooks.
+
+        1. resolve hook
+
+            Takes the module name and resolve it to the unique module key.
+            In WebCore, we use URL as a module key.
+            And for the inlined module tag (e.g. <script type="module">import ...</script>),
+            we use the ES6 symbol as a module key.
+            In WebCore, we take the module name like "./hello.js" and resolve it by using
+            the URL of the importer module.
+            This functionality is implemented in this patch.
+
+        2. fetch hook
+
+            Fetches the resource specified by the module key. In WebCore, the module key is
+            URL. We use CachedResource loading system to load the resource of the modules.
+            The actual code of the fetch hook will be implemented in the subsequent patch.
+
+        3. evaluate hook
+
+            This is additional hook to instrument the module's execution for the inspector.
+            The actual code of the evaluate hook will be implemented in the subsequent patch.
+
+        In addition to that, we added required JSC forward headers for the module loader
+        implementation.
+
+        * CMakeLists.txt:
+        * ForwardingHeaders/runtime/JSInternalPromise.h: Added.
+        * ForwardingHeaders/runtime/JSInternalPromiseDeferred.h: Added.
+        * ForwardingHeaders/runtime/JSModuleRecord.h: Added.
+        * ForwardingHeaders/runtime/Symbol.h: Added.
+        * WebCore.vcxproj/WebCore.vcxproj:
+        * WebCore.vcxproj/WebCore.vcxproj.filters:
+        * WebCore.xcodeproj/project.pbxproj:
+        * bindings/js/JSBindingsAllInOne.cpp:
+        * bindings/js/JSDOMWindowBase.cpp:
+        (WebCore::JSDOMWindowBase::moduleLoaderResolve):
+        (WebCore::JSDOMWindowBase::moduleLoaderFetch):
+        (WebCore::JSDOMWindowBase::moduleLoaderEvaluate):
+        * bindings/js/JSDOMWindowBase.h:
+        * bindings/js/JSModuleLoader.cpp: Added.
+        (WebCore::JSModuleLoader::JSModuleLoader):
+        (WebCore::JSModuleLoader::resolve):
+        (WebCore::JSModuleLoader::fetch):
+        (WebCore::JSModuleLoader::evaluate):
+        * bindings/js/JSModuleLoader.h: Added.
+        (WebCore::JSModuleLoader::document):
+        * dom/Document.cpp:
+        (WebCore::Document::Document):
+        (WebCore::Document::~Document):
+        * dom/Document.h:
+        (WebCore::Document::moduleLoader):
+
 2015-09-26  Hunseop Jeong  <hs85.jeong@samsung.com>
 
         Use modern for-loops in WebCore/inspector.
diff --git a/Source/WebCore/ForwardingHeaders/runtime/JSInternalPromise.h b/Source/WebCore/ForwardingHeaders/runtime/JSInternalPromise.h
new file mode 100644 (file)
index 0000000..7f557a2
--- /dev/null
@@ -0,0 +1,4 @@
+#ifndef WebCore_FWD_JSInternalPromise_h
+#define WebCore_FWD_JSInternalPromise_h
+#include <JavaScriptCore/JSInternalPromise.h>
+#endif
diff --git a/Source/WebCore/ForwardingHeaders/runtime/JSInternalPromiseDeferred.h b/Source/WebCore/ForwardingHeaders/runtime/JSInternalPromiseDeferred.h
new file mode 100644 (file)
index 0000000..c6c086d
--- /dev/null
@@ -0,0 +1,4 @@
+#ifndef WebCore_FWD_JSInternalPromiseDeferred_h
+#define WebCore_FWD_JSInternalPromiseDeferred_h
+#include <JavaScriptCore/JSInternalPromiseDeferred.h>
+#endif
diff --git a/Source/WebCore/ForwardingHeaders/runtime/JSModuleRecord.h b/Source/WebCore/ForwardingHeaders/runtime/JSModuleRecord.h
new file mode 100644 (file)
index 0000000..63e9ecf
--- /dev/null
@@ -0,0 +1,4 @@
+#ifndef WebCore_FWD_JSModuleRecord_h
+#define WebCore_FWD_JSModuleRecord_h
+#include <JavaScriptCore/JSModuleRecord.h>
+#endif
diff --git a/Source/WebCore/ForwardingHeaders/runtime/Symbol.h b/Source/WebCore/ForwardingHeaders/runtime/Symbol.h
new file mode 100644 (file)
index 0000000..750427f
--- /dev/null
@@ -0,0 +1,4 @@
+#ifndef WebCore_FWD_Symbol_h
+#define WebCore_FWD_Symbol_h
+#include <JavaScriptCore/Symbol.h>
+#endif
index bb8a467..f30552f 100644 (file)
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Production|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Production|x64'">true</ExcludedFromBuild>
     </ClCompile>
+    <ClCompile Include="..\bindings\js\JSModuleLoader.cpp">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug_WinCairo|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='DebugSuffix|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release_WinCairo|x64'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Production|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Production|x64'">true</ExcludedFromBuild>
+    </ClCompile>
     <ClCompile Include="..\bindings\js\JSMutationCallback.cpp">
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
     <ClInclude Include="..\bindings\js\JSLazyEventListener.h" />
     <ClInclude Include="..\bindings\js\JSMainThreadExecState.h" />
     <ClInclude Include="..\bindings\js\JSMessagePortCustom.h" />
+    <ClInclude Include="..\bindings\js\JSModuleLoader.h" />
     <ClInclude Include="..\bindings\js\JSMutationCallback.h" />
     <ClInclude Include="..\bindings\js\JSNodeCustom.h" />
     <ClInclude Include="..\bindings\js\JSNodeOrString.h" />
     <ClInclude Include="..\svg\properties\SVGTransformListPropertyTearOff.h" />
     <ClInclude Include="..\ForwardingHeaders\runtime\ArgList.h" />
     <ClInclude Include="..\ForwardingHeaders\runtime\Identifier.h" />
+    <ClInclude Include="..\ForwardingHeaders\runtime\JSInternalPromise.h" />
+    <ClInclude Include="..\ForwardingHeaders\runtime\JSInternalPromiseDeferred.h" />
     <ClInclude Include="..\ForwardingHeaders\runtime\JSLock.h" />
     <ClInclude Include="..\ForwardingHeaders\runtime\JSObject.h" />
     <ClInclude Include="..\ForwardingHeaders\runtime\JSString.h" />
+    <ClInclude Include="..\ForwardingHeaders\runtime\JSModuleRecord.h" />
     <ClInclude Include="..\ForwardingHeaders\runtime\Lookup.h" />
     <ClInclude Include="..\ForwardingHeaders\runtime\Operations.h" />
     <ClInclude Include="..\ForwardingHeaders\runtime\Protect.h" />
     <ClInclude Include="..\ForwardingHeaders\runtime\StringObject.h" />
+    <ClInclude Include="..\ForwardingHeaders\runtime\Symbol.h" />
     <ClInclude Include="..\ForwardingHeaders\yarr\RegularExpression.h" />
     <ClInclude Include="..\ForwardingHeaders\yarr\Yarr.h" />
     <ClInclude Include="..\ForwardingHeaders\yarr\YarrInterpreter.h" />
index af058e1..df4eb6d 100644 (file)
     <ClCompile Include="..\bindings\js\JSMessagePortCustom.cpp">
       <Filter>bindings\js</Filter>
     </ClCompile>
+    <ClCompile Include="..\bindings\js\JSModuleLoader.cpp">
+      <Filter>bindings\js</Filter>
+    </ClCompile>
     <ClCompile Include="..\bindings\js\JSMutationCallback.cpp">
       <Filter>bindings\js</Filter>
     </ClCompile>
     <ClInclude Include="..\bindings\js\JSMessagePortCustom.h">
       <Filter>bindings\js</Filter>
     </ClInclude>
+    <ClInclude Include="..\bindings\js\JSModuleLoader.h">
+      <Filter>bindings\js</Filter>
+    </ClInclude>
     <ClInclude Include="..\bindings\js\JSMutationCallback.h">
       <Filter>bindings\js</Filter>
     </ClInclude>
     <ClInclude Include="..\ForwardingHeaders\runtime\Identifier.h">
       <Filter>ForwardingHeaders\runtime</Filter>
     </ClInclude>
+    <ClInclude Include="..\ForwardingHeaders\runtime\JSInternalPromise.h">
+      <Filter>ForwardingHeaders\runtime</Filter>
+    </ClInclude>
+    <ClInclude Include="..\ForwardingHeaders\runtime\JSInternalPromiseDeferred.h">
+      <Filter>ForwardingHeaders\runtime</Filter>
+    </ClInclude>
     <ClInclude Include="..\ForwardingHeaders\runtime\JSLock.h">
       <Filter>ForwardingHeaders\runtime</Filter>
     </ClInclude>
     <ClInclude Include="..\ForwardingHeaders\runtime\JSObject.h">
       <Filter>ForwardingHeaders\runtime</Filter>
     </ClInclude>
+    <ClInclude Include="..\ForwardingHeaders\runtime\JSModuleRecord.h">
+      <Filter>ForwardingHeaders\runtime</Filter>
+    </ClInclude>
     <ClInclude Include="..\ForwardingHeaders\runtime\JSString.h">
       <Filter>ForwardingHeaders\runtime</Filter>
     </ClInclude>
     <ClInclude Include="..\ForwardingHeaders\runtime\StringObject.h">
       <Filter>ForwardingHeaders\runtime</Filter>
     </ClInclude>
+    <ClInclude Include="..\ForwardingHeaders\runtime\Symbol.h">
+      <Filter>ForwardingHeaders\runtime</Filter>
+    </ClInclude>
     <ClInclude Include="..\ForwardingHeaders\yarr\RegularExpression.h">
       <Filter>ForwardingHeaders\yarr</Filter>
     </ClInclude>
index 5b04223..59b13bd 100644 (file)
                E1FF8F681807460800132674 /* JSSubtleCryptoCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1FF8F661807460800132674 /* JSSubtleCryptoCustom.cpp */; };
                E1FF8F6C180DB5BE00132674 /* CryptoAlgorithmRegistry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E1FF8F6A180DB5BE00132674 /* CryptoAlgorithmRegistry.cpp */; };
                E1FF8F6D180DB5BE00132674 /* CryptoAlgorithmRegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = E1FF8F6B180DB5BE00132674 /* CryptoAlgorithmRegistry.h */; };
+               E38838981BAD145F00D62EE3 /* JSModuleLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38838941BAD145F00D62EE3 /* JSModuleLoader.cpp */; settings = {ASSET_TAGS = (); }; };
+               E38838991BAD145F00D62EE3 /* JSModuleLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = E38838951BAD145F00D62EE3 /* JSModuleLoader.h */; settings = {ASSET_TAGS = (); }; };
                E401C27517CE53EC00C41A35 /* ElementIteratorAssertions.h in Headers */ = {isa = PBXBuildFile; fileRef = E401C27417CE53EC00C41A35 /* ElementIteratorAssertions.h */; settings = {ATTRIBUTES = (Private, ); }; };
                E424A39E1330DF0100CF6DC9 /* LegacyTileGridTile.h in Headers */ = {isa = PBXBuildFile; fileRef = E424A39D1330DF0100CF6DC9 /* LegacyTileGridTile.h */; };
                E424A3A01330DF1E00CF6DC9 /* LegacyTileGridTile.mm in Sources */ = {isa = PBXBuildFile; fileRef = E424A39F1330DF1E00CF6DC9 /* LegacyTileGridTile.mm */; };
                E1FF8F661807460800132674 /* JSSubtleCryptoCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSSubtleCryptoCustom.cpp; sourceTree = "<group>"; };
                E1FF8F6A180DB5BE00132674 /* CryptoAlgorithmRegistry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CryptoAlgorithmRegistry.cpp; sourceTree = "<group>"; };
                E1FF8F6B180DB5BE00132674 /* CryptoAlgorithmRegistry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CryptoAlgorithmRegistry.h; sourceTree = "<group>"; };
+               E38838941BAD145F00D62EE3 /* JSModuleLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSModuleLoader.cpp; sourceTree = "<group>"; };
+               E38838951BAD145F00D62EE3 /* JSModuleLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSModuleLoader.h; sourceTree = "<group>"; };
                E401C27417CE53EC00C41A35 /* ElementIteratorAssertions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ElementIteratorAssertions.h; sourceTree = "<group>"; };
                E406F3FB1198307D009D59D6 /* ColorData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ColorData.cpp; sourceTree = "<group>"; };
                E41EA038119836DB00710BC5 /* CSSPropertyNames.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSSPropertyNames.cpp; sourceTree = "<group>"; };
                                41189EF81AD8233C00B90A0D /* JSReadableStreamControllerCustom.cpp */,
                                E1C36D320EB0A094007410BC /* JSWorkerGlobalScopeBase.cpp */,
                                E1C36D330EB0A094007410BC /* JSWorkerGlobalScopeBase.h */,
+                               E38838941BAD145F00D62EE3 /* JSModuleLoader.cpp */,
+                               E38838951BAD145F00D62EE3 /* JSModuleLoader.h */,
                                4198BDEE1A81123600B22FB5 /* ReadableJSStream.cpp */,
                                4198BDEF1A81123600B22FB5 /* ReadableJSStream.h */,
                                BCA378BA0D15F64200B793D6 /* ScheduledAction.cpp */,
                                CE1252411A16B1B600864480 /* MediaPlayerSPI.h in Headers */,
                                52E2CAFC19FF0207001EEB4F /* MediaProducer.h in Headers */,
                                4E19592A0A39DACC00220FE5 /* MediaQuery.h in Headers */,
+                               E38838991BAD145F00D62EE3 /* JSModuleLoader.h in Headers */,
                                4E19592C0A39DACC00220FE5 /* MediaQueryEvaluator.h in Headers */,
                                4E19592E0A39DACC00220FE5 /* MediaQueryExp.h in Headers */,
                                D3A94A39122DABAC00A37BBC /* MediaQueryList.h in Headers */,
                                3106037A143281CD00ABF4BA /* DOMWebKitCSSFilterValue.mm in Sources */,
                                498391510F1E76B400C23782 /* DOMWebKitCSSMatrix.mm in Sources */,
                                8AD0A59714C88358000D83C5 /* DOMWebKitCSSRegionRule.mm in Sources */,
+                               E38838981BAD145F00D62EE3 /* JSModuleLoader.cpp in Sources */,
                                31611E620E1C4E1400F6A579 /* DOMWebKitCSSTransformValue.mm in Sources */,
                                3F2B33EC165AF15600E3987C /* DOMWebKitCSSViewportRule.mm in Sources */,
                                8A195933147EA16E00D1EA61 /* DOMWebKitNamedFlow.mm in Sources */,
index 6600f34..19c951b 100644 (file)
 #include "JSMessageChannelCustom.cpp"
 #include "JSMessageEventCustom.cpp"
 #include "JSMessagePortCustom.cpp"
+#include "JSModuleLoader.cpp"
 #include "JSMutationCallback.cpp"
 #include "JSMutationObserverCustom.cpp"
 #include "JSNamedNodeMapCustom.cpp"
index 8350333..023f376 100644 (file)
@@ -29,6 +29,7 @@
 #include "InspectorController.h"
 #include "JSDOMGlobalObjectTask.h"
 #include "JSDOMWindowCustom.h"
+#include "JSModuleLoader.h"
 #include "JSNode.h"
 #include "Logging.h"
 #include "Page.h"
@@ -36,6 +37,7 @@
 #include "SecurityOrigin.h"
 #include "Settings.h"
 #include "WebCoreJSClientData.h"
+#include <runtime/JSInternalPromiseDeferred.h>
 #include <runtime/Microtask.h>
 #include <wtf/MainThread.h>
 
@@ -56,7 +58,7 @@ static bool shouldAllowAccessFrom(const JSGlobalObject* thisObject, ExecState* e
 
 const ClassInfo JSDOMWindowBase::s_info = { "Window", &JSDOMGlobalObject::s_info, 0, CREATE_METHOD_TABLE(JSDOMWindowBase) };
 
-const GlobalObjectMethodTable JSDOMWindowBase::s_globalObjectMethodTable = { &shouldAllowAccessFrom, &supportsProfiling, &supportsRichSourceInfo, &shouldInterruptScript, &javaScriptRuntimeFlags, &queueTaskToEventLoop, &shouldInterruptScriptBeforeTimeout, nullptr, nullptr, nullptr, nullptr, nullptr };
+const GlobalObjectMethodTable JSDOMWindowBase::s_globalObjectMethodTable = { &shouldAllowAccessFrom, &supportsProfiling, &supportsRichSourceInfo, &shouldInterruptScript, &javaScriptRuntimeFlags, &queueTaskToEventLoop, &shouldInterruptScriptBeforeTimeout, &moduleLoaderResolve, &moduleLoaderFetch, nullptr, nullptr, &moduleLoaderEvaluate };
 
 JSDOMWindowBase::JSDOMWindowBase(VM& vm, Structure* structure, PassRefPtr<DOMWindow> window, JSDOMWindowShell* shell)
     : JSDOMGlobalObject(vm, structure, &shell->world(), &s_globalObjectMethodTable)
@@ -276,4 +278,31 @@ void JSDOMWindowBase::fireFrameClearedWatchpointsForWindow(DOMWindow* window)
     }
 }
 
+
+JSC::JSInternalPromise* JSDOMWindowBase::moduleLoaderResolve(JSC::JSGlobalObject* globalObject, JSC::ExecState* exec, JSC::JSValue moduleName, JSC::JSValue importerModuleKey)
+{
+    JSDOMWindowBase* thisObject = JSC::jsCast<JSDOMWindowBase*>(globalObject);
+    if (RefPtr<Document> document = thisObject->impl().document())
+        return document->moduleLoader()->resolve(globalObject, exec, moduleName, importerModuleKey);
+    JSC::JSInternalPromiseDeferred* deferred = JSC::JSInternalPromiseDeferred::create(exec, globalObject);
+    return deferred->reject(exec, jsUndefined());
+}
+
+JSC::JSInternalPromise* JSDOMWindowBase::moduleLoaderFetch(JSC::JSGlobalObject* globalObject, JSC::ExecState* exec, JSC::JSValue moduleKey)
+{
+    JSDOMWindowBase* thisObject = JSC::jsCast<JSDOMWindowBase*>(globalObject);
+    if (RefPtr<Document> document = thisObject->impl().document())
+        return document->moduleLoader()->fetch(globalObject, exec, moduleKey);
+    JSC::JSInternalPromiseDeferred* deferred = JSC::JSInternalPromiseDeferred::create(exec, globalObject);
+    return deferred->reject(exec, jsUndefined());
+}
+
+JSC::JSValue JSDOMWindowBase::moduleLoaderEvaluate(JSC::JSGlobalObject* globalObject, JSC::ExecState* exec, JSC::JSValue moduleKey, JSC::JSValue moduleRecord)
+{
+    JSDOMWindowBase* thisObject = JSC::jsCast<JSDOMWindowBase*>(globalObject);
+    if (RefPtr<Document> document = thisObject->impl().document())
+        return document->moduleLoader()->evaluate(globalObject, exec, moduleKey, moduleRecord);
+    return JSC::jsUndefined();
+}
+
 } // namespace WebCore
index 5ed3862..8f4c562 100644 (file)
@@ -78,6 +78,10 @@ namespace WebCore {
         JSC::WatchpointSet m_windowCloseWatchpoints;
 
     private:
+        static JSC::JSInternalPromise* moduleLoaderResolve(JSC::JSGlobalObject*, JSC::ExecState*, JSC::JSValue, JSC::JSValue);
+        static JSC::JSInternalPromise* moduleLoaderFetch(JSC::JSGlobalObject*, JSC::ExecState*, JSC::JSValue);
+        static JSC::JSValue moduleLoaderEvaluate(JSC::JSGlobalObject*, JSC::ExecState*, JSC::JSValue, JSC::JSValue);
+
         RefPtr<DOMWindow> m_impl;
         JSDOMWindowShell* m_shell;
     };
diff --git a/Source/WebCore/bindings/js/JSModuleLoader.cpp b/Source/WebCore/bindings/js/JSModuleLoader.cpp
new file mode 100644 (file)
index 0000000..5457e7e
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "JSModuleLoader.h"
+
+#include "Document.h"
+#include "ExceptionCode.h"
+#include "Frame.h"
+#include "JSDOMBinding.h"
+#include <runtime/JSInternalPromiseDeferred.h>
+#include <runtime/JSModuleRecord.h>
+#include <runtime/JSString.h>
+#include <runtime/Symbol.h>
+
+namespace WebCore {
+
+JSModuleLoader::JSModuleLoader(Document& document)
+    : m_document(document)
+{
+}
+
+JSC::JSInternalPromise* JSModuleLoader::resolve(JSC::JSGlobalObject* globalObject, JSC::ExecState* exec, JSC::JSValue moduleNameValue, JSC::JSValue importerModuleKey)
+{
+    JSC::JSInternalPromiseDeferred* deferred = JSC::JSInternalPromiseDeferred::create(exec, globalObject);
+
+    // We use a Symbol as a special purpose; It means this module is an inline module.
+    // So there is no correct URL to retrieve the module source code. If the module name
+    // value is a Symbol, it is used directly as a module key.
+    //
+    // FIXME: Using symbols for an inline module is a current implementation details of WebKit.
+    // Once the spec of this part is specified, we will recast these part.
+    if (moduleNameValue.isSymbol())
+        return deferred->resolve(exec, moduleNameValue);
+
+    if (!moduleNameValue.isString())
+        return deferred->reject(exec, JSC::createTypeError(exec, "Module name is not Symbol or String."));
+
+    String moduleName = asString(moduleNameValue)->value(exec);
+
+    // Now, we consider the given moduleName as the same to the `import "..."` in the module code.
+    // We use the completed URL as the unique module key.
+    URL completedUrl;
+
+    if (importerModuleKey.isSymbol())
+        completedUrl = m_document.completeURL(moduleName);
+    else if (importerModuleKey.isUndefined())
+        completedUrl = m_document.completeURL(moduleName);
+    else if (importerModuleKey.isString()) {
+        URL importerModuleUrl(URL(), asString(importerModuleKey)->value(exec));
+        if (!importerModuleUrl.isValid())
+            return deferred->reject(exec, JSC::createTypeError(exec, "Importer module key is an invalid URL."));
+        completedUrl = m_document.completeURL(moduleName, importerModuleUrl);
+    } else
+        return deferred->reject(exec, JSC::createTypeError(exec, "Importer module key is not Symbol or String."));
+
+    if (!completedUrl.isValid())
+        return deferred->reject(exec, JSC::createTypeError(exec, "Module name constructs an invalid URL."));
+
+    return deferred->resolve(exec, jsString(exec, completedUrl.string()));
+}
+
+JSC::JSInternalPromise* JSModuleLoader::fetch(JSC::JSGlobalObject* globalObject, JSC::ExecState* exec, JSC::JSValue moduleKeyValue)
+{
+    JSC::JSInternalPromiseDeferred* deferred = JSC::JSInternalPromiseDeferred::create(exec, globalObject);
+
+    if (moduleKeyValue.isSymbol())
+        return deferred->reject(exec, JSC::createTypeError(exec, "Symbol module key should be already fulfilled with the inlined resource."));
+
+    if (!moduleKeyValue.isString())
+        return deferred->reject(exec, JSC::createTypeError(exec, "Module key is not Symbol or String."));
+
+    URL completedUrl(URL(), asString(moduleKeyValue)->value(exec));
+    if (!completedUrl.isValid())
+        return deferred->reject(exec, JSC::createTypeError(exec, "Module key is an invalid URL."));
+
+    // FIXME: Implement the module fetcher.
+
+    return deferred->promise();
+}
+
+JSC::JSValue JSModuleLoader::evaluate(JSC::JSGlobalObject*, JSC::ExecState* exec, JSC::JSValue moduleKeyValue, JSC::JSValue moduleRecordValue)
+{
+    // FIXME: Currently, we only support JSModuleRecord.
+    // Once the reflective part of the module loader is supported, we will handle arbitrary values.
+    // https://whatwg.github.io/loader/#registry-prototype-provide
+    JSC::JSModuleRecord* moduleRecord = JSC::jsDynamicCast<JSC::JSModuleRecord*>(moduleRecordValue);
+    if (!moduleRecord)
+        return JSC::jsUndefined();
+
+    URL sourceUrl;
+    if (moduleKeyValue.isSymbol())
+        sourceUrl = m_document.url();
+    else if (moduleKeyValue.isString())
+        sourceUrl = URL(URL(), asString(moduleKeyValue)->value(exec));
+    else
+        return JSC::throwTypeError(exec, "Module key is not Symbol or String.");
+
+    if (!sourceUrl.isValid())
+        return JSC::throwTypeError(exec, "Module key is an invalid URL.");
+
+    // FIXME: Implement evaluating module code.
+
+    return JSC::jsUndefined();
+}
+
+}
diff --git a/Source/WebCore/bindings/js/JSModuleLoader.h b/Source/WebCore/bindings/js/JSModuleLoader.h
new file mode 100644 (file)
index 0000000..2eaf832
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef JSModuleLoader_h
+#define JSModuleLoader_h
+
+#include <runtime/JSCJSValue.h>
+#include <wtf/Noncopyable.h>
+
+namespace JSC {
+
+class ExecState;
+class JSGlobalObject;
+class JSInternalPromise;
+
+}
+
+namespace WebCore {
+
+class Document;
+
+class JSModuleLoader {
+    WTF_MAKE_NONCOPYABLE(JSModuleLoader); WTF_MAKE_FAST_ALLOCATED;
+public:
+    explicit JSModuleLoader(Document&);
+
+    Document& document() { return m_document; }
+
+    JSC::JSInternalPromise* resolve(JSC::JSGlobalObject*, JSC::ExecState*, JSC::JSValue moduleName, JSC::JSValue importerModuleKey);
+    JSC::JSInternalPromise* fetch(JSC::JSGlobalObject*, JSC::ExecState*, JSC::JSValue moduleKey);
+    JSC::JSValue evaluate(JSC::JSGlobalObject*, JSC::ExecState*, JSC::JSValue moduleKey, JSC::JSValue moduleRecord);
+
+private:
+    Document& m_document;
+};
+
+} // namespace WebCore
+
+#endif // JSModuleLoader_h
index 1e1da99..1fd873e 100644 (file)
@@ -96,6 +96,7 @@
 #include "ImageLoader.h"
 #include "InspectorInstrumentation.h"
 #include "JSLazyEventListener.h"
+#include "JSModuleLoader.h"
 #include "Language.h"
 #include "LoaderStrategy.h"
 #include "Logging.h"
@@ -464,6 +465,7 @@ Document::Document(Frame* frame, const URL& url, unsigned documentClasses, unsig
     , m_startTime(std::chrono::steady_clock::now())
     , m_overMinimumLayoutThreshold(false)
     , m_scriptRunner(std::make_unique<ScriptRunner>(*this))
+    , m_moduleLoader(std::make_unique<JSModuleLoader>(*this))
     , m_xmlVersion(ASCIILiteral("1.0"))
     , m_xmlStandalone(StandaloneUnspecified)
     , m_hasXMLDeclaration(false)
@@ -605,6 +607,7 @@ Document::~Document()
         m_domWindow->resetUnlessSuspendedForPageCache();
 
     m_scriptRunner = nullptr;
+    m_moduleLoader = nullptr;
 
     removeAllEventListeners();
 
index f918089..b308ae2 100644 (file)
@@ -122,6 +122,7 @@ class IntPoint;
 class LayoutPoint;
 class LayoutRect;
 class LiveNodeList;
+class JSModuleLoader;
 class JSNode;
 class Locale;
 class Location;
@@ -934,6 +935,7 @@ public:
     Document& topDocument() const;
     
     ScriptRunner* scriptRunner() { return m_scriptRunner.get(); }
+    JSModuleLoader* moduleLoader() { return m_moduleLoader.get(); }
 
     HTMLScriptElement* currentScript() const { return !m_currentScriptStack.isEmpty() ? m_currentScriptStack.last().get() : 0; }
     void pushCurrentScript(PassRefPtr<HTMLScriptElement>);
@@ -1518,6 +1520,7 @@ private:
     bool m_overMinimumLayoutThreshold;
     
     std::unique_ptr<ScriptRunner> m_scriptRunner;
+    std::unique_ptr<JSModuleLoader> m_moduleLoader;
 
     Vector<RefPtr<HTMLScriptElement>> m_currentScriptStack;