Ignore:
Timestamp:
Nov 19, 2018, 11:09:53 PM (7 years ago)
Author:
[email protected]
Message:

globalFuncImportModule() should return a promise when it clears exceptions.
https://bugs.webkit.org/show_bug.cgi?id=191792
<rdar://problem/46090763>

Reviewed by Michael Saboff.

JSTests:

  • stress/global-import-function-should-return-a-promise-when-clearing-exceptions.js: Added.

Source/JavaScriptCore:

If we're clearing the exceptions in a CatchScope, then it means that we've handled
the exception, and is able to proceed in a normal manner. Hence, we should not
return the empty JSValue in this case: instead, we should return a Promise as
expected by import's API.

The only time when we can't return a promise is when we fail to create a Promise.
In that case, we should be propagating the exception.

Hence, globalFuncImportModule() contains a ThrowScope (for propagating the
exception that arises from failure to create the Promise) wrapping a CatchScope
(for catching any exception that arises from failure to execute the import).

Also fixed similar issues, and some exception check issues in JSModuleLoader and
the jsc shell.

  • jsc.cpp:

(GlobalObject::moduleLoaderImportModule):
(GlobalObject::moduleLoaderFetch):

  • runtime/JSGlobalObjectFunctions.cpp:

(JSC::globalFuncImportModule):

  • runtime/JSModuleLoader.cpp:

(JSC::JSModuleLoader::loadAndEvaluateModule):
(JSC::JSModuleLoader::loadModule):
(JSC::JSModuleLoader::requestImportModule):
(JSC::JSModuleLoader::importModule):
(JSC::JSModuleLoader::resolve):
(JSC::JSModuleLoader::fetch):
(JSC::moduleLoaderParseModule):
(JSC::moduleLoaderResolveSync):

File:
1 edited

Legend:

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

    r237714 r238391  
    784784{
    785785    VM& vm = exec->vm();
     786    auto throwScope = DECLARE_THROW_SCOPE(vm);
     787
     788    auto* globalObject = exec->lexicalGlobalObject();
     789
     790    auto* promise = JSPromiseDeferred::create(exec, globalObject);
     791    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
     792
    786793    auto catchScope = DECLARE_CATCH_SCOPE(vm);
    787 
    788     auto* globalObject = exec->lexicalGlobalObject();
    789 
    790     auto* promise = JSPromiseDeferred::create(exec, globalObject);
    791     CLEAR_AND_RETURN_IF_EXCEPTION(catchScope, encodedJSValue());
     794    auto reject = [&] (JSValue rejectionReason) {
     795        catchScope.clearException();
     796        promise->reject(exec, rejectionReason);
     797        catchScope.clearException();
     798        return JSValue::encode(promise->promise());
     799    };
    792800
    793801    auto sourceOrigin = exec->callerSourceOrigin();
    794802    RELEASE_ASSERT(exec->argumentCount() == 1);
    795803    auto* specifier = exec->uncheckedArgument(0).toString(exec);
    796     if (Exception* exception = catchScope.exception()) {
    797         catchScope.clearException();
    798         promise->reject(exec, exception->value());
    799         CLEAR_AND_RETURN_IF_EXCEPTION(catchScope, encodedJSValue());
    800         return JSValue::encode(promise->promise());
    801     }
     804    if (Exception* exception = catchScope.exception())
     805        return reject(exception->value());
    802806
    803807    // We always specify parameters as undefined. Once dynamic import() starts accepting fetching parameters,
     
    805809    JSValue parameters = jsUndefined();
    806810    auto* internalPromise = globalObject->moduleLoader()->importModule(exec, specifier, parameters, sourceOrigin);
    807     if (Exception* exception = catchScope.exception()) {
    808         catchScope.clearException();
    809         promise->reject(exec, exception->value());
    810         CLEAR_AND_RETURN_IF_EXCEPTION(catchScope, encodedJSValue());
    811         return JSValue::encode(promise->promise());
    812     }
     811    if (Exception* exception = catchScope.exception())
     812        return reject(exception->value());
    813813    promise->resolve(exec, internalPromise);
    814     CLEAR_AND_RETURN_IF_EXCEPTION(catchScope, encodedJSValue());
    815 
     814
     815    catchScope.clearException();
    816816    return JSValue::encode(promise->promise());
    817817}
Note: See TracChangeset for help on using the changeset viewer.