OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 (function(global, utils, extrasUtils) { | 5 (function(global, utils, extrasUtils) { |
6 | 6 |
7 "use strict"; | 7 "use strict"; |
8 | 8 |
9 %CheckIsBootstrapping(); | 9 %CheckIsBootstrapping(); |
10 | 10 |
(...skipping 17 matching lines...) Expand all Loading... |
28 utils.ImportNow("promise_deferred_reaction_symbol"); | 28 utils.ImportNow("promise_deferred_reaction_symbol"); |
29 var promiseHandledHintSymbol = | 29 var promiseHandledHintSymbol = |
30 utils.ImportNow("promise_handled_hint_symbol"); | 30 utils.ImportNow("promise_handled_hint_symbol"); |
31 var promiseRawSymbol = utils.ImportNow("promise_raw_symbol"); | 31 var promiseRawSymbol = utils.ImportNow("promise_raw_symbol"); |
32 var promiseStateSymbol = utils.ImportNow("promise_state_symbol"); | 32 var promiseStateSymbol = utils.ImportNow("promise_state_symbol"); |
33 var promiseResultSymbol = utils.ImportNow("promise_result_symbol"); | 33 var promiseResultSymbol = utils.ImportNow("promise_result_symbol"); |
34 var SpeciesConstructor; | 34 var SpeciesConstructor; |
35 var speciesSymbol = utils.ImportNow("species_symbol"); | 35 var speciesSymbol = utils.ImportNow("species_symbol"); |
36 var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol"); | 36 var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol"); |
37 var ObjectHasOwnProperty; | 37 var ObjectHasOwnProperty; |
| 38 var GlobalPromise = global.Promise; |
38 | 39 |
39 utils.Import(function(from) { | 40 utils.Import(function(from) { |
40 ObjectHasOwnProperty = from.ObjectHasOwnProperty; | 41 ObjectHasOwnProperty = from.ObjectHasOwnProperty; |
41 SpeciesConstructor = from.SpeciesConstructor; | 42 SpeciesConstructor = from.SpeciesConstructor; |
42 }); | 43 }); |
43 | 44 |
44 // ------------------------------------------------------------------- | 45 // ------------------------------------------------------------------- |
45 | 46 |
46 // [[PromiseState]] values: | 47 // [[PromiseState]] values: |
47 // These values should be kept in sync with PromiseStatus in globals.h | 48 // These values should be kept in sync with PromiseStatus in globals.h |
48 const kPending = 0; | 49 const kPending = 0; |
49 const kFulfilled = +1; | 50 const kFulfilled = +1; |
50 const kRejected = +2; | 51 const kRejected = +2; |
51 | 52 |
52 const kResolveCallback = 0; | 53 const kResolveCallback = 0; |
53 const kRejectCallback = 1; | 54 const kRejectCallback = 1; |
54 | 55 |
55 // ES#sec-promise-executor | |
56 // Promise ( executor ) | |
57 var GlobalPromise = function Promise(executor) { | |
58 if (executor === promiseRawSymbol) { | |
59 return %_NewObject(GlobalPromise, new.target); | |
60 } | |
61 if (IS_UNDEFINED(new.target)) throw %make_type_error(kNotAPromise, this); | |
62 if (!IS_CALLABLE(executor)) { | |
63 throw %make_type_error(kResolverNotAFunction, executor); | |
64 } | |
65 | |
66 var promise = PromiseInit(%_NewObject(GlobalPromise, new.target)); | |
67 // Calling the reject function would be a new exception, so debugEvent = true | |
68 // TODO(gsathya): Remove container for callbacks when this is moved | |
69 // to CPP/TF. | |
70 var callbacks = %create_resolving_functions(promise, true); | |
71 var debug_is_active = DEBUG_IS_ACTIVE; | |
72 try { | |
73 if (debug_is_active) %DebugPushPromise(promise); | |
74 executor(callbacks[kResolveCallback], callbacks[kRejectCallback]); | |
75 } %catch (e) { // Natives syntax to mark this catch block. | |
76 %_Call(callbacks[kRejectCallback], UNDEFINED, e); | |
77 } finally { | |
78 if (debug_is_active) %DebugPopPromise(); | |
79 } | |
80 | |
81 return promise; | |
82 } | |
83 | |
84 // Core functionality. | 56 // Core functionality. |
85 | 57 |
86 function PromiseSet(promise, status, value) { | 58 function PromiseSet(promise, status, value) { |
87 SET_PRIVATE(promise, promiseStateSymbol, status); | 59 SET_PRIVATE(promise, promiseStateSymbol, status); |
88 SET_PRIVATE(promise, promiseResultSymbol, value); | 60 SET_PRIVATE(promise, promiseResultSymbol, value); |
89 | 61 |
90 // There are 3 possible states for the resolve, reject symbols when we add | 62 // There are 3 possible states for the resolve, reject symbols when we add |
91 // a new callback -- | 63 // a new callback -- |
92 // 1) UNDEFINED -- This is the zero state where there is no callback | 64 // 1) UNDEFINED -- This is the zero state where there is no callback |
93 // registered. When we see this state, we directly attach the callbacks to | 65 // registered. When we see this state, we directly attach the callbacks to |
94 // the symbol. | 66 // the symbol. |
95 // 2) !IS_ARRAY -- There is a single callback directly attached to the | 67 // 2) !IS_ARRAY -- There is a single callback directly attached to the |
96 // symbols. We need to create a new array to store additional callbacks. | 68 // symbols. We need to create a new array to store additional callbacks. |
97 // 3) IS_ARRAY -- There are multiple callbacks already registered, | 69 // 3) IS_ARRAY -- There are multiple callbacks already registered, |
98 // therefore we can just push the new callback to the existing array. | 70 // therefore we can just push the new callback to the existing array. |
99 SET_PRIVATE(promise, promiseFulfillReactionsSymbol, UNDEFINED); | 71 SET_PRIVATE(promise, promiseFulfillReactionsSymbol, UNDEFINED); |
100 SET_PRIVATE(promise, promiseRejectReactionsSymbol, UNDEFINED); | 72 SET_PRIVATE(promise, promiseRejectReactionsSymbol, UNDEFINED); |
101 | 73 |
102 // This symbol is used only when one deferred needs to be attached. When more | 74 // This symbol is used only when one deferred needs to be attached. When more |
103 // than one deferred need to be attached the promise, we attach them directly | 75 // than one deferred need to be attached the promise, we attach them directly |
104 // to the promiseFulfillReactionsSymbol and promiseRejectReactionsSymbol and | 76 // to the promiseFulfillReactionsSymbol and promiseRejectReactionsSymbol and |
105 // reset this back to UNDEFINED. | 77 // reset this back to UNDEFINED. |
106 SET_PRIVATE(promise, promiseDeferredReactionSymbol, UNDEFINED); | 78 SET_PRIVATE(promise, promiseDeferredReactionSymbol, UNDEFINED); |
107 | 79 |
108 return promise; | 80 return promise; |
109 } | 81 } |
110 | 82 |
111 function PromiseCreateAndSet(status, value) { | 83 function PromiseCreateAndSet(status, value) { |
112 var promise = new GlobalPromise(promiseRawSymbol); | 84 var promise = %promise_internal_constructor(); |
113 // If debug is active, notify about the newly created promise first. | 85 // If debug is active, notify about the newly created promise first. |
114 if (DEBUG_IS_ACTIVE) PromiseSet(promise, kPending, UNDEFINED); | 86 if (DEBUG_IS_ACTIVE) PromiseSet(promise, kPending, UNDEFINED); |
115 return PromiseSet(promise, status, value); | 87 return PromiseSet(promise, status, value); |
116 } | 88 } |
117 | 89 |
118 function PromiseInit(promise) { | 90 function PromiseInit(promise) { |
119 return PromiseSet(promise, kPending, UNDEFINED); | 91 return PromiseSet(promise, kPending, UNDEFINED); |
120 } | 92 } |
121 | 93 |
122 function PromiseHandle(value, handler, deferred) { | 94 function PromiseHandle(value, handler, deferred) { |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
201 | 173 |
202 function PromiseIdResolveHandler(x) { return x; } | 174 function PromiseIdResolveHandler(x) { return x; } |
203 function PromiseIdRejectHandler(r) { %_ReThrow(r); } | 175 function PromiseIdRejectHandler(r) { %_ReThrow(r); } |
204 SET_PRIVATE(PromiseIdRejectHandler, promiseForwardingHandlerSymbol, true); | 176 SET_PRIVATE(PromiseIdRejectHandler, promiseForwardingHandlerSymbol, true); |
205 | 177 |
206 // ------------------------------------------------------------------- | 178 // ------------------------------------------------------------------- |
207 // Define exported functions. | 179 // Define exported functions. |
208 | 180 |
209 // For bootstrapper. | 181 // For bootstrapper. |
210 | 182 |
| 183 // Only used by utils |
211 // ES#sec-ispromise IsPromise ( x ) | 184 // ES#sec-ispromise IsPromise ( x ) |
212 function IsPromise(x) { | 185 function IsPromise(x) { |
213 return IS_RECEIVER(x) && HAS_DEFINED_PRIVATE(x, promiseStateSymbol); | 186 return IS_RECEIVER(x) && HAS_DEFINED_PRIVATE(x, promiseStateSymbol); |
214 } | 187 } |
215 | 188 |
216 function PromiseCreate() { | 189 function PromiseCreate() { |
217 return PromiseInit(new GlobalPromise(promiseRawSymbol)); | 190 return PromiseInit(%promise_internal_constructor()); |
218 } | 191 } |
219 | 192 |
220 // ES#sec-promise-resolve-functions | 193 // ES#sec-promise-resolve-functions |
221 // Promise Resolve Functions, steps 6-13 | 194 // Promise Resolve Functions, steps 6-13 |
222 function ResolvePromise(promise, resolution) { | 195 function ResolvePromise(promise, resolution) { |
223 if (resolution === promise) { | 196 if (resolution === promise) { |
224 var exception = %make_type_error(kPromiseCyclic, resolution); | 197 var exception = %make_type_error(kPromiseCyclic, resolution); |
225 %PromiseReject(promise, exception, true); | 198 %PromiseReject(promise, exception, true); |
226 PromiseSet(promise, kRejected, exception); | 199 PromiseSet(promise, kRejected, exception); |
227 return; | 200 return; |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
378 | 351 |
379 // Mark this promise as having handler. | 352 // Mark this promise as having handler. |
380 SET_PRIVATE(promise, promiseHasHandlerSymbol, true); | 353 SET_PRIVATE(promise, promiseHasHandlerSymbol, true); |
381 return resultCapability.promise; | 354 return resultCapability.promise; |
382 } | 355 } |
383 | 356 |
384 // ES#sec-promise.prototype.then | 357 // ES#sec-promise.prototype.then |
385 // Promise.prototype.then ( onFulfilled, onRejected ) | 358 // Promise.prototype.then ( onFulfilled, onRejected ) |
386 // Multi-unwrapped chaining with thenable coercion. | 359 // Multi-unwrapped chaining with thenable coercion. |
387 function PromiseThen(onResolve, onReject) { | 360 function PromiseThen(onResolve, onReject) { |
388 var status = GET_PRIVATE(this, promiseStateSymbol); | 361 if (!IsPromise(this)) { |
389 if (IS_UNDEFINED(status)) { | |
390 throw %make_type_error(kNotAPromise, this); | 362 throw %make_type_error(kNotAPromise, this); |
391 } | 363 } |
392 | 364 |
393 var constructor = SpeciesConstructor(this, GlobalPromise); | 365 var constructor = SpeciesConstructor(this, GlobalPromise); |
394 var resultCapability; | 366 var resultCapability; |
395 if (constructor === GlobalPromise) { | 367 if (constructor === GlobalPromise) { |
396 resultCapability = CreateInternalPromiseCapability(); | 368 resultCapability = CreateInternalPromiseCapability(); |
397 } else { | 369 } else { |
398 // Pass false for debugEvent so .then chaining does not trigger | 370 // Pass false for debugEvent so .then chaining does not trigger |
399 // redundant ExceptionEvents. | 371 // redundant ExceptionEvents. |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
594 } | 566 } |
595 | 567 |
596 | 568 |
597 function PromiseSpecies() { | 569 function PromiseSpecies() { |
598 return this; | 570 return this; |
599 } | 571 } |
600 | 572 |
601 // ------------------------------------------------------------------- | 573 // ------------------------------------------------------------------- |
602 // Install exported functions. | 574 // Install exported functions. |
603 | 575 |
604 %AddNamedProperty(global, 'Promise', GlobalPromise, DONT_ENUM); | |
605 %AddNamedProperty(GlobalPromise.prototype, toStringTagSymbol, "Promise", | 576 %AddNamedProperty(GlobalPromise.prototype, toStringTagSymbol, "Promise", |
606 DONT_ENUM | READ_ONLY); | 577 DONT_ENUM | READ_ONLY); |
607 | 578 |
608 utils.InstallFunctions(GlobalPromise, DONT_ENUM, [ | 579 utils.InstallFunctions(GlobalPromise, DONT_ENUM, [ |
609 "reject", PromiseReject, | 580 "reject", PromiseReject, |
610 "all", PromiseAll, | 581 "all", PromiseAll, |
611 "race", PromiseRace, | 582 "race", PromiseRace, |
612 "resolve", PromiseResolve | 583 "resolve", PromiseResolve |
613 ]); | 584 ]); |
614 | 585 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
648 to.PromiseThen = PromiseThen; | 619 to.PromiseThen = PromiseThen; |
649 | 620 |
650 to.GlobalPromise = GlobalPromise; | 621 to.GlobalPromise = GlobalPromise; |
651 to.CreateInternalPromiseCapability = CreateInternalPromiseCapability; | 622 to.CreateInternalPromiseCapability = CreateInternalPromiseCapability; |
652 to.PerformPromiseThen = PerformPromiseThen; | 623 to.PerformPromiseThen = PerformPromiseThen; |
653 to.ResolvePromise = ResolvePromise; | 624 to.ResolvePromise = ResolvePromise; |
654 to.RejectPromise = RejectPromise; | 625 to.RejectPromise = RejectPromise; |
655 }); | 626 }); |
656 | 627 |
657 }) | 628 }) |
OLD | NEW |