| OLD | NEW | 
|---|
|  | (Empty) | 
| 1 // Copyright 2016 the V8 project authors. All rights reserved. |  | 
| 2 // Use of this source code is governed by a BSD-style license that can be |  | 
| 3 // found in the LICENSE file. |  | 
| 4 |  | 
| 5 (function(global, utils, extrasUtils) { |  | 
| 6 |  | 
| 7 "use strict"; |  | 
| 8 |  | 
| 9 %CheckIsBootstrapping(); |  | 
| 10 |  | 
| 11 // ------------------------------------------------------------------- |  | 
| 12 // Imports |  | 
| 13 |  | 
| 14 var AsyncFunctionNext; |  | 
| 15 var AsyncFunctionThrow; |  | 
| 16 |  | 
| 17 utils.Import(function(from) { |  | 
| 18   AsyncFunctionNext = from.AsyncFunctionNext; |  | 
| 19   AsyncFunctionThrow = from.AsyncFunctionThrow; |  | 
| 20 }); |  | 
| 21 |  | 
| 22 var promiseHandledBySymbol = |  | 
| 23     utils.ImportNow("promise_handled_by_symbol"); |  | 
| 24 var promiseForwardingHandlerSymbol = |  | 
| 25     utils.ImportNow("promise_forwarding_handler_symbol"); |  | 
| 26 |  | 
| 27 // ------------------------------------------------------------------- |  | 
| 28 |  | 
| 29 function PromiseCastResolved(value) { |  | 
| 30   // TODO(caitp): This is non spec compliant. See v8:5694. |  | 
| 31   if (%is_promise(value)) { |  | 
| 32     return value; |  | 
| 33   } else { |  | 
| 34     var promise = %promise_internal_constructor(UNDEFINED); |  | 
| 35     %promise_resolve(promise, value); |  | 
| 36     return promise; |  | 
| 37   } |  | 
| 38 } |  | 
| 39 |  | 
| 40 // ES#abstract-ops-async-function-await |  | 
| 41 // AsyncFunctionAwait ( value ) |  | 
| 42 // Shared logic for the core of await. The parser desugars |  | 
| 43 //   await awaited |  | 
| 44 // into |  | 
| 45 //   yield AsyncFunctionAwait{Caught,Uncaught}(.generator, awaited, .promise) |  | 
| 46 // The 'awaited' parameter is the value; the generator stands in |  | 
| 47 // for the asyncContext, and .promise is the larger promise under |  | 
| 48 // construction by the enclosing async function. |  | 
| 49 function AsyncFunctionAwait(generator, awaited, outerPromise) { |  | 
| 50   // Promise.resolve(awaited).then( |  | 
| 51   //     value => AsyncFunctionNext(value), |  | 
| 52   //     error => AsyncFunctionThrow(error) |  | 
| 53   // ); |  | 
| 54   var promise = PromiseCastResolved(awaited); |  | 
| 55 |  | 
| 56   var onFulfilled = sentValue => { |  | 
| 57     %_Call(AsyncFunctionNext, generator, sentValue); |  | 
| 58     // The resulting Promise is a throwaway, so it doesn't matter what it |  | 
| 59     // resolves to. What is important is that we don't end up keeping the |  | 
| 60     // whole chain of intermediate Promises alive by returning the value |  | 
| 61     // of AsyncFunctionNext, as that would create a memory leak. |  | 
| 62     return; |  | 
| 63   }; |  | 
| 64   var onRejected = sentError => { |  | 
| 65     %_Call(AsyncFunctionThrow, generator, sentError); |  | 
| 66     // Similarly, returning the huge Promise here would cause a long |  | 
| 67     // resolution chain to find what the exception to throw is, and |  | 
| 68     // create a similar memory leak, and it does not matter what |  | 
| 69     // sort of rejection this intermediate Promise becomes. |  | 
| 70     return; |  | 
| 71   } |  | 
| 72 |  | 
| 73   var throwawayPromise = %promise_internal_constructor(promise); |  | 
| 74 |  | 
| 75   // The Promise will be thrown away and not handled, but it shouldn't trigger |  | 
| 76   // unhandled reject events as its work is done |  | 
| 77   %PromiseMarkAsHandled(throwawayPromise); |  | 
| 78 |  | 
| 79   if (DEBUG_IS_ACTIVE) { |  | 
| 80     if (%is_promise(awaited)) { |  | 
| 81       // Mark the reject handler callback to be a forwarding edge, rather |  | 
| 82       // than a meaningful catch handler |  | 
| 83       SET_PRIVATE(onRejected, promiseForwardingHandlerSymbol, true); |  | 
| 84     } |  | 
| 85 |  | 
| 86     // Mark the dependency to outerPromise in case the throwaway Promise is |  | 
| 87     // found on the Promise stack |  | 
| 88     SET_PRIVATE(throwawayPromise, promiseHandledBySymbol, outerPromise); |  | 
| 89   } |  | 
| 90 |  | 
| 91   %perform_promise_then(promise, onFulfilled, onRejected, throwawayPromise); |  | 
| 92 } |  | 
| 93 |  | 
| 94 // Called by the parser from the desugaring of 'await' when catch |  | 
| 95 // prediction indicates no locally surrounding catch block |  | 
| 96 function AsyncFunctionAwaitUncaught(generator, awaited, outerPromise) { |  | 
| 97   AsyncFunctionAwait(generator, awaited, outerPromise); |  | 
| 98 } |  | 
| 99 |  | 
| 100 // Called by the parser from the desugaring of 'await' when catch |  | 
| 101 // prediction indicates that there is a locally surrounding catch block |  | 
| 102 function AsyncFunctionAwaitCaught(generator, awaited, outerPromise) { |  | 
| 103   if (DEBUG_IS_ACTIVE && %is_promise(awaited)) { |  | 
| 104     %PromiseMarkHandledHint(awaited); |  | 
| 105   } |  | 
| 106   AsyncFunctionAwait(generator, awaited, outerPromise); |  | 
| 107 } |  | 
| 108 |  | 
| 109 %InstallToContext([ |  | 
| 110   "async_function_await_caught", AsyncFunctionAwaitCaught, |  | 
| 111   "async_function_await_uncaught", AsyncFunctionAwaitUncaught, |  | 
| 112 ]); |  | 
| 113 |  | 
| 114 }) |  | 
| OLD | NEW | 
|---|