Ignore:
Timestamp:
Oct 15, 2017, 6:55:16 PM (8 years ago)
Author:
Yusuke Suzuki
Message:

[JSC] Perform module specifier validation at parsing time
https://bugs.webkit.org/show_bug.cgi?id=178256

Reviewed by Darin Adler.

Source/JavaScriptCore:

This patch make module loader's resolve operation synchronous. And we validate
module's requested module names when instantiating the module instead of satisfying
module's dependencies. This change is not observable to users. But this is precise
to the spec and this optimizes & simplifies the current module loader a bit by
reducing object allocations.

Previously, we have an object called pair in the module loader. This is pair of
module's name and module's record. And we use it to link one module to dependent
modules. Now, it is replaced with module's registry entry.

We also change our loader functions to take a registry entry instead of a module key.
Previous design is due to the consideration that these APIs may be exposed to users
in whatwg/loader spec. However, this won't happen. This change removes unnecessary
repeatedly hash map lookups.

  • builtins/ModuleLoaderPrototype.js:

(globalPrivate.newRegistryEntry):
(requestFetch):
(requestInstantiate):
(requestSatisfy):
(link):
(moduleEvaluation):
(loadModule):

  • jsc.cpp:

(GlobalObject::moduleLoaderResolve):

  • runtime/AbstractModuleRecord.cpp:

(JSC::AbstractModuleRecord::finishCreation):
(JSC::AbstractModuleRecord::hostResolveImportedModule):

  • runtime/JSGlobalObject.h:
  • runtime/JSModuleLoader.cpp:

(JSC::JSModuleLoader::resolveSync):
(JSC::JSModuleLoader::resolve):

  • runtime/JSModuleLoader.h:
  • runtime/ModuleLoaderPrototype.cpp:

(JSC::moduleLoaderPrototypeResolveSync):

Source/WebCore:

No behavior change in the current implementation.

  • bindings/js/JSDOMWindowBase.cpp:

(WebCore::JSDOMWindowBase::moduleLoaderResolve):

  • bindings/js/JSDOMWindowBase.h:
  • bindings/js/ScriptModuleLoader.cpp:

(WebCore::ScriptModuleLoader::resolve):

  • bindings/js/ScriptModuleLoader.h:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/runtime/JSModuleLoader.cpp

    r223237 r223331  
    203203}
    204204
    205 JSInternalPromise* JSModuleLoader::resolve(ExecState* exec, JSValue name, JSValue referrer, JSValue scriptFetcher)
     205Identifier JSModuleLoader::resolveSync(ExecState* exec, JSValue name, JSValue referrer, JSValue scriptFetcher)
    206206{
    207207    if (Options::dumpModuleLoadingState())
     
    211211    if (globalObject->globalObjectMethodTable()->moduleLoaderResolve)
    212212        return globalObject->globalObjectMethodTable()->moduleLoaderResolve(globalObject, exec, this, name, referrer, scriptFetcher);
    213     JSInternalPromiseDeferred* deferred = JSInternalPromiseDeferred::create(exec, globalObject);
    214     deferred->resolve(exec, name);
    215     return deferred->promise();
     213    return name.toPropertyKey(exec);
     214}
     215
     216JSInternalPromise* JSModuleLoader::resolve(ExecState* exec, JSValue name, JSValue referrer, JSValue scriptFetcher)
     217{
     218    VM& vm = exec->vm();
     219    auto scope = DECLARE_CATCH_SCOPE(vm);
     220
     221    JSInternalPromiseDeferred* deferred = JSInternalPromiseDeferred::create(exec, exec->lexicalGlobalObject());
     222    scope.releaseAssertNoException();
     223    const Identifier moduleKey = resolveSync(exec, name, referrer, scriptFetcher);
     224    if (UNLIKELY(scope.exception())) {
     225        JSValue exception = scope.exception();
     226        scope.clearException();
     227        return deferred->reject(exec, exception);
     228    }
     229    auto result = deferred->resolve(exec, identifierToJSValue(vm, moduleKey));
     230    scope.releaseAssertNoException();
     231    return result;
    216232}
    217233
Note: See TracChangeset for help on using the changeset viewer.