Changeset 215916 in webkit


Ignore:
Timestamp:
Apr 27, 2017 8:33:57 PM (7 years ago)
Author:
Joseph Pecoraro
Message:

Support for promise rejection events (unhandledrejection)
https://bugs.webkit.org/show_bug.cgi?id=150358
<rdar://problem/28441651>

Reviewed by Saam Barati.

Patch by Joseph Pecoraro and Yusuke Suzuki.

LayoutTests/imported/w3c:

  • web-platform-tests/WebCryptoAPI/derive_bits_keys/test_ecdh_bits-expected.txt:
  • web-platform-tests/WebCryptoAPI/derive_bits_keys/test_ecdh_keys-expected.txt:
  • web-platform-tests/html/semantics/embedded-content/media-elements/event_pause_noautoplay-expected.txt:
  • web-platform-tests/html/semantics/embedded-content/media-elements/event_play_noautoplay-expected.txt:
  • web-platform-tests/html/semantics/embedded-content/media-elements/paused_true_during_pause-expected.txt:
  • web-platform-tests/html/syntax/parsing/html5lib_innerHTML_adoption01-expected.txt:
  • web-platform-tests/html/webappapis/scripting/events/body-exposed-window-event-handlers-expected.txt:
  • web-platform-tests/streams/piping/close-propagation-forward-expected.txt:
  • web-platform-tests/streams/piping/error-propagation-backward-expected.txt:
  • web-platform-tests/streams/piping/error-propagation-forward-expected.txt:
  • web-platform-tests/streams/piping/flow-control-expected.txt:
  • web-platform-tests/streams/piping/general-expected.txt:
  • web-platform-tests/user-timing/measure_exceptions_navigation_timing-expected.txt:

Rebaseline expectations to include unhandled promise rejection messages.
Also change how the test harness reports success or failure to use the values
immediately on completion and then allow a run loop cycle before completing
the test to gather the output.

  • web-platform-tests/resource-timing/rt-resource-errors.html:

This is our own WPT test yet to be uploaded, so update the test to prevent
an unexpected unhandled rejection.

Source/JavaScriptCore:

Implement support for promise.PromiseIsHandled? and the
HostPromiseRejectionTracker hook for HTML to track promise rejections:
https://tc39.github.io/ecma262/#sec-host-promise-rejection-tracker
https://html.spec.whatwg.org/multipage/webappapis.html#unhandled-promise-rejections

  • builtins/BuiltinNames.h:

New private symbols.

  • builtins/PromiseOperations.js:

(globalPrivate.newHandledRejectedPromise):
Utility to create a rejected promise with PromiseIsHandled? to true.

(globalPrivate.rejectPromise):
(globalPrivate.initializePromise):

  • builtins/PromisePrototype.js:

(then):
Implement standard behavior of PromiseIsHandled? and the host hook.

  • runtime/JSPromise.cpp:

(JSC::JSPromise::isHandled):

  • runtime/JSPromise.h:

C++ accessors for the PromiseIsHandled? state.

  • bytecode/BytecodeIntrinsicRegistry.cpp:

(JSC::BytecodeIntrinsicRegistry::BytecodeIntrinsicRegistry):

  • bytecode/BytecodeIntrinsicRegistry.h:

Expose private values for the Reject / Handle enum values in built-ins.

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

(JSC::JSGlobalObject::promiseResolveFunction):
Add a new GlobalObjectMethodTable hook matching the promise rejection hook.

  • runtime/JSGlobalObject.cpp:

(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::visitChildren):

  • runtime/JSGlobalObjectFunctions.cpp:

(JSC::globalFuncHostPromiseRejectionTracker):

  • runtime/JSGlobalObjectFunctions.h:

Plumb the builtin hook through to the optional GlobalObjectMethodTable hook.

  • inspector/InjectedScriptSource.js:

(InjectedScript.prototype.createFakeValueDescriptor):
Silence possible rejected promises created internally via Web Inspector.

Source/WebCore:

Implement support for the onunhandledrejection and rejectionhandled events.
They dispatch a new PromiseRejectionEvent using the ES6 HostPromiseRejectionTracker hook:
https://tc39.github.io/ecma262/#sec-host-promise-rejection-tracker
https://html.spec.whatwg.org/multipage/webappapis.html#unhandled-promise-rejections

This is currently implemented only for Documents and not yet Web Workers.

Tests: js/dom/unhandled-promise-rejection-basic.html

js/dom/unhandled-promise-rejection-bindings-type-error.html
js/dom/unhandled-promise-rejection-console-no-report.html
js/dom/unhandled-promise-rejection-console-report.html
js/dom/unhandled-promise-rejection-handle-during-event.html
js/dom/unhandled-promise-rejection-handle-in-handler.html
js/dom/unhandled-promise-rejection-handle.html
js/dom/unhandled-promise-rejection-order.html

  • CMakeLists.txt:
  • DerivedSources.cpp:
  • DerivedSources.make:
  • WebCore.xcodeproj/project.pbxproj:
  • dom/DOMAllInOne.cpp:

New files.

  • bindings/scripts/CodeGenerator.pm:

(IsPromiseType):

  • bindings/scripts/CodeGeneratorJS.pm:

(AddToIncludesForIDLType):
(GetBaseIDLType):
Binding support for Promise<T> attributes.

  • bindings/js/JSDOMConvert.h:
  • bindings/js/JSDOMConvertPromise.h: Copied from Source/JavaScriptCore/runtime/JSPromise.h.

(WebCore::Converter<IDLPromise<T>>::convert):
(WebCore::JSConverter<IDLPromise<T>>::convert):
Promise<T> binding conversion is currently unimplemented, which only means
web developers creating their own PromiseRejectionEvent will not get
autowrapping of values assigned to promise in event initialization.
Engine generated events will have expected behavior.

  • bindings/js/JSDOMWindowBase.cpp:

(WebCore::JSDOMWindowBase::promiseRejectionTracker):

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

Implement HostPromiseRejectionTracker hook for Document but not Worker.
Passes through to the ScriptExecutionContext's tracker.

  • bindings/js/JSMainThreadExecState.cpp:

(WebCore::JSMainThreadExecState::didLeaveScriptContext):

  • bindings/js/JSMainThreadExecState.h:

(WebCore::JSMainThreadExecState::~JSMainThreadExecState):
When completing script execution and performing microtasks notify
about rejected promises. Technically this should go inside of
performing a microtask checkpoint, except lacking EventLoop
concepts we use ScriptExecutionState.

  • dom/EventNames.h:
  • dom/EventNames.in:
  • dom/PromiseRejectionEvent.cpp: Added.

(WebCore::PromiseRejectionEvent::PromiseRejectionEvent):
(WebCore::PromiseRejectionEvent::~PromiseRejectionEvent):

  • dom/PromiseRejectionEvent.h: Added.
  • dom/PromiseRejectionEvent.idl: Added.

New PromiseRejectionEvent event interface.

  • dom/GlobalEventHandlers.idl:

New onunhandledrejection and onrejectionhandled.

  • dom/RejectedPromiseTracker.cpp: Added.

(WebCore::RejectedPromise::RejectedPromise):
(WebCore::RejectedPromise::globalObject):
(WebCore::RejectedPromise::promise):
(WebCore::UnhandledPromise::UnhandledPromise):
(WebCore::UnhandledPromise::callStack):
(WebCore::RejectedPromiseTracker::RejectedPromiseTracker):
(WebCore::RejectedPromiseTracker::~RejectedPromiseTracker):
(WebCore::createScriptCallStackFromReason):
(WebCore::RejectedPromiseTracker::promiseRejected):
(WebCore::RejectedPromiseTracker::promiseHandled):
(WebCore::RejectedPromiseTracker::processQueueSoon):
(WebCore::RejectedPromiseTracker::reportUnhandledRejections):
(WebCore::RejectedPromiseTracker::reportRejectionHandled):

  • dom/RejectedPromiseTracker.h: Added.

Track and report rejected promises. The promises are tracked weakly
allowing them to be collected before they are reported. When reporting
we dispatch PromiseRejectionEvent events, and if the default is not
prevented we log a message to the console.

  • dom/ScriptExecutionContext.cpp:

(WebCore::ScriptExecutionContext::reportUnhandledPromiseRejection):
(WebCore::ScriptExecutionContext::ensureRejectedPromiseTrackerSlow):

  • dom/ScriptExecutionContext.h:

(WebCore::ScriptExecutionContext::ensureRejectedPromiseTracker):
Each ScriptExecutionContext can own a rejected promise tracker.

  • html/HTMLMediaElement.cpp:

(WebCore::HTMLMediaElement::pauseInternal):
https://html.spec.whatwg.org/multipage/embedded-content.html#internal-pause-steps
Internal pause steps say to timeupdate, pause, and rejecting pending play promises
should all happen in a queued task. Here the first two actions are already scheduled
on tasks, but rejecting play promises was not being done in a task, so this makes
that change.

  • Modules/streams/ReadableStream.js:

(pipeThrough):

  • Modules/streams/ReadableStreamInternals.js:

(readableStreamReaderGenericInitialize):
(readableStreamError):
(readableStreamReaderGenericRelease):
Satisfy parts of the Streams specification which state to set the
PromiseIsHandled? internal state of promises created internally
by the Streams APIs. This prevents some internal promises from
appearing as unhandled promise rejections.

LayoutTests:

  • js/dom/unhandled-promise-rejection-basic-expected.txt: Added.
  • js/dom/unhandled-promise-rejection-basic.html: Added.
  • js/dom/unhandled-promise-rejection-bindings-type-error-expected.txt: Added.
  • js/dom/unhandled-promise-rejection-bindings-type-error.html: Added.
  • js/dom/unhandled-promise-rejection-console-no-report-expected.txt: Added.
  • js/dom/unhandled-promise-rejection-console-no-report.html: Added.
  • js/dom/unhandled-promise-rejection-console-report-expected.txt: Added.
  • js/dom/unhandled-promise-rejection-console-report.html: Added.
  • js/dom/unhandled-promise-rejection-handle-during-event-expected.txt: Added.
  • js/dom/unhandled-promise-rejection-handle-during-event.html: Added.
  • js/dom/unhandled-promise-rejection-handle-expected.txt: Added.
  • js/dom/unhandled-promise-rejection-handle-in-handler-expected.txt: Added.
  • js/dom/unhandled-promise-rejection-handle-in-handler.html: Added.
  • js/dom/unhandled-promise-rejection-handle.html: Added.
  • js/dom/unhandled-promise-rejection-order-expected.txt: Added.
  • js/dom/unhandled-promise-rejection-order.html: Added.

New tests specific to the onunhandledrejection and onrejectionhandled events.

  • resources/testharnessreport.js:

(self.testRunner.add_completion_callback.sanitize):
(self.testRunner.add_completion_callback):
Report results immediately and then finish the test after a turn. This way
if the test ends with a pass, but may get unhandled rejections after
completing which should not make the test appear as if it failed. Some tests
have unhandled promise rejections but are expected to pass. Likewise some
tests perform cleanup in their own completion callbacks, which happen after
this initial completion callback, and we want to report results after all
the work is done as it may eliminate non-deterministic debug test output.

Mark some tests as flakey that have sometimes have unhandled promise rejections.
These tests are all various imported tests that use the testharness.

  • fast/mediastream/MediaStream-MediaElement-setObject-null-expected.txt:
  • http/tests/security/video-cross-origin-caching-expected.txt:
  • inspector/debugger/break-on-exception-throw-in-promise-expected.txt:
  • inspector/debugger/break-on-uncaught-exception-throw-in-promise-expected.txt:
  • inspector/worker/resources-in-worker-expected.txt:
  • js/dom/dom-static-property-for-in-iteration-expected.txt:
  • js/dom/global-constructors-attributes-dedicated-worker-expected.txt:
  • js/promises-tests/promises-tests-2-2-6-expected.txt:
  • platform/mac/inspector/model/remote-object-expected.txt:
  • webrtc/libwebrtc/release-while-creating-offer-expected.txt:
  • webrtc/libwebrtc/release-while-setting-local-description-expected.txt:

Update tests with unhandled promise rejection messages.

  • media/W3C/audio/events/event_pause_manual.html:
  • media/audio-playback-restriction-play-expected.txt:
  • media/audio-playback-restriction-play.html:
  • media/click-volume-bar-not-pausing.html:
  • media/remote-control-command-is-user-gesture-expected.txt:
  • media/remote-control-command-is-user-gesture.html:
  • media/track/track-mode.html:
  • media/video-autoplay-allowed-but-fullscreen-required.html:
  • media/video-display-none-crash.html:
  • media/video-main-content-deny-display-none.html:
  • media/video-main-content-deny-not-in-dom.html:
  • media/video-main-content-deny-not-visible.html:
  • media/video-main-content-deny-obscured.html:
  • media/video-main-content-deny-too-small.html:
  • media/video-multiple-concurrent-playback-expected.txt:
  • media/video-play-audio-require-user-gesture-expected.txt:
  • media/video-play-audio-require-user-gesture.html:
  • media/video-play-pause-events-expected.txt:
  • media/video-play-pause-events.html:
  • media/video-play-pause-exception-expected.txt:
  • media/video-play-pause-exception.html:
  • media/video-play-require-user-gesture-expected.txt:
  • media/video-play-require-user-gesture.html:
  • media/video-preload-expected.txt:
  • media/video-preload.html:
  • media/video-test.js:

(handlePromise.handle):
Snuff many possible unhandled promise rejections in media via media.play().

  • streams/reference-implementation/pipe-to-expected.txt:
  • streams/reference-implementation/pipe-to-options-expected.txt:
  • streams/reference-implementation/readable-stream-templated-expected.txt:
  • streams/reference-implementation/writable-stream-abort-expected.txt:
  • streams/reference-implementation/writable-stream-expected.txt:

These stream tests are out of date and produce unhandled rejections.

  • streams/shadowing-Promise.html:

Update non-imported tests to prevent unhandled rejection messages.

Location:
trunk
Files:
21 added
106 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r215914 r215916  
     12017-04-27  Joseph Pecoraro  <pecoraro@apple.com>
     2
     3        Support for promise rejection events (unhandledrejection)
     4        https://bugs.webkit.org/show_bug.cgi?id=150358
     5        <rdar://problem/28441651>
     6
     7        Reviewed by Saam Barati.
     8
     9        Patch by Joseph Pecoraro and Yusuke Suzuki.
     10
     11        * js/dom/unhandled-promise-rejection-basic-expected.txt: Added.
     12        * js/dom/unhandled-promise-rejection-basic.html: Added.
     13        * js/dom/unhandled-promise-rejection-bindings-type-error-expected.txt: Added.
     14        * js/dom/unhandled-promise-rejection-bindings-type-error.html: Added.
     15        * js/dom/unhandled-promise-rejection-console-no-report-expected.txt: Added.
     16        * js/dom/unhandled-promise-rejection-console-no-report.html: Added.
     17        * js/dom/unhandled-promise-rejection-console-report-expected.txt: Added.
     18        * js/dom/unhandled-promise-rejection-console-report.html: Added.
     19        * js/dom/unhandled-promise-rejection-handle-during-event-expected.txt: Added.
     20        * js/dom/unhandled-promise-rejection-handle-during-event.html: Added.
     21        * js/dom/unhandled-promise-rejection-handle-expected.txt: Added.
     22        * js/dom/unhandled-promise-rejection-handle-in-handler-expected.txt: Added.
     23        * js/dom/unhandled-promise-rejection-handle-in-handler.html: Added.
     24        * js/dom/unhandled-promise-rejection-handle.html: Added.
     25        * js/dom/unhandled-promise-rejection-order-expected.txt: Added.
     26        * js/dom/unhandled-promise-rejection-order.html: Added.
     27        New tests specific to the `onunhandledrejection` and `onrejectionhandled` events.
     28
     29        * resources/testharnessreport.js:
     30        (self.testRunner.add_completion_callback.sanitize):
     31        (self.testRunner.add_completion_callback):
     32        Report results immediately and then finish the test after a turn. This way
     33        if the test ends with a pass, but may get unhandled rejections after
     34        completing which should not make the test appear as if it failed. Some tests
     35        have unhandled promise rejections but are expected to pass. Likewise some
     36        tests perform cleanup in their own completion callbacks, which happen after
     37        this initial completion callback, and we want to report results after all
     38        the work is done as it may eliminate non-deterministic debug test output.
     39
     40        * TestExpectations:
     41        Mark some tests as flakey that have sometimes have unhandled promise rejections.
     42        These tests are all various imported tests that use the testharness.
     43
     44        * fast/mediastream/MediaStream-MediaElement-setObject-null-expected.txt:
     45        * http/tests/security/video-cross-origin-caching-expected.txt:
     46        * inspector/debugger/break-on-exception-throw-in-promise-expected.txt:
     47        * inspector/debugger/break-on-uncaught-exception-throw-in-promise-expected.txt:
     48        * inspector/worker/resources-in-worker-expected.txt:
     49        * js/dom/dom-static-property-for-in-iteration-expected.txt:
     50        * js/dom/global-constructors-attributes-dedicated-worker-expected.txt:
     51        * js/promises-tests/promises-tests-2-2-6-expected.txt:
     52        * platform/mac/inspector/model/remote-object-expected.txt:
     53        * webrtc/libwebrtc/release-while-creating-offer-expected.txt:
     54        * webrtc/libwebrtc/release-while-setting-local-description-expected.txt:
     55        Update tests with unhandled promise rejection messages.
     56
     57        * media/W3C/audio/events/event_pause_manual.html:
     58        * media/audio-playback-restriction-play-expected.txt:
     59        * media/audio-playback-restriction-play.html:
     60        * media/click-volume-bar-not-pausing.html:
     61        * media/remote-control-command-is-user-gesture-expected.txt:
     62        * media/remote-control-command-is-user-gesture.html:
     63        * media/track/track-mode.html:
     64        * media/video-autoplay-allowed-but-fullscreen-required.html:
     65        * media/video-display-none-crash.html:
     66        * media/video-main-content-deny-display-none.html:
     67        * media/video-main-content-deny-not-in-dom.html:
     68        * media/video-main-content-deny-not-visible.html:
     69        * media/video-main-content-deny-obscured.html:
     70        * media/video-main-content-deny-too-small.html:
     71        * media/video-multiple-concurrent-playback-expected.txt:
     72        * media/video-play-audio-require-user-gesture-expected.txt:
     73        * media/video-play-audio-require-user-gesture.html:
     74        * media/video-play-pause-events-expected.txt:
     75        * media/video-play-pause-events.html:
     76        * media/video-play-pause-exception-expected.txt:
     77        * media/video-play-pause-exception.html:
     78        * media/video-play-require-user-gesture-expected.txt:
     79        * media/video-play-require-user-gesture.html:
     80        * media/video-preload-expected.txt:
     81        * media/video-preload.html:
     82        * media/video-test.js:
     83        (handlePromise.handle):
     84        Snuff many possible unhandled promise rejections in media via media.play().
     85
     86        * streams/reference-implementation/pipe-to-expected.txt:
     87        * streams/reference-implementation/pipe-to-options-expected.txt:
     88        * streams/reference-implementation/readable-stream-templated-expected.txt:
     89        * streams/reference-implementation/writable-stream-abort-expected.txt:
     90        * streams/reference-implementation/writable-stream-expected.txt:
     91        These stream tests are out of date and produce unhandled rejections.
     92
     93        * streams/shadowing-Promise.html:
     94        Update non-imported tests to prevent unhandled rejection messages.
     95
    1962017-04-27  Chris Dumez  <cdumez@apple.com>
    297
  • trunk/LayoutTests/TestExpectations

    r215913 r215916  
    330330webkit.org/b/169565 imported/w3c/web-platform-tests/cors/status-async.htm [ Failure ]
    331331webkit.org/b/169565 imported/w3c/web-platform-tests/cors/304.htm [ Failure ]
     332
     333# Tests that are flakey due to unhandled promise rejection error messages
     334webkit.org/b/171094 imported/w3c/web-platform-tests/streams/readable-streams/tee.html [ Pass Failure ]
     335webkit.org/b/171094 streams/brand-checks.html [ Pass Failure ]
     336webkit.org/b/171094 streams/reference-implementation/abstract-ops.html [ Pass Failure ]
    332337
    333338# WPT tests that fail after doing full test repository reimport and need further investigation
  • trunk/LayoutTests/fast/mediastream/MediaStream-MediaElement-setObject-null-expected.txt

    r212311 r215916  
     1CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: [object DOMError]
    12PASS video.srcObject = stream did not throw exception.
    23PASS video.duration is Number.POSITIVE_INFINITY
  • trunk/LayoutTests/http/tests/security/video-cross-origin-caching-expected.txt

    r200493 r215916  
     1CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: [object DOMError]
    12
    23This test passes if you do not see a CORS error.
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r215914 r215916  
     12017-04-27  Joseph Pecoraro  <pecoraro@apple.com>
     2
     3        Support for promise rejection events (unhandledrejection)
     4        https://bugs.webkit.org/show_bug.cgi?id=150358
     5        <rdar://problem/28441651>
     6
     7        Reviewed by Saam Barati.
     8
     9        Patch by Joseph Pecoraro and Yusuke Suzuki.
     10
     11        * web-platform-tests/WebCryptoAPI/derive_bits_keys/test_ecdh_bits-expected.txt:
     12        * web-platform-tests/WebCryptoAPI/derive_bits_keys/test_ecdh_keys-expected.txt:
     13        * web-platform-tests/html/semantics/embedded-content/media-elements/event_pause_noautoplay-expected.txt:
     14        * web-platform-tests/html/semantics/embedded-content/media-elements/event_play_noautoplay-expected.txt:
     15        * web-platform-tests/html/semantics/embedded-content/media-elements/paused_true_during_pause-expected.txt:
     16        * web-platform-tests/html/syntax/parsing/html5lib_innerHTML_adoption01-expected.txt:
     17        * web-platform-tests/html/webappapis/scripting/events/body-exposed-window-event-handlers-expected.txt:
     18        * web-platform-tests/streams/piping/close-propagation-forward-expected.txt:
     19        * web-platform-tests/streams/piping/error-propagation-backward-expected.txt:
     20        * web-platform-tests/streams/piping/error-propagation-forward-expected.txt:
     21        * web-platform-tests/streams/piping/flow-control-expected.txt:
     22        * web-platform-tests/streams/piping/general-expected.txt:
     23        * web-platform-tests/user-timing/measure_exceptions_navigation_timing-expected.txt:
     24        Rebaseline expectations to include unhandled promise rejection messages.
     25        Also change how the test harness reports success or failure to use the values
     26        immediately on completion and then allow a run loop cycle before completing
     27        the test to gather the output.
     28
     29        * web-platform-tests/resource-timing/rt-resource-errors.html:
     30        This is our own WPT test yet to be uploaded, so update the test to prevent
     31        an unexpected unhandled rejection.
     32
    1332017-04-27  Chris Dumez  <cdumez@apple.com>
    234
  • trunk/LayoutTests/imported/w3c/web-platform-tests/WebCryptoAPI/derive_bits_keys/test_ecdh_bits-expected.txt

    r212124 r215916  
     1CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: DataError (DOM Exception 30): Data provided to an operation does not meet requirements
    12deriveBits Tests for ECDH
    23
    34
    4 Harness Error (TIMEOUT), message = null
     5Harness Error (FAIL), message = Data provided to an operation does not meet requirements
    56
    67
  • trunk/LayoutTests/imported/w3c/web-platform-tests/WebCryptoAPI/derive_bits_keys/test_ecdh_keys-expected.txt

    r212124 r215916  
     1CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: DataError (DOM Exception 30): Data provided to an operation does not meet requirements
    12deriveKey Tests for ECDH
    23
    34
    4 Harness Error (TIMEOUT), message = null
     5Harness Error (FAIL), message = Data provided to an operation does not meet requirements
    56
    67
  • trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/event_pause_noautoplay-expected.txt

    r189476 r215916  
     1CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: [object DOMError]
     2CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: [object DOMError]
    13spec reference
    24
    35 
     6
     7Harness Error (FAIL), message = The operation was aborted.
    48
    59PASS audio events - pause
  • trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/event_play_noautoplay-expected.txt

    r189476 r215916  
     1CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: [object DOMError]
     2CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: [object DOMError]
    13spec reference
    24
    35 
     6
     7Harness Error (FAIL), message = The operation was aborted.
    48
    59PASS audio events - play
  • trunk/LayoutTests/imported/w3c/web-platform-tests/html/semantics/embedded-content/media-elements/paused_true_during_pause-expected.txt

    r189476 r215916  
     1CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: [object DOMError]
     2CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: [object DOMError]
    13spec reference
    24
    35 
     6
     7Harness Error (FAIL), message = The operation was aborted.
    48
    59PASS audio events - paused property
  • trunk/LayoutTests/imported/w3c/web-platform-tests/html/syntax/parsing/html5lib_innerHTML_adoption01-expected.txt

    r210823 r215916  
    33
    44
    5 Harness Error (FAIL), message = ReferenceError: Can't find variable: template
    6 
    75FAIL html5lib_innerHTML_adoption01.html 0bf80e1546d4c221354aa9734f61713b7d64ee6d assert_equals: expected "#document\n| <b>\n|   <em>\n|     <foo>\n|       <foob>\n|         <fooc>\n| <aside>\n|   <b>" but got "#document\n| <b>\n|   <em>\n|     <foo>\n|       <foob>\n|         <fooc>\n| <aside>\n|   <em>\n|     <b>"
    86
  • trunk/LayoutTests/imported/w3c/web-platform-tests/html/webappapis/scripting/events/body-exposed-window-event-handlers-expected.txt

    r213882 r215916  
    3232PASS Return null when getting the popstate event handler of a windowless body
    3333PASS Ignore setting of popstate window event handlers on windowless body
    34 FAIL Return null when getting the rejectionhandled event handler of a windowless body assert_equals: expected (object) null but got (undefined) undefined
     34PASS Return null when getting the rejectionhandled event handler of a windowless body
    3535FAIL Ignore setting of rejectionhandled window event handlers on windowless body assert_equals: expected (object) null but got (function) function "function () { return "Handler attached to windowless element"; }"
    3636PASS Return null when getting the storage event handler of a windowless body
    3737PASS Ignore setting of storage window event handlers on windowless body
    38 FAIL Return null when getting the unhandledrejection event handler of a windowless body assert_equals: expected (object) null but got (undefined) undefined
     38PASS Return null when getting the unhandledrejection event handler of a windowless body
    3939FAIL Ignore setting of unhandledrejection window event handlers on windowless body assert_equals: expected (object) null but got (function) function "function () { return "Handler attached to windowless element"; }"
    4040PASS Return null when getting the unload event handler of a windowless body
     
    7272PASS Return null when getting the popstate event handler of a windowless frameset
    7373PASS Ignore setting of popstate window event handlers on windowless frameset
    74 FAIL Return null when getting the rejectionhandled event handler of a windowless frameset assert_equals: expected (object) null but got (undefined) undefined
     74PASS Return null when getting the rejectionhandled event handler of a windowless frameset
    7575FAIL Ignore setting of rejectionhandled window event handlers on windowless frameset assert_equals: expected (object) null but got (function) function "function () { return "Handler attached to windowless element"; }"
    7676PASS Return null when getting the storage event handler of a windowless frameset
    7777PASS Ignore setting of storage window event handlers on windowless frameset
    78 FAIL Return null when getting the unhandledrejection event handler of a windowless frameset assert_equals: expected (object) null but got (undefined) undefined
     78PASS Return null when getting the unhandledrejection event handler of a windowless frameset
    7979FAIL Ignore setting of unhandledrejection window event handlers on windowless frameset assert_equals: expected (object) null but got (function) function "function () { return "Handler attached to windowless element"; }"
    8080PASS Return null when getting the unload event handler of a windowless frameset
  • trunk/LayoutTests/imported/w3c/web-platform-tests/resource-timing/rt-resource-errors.html

    r212449 r215916  
    3434    let allowedDataURL = crossOriginURL("cors-allowed", "resource-timing/resources/data.json") + "&pipe=header(Access-Control-Allow-Origin,*)";
    3535
    36     fetch(rejectedDataURL);
     36    fetch(rejectedDataURL).catch(function(){});
    3737    fetch(allowedDataURL);
    3838
  • trunk/LayoutTests/imported/w3c/web-platform-tests/streams/piping/close-propagation-forward-expected.txt

    r215164 r215916  
     1CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     2CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     3CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     4CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     5CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     6CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     7CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     8CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     9CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     10CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     11CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     12CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     13CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     14CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     15CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     16CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     17
     18Harness Error (FAIL), message = cancel() called on a reader owned by no readable stream
    119
    220FAIL Closing must be propagated forward: starts closed; preventClose omitted; fulfilled close promise assert_array_equals: close must always be called with the controller lengths differ, expected 1 got 0
  • trunk/LayoutTests/imported/w3c/web-platform-tests/streams/piping/error-propagation-backward-expected.txt

    r212202 r215916  
     1CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: error2: error2!
     2CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: error1: error1!
    13
    2 Harness Error (TIMEOUT), message = null
     4Harness Error (FAIL), message = error1!
    35
    46PASS Errors must be propagated backward: starts errored; preventCancel omitted; fulfilled cancel promise
  • trunk/LayoutTests/imported/w3c/web-platform-tests/streams/piping/error-propagation-forward-expected.txt

    r212202 r215916  
     1CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: error1: error1!
     2CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     3CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: error1: error1!
     4CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     5CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: error2: error2!
     6CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: error1: error1!
     7CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     8CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: error1: error1!
     9CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     10CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: error1: error1!
     11CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     12CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: error1: error1!
     13CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     14CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: error1: error1!
     15CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     16CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: error1: error1!
     17CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     18CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: error1: error1!
     19CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     20CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: error1: error1!
     21CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: error1: error1!
     22CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: error1: error1!
     23CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: error1: error1!
     24CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: error1: error1!
     25CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: error1: error1!
     26CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: error1: error1!
     27CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: error1: error1!
     28CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     29CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: error1: error1!
     30CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     31CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: error2: error2!
     32CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: error1: error1!
     33CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: error1: error1!
     34CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     35CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: error1: error1!
     36CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     37CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: error2: error2!
     38CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: error1: error1!
     39CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: error1: error1!
     40CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     41CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: error1: error1!
     42CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     43CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: error2: error2!
     44CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: error1: error1!
     45CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: error1: error1!
     46CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     47CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: error1: error1!
     48CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     49CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: error2: error2!
     50CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: error1: error1!
     51CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: error1: error1!
     52CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: error1: error1!
     53CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     54
     55Harness Error (FAIL), message = cancel() called on a reader owned by no readable stream
    156
    257PASS Errors must be propagated forward: starts errored; preventAbort = false; fulfilled abort promise
  • trunk/LayoutTests/imported/w3c/web-platform-tests/streams/piping/flow-control-expected.txt

    r215164 r215916  
     1CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: Error: assert_array_equals: close must always be called with the controller lengths differ, expected 1 got 0
     2
     3Harness Error (FAIL), message = assert_array_equals: close must always be called with the controller lengths differ, expected 1 got 0
    14
    25FAIL Piping from a non-empty ReadableStream into a WritableStream that does not desire chunks promise_test: Unhandled rejection with value: object "TypeError: ws.controller.error is not a function. (In 'ws.controller.error(error1)', 'ws.controller.error' is undefined)"
  • trunk/LayoutTests/imported/w3c/web-platform-tests/streams/piping/general-expected.txt

    r212202 r215916  
     1CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: The WritableStream.ready getter can only be used on instances of WritableStream
     2CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     3CONSOLE MESSAGE: line 2684: TypeError: undefined is not an object (evaluating 'e.message')
     4CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: undefined
     5CONSOLE MESSAGE: line 2684: TypeError: undefined is not an object (evaluating 'e.message')
     6CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: undefined
     7CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     8CONSOLE MESSAGE: line 2684: TypeError: undefined is not an object (evaluating 'e.message')
     9CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: undefined
     10CONSOLE MESSAGE: line 2684: TypeError: undefined is not an object (evaluating 'e.message')
     11CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: undefined
     12CONSOLE MESSAGE: line 2684: TypeError: undefined is not an object (evaluating 'e.message')
     13CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: undefined
     14
     15Harness Error (FAIL), message = The WritableStream.ready getter can only be used on instances of WritableStream
    116
    217FAIL Piping must lock both the ReadableStream and WritableStream assert_false: sanity check: the WritableStream must not start locked expected false got undefined
  • trunk/LayoutTests/imported/w3c/web-platform-tests/user-timing/measure_exceptions_navigation_timing-expected.txt

    r215164 r215916  
    55
    66
    7 Harness Error (FAIL), message = ReferenceError: Can't find variable: onload_test
    8 
    97PASS window.performance.measure("measure", "loadEventEnd"), where "loadEventEnd" is a navigation timing attribute with a value of 0, throws a InvalidAccessError exception.
    108PASS window.performance.measure("measure", "loadEventEnd", "responseEnd"), where "loadEventEnd" is a navigation timing attribute with a value of 0, throws a InvalidAccessError exception.
  • trunk/LayoutTests/inspector/debugger/break-on-exception-throw-in-promise-expected.txt

    r202825 r215916  
    22CONSOLE MESSAGE: line 38: in promise
    33CONSOLE MESSAGE: line 7: throwing TestError
     4CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TestError
    45CONSOLE MESSAGE: line 55: testThrowingInPromiseThen
    56CONSOLE MESSAGE: line 57: in promise
    67CONSOLE MESSAGE: line 60: in promise.then
    78CONSOLE MESSAGE: line 7: throwing TestError
     9CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TestError
    810CONSOLE MESSAGE: line 66: testThrowingInPromiseThenWithCatch
    911CONSOLE MESSAGE: line 68: in promise
     
    2123CONSOLE MESSAGE: line 7: throwing TestError
    2224CONSOLE MESSAGE: line 85: in promise.catch
     25CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TestError
    2326Checking pause locations within Promises when pausing on all exceptions.
    2427
  • trunk/LayoutTests/inspector/debugger/break-on-uncaught-exception-throw-in-promise-expected.txt

    r202825 r215916  
    22CONSOLE MESSAGE: line 38: in promise
    33CONSOLE MESSAGE: line 7: throwing TestError
     4CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TestError
    45CONSOLE MESSAGE: line 55: testThrowingInPromiseThen
    56CONSOLE MESSAGE: line 57: in promise
    67CONSOLE MESSAGE: line 60: in promise.then
    78CONSOLE MESSAGE: line 7: throwing TestError
     9CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TestError
    810CONSOLE MESSAGE: line 66: testThrowingInPromiseThenWithCatch
    911CONSOLE MESSAGE: line 68: in promise
     
    2123CONSOLE MESSAGE: line 7: throwing TestError
    2224CONSOLE MESSAGE: line 85: in promise.catch
     25CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TestError
    2326Checking no pauses within Promises when pausing on uncaught exceptions.
    2427
  • trunk/LayoutTests/inspector/worker/resources-in-worker-expected.txt

    r208520 r215916  
     1CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: Type error
    12Test for Resources in a Worker.
    23
  • trunk/LayoutTests/js/dom/dom-static-property-for-in-iteration-expected.txt

    r210029 r215916  
    9090PASS a["onprogress"] is null
    9191PASS a["onratechange"] is null
     92PASS a["onrejectionhandled"] is null
    9293PASS a["onreset"] is null
    9394PASS a["onresize"] is null
     
    101102PASS a["ontimeupdate"] is null
    102103PASS a["ontoggle"] is null
     104PASS a["onunhandledrejection"] is null
    103105PASS a["onvolumechange"] is null
    104106PASS a["onwaiting"] is null
     
    111113PASS a["localName"] is a
    112114PASS a["offsetLeft"] is 8
    113 PASS a["offsetTop"] is 1689
     115PASS a["offsetTop"] is 1719
    114116PASS a["offsetWidth"] is 40
    115117PASS a["offsetHeight"] is 18
  • trunk/LayoutTests/js/dom/global-constructors-attributes-dedicated-worker-expected.txt

    r212449 r215916  
    240240PASS [Worker] Object.getOwnPropertyDescriptor(global, 'Promise').enumerable is false
    241241PASS [Worker] Object.getOwnPropertyDescriptor(global, 'Promise').configurable is true
     242PASS [Worker] Object.getOwnPropertyDescriptor(global, 'PromiseRejectionEvent').value is PromiseRejectionEvent
     243PASS [Worker] Object.getOwnPropertyDescriptor(global, 'PromiseRejectionEvent').hasOwnProperty('get') is false
     244PASS [Worker] Object.getOwnPropertyDescriptor(global, 'PromiseRejectionEvent').hasOwnProperty('set') is false
     245PASS [Worker] Object.getOwnPropertyDescriptor(global, 'PromiseRejectionEvent').enumerable is false
     246PASS [Worker] Object.getOwnPropertyDescriptor(global, 'PromiseRejectionEvent').configurable is true
    242247PASS [Worker] Object.getOwnPropertyDescriptor(global, 'RangeError').value is RangeError
    243248PASS [Worker] Object.getOwnPropertyDescriptor(global, 'RangeError').hasOwnProperty('get') is false
  • trunk/LayoutTests/js/promises-tests/promises-tests-2-2-6-expected.txt

    r174307 r215916  
     1CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: [object Object]
     2CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: [object Object]
     3CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: [object Object]
     4CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: [object Object]
     5CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: [object Object]
     6CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: [object Object]
    17Test Promise with Promise A+ tests 2.2.6.
    28
  • trunk/LayoutTests/media/W3C/w3cwrapper.js

    r155282 r215916  
    6060assert_false = function(a) { shouldBeFalse("" + a); }
    6161
     62// Don't report unhandled promise rejections in these tests.
     63window.onunhandledrejection = function() { return false; }
     64
    6265var successfullyParsed = true;
  • trunk/LayoutTests/media/audio-playback-restriction-play-expected.txt

    r197953 r215916  
    55RUN(video.src = findMediaFile('audio', 'content/test'))
    66EVENT(canplaythrough)
    7 RUN(video.play())
     7RUN(handlePromise(video.play()))
    88EXPECTED (video.paused == 'true') OK
    99Running with keyDown.
  • trunk/LayoutTests/media/audio-playback-restriction-play.html

    r197953 r215916  
    2121    function canplaythrough()
    2222    {
    23         run("video.play()");
     23        run("handlePromise(video.play())");
    2424        testExpected('video.paused', true);
    2525        runWithKeyDown(playWithKeyDown);
  • trunk/LayoutTests/media/click-volume-bar-not-pausing.html

    r210959 r215916  
    7979
    8080                mediaElement.pause();
    81                 mediaElement.play();
     81                handlePromise(mediaElement.play());
    8282            }
    8383
  • trunk/LayoutTests/media/media-file.js

    r83210 r215916  
    7373  return filename;
    7474}
     75
     76function handlePromise(promise) {
     77    function handle() { }
     78    return promise.then(handle, handle);
     79}
  • trunk/LayoutTests/media/modern-media-controls/media-controller/media-controller-auto-hide-mouse-leave-after-play.html

    r211374 r215916  
    3939    debug("Resuming media playback.");
    4040    media.addEventListener("play", mediaResumedPlaying);
    41     media.play();
     41    media.play().catch(function(){});
    4242}
    4343
  • trunk/LayoutTests/media/modern-media-controls/playback-support/playback-support-media-api.html

    r208226 r215916  
    3434});
    3535
    36 media.play();
     36media.play().catch(function(){});
    3737
    3838</script>
  • trunk/LayoutTests/media/modern-media-controls/start-support/start-support-manual-play.html

    r208226 r215916  
    3232});
    3333
    34 media.play();
     34media.play().catch(function(){});
    3535
    3636</script>
  • trunk/LayoutTests/media/remote-control-command-is-user-gesture-expected.txt

    r199515 r215916  
    77
    88* video.play() should fail
    9 RUN(video.play())
     9RUN(handlePromise(video.play()))
    1010EXPECTED (video.paused == 'true') OK
    1111
  • trunk/LayoutTests/media/remote-control-command-is-user-gesture.html

    r199515 r215916  
    2626            {
    2727                consoleWrite('<br>* video.play() should fail ');
    28                 run('video.play()');
     28                run('handlePromise(video.play())');
    2929                testExpected('video.paused', true);
    3030
  • trunk/LayoutTests/media/track/track-cues-pause-on-exit.html

    r154815 r215916  
    66        <script src=../media-file.js></script>
    77        <script src=../video-test.js></script>
     8    </head>
     9    <body onload="bodyLoaded()">
     10        <p>Tests that the video is paused after cues that have pause-on-exit flag are processed</p>
     11        <video controls>
     12            <track id="testTrack" src="captions-webvtt/simple-captions.vtt" onload="loaded()" default>
     13        </video>
    814        <script>
    915            var videoCanPlayThrough = false;
     
    7682            setCaptionDisplayMode('Automatic');
    7783        </script>
    78     </head>
    79     <body onload="bodyLoaded()">
    80         <p>Tests that the video is paused after cues that have pause-on-exit flag are processed</p>
    81         <video controls>
    82             <track id="testTrack" src="captions-webvtt/simple-captions.vtt" onload="loaded()" default>
    83         </video>
    8484    </body>
    8585</html>
  • trunk/LayoutTests/media/track/track-mode.html

    r154527 r215916  
    7777
    7878                consoleWrite("<b>++ at least " + textTrack.cues.length + " events expected while mode = showing</b>");
    79                 video.play();
     79                handlePromise(video.play());
    8080            }
    8181           
  • trunk/LayoutTests/media/video-autoplay-allowed-but-fullscreen-required.html

    r198609 r215916  
    1616
    1717    function canPlayThrough() {
    18         video.play();
     18        var promise = video.play();
    1919        waitForEventAndFail('playing');
    2020        setTimeout(didNotPlay, 100);
     21        promise.catch(didNotPlay);
    2122    }
    2223
  • trunk/LayoutTests/media/video-display-none-crash.html

    r79630 r215916  
    55<script>
    66    video.src = findMediaFile("video", "content/test");
    7     video.play();
     7    handlePromise(video.play());
    88    video.style.display = "none";
    99    video.pause();
  • trunk/LayoutTests/media/video-main-content-deny-display-none.html

    r197953 r215916  
    1616
    1717    function canPlayThrough() {
    18         video.play();
     18        var promise = video.play();
    1919        waitForEventAndFail('playing');
    2020        setTimeout(didNotBeginPlaying, 100);
     21        promise.catch(didNotBeginPlaying);
    2122    }
    2223
  • trunk/LayoutTests/media/video-main-content-deny-not-in-dom.html

    r197953 r215916  
    1616
    1717    function canPlayThrough() {
    18         video.play();
     18        var promise = video.play();
    1919        waitForEventAndFail('playing');
    2020        setTimeout(didNotBeginPlaying, 100);
     21        promise.catch(didNotBeginPlaying);
    2122    }
    2223
  • trunk/LayoutTests/media/video-main-content-deny-not-visible.html

    r197953 r215916  
    1616
    1717    function canPlayThrough() {
    18         video.play();
     18        var promise = video.play();
    1919        waitForEventAndFail('playing');
    2020        setTimeout(didNotBeginPlaying, 100);
     21        promise.catch(didNotBeginPlaying);
    2122    }
    2223
  • trunk/LayoutTests/media/video-main-content-deny-obscured.html

    r197953 r215916  
    1616
    1717    function canPlayThrough() {
    18         video.play();
     18        var promise = video.play();
    1919        waitForEventAndFail('playing');
    2020        setTimeout(didNotBeginPlaying, 100);
     21        promise.catch(didNotBeginPlaying);
    2122    }
    2223
  • trunk/LayoutTests/media/video-main-content-deny-too-small.html

    r200778 r215916  
    1717
    1818    function canPlayThrough() {
    19         video.play();
     19        var promise = video.play();
    2020        waitForEventAndFail('playing');
    2121        setTimeout(didNotBeginPlaying, 100);
     22        promise.catch(didNotBeginPlaying);
    2223    }
    2324
  • trunk/LayoutTests/media/video-paint-test.js

    r120416 r215916  
    1414    waitForMultipleEvents("canplaythrough", videos.length, function() {
    1515        for (var i = 0; i < videos.length; ++i) {
    16             videos[i].play();
     16            handlePromise(videos[i].play());
    1717            videos[i].addEventListener("playing", function(event) {
    1818                event.target.pause();
     
    4343    waitForMultipleEvents("canplaythrough", videos.length, function() {
    4444        for (var i = 0; i < videos.length; ++i) {
    45             videos[i].play();
     45            handlePromise(videos[i].play());
    4646            videos[i].addEventListener("playing", function(event) {
    4747                event.target.pause();
     
    6666    });
    6767}
     68
     69function handlePromise(promise)
     70{
     71    function handle() { }
     72    return promise.then(handle, handle);
     73}
  • trunk/LayoutTests/media/video-play-audio-require-user-gesture-expected.txt

    r201109 r215916  
    55
    66* No user gesture initiated
    7 RUN(video.play())
     7RUN(handlePromise(video.play()))
    88TEST(video.webkitEnterFullScreen()) THROWS(DOMException.INVALID_STATE_ERR) OK
    99EXPECTED (video.paused == 'true') OK
  • trunk/LayoutTests/media/video-play-audio-require-user-gesture.html

    r210959 r215916  
    3838                consoleWrite("");
    3939                consoleWrite("* No user gesture initiated");
    40                 run("video.play()");
     40                run("handlePromise(video.play())");
    4141                testDOMException("video.webkitEnterFullScreen()", "DOMException.INVALID_STATE_ERR");
    4242                testExpected("video.paused", true);
  • trunk/LayoutTests/media/video-play-pause-events-expected.txt

    r158743 r215916  
    22Test that calling play() and pause() triggers async play, timeupdate and pause events.
    33
    4 RUN(video.play())
     4RUN(handlePromise(video.play()))
    55RUN(video.pause())
    66SCRIPT DONE
  • trunk/LayoutTests/media/video-play-pause-events.html

    r79630 r215916  
    44<script src=video-test.js></script>
    55<script>
    6     video.src = findMediaFile("video", "content/test.mp4");
     6    video.src = findMediaFile("video", "content/test");
    77
    88    waitForEvent("loadstart");
     
    2020
    2121
    22     run("video.play()");
     22    run("handlePromise(video.play())");
    2323    run("video.pause()");
    2424   
  • trunk/LayoutTests/media/video-play-pause-exception-expected.txt

    r158743 r215916  
    22Video has no src. Test that the playing event is not dispatched.
    33
    4 RUN(video.play())
     4RUN(handlePromise(video.play()))
    55RUN(video.pause())
    66EVENT(waiting)
  • trunk/LayoutTests/media/video-play-pause-exception.html

    r176043 r215916  
    2727    waitForEvent("pause", onpause);
    2828
    29     run("video.play()");
     29    run("handlePromise(video.play())");
    3030    run("video.pause()");
    3131</script>
  • trunk/LayoutTests/media/video-play-require-user-gesture-expected.txt

    r158743 r215916  
    55
    66* No user gesture initiated
    7 RUN(video.play())
     7RUN(handlePromise(video.play()))
    88TEST(video.webkitEnterFullScreen()) THROWS(DOMException.INVALID_STATE_ERR) OK
    99EXPECTED (video.paused == 'true') OK
  • trunk/LayoutTests/media/video-play-require-user-gesture.html

    r210959 r215916  
    3838                consoleWrite("");
    3939                consoleWrite("* No user gesture initiated");
    40                 run("video.play()");
     40                run("handlePromise(video.play())");
    4141                testDOMException("video.webkitEnterFullScreen()", "DOMException.INVALID_STATE_ERR");
    4242                testExpected("video.paused", true);
  • trunk/LayoutTests/media/video-played-collapse-expected.txt

    r158743 r215916  
    99Test playing when there are no ranges
    1010EVENT(seeked)
    11 RUN(video.play())
     11RUN(handlePromise(video.play()))
    1212RUN(video.pause())
    1313EVENT(pause)
     
    1818Create a new range
    1919EVENT(seeked)
    20 RUN(video.play())
     20RUN(handlePromise(video.play()))
    2121RUN(video.pause())
    2222EVENT(pause)
     
    2929Test playing from one range into another, should collapse the two ranges
    3030EVENT(seeked)
    31 RUN(video.play())
     31RUN(handlePromise(video.play()))
    3232RUN(video.pause())
    3333EVENT(pause)
     
    3939RUN(video.loop = true)
    4040EVENT(seeked)
    41 RUN(video.play())
     41RUN(handlePromise(video.play()))
    4242RUN(video.pause())
    4343EVENT(pause)
  • trunk/LayoutTests/media/video-played-ranges-1-expected.txt

    r158743 r215916  
    88
    99Test playing when there are no ranges
    10 RUN(video.play())
     10RUN(handlePromise(video.play()))
    1111RUN(video.pause())
    1212EVENT(pause)
     
    1616
    1717Test jumping forward into a new range and play
    18 RUN(video.play())
     18RUN(handlePromise(video.play()))
    1919RUN(video.pause())
    2020EVENT(pause)
     
    2626
    2727Test jumping backwards into a new range and play, should insert new range
    28 RUN(video.play())
     28RUN(handlePromise(video.play()))
    2929RUN(video.pause())
    3030EVENT(pause)
     
    3838
    3939Test playing into an existing range, should extend range start
    40 RUN(video.play())
     40RUN(handlePromise(video.play()))
    4141RUN(video.pause())
    4242EVENT(pause)
     
    5050
    5151Test jumping into an existing range and play beyond end, should extend range end
    52 RUN(video.play())
     52RUN(handlePromise(video.play()))
    5353RUN(video.pause())
    5454EVENT(pause)
  • trunk/LayoutTests/media/video-played-reset-expected.txt

    r158743 r215916  
    88
    99Test playing when there are no ranges
    10 RUN(video.play())
     10RUN(handlePromise(video.play()))
    1111RUN(video.pause())
    1212EVENT(pause)
     
    2323
    2424Test jumping forward into a new range and play
    25 RUN(video.play())
     25RUN(handlePromise(video.play()))
    2626RUN(video.pause())
    2727EVENT(pause)
  • trunk/LayoutTests/media/video-played.js

    r151942 r215916  
    109109    }
    110110
    111     run("video.play()");
     111    run("handlePromise(video.play())");
    112112
    113113    var startTime = nowInSecs();
  • trunk/LayoutTests/media/video-preload-expected.txt

    r158743 r215916  
    88EVENT(loadstart)
    99did not buffer automatically OK
    10 RUN(video.play())
     10RUN(handlePromise(video.play()))
    1111EVENT(play)
    1212EVENT(loadedmetadata)
  • trunk/LayoutTests/media/video-preload.html

    r79630 r215916  
    5151                // start playback, which should force data to load
    5252                movie.shouldBuffer = true;
    53                 run("video.play()");
     53                run("handlePromise(video.play())");
    5454            }
    5555
  • trunk/LayoutTests/media/video-test.js

    r210555 r215916  
    442442
    443443}
     444
     445function handlePromise(promise) {
     446    function handle() { }
     447    return promise.then(handle, handle);
     448}
  • trunk/LayoutTests/platform/mac/inspector/model/remote-object-expected.txt

    r215855 r215916  
     1CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: undefined
     2CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: result
    13
    24-----------------------------------------------------
  • trunk/LayoutTests/resources/testharnessreport.js

    r212150 r215916  
    4545    setup({"output": false, "explicit_timeout": true});
    4646
    47     /*  Using a callback function, test results will be added to the page in a 
     47    /*  Using a callback function, test results will be added to the page in a
    4848    *   manner that allows dumpAsText to produce readable test results
    4949    */
    5050    add_completion_callback(function (tests, harness_status) {
    51         // Wait for any other completion callbacks
    52         setTimeout(function() {
    53             var results = document.createElement("pre");
    54             var resultStr = "\n";
     51        var results = document.createElement("pre");
     52        var resultStr = "\n";
    5553
    56             // Sanitizes the given text for display in test results.
    57             function sanitize(text) {
    58                 if (!text) {
    59                     return "";
    60                 }
    61                 text = text.replace(/\0/g, "\\0");
    62                 return text.replace(/\r/g, "\\r");
     54        // Sanitizes the given text for display in test results.
     55        function sanitize(text) {
     56            if (!text) {
     57                return "";
    6358            }
     59            text = text.replace(/\0/g, "\\0");
     60            return text.replace(/\r/g, "\\r");
     61        }
    6462
    65             if(harness_status.status != 0)
    66                 resultStr += "Harness Error (" + convertResult(harness_status.status) + "), message = " + harness_status.message + "\n\n";
     63        if(harness_status.status != 0)
     64            resultStr += "Harness Error (" + convertResult(harness_status.status) + "), message = " + harness_status.message + "\n\n";
    6765
    68             for (var i = 0; i < tests.length; i++) {
    69                 var message = sanitize(tests[i].message);
    70                 if (tests[i].status == 1 && !tests[i].dumpStack) {
    71                     // Remove stack for failed tests for proper string comparison without file paths.
    72                     // For a test to dump the stack set its dumpStack attribute to true.
    73                     var stackIndex = message.indexOf("(stack:");
    74                     if (stackIndex > 0)
    75                         message = message.substr(0, stackIndex);
    76                 }
    77                 resultStr += convertResult(tests[i].status) + " " + sanitize(tests[i].name) + " " + message + "\n";
     66        for (var i = 0; i < tests.length; i++) {
     67            var message = sanitize(tests[i].message);
     68            if (tests[i].status == 1 && !tests[i].dumpStack) {
     69                // Remove stack for failed tests for proper string comparison without file paths.
     70                // For a test to dump the stack set its dumpStack attribute to true.
     71                var stackIndex = message.indexOf("(stack:");
     72                if (stackIndex > 0)
     73                    message = message.substr(0, stackIndex);
    7874            }
     75            resultStr += convertResult(tests[i].status) + " " + sanitize(tests[i].name) + " " + message + "\n";
     76        }
    7977
    80             results.innerText = resultStr;
    81             var log = document.getElementById("log");
    82             if (log)
    83                 log.appendChild(results);
    84             else
    85                 document.body.appendChild(results);
     78        results.innerText = resultStr;
     79        var log = document.getElementById("log");
     80        if (log)
     81            log.appendChild(results);
     82        else
     83            document.body.appendChild(results);
    8684
     85        // Wait for any other completion callbacks, which may eliminate test elements
     86        // from the page and therefore reduce the output.
     87        setTimeout(function () {
    8788            testRunner.notifyDone();
    8889        }, 0);
  • trunk/LayoutTests/streams/reference-implementation/pipe-to-expected.txt

    r192765 r215916  
     1CONSOLE MESSAGE: line 2687: TypeError: undefined is not an object (evaluating 'e.message')
     2CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: undefined
     3CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: Error: horrible things
     4CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: Error: horrible things
     5CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     6CONSOLE MESSAGE: line 2687: TypeError: undefined is not an object (evaluating 'e.message')
     7CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: undefined
     8CONSOLE MESSAGE: line 2687: TypeError: undefined is not an object (evaluating 'e.message')
     9CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: undefined
     10CONSOLE MESSAGE: line 2687: TypeError: undefined is not an object (evaluating 'e.message')
     11CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: undefined
     12CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: Error: horrible things
     13CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: Error: horrible things
     14CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     15CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     16CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: Error: horrible things
     17CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     18CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: Error: I don't like you.
     19CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: Error: I don't like you.
     20CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: Error: I don't like you.
     21CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: Error: I don't like you.
     22CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: Error: I don't like you.
     23
     24Harness Error (FAIL), message = I don't like you.
    125
    226PASS Piping from a ReadableStream from which lots of data are readable synchronously
  • trunk/LayoutTests/streams/reference-implementation/pipe-to-options-expected.txt

    r192765 r215916  
     1CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: Error: destination error
     2CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: Error: destination error
     3CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: Error: destination error
     4CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: Error: destination error
     5
     6Harness Error (FAIL), message = destination error
    17
    28PASS Piping with no options and a destination error
  • trunk/LayoutTests/streams/reference-implementation/readable-stream-templated-expected.txt

    r193824 r215916  
     1CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     2CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: Error: boo!
     3CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     4CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: Error: boo!
     5CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: Error: boo!
     6CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     7CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: Error: boo!
     8CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     9CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: Error: boo!
     10CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: Error: !!!
     11CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: Error: !!!
     12CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: Error: !!!
     13CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: Error: !!!
     14CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     15CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     16CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: cancel() called on a reader owned by no readable stream
     17
     18Harness Error (FAIL), message = cancel() called on a reader owned by no readable stream
    119
    220PASS Running templatedRSClosed with ReadableStream (closed via call in start)
  • trunk/LayoutTests/streams/reference-implementation/writable-stream-abort-expected.txt

    r191669 r215916  
     1CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: a
     2CONSOLE MESSAGE: line 2687: TypeError: undefined is not an object (evaluating 'e.message')
     3CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: undefined
     4CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: Error: Sorry, it just wasn't meant to be.
     5CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: Error: Sorry, it just wasn't meant to be.
     6CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: Error: Sorry, it just wasn't meant to be.
     7CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: Error: Sorry, it just wasn't meant to be.
     8CONSOLE MESSAGE: line 2687: TypeError: undefined is not an object (evaluating 'e.message')
     9CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: undefined
     10CONSOLE MESSAGE: line 2687: TypeError: undefined is not an object (evaluating 'e.message')
     11CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: undefined
     12CONSOLE MESSAGE: line 2687: TypeError: undefined is not an object (evaluating 'e.message')
     13CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: undefined
     14CONSOLE MESSAGE: line 2687: TypeError: undefined is not an object (evaluating 'e.message')
     15CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: undefined
     16CONSOLE MESSAGE: line 2687: TypeError: undefined is not an object (evaluating 'e.message')
     17CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: undefined
     18CONSOLE MESSAGE: line 2687: TypeError: undefined is not an object (evaluating 'e.message')
     19CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: undefined
     20CONSOLE MESSAGE: line 2687: TypeError: undefined is not an object (evaluating 'e.message')
     21CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: undefined
     22CONSOLE MESSAGE: line 2687: TypeError: undefined is not an object (evaluating 'e.message')
     23CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: undefined
     24CONSOLE MESSAGE: line 2687: TypeError: undefined is not an object (evaluating 'e.message')
     25CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: undefined
     26CONSOLE MESSAGE: line 2687: TypeError: undefined is not an object (evaluating 'e.message')
     27CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: undefined
     28
     29Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'e.message')
    130
    231PASS Aborting a WritableStream immediately prevents future writes
  • trunk/LayoutTests/streams/reference-implementation/writable-stream-expected.txt

    r194366 r215916  
     1CONSOLE MESSAGE: line 2687: TypeError: undefined is not an object (evaluating 'e.message')
     2CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: undefined
     3
     4Harness Error (FAIL), message = TypeError: undefined is not an object (evaluating 'e.message')
    15
    26PASS error argument is given to start method
  • trunk/LayoutTests/streams/shadowing-Promise.html

    r212147 r215916  
    3232    const PromiseRejectBackup = Promise.reject;
    3333
     34    function handle() { }
     35
    3436    try {
    3537        Promise.reject = function() { assert_unreached("streams should not use this Promise.reject method"); };
    3638
    37         ReadableStream.prototype.cancel.call({}, "reason");
    38         WritableStream.prototype.abort.call({}, "reason");
     39        ReadableStream.prototype.cancel.call({}, "reason").then(handle, handle);
     40        WritableStream.prototype.abort.call({}, "reason").then(handle, handle);
    3941    } finally {
    4042        Promise.reject = PromiseRejectBackup;
  • trunk/LayoutTests/webrtc/libwebrtc/release-while-creating-offer-expected.txt

    r213282 r215916  
     1CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: Argument 1 ('candidate') to RTCPeerConnection.addIceCandidate must be an instance of RTCIceCandidate
    12PASS successfullyParsed is true
    23
  • trunk/LayoutTests/webrtc/libwebrtc/release-while-setting-local-description-expected.txt

    r213282 r215916  
     1CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: TypeError: Argument 1 ('candidate') to RTCPeerConnection.addIceCandidate must be an instance of RTCIceCandidate
     2CONSOLE MESSAGE: line 1: Unhandled Promise Rejection: InvalidStateError (DOM Exception 11): The object is in an invalid state.
    13PASS successfullyParsed is true
    24
  • trunk/Source/JavaScriptCore/ChangeLog

    r215908 r215916  
     12017-04-27  Joseph Pecoraro  <pecoraro@apple.com>
     2
     3        Support for promise rejection events (unhandledrejection)
     4        https://bugs.webkit.org/show_bug.cgi?id=150358
     5        <rdar://problem/28441651>
     6
     7        Reviewed by Saam Barati.
     8
     9        Patch by Joseph Pecoraro and Yusuke Suzuki.
     10
     11        Implement support for promise.[[PromiseIsHandled]] and the
     12        HostPromiseRejectionTracker hook for HTML to track promise rejections:
     13        https://tc39.github.io/ecma262/#sec-host-promise-rejection-tracker
     14        https://html.spec.whatwg.org/multipage/webappapis.html#unhandled-promise-rejections
     15
     16        * builtins/BuiltinNames.h:
     17        New private symbols.
     18
     19        * builtins/PromiseOperations.js:
     20        (globalPrivate.newHandledRejectedPromise):
     21        Utility to create a rejected promise with [[PromiseIsHandled]] to true.
     22
     23        (globalPrivate.rejectPromise):
     24        (globalPrivate.initializePromise):
     25        * builtins/PromisePrototype.js:
     26        (then):
     27        Implement standard behavior of [[PromiseIsHandled]] and the host hook.
     28
     29        * runtime/JSPromise.cpp:
     30        (JSC::JSPromise::isHandled):
     31        * runtime/JSPromise.h:
     32        C++ accessors for the [[PromiseIsHandled]] state.
     33
     34        * bytecode/BytecodeIntrinsicRegistry.cpp:
     35        (JSC::BytecodeIntrinsicRegistry::BytecodeIntrinsicRegistry):
     36        * bytecode/BytecodeIntrinsicRegistry.h:
     37        Expose private values for the Reject / Handle enum values in built-ins.
     38
     39        * jsc.cpp:
     40        * runtime/JSGlobalObject.h:
     41        (JSC::JSGlobalObject::promiseResolveFunction):
     42        Add a new GlobalObjectMethodTable hook matching the promise rejection hook.
     43
     44        * runtime/JSGlobalObject.cpp:
     45        (JSC::JSGlobalObject::init):
     46        (JSC::JSGlobalObject::visitChildren):
     47        * runtime/JSGlobalObjectFunctions.cpp:
     48        (JSC::globalFuncHostPromiseRejectionTracker):
     49        * runtime/JSGlobalObjectFunctions.h:
     50        Plumb the builtin hook through to the optional GlobalObjectMethodTable hook.
     51
     52        * inspector/InjectedScriptSource.js:
     53        (InjectedScript.prototype.createFakeValueDescriptor):
     54        Silence possible rejected promises created internally via Web Inspector.
     55
    1562017-04-27  Saam Barati  <sbarati@apple.com>
    257
  • trunk/Source/JavaScriptCore/builtins/BuiltinNames.h

    r214931 r215916  
    8383    macro(templateRegistryKey) \
    8484    macro(enqueueJob) \
     85    macro(hostPromiseRejectionTracker) \
     86    macro(promiseIsHandled) \
    8587    macro(promiseState) \
    8688    macro(promiseReactions) \
  • trunk/Source/JavaScriptCore/builtins/PromiseOperations.js

    r209455 r215916  
    8686
    8787@globalPrivate
     88function newHandledRejectedPromise(error)
     89{
     90    let promise = @Promise.@reject(error);
     91    promise.@promiseIsHandled = true;
     92    return promise;
     93}
     94
     95@globalPrivate
    8896function triggerPromiseReactions(state, reactions, argument)
    8997{
     
    105113
    106114    @InspectorInstrumentation.promiseRejected(promise, reason, reactions);
     115
     116    if (!promise.@promiseIsHandled)
     117        @hostPromiseRejectionTracker(promise, @promiseRejectionReject);
    107118
    108119    @triggerPromiseReactions(@promiseStateRejected, reactions, reason);
     
    213224    this.@promiseState = @promiseStatePending;
    214225    this.@promiseReactions = [];
     226    this.@promiseIsHandled = false;
    215227
    216228    var resolvingFunctions = @createResolvingFunctions(this);
  • trunk/Source/JavaScriptCore/builtins/PromisePrototype.js

    r209455 r215916  
    5353    if (state === @promiseStatePending)
    5454        @putByValDirect(this.@promiseReactions, this.@promiseReactions.length, reaction);
    55     else
     55    else {
     56        if (state === @promiseStateRejected && !this.@promiseIsHandled)
     57            @hostPromiseRejectionTracker(this, @promiseRejectionHandle);
    5658        @enqueueJob(@promiseReactionJob, [state, reaction, this.@promiseResult]);
     59    }
     60
     61    this.@promiseIsHandled = true;
    5762
    5863    return resultCapability.@promise;
  • trunk/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.cpp

    r212019 r215916  
    3333#include "JSCJSValueInlines.h"
    3434#include "JSGeneratorFunction.h"
     35#include "JSGlobalObject.h"
    3536#include "JSModuleLoader.h"
    3637#include "JSPromise.h"
     
    6263    m_ModuleLink.set(m_vm, jsNumber(static_cast<unsigned>(JSModuleLoader::Status::Link)));
    6364    m_ModuleReady.set(m_vm, jsNumber(static_cast<unsigned>(JSModuleLoader::Status::Ready)));
     65    m_promiseRejectionReject.set(m_vm, jsNumber(static_cast<unsigned>(JSPromiseRejectionOperation::Reject)));
     66    m_promiseRejectionHandle.set(m_vm, jsNumber(static_cast<unsigned>(JSPromiseRejectionOperation::Handle)));
    6467    m_promiseStatePending.set(m_vm, jsNumber(static_cast<unsigned>(JSPromise::Status::Pending)));
    6568    m_promiseStateFulfilled.set(m_vm, jsNumber(static_cast<unsigned>(JSPromise::Status::Fulfilled)));
  • trunk/Source/JavaScriptCore/bytecode/BytecodeIntrinsicRegistry.h

    r212019 r215916  
    7474    macro(ModuleLink) \
    7575    macro(ModuleReady) \
     76    macro(promiseRejectionReject) \
     77    macro(promiseRejectionHandle) \
    7678    macro(promiseStatePending) \
    7779    macro(promiseStateFulfilled) \
  • trunk/Source/JavaScriptCore/inspector/InjectedScriptSource.js

    r210910 r215916  
    590590                if (symbol)
    591591                    descriptor.symbol = symbol;
     592                // Silence any possible unhandledrejection exceptions created from accessing a native accessor with a wrong this object.
     593                if (descriptor.value instanceof Promise)
     594                    descriptor.value.catch(function(){});
    592595                return descriptor;
    593596            } catch (e) {
  • trunk/Source/JavaScriptCore/jsc.cpp

    r215896 r215916  
    14321432    &shouldInterruptScript,
    14331433    &javaScriptRuntimeFlags,
    1434     nullptr,
     1434    nullptr, // queueTaskToEventLoop
    14351435    &shouldInterruptScriptBeforeTimeout,
    14361436    &moduleLoaderImportModule,
    14371437    &moduleLoaderResolve,
    14381438    &moduleLoaderFetch,
    1439     nullptr,
    1440     nullptr,
    1441     nullptr
     1439    nullptr, // moduleLoaderInstantiate
     1440    nullptr, // moduleLoaderEvaluate
     1441    nullptr, // promiseRejectionTracker
     1442    nullptr, // defaultLanguage
    14421443};
    14431444
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp

    r215673 r215916  
    249249    &shouldInterruptScript,
    250250    &javaScriptRuntimeFlags,
    251     nullptr,
     251    nullptr, // queueTaskToEventLoop
    252252    &shouldInterruptScriptBeforeTimeout,
    253     nullptr,
    254     nullptr,
    255     nullptr,
    256     nullptr,
    257     nullptr,
    258     nullptr
     253    nullptr, // moduleLoaderImportModule
     254    nullptr, // moduleLoaderResolve
     255    nullptr, // moduleLoaderFetch
     256    nullptr, // moduleLoaderInstantiate
     257    nullptr, // moduleLoaderEvaluate
     258    nullptr, // promiseRejectionTracker
     259    nullptr, // defaultLanguage
    259260};
    260261
     
    814815        GlobalPropertyInfo(vm.propertyNames->builtinNames().mapIteratorNextPrivateName(), JSFunction::create(vm, this, 0, String(), privateFuncMapIteratorNext), DontEnum | DontDelete | ReadOnly),
    815816
     817        GlobalPropertyInfo(vm.propertyNames->builtinNames().hostPromiseRejectionTrackerPrivateName(), JSFunction::create(vm, this, 2, String(), globalFuncHostPromiseRejectionTracker), DontEnum | DontDelete | ReadOnly),
    816818        GlobalPropertyInfo(vm.propertyNames->builtinNames().InspectorInstrumentationPrivateName(), InspectorInstrumentationObject::create(vm, this, InspectorInstrumentationObject::createStructure(vm, this, m_objectPrototype.get())), DontEnum | DontDelete | ReadOnly),
    817819        GlobalPropertyInfo(vm.propertyNames->builtinNames().MapPrivateName(), mapConstructor, DontEnum | DontDelete | ReadOnly),
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h

    r215777 r215916  
    162162#undef DECLARE_SIMPLE_BUILTIN_TYPE
    163163
    164 class JSInternalPromise;
    165 class InternalPromisePrototype;
    166 class InternalPromiseConstructor;
    167 
    168 typedef Vector<ExecState*, 16> ExecStateStack;
     164enum class JSPromiseRejectionOperation : unsigned {
     165    Reject, // When a promise is rejected without any handlers.
     166    Handle, // When a handler is added to a rejected promise for the first time.
     167};
    169168
    170169struct GlobalObjectMethodTable {
     
    198197    typedef JSValue (*ModuleLoaderEvaluatePtr)(JSGlobalObject*, ExecState*, JSModuleLoader*, JSValue, JSValue, JSValue);
    199198    ModuleLoaderEvaluatePtr moduleLoaderEvaluate;
     199
     200    typedef void (*PromiseRejectionTrackerPtr)(JSGlobalObject*, ExecState*, JSPromise*, JSPromiseRejectionOperation);
     201    PromiseRejectionTrackerPtr promiseRejectionTracker;
    200202
    201203    typedef String (*DefaultLanguageFunctionPtr)();
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp

    r214143 r215916  
    3131#include "IndirectEvalExecutable.h"
    3232#include "Interpreter.h"
     33#include "JSCInlines.h"
    3334#include "JSFunction.h"
    3435#include "JSGlobalObject.h"
    3536#include "JSInternalPromise.h"
    3637#include "JSModuleLoader.h"
     38#include "JSPromise.h"
    3739#include "JSPromiseDeferred.h"
    3840#include "JSString.h"
     
    4547#include "Parser.h"
    4648#include "StackVisitor.h"
    47 #include <wtf/dtoa.h>
    4849#include <stdio.h>
    4950#include <stdlib.h>
     
    5354#include <wtf/MathExtras.h>
    5455#include <wtf/StringExtras.h>
     56#include <wtf/dtoa.h>
    5557#include <wtf/text/StringBuilder.h>
    5658#include <wtf/unicode/UTF8.h>
     
    296298    if (number >= mantissaOverflowLowerBound)
    297299        number = parseIntOverflow(firstDigitPosition, data - firstDigitPosition, 8);
    298    
     300
    299301    return number;
    300302}
     
    373375            break;
    374376    }
    375    
     377
    376378    // Empty string.
    377379    if (characters == endCharacters)
    378380        return 0.0;
    379    
     381
    380382    double number;
    381383    if (characters[0] == '0' && characters + 2 < endCharacters) {
     
    390392    } else
    391393        number = jsStrDecimalLiteral(characters, endCharacters);
    392    
     394
    393395    // Allow trailing white space.
    394396    for (; characters < endCharacters; ++characters) {
     
    398400    if (characters != endCharacters)
    399401        return PNaN;
    400    
     402
    401403    return number;
    402404}
     
    490492        LiteralParser<UChar> preparser(exec, s.characters16(), s.length(), NonStrictJSON);
    491493        if (JSValue parsedObject = preparser.tryLiteralParse())
    492             return JSValue::encode(parsedObject);       
     494            return JSValue::encode(parsedObject);
    493495    }
    494496
     
    683685    return throwVMTypeError(exec, scope);
    684686}
    685    
     687
    686688EncodedJSValue JSC_HOST_CALL globalFuncThrowTypeErrorArgumentsCalleeAndCaller(ExecState* exec)
    687689{
     
    734736    bool shouldThrowIfCantSet = true;
    735737    thisObject->setPrototype(vm, exec, value, shouldThrowIfCantSet);
     738    return JSValue::encode(jsUndefined());
     739}
     740
     741EncodedJSValue JSC_HOST_CALL globalFuncHostPromiseRejectionTracker(ExecState* exec)
     742{
     743    JSGlobalObject* globalObject = exec->lexicalGlobalObject();
     744    VM& vm = globalObject->vm();
     745    auto scope = DECLARE_THROW_SCOPE(vm);
     746
     747    if (!globalObject->globalObjectMethodTable()->promiseRejectionTracker)
     748        return JSValue::encode(jsUndefined());
     749
     750    JSPromise* promise = jsCast<JSPromise*>(exec->argument(0));
     751    JSValue operationValue = exec->argument(1);
     752
     753    ASSERT(operationValue.isNumber());
     754    auto operation = static_cast<JSPromiseRejectionOperation>(operationValue.toUInt32(exec));
     755    ASSERT(operation == JSPromiseRejectionOperation::Reject || operation == JSPromiseRejectionOperation::Handle);
     756    ASSERT(!scope.exception());
     757
     758    globalObject->globalObjectMethodTable()->promiseRejectionTracker(globalObject, exec, promise, operation);
     759    RETURN_IF_EXCEPTION(scope, { });
     760
    736761    return JSValue::encode(jsUndefined());
    737762}
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.h

    r214038 r215916  
    5050EncodedJSValue JSC_HOST_CALL globalFuncProtoGetter(ExecState*);
    5151EncodedJSValue JSC_HOST_CALL globalFuncProtoSetter(ExecState*);
     52EncodedJSValue JSC_HOST_CALL globalFuncHostPromiseRejectionTracker(ExecState*);
    5253EncodedJSValue JSC_HOST_CALL globalFuncBuiltinLog(ExecState*);
    5354EncodedJSValue JSC_HOST_CALL globalFuncImportModule(ExecState*);
  • trunk/Source/JavaScriptCore/runtime/JSPromise.cpp

    r209455 r215916  
    8686}
    8787
     88bool JSPromise::isHandled(VM& vm) const
     89{
     90    JSValue value = getDirect(vm, vm.propertyNames->builtinNames().promiseIsHandledPrivateName());
     91    ASSERT(value.isBoolean());
     92    return value.asBoolean();
     93}
     94
    8895} // namespace JSC
  • trunk/Source/JavaScriptCore/runtime/JSPromise.h

    r206525 r215916  
    4646
    4747    Status status(VM&) const;
    48     JSValue result(VM&) const;
     48    JS_EXPORT_PRIVATE JSValue result(VM&) const;
     49    JS_EXPORT_PRIVATE bool isHandled(VM&) const;
    4950
    5051    // Initialize the promise with the executor.
  • trunk/Source/WebCore/CMakeLists.txt

    r215907 r215916  
    467467    dom/ProcessingInstruction.idl
    468468    dom/ProgressEvent.idl
     469    dom/PromiseRejectionEvent.idl
    469470    dom/Range.idl
    470471    dom/RequestAnimationFrameCallback.idl
     
    15371538    dom/ProcessingInstruction.cpp
    15381539    dom/ProgressEvent.cpp
     1540    dom/PromiseRejectionEvent.cpp
    15391541    dom/PseudoElement.cpp
    15401542    dom/QualifiedName.cpp
    15411543    dom/RadioButtonGroups.cpp
    15421544    dom/Range.cpp
     1545    dom/RejectedPromiseTracker.cpp
    15431546    dom/ScopedEventQueue.cpp
    15441547    dom/ScriptElement.cpp
  • trunk/Source/WebCore/ChangeLog

    r215914 r215916  
     12017-04-27  Joseph Pecoraro  <pecoraro@apple.com>
     2
     3        Support for promise rejection events (unhandledrejection)
     4        https://bugs.webkit.org/show_bug.cgi?id=150358
     5        <rdar://problem/28441651>
     6
     7        Reviewed by Saam Barati.
     8
     9        Patch by Joseph Pecoraro and Yusuke Suzuki.
     10
     11        Implement support for the `onunhandledrejection` and `rejectionhandled` events.
     12        They dispatch a new PromiseRejectionEvent using the ES6 HostPromiseRejectionTracker hook:
     13        https://tc39.github.io/ecma262/#sec-host-promise-rejection-tracker
     14        https://html.spec.whatwg.org/multipage/webappapis.html#unhandled-promise-rejections
     15
     16        This is currently implemented only for Documents and not yet Web Workers.
     17
     18        Tests: js/dom/unhandled-promise-rejection-basic.html
     19               js/dom/unhandled-promise-rejection-bindings-type-error.html
     20               js/dom/unhandled-promise-rejection-console-no-report.html
     21               js/dom/unhandled-promise-rejection-console-report.html
     22               js/dom/unhandled-promise-rejection-handle-during-event.html
     23               js/dom/unhandled-promise-rejection-handle-in-handler.html
     24               js/dom/unhandled-promise-rejection-handle.html
     25               js/dom/unhandled-promise-rejection-order.html
     26
     27        * CMakeLists.txt:
     28        * DerivedSources.cpp:
     29        * DerivedSources.make:
     30        * WebCore.xcodeproj/project.pbxproj:
     31        * dom/DOMAllInOne.cpp:
     32        New files.
     33
     34        * bindings/scripts/CodeGenerator.pm:
     35        (IsPromiseType):
     36        * bindings/scripts/CodeGeneratorJS.pm:
     37        (AddToIncludesForIDLType):
     38        (GetBaseIDLType):
     39        Binding support for Promise<T> attributes.
     40
     41        * bindings/js/JSDOMConvert.h:
     42        * bindings/js/JSDOMConvertPromise.h: Copied from Source/JavaScriptCore/runtime/JSPromise.h.
     43        (WebCore::Converter<IDLPromise<T>>::convert):
     44        (WebCore::JSConverter<IDLPromise<T>>::convert):
     45        Promise<T> binding conversion is currently unimplemented, which only means
     46        web developers creating their own PromiseRejectionEvent will not get
     47        autowrapping of values assigned to `promise` in event initialization.
     48        Engine generated events will have expected behavior.
     49
     50        * bindings/js/JSDOMWindowBase.cpp:
     51        (WebCore::JSDOMWindowBase::promiseRejectionTracker):
     52        * bindings/js/JSDOMWindowBase.h:
     53        * bindings/js/JSWorkerGlobalScopeBase.cpp:
     54        Implement HostPromiseRejectionTracker hook for Document but not Worker.
     55        Passes through to the ScriptExecutionContext's tracker.
     56
     57        * bindings/js/JSMainThreadExecState.cpp:
     58        (WebCore::JSMainThreadExecState::didLeaveScriptContext):
     59        * bindings/js/JSMainThreadExecState.h:
     60        (WebCore::JSMainThreadExecState::~JSMainThreadExecState):
     61        When completing script execution and performing microtasks notify
     62        about rejected promises. Technically this should go inside of
     63        performing a microtask checkpoint, except lacking EventLoop
     64        concepts we use ScriptExecutionState.
     65
     66        * dom/EventNames.h:
     67        * dom/EventNames.in:
     68        * dom/PromiseRejectionEvent.cpp: Added.
     69        (WebCore::PromiseRejectionEvent::PromiseRejectionEvent):
     70        (WebCore::PromiseRejectionEvent::~PromiseRejectionEvent):
     71        * dom/PromiseRejectionEvent.h: Added.
     72        * dom/PromiseRejectionEvent.idl: Added.
     73        New PromiseRejectionEvent event interface.
     74
     75        * dom/GlobalEventHandlers.idl:
     76        New onunhandledrejection and onrejectionhandled.
     77
     78        * dom/RejectedPromiseTracker.cpp: Added.
     79        (WebCore::RejectedPromise::RejectedPromise):
     80        (WebCore::RejectedPromise::globalObject):
     81        (WebCore::RejectedPromise::promise):
     82        (WebCore::UnhandledPromise::UnhandledPromise):
     83        (WebCore::UnhandledPromise::callStack):
     84        (WebCore::RejectedPromiseTracker::RejectedPromiseTracker):
     85        (WebCore::RejectedPromiseTracker::~RejectedPromiseTracker):
     86        (WebCore::createScriptCallStackFromReason):
     87        (WebCore::RejectedPromiseTracker::promiseRejected):
     88        (WebCore::RejectedPromiseTracker::promiseHandled):
     89        (WebCore::RejectedPromiseTracker::processQueueSoon):
     90        (WebCore::RejectedPromiseTracker::reportUnhandledRejections):
     91        (WebCore::RejectedPromiseTracker::reportRejectionHandled):
     92        * dom/RejectedPromiseTracker.h: Added.
     93        Track and report rejected promises. The promises are tracked weakly
     94        allowing them to be collected before they are reported. When reporting
     95        we dispatch PromiseRejectionEvent events, and if the default is not
     96        prevented we log a message to the console.
     97
     98        * dom/ScriptExecutionContext.cpp:
     99        (WebCore::ScriptExecutionContext::reportUnhandledPromiseRejection):
     100        (WebCore::ScriptExecutionContext::ensureRejectedPromiseTrackerSlow):
     101        * dom/ScriptExecutionContext.h:
     102        (WebCore::ScriptExecutionContext::ensureRejectedPromiseTracker):
     103        Each ScriptExecutionContext can own a rejected promise tracker.
     104
     105        * html/HTMLMediaElement.cpp:
     106        (WebCore::HTMLMediaElement::pauseInternal):
     107        https://html.spec.whatwg.org/multipage/embedded-content.html#internal-pause-steps
     108        Internal pause steps say to timeupdate, pause, and rejecting pending play promises
     109        should all happen in a queued task. Here the first two actions are already scheduled
     110        on tasks, but rejecting play promises was not being done in a task, so this makes
     111        that change.
     112
     113        * Modules/streams/ReadableStream.js:
     114        (pipeThrough):
     115        * Modules/streams/ReadableStreamInternals.js:
     116        (readableStreamReaderGenericInitialize):
     117        (readableStreamError):
     118        (readableStreamReaderGenericRelease):
     119        Satisfy parts of the Streams specification which state to set the
     120        [[PromiseIsHandled]] internal state of promises created internally
     121        by the Streams APIs. This prevents some internal promises from
     122        appearing as unhandled promise rejections.
     123
    11242017-04-27  Chris Dumez  <cdumez@apple.com>
    2125
  • trunk/Source/WebCore/DerivedSources.cpp

    r215429 r215916  
    380380#include "JSProcessingInstruction.cpp"
    381381#include "JSProgressEvent.cpp"
     382#include "JSPromiseRejectionEvent.cpp"
    382383#include "JSRadioNodeList.cpp"
    383384#include "JSRange.cpp"
  • trunk/Source/WebCore/DerivedSources.make

    r215629 r215916  
    404404    $(WebCore)/dom/ProcessingInstruction.idl \
    405405    $(WebCore)/dom/ProgressEvent.idl \
    406     $(WebCore)/dom/ProgressEvent.idl \
     406    $(WebCore)/dom/PromiseRejectionEvent.idl \
    407407    $(WebCore)/dom/Range.idl \
    408408    $(WebCore)/dom/RequestAnimationFrameCallback.idl \
  • trunk/Source/WebCore/Modules/streams/ReadableStream.js

    r215429 r215916  
    111111    const writable = streams.writable;
    112112    const readable = streams.readable;
    113     this.pipeTo(writable, options);
     113    const promise = this.pipeTo(writable, options);
     114    if (@isPromise(promise))
     115        promise.@promiseIsHandled = true;
    114116    return readable;
    115117}
  • trunk/Source/WebCore/Modules/streams/ReadableStreamInternals.js

    r215429 r215916  
    5555    else {
    5656        @assert(stream.@state === @streamErrored);
    57         reader.@closedPromiseCapability = { @promise: @Promise.@reject(stream.@storedError) };
     57        reader.@closedPromiseCapability = { @promise: @newHandledRejectedPromise(stream.@storedError) };
    5858    }
    5959}
     
    280280
    281281    reader.@closedPromiseCapability.@reject.@call(@undefined, error);
     282    reader.@closedPromiseCapability.@promise.@promiseIsHandled = true;
    282283}
    283284
     
    494495    @assert(reader.@ownerReadableStream.@reader === reader);
    495496
    496     if (reader.@ownerReadableStream.@state === @streamReadable)
     497    if (reader.@ownerReadableStream.@state === @streamReadable) {
    497498        reader.@closedPromiseCapability.@reject.@call(@undefined, new @TypeError("releasing lock of reader whose stream is still in readable state"));
    498     else
    499         reader.@closedPromiseCapability = { @promise: @Promise.@reject(new @TypeError("reader released lock")) };
     499        reader.@closedPromiseCapability.@promise.@promiseIsHandled = true;
     500    } else
     501        reader.@closedPromiseCapability = { @promise: @newHandledRejectedPromise(new @TypeError("reader released lock")) };
    500502
    501503    reader.@ownerReadableStream.@reader = @undefined;
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r215907 r215916  
    43574357                A5732B0A136A161D005C8D7C /* DateComponents.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A5732B08136A161D005C8D7C /* DateComponents.cpp */; };
    43584358                A5732B0B136A161D005C8D7C /* DateComponents.h in Headers */ = {isa = PBXBuildFile; fileRef = A5732B09136A161D005C8D7C /* DateComponents.h */; settings = {ATTRIBUTES = (Private, ); }; };
     4359                A578F4351DE00EEB003DFC6A /* PromiseRejectionEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = A578F4331DE00ED6003DFC6A /* PromiseRejectionEvent.h */; };
     4360                A578F4361DE00EED003DFC6A /* PromiseRejectionEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A578F4321DE00ED6003DFC6A /* PromiseRejectionEvent.cpp */; };
     4361                A578F43B1DE01421003DFC6A /* JSPromiseRejectionEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A578F4391DE013FB003DFC6A /* JSPromiseRejectionEvent.cpp */; };
     4362                A578F43C1DE01423003DFC6A /* JSPromiseRejectionEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = A578F43A1DE013FB003DFC6A /* JSPromiseRejectionEvent.h */; };
     4363                A578F43F1DE0B630003DFC6A /* RejectedPromiseTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = A578F43E1DE0B62B003DFC6A /* RejectedPromiseTracker.h */; settings = {ATTRIBUTES = (Private, ); }; };
     4364                A578F4401DE0B634003DFC6A /* RejectedPromiseTracker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A578F43D1DE0B62B003DFC6A /* RejectedPromiseTracker.cpp */; };
    43594365                A57FD71B1DB9423E006AE24B /* WorkerRuntimeAgent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A57FD7191DB94236006AE24B /* WorkerRuntimeAgent.cpp */; };
    43604366                A57FD71C1DB9423E006AE24B /* WorkerRuntimeAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = A57FD71A1DB94236006AE24B /* WorkerRuntimeAgent.h */; };
     
    66576663                E3150EA71DA7219300194012 /* DOMJITHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = E3150EA51DA7218D00194012 /* DOMJITHelpers.h */; };
    66586664                E318039D1DC40099009932C2 /* JSDynamicDowncast.h in Headers */ = {isa = PBXBuildFile; fileRef = E3A5872E1DC3F52600F607A6 /* JSDynamicDowncast.h */; settings = {ATTRIBUTES = (Private, ); }; };
     6665                E323CFFA1E5AF6AF00F0B4A0 /* JSDOMConvertPromise.h in Headers */ = {isa = PBXBuildFile; fileRef = E323CFF91E5AF6A500F0B4A0 /* JSDOMConvertPromise.h */; settings = {ATTRIBUTES = (Private, ); }; };
    66596666                E3565B7B1DC2D6C900217DBD /* JSEventCustom.h in Headers */ = {isa = PBXBuildFile; fileRef = E34EE49F1DC2D57500EAA9D3 /* JSEventCustom.h */; settings = {ATTRIBUTES = (Private, ); }; };
    66606667                E35802B61DC8435D00A9773C /* DOMJITIDLTypeFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = E35802B51DC8435800A9773C /* DOMJITIDLTypeFilter.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    1256012567                A5732B08136A161D005C8D7C /* DateComponents.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DateComponents.cpp; sourceTree = "<group>"; };
    1256112568                A5732B09136A161D005C8D7C /* DateComponents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DateComponents.h; sourceTree = "<group>"; };
     12569                A578F4321DE00ED6003DFC6A /* PromiseRejectionEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PromiseRejectionEvent.cpp; sourceTree = "<group>"; };
     12570                A578F4331DE00ED6003DFC6A /* PromiseRejectionEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PromiseRejectionEvent.h; sourceTree = "<group>"; };
     12571                A578F4341DE00ED6003DFC6A /* PromiseRejectionEvent.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = PromiseRejectionEvent.idl; sourceTree = "<group>"; };
     12572                A578F4391DE013FB003DFC6A /* JSPromiseRejectionEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSPromiseRejectionEvent.cpp; sourceTree = "<group>"; };
     12573                A578F43A1DE013FB003DFC6A /* JSPromiseRejectionEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSPromiseRejectionEvent.h; sourceTree = "<group>"; };
     12574                A578F43D1DE0B62B003DFC6A /* RejectedPromiseTracker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RejectedPromiseTracker.cpp; sourceTree = "<group>"; };
     12575                A578F43E1DE0B62B003DFC6A /* RejectedPromiseTracker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RejectedPromiseTracker.h; sourceTree = "<group>"; };
    1256212576                A57FD7191DB94236006AE24B /* WorkerRuntimeAgent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WorkerRuntimeAgent.cpp; sourceTree = "<group>"; };
    1256312577                A57FD71A1DB94236006AE24B /* WorkerRuntimeAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WorkerRuntimeAgent.h; sourceTree = "<group>"; };
     
    1520015214                E307DED31D81E4ED00141CAF /* LoadableModuleScript.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LoadableModuleScript.h; sourceTree = "<group>"; };
    1520115215                E3150EA51DA7218D00194012 /* DOMJITHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMJITHelpers.h; sourceTree = "<group>"; };
     15216                E323CFF91E5AF6A500F0B4A0 /* JSDOMConvertPromise.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSDOMConvertPromise.h; sourceTree = "<group>"; };
    1520215217                E334825E1DC93AA0009C9544 /* DOMJITAbstractHeapRepository.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DOMJITAbstractHeapRepository.h; sourceTree = "<group>"; };
    1520315218                E34EE49F1DC2D57500EAA9D3 /* JSEventCustom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSEventCustom.h; sourceTree = "<group>"; };
     
    1965919674                                7C8E34A21E4A338E0054CE23 /* JSDOMConvertNumbers.h */,
    1966019675                                7C8E34A31E4A338E0054CE23 /* JSDOMConvertObject.h */,
     19676                                E323CFF91E5AF6A500F0B4A0 /* JSDOMConvertPromise.h */,
    1966119677                                7C8E34A41E4A338E0054CE23 /* JSDOMConvertRecord.h */,
    1966219678                                7C8E34A51E4A338E0054CE23 /* JSDOMConvertSequences.h */,
     
    2203122047                                5189F01B10B37BD900F3C739 /* JSPopStateEvent.cpp */,
    2203222048                                5189F01C10B37BD900F3C739 /* JSPopStateEvent.h */,
     22049                                A578F4391DE013FB003DFC6A /* JSPromiseRejectionEvent.cpp */,
     22050                                A578F43A1DE013FB003DFC6A /* JSPromiseRejectionEvent.h */,
    2203322051                                CED06ACE1C77754800FDFAF1 /* JSSecurityPolicyViolationEvent.cpp */,
    2203422052                                CED06ACF1C77754800FDFAF1 /* JSSecurityPolicyViolationEvent.h */,
     
    2572625744                                E4B41E020CBF8EAA00AF2ECE /* ProgressEvent.h */,
    2572725745                                E4B41E030CBF8EAA00AF2ECE /* ProgressEvent.idl */,
     25746                                A578F4321DE00ED6003DFC6A /* PromiseRejectionEvent.cpp */,
     25747                                A578F4331DE00ED6003DFC6A /* PromiseRejectionEvent.h */,
     25748                                A578F4341DE00ED6003DFC6A /* PromiseRejectionEvent.idl */,
    2572825749                                FF945EC9161F7F3600971BC8 /* PseudoElement.cpp */,
    2572925750                                FF945ECA161F7F3600971BC8 /* PseudoElement.h */,
     
    2573825759                                A84D827B11D333ED00972990 /* RawDataDocumentParser.h */,
    2573925760                                85031B360A44EFC700F992E0 /* RegisteredEventListener.h */,
     25761                                A578F43D1DE0B62B003DFC6A /* RejectedPromiseTracker.cpp */,
     25762                                A578F43E1DE0B62B003DFC6A /* RejectedPromiseTracker.h */,
    2574025763                                A76E5F7E135E0DCF00A69837 /* RenderedDocumentMarker.h */,
    2574125764                                4998AEC413F9D0EA0090B1AA /* RequestAnimationFrameCallback.h */,
     
    2677426797                                BC23EE920DAED2BC009FDC91 /* CSSImageGeneratorValue.h in Headers */,
    2677526798                                9393E600151A99F200066F06 /* CSSImageSetValue.h in Headers */,
     26799                                A578F4351DE00EEB003DFC6A /* PromiseRejectionEvent.h in Headers */,
    2677626800                                A80E6CFA0A1989CA007FB8C5 /* CSSImageValue.h in Headers */,
    2677726801                                A80E6CF60A1989CA007FB8C5 /* CSSImportRule.h in Headers */,
     
    2695526979                                A8185F3909765766005826D9 /* DocumentType.h in Headers */,
    2695626980                                973889A1116EA9DC00ADF313 /* DocumentWriter.h in Headers */,
     26981                                A578F43C1DE01423003DFC6A /* JSPromiseRejectionEvent.h in Headers */,
    2695726982                                1A8F6BC30DB55CDC001DB794 /* DOMApplicationCache.h in Headers */,
    2695826983                                BC60D6E90D28D83400B9918F /* DOMCoreException.h in Headers */,
     
    2875328778                                493E5E0912D6420500020081 /* PlatformCALayerClient.h in Headers */,
    2875428779                                2D70BA1318074DDF0001908A /* PlatformCALayerCocoa.h in Headers */,
     28780                                A578F43F1DE0B630003DFC6A /* RejectedPromiseTracker.h in Headers */,
    2875528781                                A14978711ABAF3A500CEF7E4 /* PlatformContentFilter.h in Headers */,
    2875628782                                E1424C8A164B3B4E00F32D40 /* PlatformCookieJar.h in Headers */,
     
    2952529551                                83C1D428178D5AB400141E68 /* SVGPathSegCurvetoCubicRel.h in Headers */,
    2952629552                                B2227A690D00BF220071B782 /* SVGPathSegCurvetoCubicSmooth.h in Headers */,
     29553                                E323CFFA1E5AF6AF00F0B4A0 /* JSDOMConvertPromise.h in Headers */,
    2952729554                                83C1D429178D5AB400141E68 /* SVGPathSegCurvetoCubicSmoothAbs.h in Headers */,
    2952829555                                83C1D42A178D5AB400141E68 /* SVGPathSegCurvetoCubicSmoothRel.h in Headers */,
     
    3157731604                                70F546E8B8B5D7DC54EE144E /* JSBeforeUnloadEvent.cpp in Sources */,
    3157831605                                FDF09DC81399B62200688E5B /* JSBiquadFilterNode.cpp in Sources */,
     31606                A578F43B1DE01421003DFC6A /* JSPromiseRejectionEvent.cpp in Sources */,
    3157931607                                2E2D99CD10E2BBDA00496337 /* JSBlob.cpp in Sources */,
    3158031608                                A15D751A1E68F89E00A35FBC /* JSBlobCallback.cpp in Sources */,
     
    3246232490                                2D9BF7461DBFDC47007A7D99 /* MediaKeys.cpp in Sources */,
    3246332491                                2D9BF7451DBFDC44007A7D99 /* MediaKeySession.cpp in Sources */,
     32492                                A578F4401DE0B634003DFC6A /* RejectedPromiseTracker.cpp in Sources */,
    3246432493                                2D9BF7441DBFDC41007A7D99 /* MediaKeyStatusMap.cpp in Sources */,
    3246532494                                2D9BF7431DBFDC3E007A7D99 /* MediaKeySystemAccess.cpp in Sources */,
     
    3372033749                                A833C7CC0A2CF07400D57664 /* XLinkNames.cpp in Sources */,
    3372133750                                00B9318713BA8DB30035A948 /* XMLDocumentParser.cpp in Sources */,
     33751                                A578F4361DE00EED003DFC6A /* PromiseRejectionEvent.cpp in Sources */,
    3372233752                                00B9318913BA8DBC0035A948 /* XMLDocumentParserLibxml2.cpp in Sources */,
    3372333753                                00B9318B13BA8DC90035A948 /* XMLDocumentParserScope.cpp in Sources */,
  • trunk/Source/WebCore/bindings/js/JSDOMConvert.h

    r211821 r215916  
    4141#include "JSDOMConvertNumbers.h"
    4242#include "JSDOMConvertObject.h"
     43#include "JSDOMConvertPromise.h"
    4344#include "JSDOMConvertRecord.h"
    4445#include "JSDOMConvertSequences.h"
  • trunk/Source/WebCore/bindings/js/JSDOMConvertPromise.h

    r215915 r215916  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2017 Yusuke Suzuki <utatane.tea@gmail.com>
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2626#pragma once
    2727
    28 #include "JSObject.h"
     28#include "IDLTypes.h"
     29#include "JSDOMConvertBase.h"
    2930
    30 namespace JSC {
     31namespace WebCore {
    3132
    32 class JSPromise : public JSNonFinalObject {
    33 public:
    34     typedef JSNonFinalObject Base;
     33// FIXME: Implement IDLPromise<> conversions.
     34// https://bugs.webkit.org/show_bug.cgi?id=166752
     35template<typename T>
     36struct Converter<IDLPromise<T>> : DefaultConverter<IDLPromise<T>> {
     37    using ReturnType = JSC::JSValue;
    3538
    36     static JSPromise* create(VM&, Structure*);
    37     static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
    38 
    39     DECLARE_EXPORT_INFO;
    40 
    41     enum class Status : unsigned {
    42         Pending = 1,
    43         Fulfilled,
    44         Rejected
    45     };
    46 
    47     Status status(VM&) const;
    48     JSValue result(VM&) const;
    49 
    50     // Initialize the promise with the executor.
    51     // This may raise a JS exception.
    52     void initialize(ExecState*, JSGlobalObject*, JSValue executor);
    53 
    54 protected:
    55     JSPromise(VM&, Structure*);
    56     void finishCreation(VM&);
     39    static JSC::JSValue convert(JSC::ExecState&, JSC::JSValue value)
     40    {
     41        return value;
     42    }
    5743};
    5844
    59 } // namespace JSC
     45template<typename T>
     46struct JSConverter<IDLPromise<T>> {
     47    using Type = JSC::JSValue;
     48    static constexpr bool needsState = false;
     49    static constexpr bool needsGlobalObject = false;
     50
     51    static JSC::JSValue convert(JSC::JSValue value)
     52    {
     53        return value;
     54    }
     55};
     56
     57} // namespace WebCore
  • trunk/Source/WebCore/bindings/js/JSDOMWindowBase.cpp

    r215904 r215916  
    3939#include "Logging.h"
    4040#include "Page.h"
     41#include "RejectedPromiseTracker.h"
    4142#include "RuntimeApplicationChecks.h"
    4243#include "ScriptController.h"
     
    4748#include <bytecode/CodeBlock.h>
    4849#include <heap/StrongInlines.h>
     50#include <runtime/JSInternalPromise.h>
    4951#include <runtime/JSInternalPromiseDeferred.h>
    5052#include <runtime/Microtask.h>
     
    7072    &moduleLoaderResolve,
    7173    &moduleLoaderFetch,
    72     nullptr,
     74    nullptr, // moduleLoaderInstantiate
    7375    &moduleLoaderEvaluate,
     76    &promiseRejectionTracker,
    7477    &defaultLanguage
    7578};
     
    356359}
    357360
    358 
    359361JSC::JSInternalPromise* JSDOMWindowBase::moduleLoaderResolve(JSC::JSGlobalObject* globalObject, JSC::ExecState* exec, JSC::JSModuleLoader* moduleLoader, JSC::JSValue moduleName, JSC::JSValue importerModuleKey, JSC::JSValue scriptFetcher)
    360362{
     
    392394}
    393395
     396void JSDOMWindowBase::promiseRejectionTracker(JSGlobalObject* jsGlobalObject, ExecState* exec, JSPromise* promise, JSPromiseRejectionOperation operation)
     397{
     398    // https://html.spec.whatwg.org/multipage/webappapis.html#the-hostpromiserejectiontracker-implementation
     399
     400    VM& vm = exec->vm();
     401    auto& globalObject = *JSC::jsCast<JSDOMWindowBase*>(jsGlobalObject);
     402    auto* context = globalObject.scriptExecutionContext();
     403    if (!context)
     404        return;
     405
     406    // InternalPromises should not be exposed to user scripts.
     407    if (JSC::jsDynamicCast<JSC::JSInternalPromise*>(vm, promise))
     408        return;
     409
     410    // FIXME: If script has muted errors (cross origin), terminate these steps.
     411    // <https://webkit.org/b/171415> Implement the `muted-errors` property of Scripts to avoid onerror/onunhandledrejection for cross-origin scripts
     412
     413    switch (operation) {
     414    case JSPromiseRejectionOperation::Reject:
     415        context->ensureRejectedPromiseTracker().promiseRejected(*exec, globalObject, *promise);
     416        break;
     417    case JSPromiseRejectionOperation::Handle:
     418        context->ensureRejectedPromiseTracker().promiseHandled(*exec, globalObject, *promise);
     419        break;
     420    }
     421}
     422
    394423} // namespace WebCore
  • trunk/Source/WebCore/bindings/js/JSDOMWindowBase.h

    r215904 r215916  
    8181        static JSC::JSValue moduleLoaderEvaluate(JSC::JSGlobalObject*, JSC::ExecState*, JSC::JSModuleLoader*, JSC::JSValue, JSC::JSValue, JSC::JSValue);
    8282        static JSC::JSInternalPromise* moduleLoaderImportModule(JSC::JSGlobalObject*, JSC::ExecState*, JSC::JSModuleLoader*, JSC::JSString*, const JSC::SourceOrigin&);
     83        static void promiseRejectionTracker(JSC::JSGlobalObject*, JSC::ExecState*, JSC::JSPromise*, JSC::JSPromiseRejectionOperation);
    8384
    8485        RefPtr<DOMWindow> m_wrapped;
  • trunk/Source/WebCore/bindings/js/JSMainThreadExecState.cpp

    r197131 r215916  
    2828
    2929#include "Microtasks.h"
    30 #include "MutationObserver.h"
     30#include "RejectedPromiseTracker.h"
     31#include "ScriptExecutionContext.h"
     32#include "ScriptState.h"
    3133
    3234namespace WebCore {
     
    3436JSC::ExecState* JSMainThreadExecState::s_mainThreadState = 0;
    3537
    36 void JSMainThreadExecState::didLeaveScriptContext()
     38void JSMainThreadExecState::didLeaveScriptContext(JSC::ExecState* exec)
    3739{
    3840    MicrotaskQueue::mainThreadQueue().performMicrotaskCheckpoint();
     41    scriptExecutionContextFromExecState(exec)->ensureRejectedPromiseTracker().processQueueSoon();
    3942}
    4043
  • trunk/Source/WebCore/bindings/js/JSMainThreadExecState.h

    r210585 r215916  
    3232#include <runtime/Microtask.h>
    3333#include <wtf/MainThread.h>
    34 
    35 #if PLATFORM(IOS)
    36 #include "WebCoreThread.h"
    37 #endif
    3834
    3935namespace WebCore {
     
    140136        ASSERT_UNUSED(scope, !scope.exception());
    141137
     138        JSC::ExecState* state = s_mainThreadState;
    142139        bool didExitJavaScript = s_mainThreadState && !m_previousState;
    143140
     
    145142
    146143        if (didExitJavaScript)
    147             didLeaveScriptContext();
     144            didLeaveScriptContext(state);
    148145    }
    149146
     
    154151    JSC::JSLockHolder m_lock;
    155152
    156     static void didLeaveScriptContext();
     153    static void didLeaveScriptContext(JSC::ExecState*);
    157154};
    158155
  • trunk/Source/WebCore/bindings/js/JSWorkerGlobalScopeBase.cpp

    r211247 r215916  
    5353    &queueTaskToEventLoop,
    5454    &shouldInterruptScriptBeforeTimeout,
    55     nullptr,
    56     nullptr,
    57     nullptr,
    58     nullptr,
    59     nullptr,
     55    nullptr, // moduleLoaderImportModule
     56    nullptr, // moduleLoaderResolve
     57    nullptr, // moduleLoaderFetch
     58    nullptr, // moduleLoaderInstantiate
     59    nullptr, // moduleLoaderEvaluate
     60    nullptr, // promiseRejectionTracker
    6061    &defaultLanguage
    6162};
  • trunk/Source/WebCore/bindings/scripts/CodeGenerator.pm

    r215403 r215916  
    689689}
    690690
     691sub IsPromiseType
     692{
     693    my ($object, $type) = @_;
     694
     695    assert("Not a type") if ref($type) ne "IDLType";
     696
     697    return $type->name eq "Promise";
     698}
     699
    691700# These match WK_lcfirst and WK_ucfirst defined in builtins_generator.py.
    692701# Uppercase the first letter while respecting WebKit style guidelines.
  • trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm

    r215904 r215916  
    301301        AddToIncludesForIDLType(@{$type->subtypes}[0], $includesRef, $conditional);
    302302        AddToIncludesForIDLType(@{$type->subtypes}[1], $includesRef, $conditional);
     303        return;
     304    }
     305
     306    if ($codeGenerator->IsPromiseType($type)) {
     307        AddToIncludes("JSDOMPromise.h", $includesRef, $conditional);
     308        AddToIncludesForIDLType(@{$type->subtypes}[0], $includesRef, $conditional);
    303309        return;
    304310    }
     
    54335439    return "IDLFrozenArray<" . GetIDLType($interface, @{$type->subtypes}[0]) . ">" if $codeGenerator->IsFrozenArrayType($type);
    54345440    return "IDLRecord<" . GetIDLType($interface, @{$type->subtypes}[0]) . ", " . GetIDLType($interface, @{$type->subtypes}[1]) . ">" if $codeGenerator->IsRecordType($type);
     5441    return "IDLPromise<" . GetIDLType($interface, @{$type->subtypes}[0]) . ">" if $codeGenerator->IsPromiseType($type);
    54355442    return "IDLUnion<" . join(", ", GetIDLUnionMemberTypes($interface, $type)) . ">" if $type->isUnion;
    54365443    return "IDLCallbackFunction<" . GetCallbackClassName($type->name) . ">" if $codeGenerator->IsCallbackFunction($type);
  • trunk/Source/WebCore/dom/DOMAllInOne.cpp

    r210216 r215916  
    127127#include "RadioButtonGroups.cpp"
    128128#include "Range.cpp"
     129#include "RejectedPromiseTracker.cpp"
    129130#include "ScopedEventQueue.cpp"
    130131#include "ScriptElement.cpp"
  • trunk/Source/WebCore/dom/EventNames.h

    r214819 r215916  
    183183    macro(ratechange) \
    184184    macro(readystatechange) \
     185    macro(rejectionhandled) \
    185186    macro(removesourcebuffer) \
    186187    macro(removestream) \
     
    231232    macro(track) \
    232233    macro(transitionend) \
     234    macro(unhandledrejection) \
    233235    macro(unload) \
    234236    macro(unmute) \
  • trunk/Source/WebCore/dom/EventNames.in

    r214536 r215916  
    2727PopStateEvent
    2828ProgressEvent
     29PromiseRejectionEvent
    2930TextEvent
    3031TransitionEvent
  • trunk/Source/WebCore/dom/GlobalEventHandlers.idl

    r207514 r215916  
    8080    attribute EventHandler onprogress;
    8181    attribute EventHandler onratechange;
     82    attribute EventHandler onrejectionhandled;
    8283    attribute EventHandler onreset;
    8384    attribute EventHandler onresize;
     
    9394    attribute EventHandler ontimeupdate;
    9495    attribute EventHandler ontoggle;
     96    attribute EventHandler onunhandledrejection;
    9597    attribute EventHandler onvolumechange;
    9698    attribute EventHandler onwaiting;
  • trunk/Source/WebCore/dom/ScriptExecutionContext.cpp

    r213519 r215916  
    3535#include "Document.h"
    3636#include "ErrorEvent.h"
     37#include "JSDOMExceptionHandling.h"
    3738#include "JSDOMWindow.h"
    3839#include "MessagePort.h"
    3940#include "NoEventDispatchAssertion.h"
    4041#include "PublicURLManager.h"
     42#include "RejectedPromiseTracker.h"
    4143#include "ResourceRequest.h"
    4244#include "ScriptState.h"
     
    4749#include <inspector/ScriptCallStack.h>
    4850#include <runtime/Exception.h>
     51#include <runtime/JSPromise.h>
    4952#include <wtf/MainThread.h>
    5053#include <wtf/Ref.h>
     
    380383}
    381384
     385void ScriptExecutionContext::reportUnhandledPromiseRejection(JSC::ExecState& state, JSC::JSPromise& promise, Inspector::ScriptCallStack& callStack)
     386{
     387    JSC::VM& vm = state.vm();
     388    auto scope = DECLARE_CATCH_SCOPE(vm);
     389
     390    int lineNumber = 0;
     391    int columnNumber = 0;
     392    String sourceURL;
     393
     394    JSC::JSValue result = promise.result(vm);
     395    String resultMessage = retrieveErrorMessage(state, vm, result, scope);
     396    String errorMessage = makeString("Unhandled Promise Rejection: ", resultMessage);
     397    if (const ScriptCallFrame* callFrame = callStack.firstNonNativeCallFrame()) {
     398        lineNumber = callFrame->lineNumber();
     399        columnNumber = callFrame->columnNumber();
     400        sourceURL = callFrame->sourceURL();
     401    }
     402
     403    logExceptionToConsole(errorMessage, sourceURL, lineNumber, columnNumber, &callStack);
     404}
     405
    382406void ScriptExecutionContext::addConsoleMessage(MessageSource source, MessageLevel level, const String& message, const String& sourceURL, unsigned lineNumber, unsigned columnNumber, JSC::ExecState* state, unsigned long requestIdentifier)
    383407{
     
    465489}
    466490
     491RejectedPromiseTracker& ScriptExecutionContext::ensureRejectedPromiseTrackerSlow()
     492{
     493    // ScriptExecutionContext::vm() in Worker is only available after WorkerGlobalScope initialization is done.
     494    // When initializing ScriptExecutionContext, vm() is not ready.
     495
     496    ASSERT(!m_rejectedPromiseTracker);
     497    m_rejectedPromiseTracker = std::make_unique<RejectedPromiseTracker>(*this, vm());
     498    return *m_rejectedPromiseTracker.get();
     499}
     500
    467501void ScriptExecutionContext::setDatabaseContext(DatabaseContext* databaseContext)
    468502{
  • trunk/Source/WebCore/dom/ScriptExecutionContext.h

    r214203 r215916  
    4141class Exception;
    4242class ExecState;
     43class JSPromise;
    4344class VM;
    4445template<typename> class Strong;
     
    5758class MessagePort;
    5859class PublicURLManager;
     60class RejectedPromiseTracker;
    5961class ResourceRequest;
    6062class SecurityOrigin;
     
    9597    bool sanitizeScriptError(String& errorMessage, int& lineNumber, int& columnNumber, String& sourceURL, JSC::Strong<JSC::Unknown>& error, CachedScript* = nullptr);
    9698    void reportException(const String& errorMessage, int lineNumber, int columnNumber, const String& sourceURL, JSC::Exception*, RefPtr<Inspector::ScriptCallStack>&&, CachedScript* = nullptr);
     99    void reportUnhandledPromiseRejection(JSC::ExecState&, JSC::JSPromise&, Inspector::ScriptCallStack&);
    97100
    98101    void addConsoleMessage(MessageSource, MessageLevel, const String& message, const String& sourceURL, unsigned lineNumber, unsigned columnNumber, JSC::ExecState* = nullptr, unsigned long requestIdentifier = 0);
     
    197200
    198201    virtual EventQueue& eventQueue() const = 0;
     202    virtual EventTarget* errorEventTarget() = 0;
    199203
    200204    DatabaseContext* databaseContext() { return m_databaseContext.get(); }
     
    208212    int timerNestingLevel() const { return m_timerNestingLevel; }
    209213    void setTimerNestingLevel(int timerNestingLevel) { m_timerNestingLevel = timerNestingLevel; }
     214
     215    RejectedPromiseTracker& ensureRejectedPromiseTracker()
     216    {
     217        if (m_rejectedPromiseTracker)
     218            return *m_rejectedPromiseTracker.get();
     219        return ensureRejectedPromiseTrackerSlow();
     220    }
    210221
    211222    JSC::ExecState* execState();
     
    228239private:
    229240    virtual void addMessage(MessageSource, MessageLevel, const String& message, const String& sourceURL, unsigned lineNumber, unsigned columnNumber, RefPtr<Inspector::ScriptCallStack>&&, JSC::ExecState* = nullptr, unsigned long requestIdentifier = 0) = 0;
    230     virtual EventTarget* errorEventTarget() = 0;
    231241    virtual void logExceptionToConsole(const String& errorMessage, const String& sourceURL, int lineNumber, int columnNumber, RefPtr<Inspector::ScriptCallStack>&&) = 0;
    232242    bool dispatchErrorEvent(const String& errorMessage, int lineNumber, int columnNumber, const String& sourceURL, JSC::Exception*, CachedScript*);
     
    234244    virtual void refScriptExecutionContext() = 0;
    235245    virtual void derefScriptExecutionContext() = 0;
     246
     247    RejectedPromiseTracker& ensureRejectedPromiseTrackerSlow();
    236248
    237249    void checkConsistency() const;
     
    245257    struct PendingException;
    246258    std::unique_ptr<Vector<std::unique_ptr<PendingException>>> m_pendingExceptions;
     259    std::unique_ptr<RejectedPromiseTracker> m_rejectedPromiseTracker;
    247260
    248261    ActiveDOMObject::ReasonForSuspension m_reasonForSuspendingActiveDOMObjects { static_cast<ActiveDOMObject::ReasonForSuspension>(-1) };
  • trunk/Source/WebCore/html/HTMLMediaElement.cpp

    r215771 r215916  
    32983298        scheduleTimeupdateEvent(false);
    32993299        scheduleEvent(eventNames().pauseEvent);
    3300         rejectPendingPlayPromises(DOMError::create("AbortError", "The operation was aborted."));
    3301 
     3300        m_promiseTaskQueue.enqueueTask([this]() {
     3301            rejectPendingPlayPromises(DOMError::create("AbortError", "The operation was aborted."));
     3302        });
    33023303        if (MemoryPressureHandler::singleton().isUnderMemoryPressure())
    33033304            purgeBufferedDataIfPossible();
Note: See TracChangeset for help on using the changeset viewer.