Ignore:
Timestamp:
Sep 17, 2015, 3:26:18 PM (10 years ago)
Author:
Yusuke Suzuki
Message:

[ES6] Add more fine-grained APIs and additional hooks to control module loader from WebCore
https://bugs.webkit.org/show_bug.cgi?id=149129

Reviewed by Saam Barati.

No behavior change.

Source/JavaScriptCore:

Module tag <script type="module> will be executed asynchronously.
But we would like to fetch the resources before when the postTask-ed task is performed.
So instead of 1 API that fetch, instantiate and execute the module,
we need 2 fine-grained APIs.

  1. Fetch and initialize a module, but not execute it yet.
  2. Link and execute a module specified by the key (this will be invoked asynchronously).

And to instrument the script execution (like reporting the execution time of the module to
the inspector), we need a hook to inject code around an execution of a module body.

  • builtins/ModuleLoaderObject.js:

(moduleEvaluation):
(loadAndEvaluateModule):
(loadModule):
(linkAndEvaluateModule):

  • jsc.cpp:

(functionLoadModule):
(runWithScripts):

  • runtime/Completion.cpp:

(JSC::identifierToJSValue):
(JSC::createSymbolForEntryPointModule):
(JSC::rejectPromise):
(JSC::loadAndEvaluateModule):
(JSC::loadModule):
(JSC::linkAndEvaluateModule):
(JSC::evaluateModule): Deleted.

  • runtime/Completion.h:
  • runtime/JSGlobalObject.cpp:
  • runtime/JSGlobalObject.h:
  • runtime/JSModuleRecord.cpp:

(JSC::JSModuleRecord::evaluate):
(JSC::JSModuleRecord::execute): Deleted.

  • runtime/JSModuleRecord.h:
  • runtime/ModuleLoaderObject.cpp:

(JSC::ModuleLoaderObject::loadAndEvaluateModule):
(JSC::ModuleLoaderObject::linkAndEvaluateModule):
(JSC::ModuleLoaderObject::evaluate):
(JSC::moduleLoaderObjectEvaluate):

  • runtime/ModuleLoaderObject.h:

Source/WebCore:

  • bindings/js/JSDOMWindowBase.cpp:
  • bindings/js/JSWorkerGlobalScopeBase.cpp:
File:
1 edited

Legend:

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

    r189088 r189941  
    114114}
    115115
    116 static JSInternalPromise* evaluateModule(const JSLockHolder&, ExecState* exec, JSGlobalObject* globalObject, JSValue moduleName, JSValue referrer)
    117 {
    118     return globalObject->moduleLoader()->loadModule(exec, moduleName, referrer);
    119 }
    120 
    121 static JSInternalPromise* evaluateModule(const JSLockHolder& lock, ExecState* exec, JSGlobalObject* globalObject, const Identifier& moduleName)
    122 {
    123     JSValue moduleNameValue;
    124     if (moduleName.isSymbol())
    125         moduleNameValue = Symbol::create(exec->vm(), static_cast<SymbolImpl&>(*moduleName.impl()));
    126     else
    127         moduleNameValue = jsString(&exec->vm(), moduleName.impl());
    128 
    129     return evaluateModule(lock, exec, globalObject, moduleNameValue, jsUndefined());
    130 }
    131 
    132 JSInternalPromise* evaluateModule(ExecState* exec, const SourceCode& source)
    133 {
    134     JSLockHolder lock(exec);
    135     RELEASE_ASSERT(exec->vm().atomicStringTable() == wtfThreadData().atomicStringTable());
    136     RELEASE_ASSERT(!exec->vm().isCollectorBusy());
    137 
    138     JSGlobalObject* globalObject = exec->vmEntryGlobalObject();
    139 
     116static JSValue identifierToJSValue(VM& vm, const Identifier& identifier)
     117{
     118    if (identifier.isSymbol())
     119        return Symbol::create(vm, static_cast<SymbolImpl&>(*identifier.impl()));
     120    return jsString(&vm, identifier.impl());
     121}
     122
     123static Symbol* createSymbolForEntryPointModule(VM& vm)
     124{
    140125    // Generate the unique key for the source-provided module.
    141126    PrivateName privateName(PrivateName::Description, "EntryPointModule");
    142     Symbol* key = Symbol::create(exec->vm(), *privateName.uid());
     127    return Symbol::create(vm, *privateName.uid());
     128}
     129
     130static JSInternalPromise* rejectPromise(ExecState* exec, JSGlobalObject* globalObject)
     131{
     132    ASSERT(exec->hadException());
     133    JSValue exception = exec->exception()->value();
     134    exec->clearException();
     135    JSInternalPromiseDeferred* deferred = JSInternalPromiseDeferred::create(exec, globalObject);
     136    deferred->reject(exec, exception);
     137    return deferred->promise();
     138}
     139
     140static JSInternalPromise* loadAndEvaluateModule(const JSLockHolder&, ExecState* exec, JSGlobalObject* globalObject, JSValue moduleName, JSValue referrer)
     141{
     142    return globalObject->moduleLoader()->loadAndEvaluateModule(exec, moduleName, referrer);
     143}
     144
     145static JSInternalPromise* loadAndEvaluateModule(const JSLockHolder& lock, ExecState* exec, JSGlobalObject* globalObject, const Identifier& moduleName)
     146{
     147    return loadAndEvaluateModule(lock, exec, globalObject, identifierToJSValue(exec->vm(), moduleName), jsUndefined());
     148}
     149
     150JSInternalPromise* loadAndEvaluateModule(ExecState* exec, const String& moduleName)
     151{
     152    JSLockHolder lock(exec);
     153    RELEASE_ASSERT(exec->vm().atomicStringTable() == wtfThreadData().atomicStringTable());
     154    RELEASE_ASSERT(!exec->vm().isCollectorBusy());
     155
     156    return loadAndEvaluateModule(lock, exec, exec->vmEntryGlobalObject(), Identifier::fromString(exec, moduleName));
     157}
     158
     159JSInternalPromise* loadAndEvaluateModule(ExecState* exec, const SourceCode& source)
     160{
     161    JSLockHolder lock(exec);
     162    RELEASE_ASSERT(exec->vm().atomicStringTable() == wtfThreadData().atomicStringTable());
     163    RELEASE_ASSERT(!exec->vm().isCollectorBusy());
     164
     165    Symbol* key = createSymbolForEntryPointModule(exec->vm());
     166
     167    JSGlobalObject* globalObject = exec->vmEntryGlobalObject();
    143168
    144169    // Insert the given source code to the ModuleLoader registry as the fetched registry entry.
    145170    globalObject->moduleLoader()->provide(exec, key, ModuleLoaderObject::Status::Fetch, source.toString());
    146     if (exec->hadException()) {
    147         JSValue exception = exec->exception()->value();
    148         exec->clearException();
    149         JSInternalPromiseDeferred* deferred = JSInternalPromiseDeferred::create(exec, globalObject);
    150         deferred->reject(exec, exception);
    151         return deferred->promise();
    152     }
    153 
    154     return evaluateModule(lock, exec, globalObject, key, jsUndefined());
    155 }
    156 
    157 JSInternalPromise* evaluateModule(ExecState* exec, const Identifier& moduleName)
    158 {
    159     JSLockHolder lock(exec);
    160     RELEASE_ASSERT(exec->vm().atomicStringTable() == wtfThreadData().atomicStringTable());
    161     RELEASE_ASSERT(!exec->vm().isCollectorBusy());
    162 
    163     return evaluateModule(lock, exec, exec->vmEntryGlobalObject(), moduleName);
    164 }
    165 
    166 JSInternalPromise* evaluateModule(ExecState* exec, const String& moduleName)
    167 {
    168     JSLockHolder lock(exec);
    169     RELEASE_ASSERT(exec->vm().atomicStringTable() == wtfThreadData().atomicStringTable());
    170     RELEASE_ASSERT(!exec->vm().isCollectorBusy());
    171 
    172     return evaluateModule(lock, exec, exec->vmEntryGlobalObject(), Identifier::fromString(exec, moduleName));
     171    if (exec->hadException())
     172        return rejectPromise(exec, globalObject);
     173
     174    return loadAndEvaluateModule(lock, exec, globalObject, key, jsUndefined());
     175}
     176
     177static JSInternalPromise* loadModule(const JSLockHolder&, ExecState* exec, JSGlobalObject* globalObject, JSValue moduleName, JSValue referrer)
     178{
     179    return globalObject->moduleLoader()->loadModule(exec, moduleName, referrer);
     180}
     181
     182static JSInternalPromise* loadModule(const JSLockHolder& lock, ExecState* exec, JSGlobalObject* globalObject, const Identifier& moduleName)
     183{
     184    return loadModule(lock, exec, globalObject, identifierToJSValue(exec->vm(), moduleName), jsUndefined());
     185}
     186
     187JSInternalPromise* loadModule(ExecState* exec, const String& moduleName)
     188{
     189    JSLockHolder lock(exec);
     190    RELEASE_ASSERT(exec->vm().atomicStringTable() == wtfThreadData().atomicStringTable());
     191    RELEASE_ASSERT(!exec->vm().isCollectorBusy());
     192
     193    return loadModule(lock, exec, exec->vmEntryGlobalObject(), Identifier::fromString(exec, moduleName));
     194}
     195
     196JSInternalPromise* loadModule(ExecState* exec, const SourceCode& source)
     197{
     198    JSLockHolder lock(exec);
     199    RELEASE_ASSERT(exec->vm().atomicStringTable() == wtfThreadData().atomicStringTable());
     200    RELEASE_ASSERT(!exec->vm().isCollectorBusy());
     201
     202    Symbol* key = createSymbolForEntryPointModule(exec->vm());
     203
     204    JSGlobalObject* globalObject = exec->vmEntryGlobalObject();
     205
     206    // Insert the given source code to the ModuleLoader registry as the fetched registry entry.
     207    globalObject->moduleLoader()->provide(exec, key, ModuleLoaderObject::Status::Fetch, source.toString());
     208    if (exec->hadException())
     209        return rejectPromise(exec, globalObject);
     210
     211    return loadModule(lock, exec, globalObject, key, jsUndefined());
     212}
     213
     214JSInternalPromise* linkAndEvaluateModule(ExecState* exec, const Identifier& moduleKey)
     215{
     216    JSLockHolder lock(exec);
     217    RELEASE_ASSERT(exec->vm().atomicStringTable() == wtfThreadData().atomicStringTable());
     218    RELEASE_ASSERT(!exec->vm().isCollectorBusy());
     219
     220    JSGlobalObject* globalObject = exec->vmEntryGlobalObject();
     221    return globalObject->moduleLoader()->linkAndEvaluateModule(exec, identifierToJSValue(exec->vm(), moduleKey));
    173222}
    174223
Note: See TracChangeset for help on using the changeset viewer.