diff options
| author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-04-10 09:28:39 +0000 |
|---|---|---|
| committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2016-04-10 09:28:39 +0000 |
| commit | 32761a6cee1d0dee366b885b7b9c777e67885688 (patch) | |
| tree | d6bec92bebfb216f4126356e55518842c2f476a1 /Source/JavaScriptCore/builtins/ModuleLoaderObject.js | |
| parent | a4e969f4965059196ca948db781e52f7cfebf19e (diff) | |
| download | WebKitGtk-tarball-32761a6cee1d0dee366b885b7b9c777e67885688.tar.gz | |
webkitgtk-2.4.11webkitgtk-2.4.11
Diffstat (limited to 'Source/JavaScriptCore/builtins/ModuleLoaderObject.js')
| -rw-r--r-- | Source/JavaScriptCore/builtins/ModuleLoaderObject.js | 562 |
1 files changed, 0 insertions, 562 deletions
diff --git a/Source/JavaScriptCore/builtins/ModuleLoaderObject.js b/Source/JavaScriptCore/builtins/ModuleLoaderObject.js deleted file mode 100644 index 568a307b7..000000000 --- a/Source/JavaScriptCore/builtins/ModuleLoaderObject.js +++ /dev/null @@ -1,562 +0,0 @@ -/* - * 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. ``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 - * 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. - */ - -// https://whatwg.github.io/loader/#loader-object -// Module Loader has several hooks that can be customized by the platform. -// For example, the [[Fetch]] hook can be provided by the JavaScriptCore shell -// as fetching the payload from the local file system. -// Currently, there are 4 hooks. -// 1. Loader.resolve -// 2. Loader.fetch -// 3. Loader.translate -// 4. Loader.instantiate - -function setStateToMax(entry, newState) -{ - // https://whatwg.github.io/loader/#set-state-to-max - - "use strict"; - - if (entry.state < newState) - entry.state = newState; -} - -function newRegistryEntry(key) -{ - // https://whatwg.github.io/loader/#registry - // - // Each registry entry becomes one of the 5 states. - // 1. Fetch - // Ready to fetch (or now fetching) the resource of this module. - // Typically, we fetch the source code over the network or from the file system. - // a. If the status is Fetch and there is no entry.fetch promise, the entry is ready to fetch. - // b. If the status is Fetch and there is the entry.fetch promise, the entry is just fetching the resource. - // - // 2. Translate - // Ready to translate (or now translating) the raw fetched resource to the ECMAScript source code. - // We can insert the hook that translates the resources e.g. transpilers. - // a. If the status is Translate and there is no entry.translate promise, the entry is ready to translate. - // b. If the status is Translate and there is the entry.translate promise, the entry is just translating - // the payload to the source code. - // - // 3. Instantiate (AnalyzeModule) - // Ready to instantiate (or now instantiating) the module record from the fetched (and translated) - // source code. - // Typically, we parse the module code, extract the dependencies and binding information. - // a. If the status is Instantiate and there is no entry.instantiate promise, the entry is ready to instantiate. - // b. If the status is Instantiate and there is the entry.translate promise, the entry is just instantiating - // the module record. - // - // 4. ResolveDependencies (not in the draft) https://github.com/whatwg/loader/issues/68 - // Ready to request the dependent modules (or now requesting & resolving). - // Without this state, the current draft causes infinite recursion when there is circular dependency. - // a. If the status is ResolveDependencies and there is no entry.resolveDependencies promise, the entry is ready to resolve the dependencies. - // b. If the status is ResolveDependencies and there is the entry.resolveDependencies promise, the entry is just resolving - // the dependencies. - // - // 5. Link - // Ready to link the module with the other modules. - // Linking means that the module imports and exports the bindings from/to the other modules. - // - // 6. Ready - // The module is linked, so the module is ready to be executed. - // - // Each registry entry has the 4 promises; "fetch", "translate", "instantiate" and "resolveDependencies". - // They are assigned when starting the each phase. And they are fulfilled when the each phase is completed. - // - // In the current module draft, linking will be performed after the whole modules are instantiated and the dependencies are resolved. - // And execution is also done after the all modules are linked. - // - // TODO: We need to exploit the way to execute the module while fetching non-related modules. - // One solution; introducing the ready promise chain to execute the modules concurrently while keeping - // the execution order. - - "use strict"; - - return { - key: key, - state: this.Fetch, - metadata: @undefined, - fetch: @undefined, - translate: @undefined, - instantiate: @undefined, - resolveDependencies: @undefined, - dependencies: [], // To keep the module order, we store the module keys in the array. - dependenciesMap: @undefined, - module: @undefined, // JSModuleRecord - error: @undefined, - }; -} - -function ensureRegistered(key) -{ - // https://whatwg.github.io/loader/#ensure-registered - - "use strict"; - - var entry = this.registry.@get(key); - if (entry) - return entry; - - entry = this.newRegistryEntry(key); - this.registry.@set(key, entry); - - return entry; -} - -function forceFulfillPromise(promise, value) -{ - "use strict"; - - if (promise.@promiseState === @promiseStatePending) - @fulfillPromise(promise, value); -} - -function fulfillFetch(entry, payload) -{ - // https://whatwg.github.io/loader/#fulfill-fetch - - "use strict"; - - if (!entry.fetch) - entry.fetch = @newPromiseCapability(@InternalPromise).@promise; - this.forceFulfillPromise(entry.fetch, payload); - this.setStateToMax(entry, this.Translate); -} - -function fulfillTranslate(entry, source) -{ - // https://whatwg.github.io/loader/#fulfill-translate - - "use strict"; - - if (!entry.translate) - entry.translate = @newPromiseCapability(@InternalPromise).@promise; - this.forceFulfillPromise(entry.translate, source); - this.setStateToMax(entry, this.Instantiate); -} - -function fulfillInstantiate(entry, optionalInstance, source) -{ - // https://whatwg.github.io/loader/#fulfill-instantiate - - "use strict"; - - if (!entry.instantiate) - entry.instantiate = @newPromiseCapability(@InternalPromise).@promise; - this.commitInstantiated(entry, optionalInstance, source); - - // FIXME: The draft fulfills the promise in the CommitInstantiated operation. - // But it CommitInstantiated is also used in the requestInstantiate and - // we should not "force fulfill" there. - // So we separate "force fulfill" operation from the CommitInstantiated operation. - // https://github.com/whatwg/loader/pull/67 - this.forceFulfillPromise(entry.instantiate, entry); -} - -function commitInstantiated(entry, optionalInstance, source) -{ - // https://whatwg.github.io/loader/#commit-instantiated - - "use strict"; - - var moduleRecord = this.instantiation(optionalInstance, source, entry); - - // FIXME: Described in the draft, - // 4. Fulfill entry.[[Instantiate]] with instance. - // But, instantiate promise should be fulfilled with the entry. - // We remove this statement because instantiate promise will be - // fulfilled without this "force fulfill" operation. - // https://github.com/whatwg/loader/pull/67 - - var dependencies = []; - var dependenciesMap = moduleRecord.dependenciesMap; - moduleRecord.registryEntry = entry; - var requestedModules = this.requestedModules(moduleRecord); - for (var i = 0, length = requestedModules.length; i < length; ++i) { - var depKey = requestedModules[i]; - var pair = { - key: depKey, - value: @undefined - }; - @putByValDirect(dependencies, i, pair); - dependenciesMap.@set(depKey, pair); - } - entry.dependencies = dependencies; - entry.dependenciesMap = dependenciesMap; - entry.module = moduleRecord; - this.setStateToMax(entry, this.ResolveDependencies); -} - -function instantiation(result, source, entry) -{ - // https://whatwg.github.io/loader/#instantiation - // FIXME: Current implementation does not support optionalInstance. - // https://bugs.webkit.org/show_bug.cgi?id=148171 - - "use strict"; - - return this.parseModule(entry.key, source); -} - -// Loader. - -function requestFetch(key) -{ - // https://whatwg.github.io/loader/#request-fetch - - "use strict"; - - var entry = this.ensureRegistered(key); - if (entry.state > this.Link) { - var deferred = @newPromiseCapability(@InternalPromise); - deferred.@reject.@call(@undefined, new @TypeError("Requested module is already ready to be executed.")); - return deferred.@promise; - } - - if (entry.fetch) - return entry.fetch; - - var loader = this; - - // Hook point. - // 2. Loader.fetch - // https://whatwg.github.io/loader/#browser-fetch - // Take the key and fetch the resource actually. - // For example, JavaScriptCore shell can provide the hook fetching the resource - // from the local file system. - var fetchPromise = this.fetch(key).then(function (payload) { - loader.setStateToMax(entry, loader.Translate); - return payload; - }); - entry.fetch = fetchPromise; - return fetchPromise; -} - -function requestTranslate(key) -{ - // https://whatwg.github.io/loader/#request-translate - - "use strict"; - - var entry = this.ensureRegistered(key); - if (entry.state > this.Link) { - var deferred = @newPromiseCapability(@InternalPromise); - deferred.@reject.@call(@undefined, new @TypeError("Requested module is already ready to be executed.")); - return deferred.@promise; - } - - if (entry.translate) - return entry.translate; - - var loader = this; - var translatePromise = this.requestFetch(key).then(function (payload) { - // Hook point. - // 3. Loader.translate - // https://whatwg.github.io/loader/#browser-translate - // Take the key and the fetched source code and translate it to the ES6 source code. - // Typically it is used by the transpilers. - return loader.translate(key, payload).then(function (source) { - loader.setStateToMax(entry, loader.Instantiate); - return source; - }); - }); - entry.translate = translatePromise; - return translatePromise; -} - -function requestInstantiate(key) -{ - // https://whatwg.github.io/loader/#request-instantiate - - "use strict"; - - var entry = this.ensureRegistered(key); - if (entry.state > this.Link) { - var deferred = @newPromiseCapability(@InternalPromise); - deferred.@reject.@call(@undefined, new @TypeError("Requested module is already ready to be executed.")); - return deferred.@promise; - } - - if (entry.instantiate) - return entry.instantiate; - - var loader = this; - var instantiatePromise = this.requestTranslate(key).then(function (source) { - // Hook point. - // 4. Loader.instantiate - // https://whatwg.github.io/loader/#browser-instantiate - // Take the key and the translated source code, and instantiate the module record - // by parsing the module source code. - // It has the chance to provide the optional module instance that is different from - // the ordinary one. - return loader.instantiate(key, source).then(function (optionalInstance) { - loader.commitInstantiated(entry, optionalInstance, source); - return entry; - }); - }); - entry.instantiate = instantiatePromise; - return instantiatePromise; -} - -function requestResolveDependencies(key) -{ - // FIXME: In the spec, after requesting instantiation, we will resolve - // the dependencies without any status change. As a result, when there - // is circular dependencies, instantiation is done only once, but - // repeatedly resolving the dependencies. This means that infinite - // recursion occur when the given modules have circular dependency. To - // avoid this situation, we introduce new state, "ResolveDependencies". This means - // "Now the module is instantiated, so ready to resolve the dependencies - // or now resolving them". - // https://github.com/whatwg/loader/issues/68 - - "use strict"; - - var entry = this.ensureRegistered(key); - if (entry.state > this.Link) { - var deferred = @newPromiseCapability(@InternalPromise); - deferred.@reject.@call(@undefined, new @TypeError("Requested module is already ready to be executed.")); - return deferred.@promise; - } - - if (entry.resolveDependencies) - return entry.resolveDependencies; - - var loader = this; - var resolveDependenciesPromise = this.requestInstantiate(key).then(function (entry) { - var depLoads = []; - for (var i = 0, length = entry.dependencies.length; i < length; ++i) { - let pair = entry.dependencies[i]; - - // Hook point. - // 1. Loader.resolve. - // https://whatwg.github.io/loader/#browser-resolve - // Take the name and resolve it to the unique identifier for the resource location. - // For example, take the "jquery" and return the URL for the resource. - var promise = loader.resolve(pair.key, key).then(function (depKey) { - var depEntry = loader.ensureRegistered(depKey); - - // Recursive resolving. The dependencies of this entry is being resolved or already resolved. - // Stop tracing the circular dependencies. - // But to retrieve the instantiated module record correctly, - // we need to wait for the instantiation for the dependent module. - // For example, reaching here, the module is starting resolving the dependencies. - // But the module may or may not reach the instantiation phase in the loader's pipeline. - // If we wait for the ResolveDependencies for this module, it construct the circular promise chain and - // rejected by the Promises runtime. Since only we need is the instantiated module, instead of waiting - // the ResolveDependencies for this module, we just wait Instantiate for this. - if (depEntry.resolveDependencies) { - return depEntry.instantiate.then(function (entry) { - pair.value = entry.module; - return entry; - }); - } - - return loader.requestResolveDependencies(depKey).then(function (entry) { - pair.value = entry.module; - return entry; - }); - }); - @putByValDirect(depLoads, i, promise); - } - - return @InternalPromise.internalAll(depLoads).then(function (modules) { - loader.setStateToMax(entry, loader.Link); - return entry; - }); - }); - - entry.resolveDependencies = resolveDependenciesPromise; - return resolveDependenciesPromise; -} - -function requestInstantiateAll(key) -{ - // https://whatwg.github.io/loader/#request-instantiate-all - - "use strict"; - - return this.requestResolveDependencies(key); -} - -function requestLink(key) -{ - // https://whatwg.github.io/loader/#request-link - - "use strict"; - - var entry = this.ensureRegistered(key); - if (entry.state > this.Link) { - var deferred = @newPromiseCapability(@InternalPromise); - deferred.@resolve.@call(@undefined, entry.module); - return deferred.@promise; - } - - var loader = this; - return this.requestInstantiateAll(key).then(function (entry) { - loader.link(entry); - return entry; - }); -} - -function requestReady(key) -{ - // https://whatwg.github.io/loader/#request-ready - - "use strict"; - - var loader = this; - return this.requestLink(key).then(function (entry) { - loader.moduleEvaluation(entry.module); - }); -} - -// Linking semantics. - -function link(entry) -{ - // https://whatwg.github.io/loader/#link - - "use strict"; - - // FIXME: Current implementation does not support optionalInstance. - // So Link's step 3 is skipped. - // https://bugs.webkit.org/show_bug.cgi?id=148171 - - if (entry.state === this.Ready) - return; - this.setStateToMax(entry, this.Ready); - - // Since we already have the "dependencies" field, - // we can call moduleDeclarationInstantiation with the correct order - // without constructing the dependency graph by calling dependencyGraph. - var dependencies = entry.dependencies; - for (var i = 0, length = dependencies.length; i < length; ++i) { - var pair = dependencies[i]; - this.link(pair.value.registryEntry); - } - - this.moduleDeclarationInstantiation(entry.module); -} - -// Module semantics. - -function moduleEvaluation(moduleRecord) -{ - // http://www.ecma-international.org/ecma-262/6.0/#sec-moduleevaluation - - "use strict"; - - if (moduleRecord.evaluated) - return; - moduleRecord.evaluated = true; - - var entry = moduleRecord.registryEntry; - - // The contents of the [[RequestedModules]] is cloned into entry.dependencies. - var dependencies = entry.dependencies; - for (var i = 0, length = dependencies.length; i < length; ++i) { - var pair = dependencies[i]; - var requiredModuleRecord = pair.value; - this.moduleEvaluation(requiredModuleRecord); - } - this.evaluate(entry.key, moduleRecord); -} - -// APIs to control the module loader. - -function provide(key, stage, value) -{ - "use strict"; - - var entry = this.ensureRegistered(key); - - if (stage === this.Fetch) { - if (entry.status > this.Fetch) - throw new @TypeError("Requested module is already fetched."); - this.fulfillFetch(entry, value); - return; - } - - if (stage === this.Translate) { - if (entry.status > this.Translate) - throw new @TypeError("Requested module is already translated."); - this.fulfillFetch(entry, @undefined); - this.fulfillTranslate(entry, value); - return; - } - - if (stage === this.Instantiate) { - if (entry.status > this.Instantiate) - throw new @TypeError("Requested module is already instantiated."); - this.fulfillFetch(entry, @undefined); - this.fulfillTranslate(entry, value); - var loader = this; - entry.translate.then(function (source) { - loader.fulfillInstantiate(entry, value, source); - }); - return; - } - - throw new @TypeError("Requested module is already ready to be executed."); -} - -function loadAndEvaluateModule(moduleName, referrer) -{ - "use strict"; - - var loader = this; - // Loader.resolve hook point. - // resolve: moduleName => Promise(moduleKey) - // Take the name and resolve it to the unique identifier for the resource location. - // For example, take the "jquery" and return the URL for the resource. - return this.resolve(moduleName, referrer).then(function (key) { - return loader.requestReady(key); - }); -} - -function loadModule(moduleName, referrer) -{ - "use strict"; - - var loader = this; - // Loader.resolve hook point. - // resolve: moduleName => Promise(moduleKey) - // Take the name and resolve it to the unique identifier for the resource location. - // For example, take the "jquery" and return the URL for the resource. - return this.resolve(moduleName, referrer).then(function (key) { - return loader.requestInstantiateAll(key); - }).then(function (entry) { - return entry.key; - }); -} - -function linkAndEvaluateModule(key) -{ - "use strict"; - - return this.requestReady(key); -} |
