Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: src/promise.js

Issue 607913002: Report promise reject with no handler (behind a flag). (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: more comments Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects-printer.cc ('k') | src/runtime/runtime.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "use strict"; 5 "use strict";
6 6
7 // This file relies on the fact that the following declaration has been made 7 // This file relies on the fact that the following declaration has been made
8 // in runtime.js: 8 // in runtime.js:
9 // var $Object = global.Object 9 // var $Object = global.Object
10 // var $WeakMap = global.WeakMap 10 // var $WeakMap = global.WeakMap
(...skipping 12 matching lines...) Expand all
23 // mirror-debugger.js currently uses builtins.promiseStatus. It would be nice 23 // mirror-debugger.js currently uses builtins.promiseStatus. It would be nice
24 // if we could move these property names into the closure below. 24 // if we could move these property names into the closure below.
25 // TODO(jkummerow/rossberg/yangguo): Find a better solution. 25 // TODO(jkummerow/rossberg/yangguo): Find a better solution.
26 26
27 // Status values: 0 = pending, +1 = resolved, -1 = rejected 27 // Status values: 0 = pending, +1 = resolved, -1 = rejected
28 var promiseStatus = GLOBAL_PRIVATE("Promise#status"); 28 var promiseStatus = GLOBAL_PRIVATE("Promise#status");
29 var promiseValue = GLOBAL_PRIVATE("Promise#value"); 29 var promiseValue = GLOBAL_PRIVATE("Promise#value");
30 var promiseOnResolve = GLOBAL_PRIVATE("Promise#onResolve"); 30 var promiseOnResolve = GLOBAL_PRIVATE("Promise#onResolve");
31 var promiseOnReject = GLOBAL_PRIVATE("Promise#onReject"); 31 var promiseOnReject = GLOBAL_PRIVATE("Promise#onReject");
32 var promiseRaw = GLOBAL_PRIVATE("Promise#raw"); 32 var promiseRaw = GLOBAL_PRIVATE("Promise#raw");
33 var promiseDebug = GLOBAL_PRIVATE("Promise#debug"); 33 var promiseHasReject = GLOBAL_PRIVATE("Promise#hasReject");
34 var lastMicrotaskId = 0; 34 var lastMicrotaskId = 0;
35 35
36 (function() { 36 (function() {
37 37
38 var $Promise = function Promise(resolver) { 38 var $Promise = function Promise(resolver) {
39 if (resolver === promiseRaw) return; 39 if (resolver === promiseRaw) return;
40 if (!%_IsConstructCall()) throw MakeTypeError('not_a_promise', [this]); 40 if (!%_IsConstructCall()) throw MakeTypeError('not_a_promise', [this]);
41 if (!IS_SPEC_FUNCTION(resolver)) 41 if (!IS_SPEC_FUNCTION(resolver))
42 throw MakeTypeError('resolver_not_a_function', [resolver]); 42 throw MakeTypeError('resolver_not_a_function', [resolver]);
43 var promise = PromiseInit(this); 43 var promise = PromiseInit(this);
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 PromiseCreate = function PromiseCreate() { 152 PromiseCreate = function PromiseCreate() {
153 return new $Promise(PromiseNopResolver) 153 return new $Promise(PromiseNopResolver)
154 } 154 }
155 155
156 PromiseResolve = function PromiseResolve(promise, x) { 156 PromiseResolve = function PromiseResolve(promise, x) {
157 PromiseDone(promise, +1, x, promiseOnResolve) 157 PromiseDone(promise, +1, x, promiseOnResolve)
158 } 158 }
159 159
160 PromiseReject = function PromiseReject(promise, r) { 160 PromiseReject = function PromiseReject(promise, r) {
161 // Check promise status to confirm that this reject has an effect. 161 // Check promise status to confirm that this reject has an effect.
162 // Check promiseDebug property to avoid duplicate event. 162 if (GET_PRIVATE(promise, promiseStatus) == 0) {
163 if (DEBUG_IS_ACTIVE && 163 %PromiseRejectEvent(promise, r);
164 GET_PRIVATE(promise, promiseStatus) == 0 &&
165 !HAS_DEFINED_PRIVATE(promise, promiseDebug)) {
166 %DebugPromiseRejectEvent(promise, r);
167 } 164 }
168 PromiseDone(promise, -1, r, promiseOnReject) 165 PromiseDone(promise, -1, r, promiseOnReject)
169 } 166 }
170 167
171 // Convenience. 168 // Convenience.
172 169
173 function PromiseDeferred() { 170 function PromiseDeferred() {
174 if (this === $Promise) { 171 if (this === $Promise) {
175 // Optimized case, avoid extra closure. 172 // Optimized case, avoid extra closure.
176 var promise = PromiseInit(new $Promise(promiseRaw)); 173 var promise = PromiseInit(new $Promise(promiseRaw));
(...skipping 29 matching lines...) Expand all
206 return new this(function(resolve, reject) { reject(r) }); 203 return new this(function(resolve, reject) { reject(r) });
207 } 204 }
208 } 205 }
209 206
210 // Simple chaining. 207 // Simple chaining.
211 208
212 PromiseChain = function PromiseChain(onResolve, onReject) { // a.k.a. 209 PromiseChain = function PromiseChain(onResolve, onReject) { // a.k.a.
213 // flatMap 210 // flatMap
214 onResolve = IS_UNDEFINED(onResolve) ? PromiseIdResolveHandler : onResolve; 211 onResolve = IS_UNDEFINED(onResolve) ? PromiseIdResolveHandler : onResolve;
215 onReject = IS_UNDEFINED(onReject) ? PromiseIdRejectHandler : onReject; 212 onReject = IS_UNDEFINED(onReject) ? PromiseIdRejectHandler : onReject;
213 if (onReject != PromiseIdRejectHandler) {
214 // Mark this promise as having reject handler.
215 SET_PRIVATE(this, promiseHasReject, true);
216 }
216 var deferred = %_CallFunction(this.constructor, PromiseDeferred); 217 var deferred = %_CallFunction(this.constructor, PromiseDeferred);
217 switch (GET_PRIVATE(this, promiseStatus)) { 218 switch (GET_PRIVATE(this, promiseStatus)) {
218 case UNDEFINED: 219 case UNDEFINED:
219 throw MakeTypeError('not_a_promise', [this]); 220 throw MakeTypeError('not_a_promise', [this]);
220 case 0: // Pending 221 case 0: // Pending
221 GET_PRIVATE(this, promiseOnResolve).push(onResolve, deferred); 222 GET_PRIVATE(this, promiseOnResolve).push(onResolve, deferred);
222 GET_PRIVATE(this, promiseOnReject).push(onReject, deferred); 223 GET_PRIVATE(this, promiseOnReject).push(onReject, deferred);
223 break; 224 break;
224 case +1: // Resolved 225 case +1: // Resolved
225 PromiseEnqueue(GET_PRIVATE(this, promiseValue), 226 PromiseEnqueue(GET_PRIVATE(this, promiseValue),
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
319 } catch (e) { 320 } catch (e) {
320 deferred.reject(e) 321 deferred.reject(e)
321 } 322 }
322 return deferred.promise; 323 return deferred.promise;
323 } 324 }
324 325
325 326
326 // Utility for debugger 327 // Utility for debugger
327 328
328 function PromiseHasRejectHandlerRecursive(promise) { 329 function PromiseHasRejectHandlerRecursive(promise) {
330 if (GET_PRIVATE(promise, promiseHasReject)) return true;
329 var queue = GET_PRIVATE(promise, promiseOnReject); 331 var queue = GET_PRIVATE(promise, promiseOnReject);
330 if (IS_UNDEFINED(queue)) return false; 332 if (IS_UNDEFINED(queue)) return false;
331 // Do a depth first search for a reject handler that's not 333 // Do a depth first search for a promise that has been marked as having
332 // the default PromiseIdRejectHandler. 334 // a reject handler.
333 for (var i = 0; i < queue.length; i += 2) { 335 for (var i = 0; i < queue.length; i += 2) {
334 if (queue[i] != PromiseIdRejectHandler) return true;
335 if (PromiseHasRejectHandlerRecursive(queue[i + 1].promise)) return true; 336 if (PromiseHasRejectHandlerRecursive(queue[i + 1].promise)) return true;
336 } 337 }
337 return false; 338 return false;
338 } 339 }
339 340
340 PromiseHasRejectHandler = function PromiseHasRejectHandler() { 341 PromiseHasRejectHandler = function PromiseHasRejectHandler() {
341 // Mark promise as already having triggered a reject event.
342 SET_PRIVATE(this, promiseDebug, true);
343 return PromiseHasRejectHandlerRecursive(this); 342 return PromiseHasRejectHandlerRecursive(this);
344 }; 343 };
345 344
346 // ------------------------------------------------------------------- 345 // -------------------------------------------------------------------
347 // Install exported functions. 346 // Install exported functions.
348 347
349 %CheckIsBootstrapping(); 348 %CheckIsBootstrapping();
350 %AddNamedProperty(global, 'Promise', $Promise, DONT_ENUM); 349 %AddNamedProperty(global, 'Promise', $Promise, DONT_ENUM);
351 InstallFunctions($Promise, DONT_ENUM, [ 350 InstallFunctions($Promise, DONT_ENUM, [
352 "defer", PromiseDeferred, 351 "defer", PromiseDeferred,
353 "accept", PromiseResolved, 352 "accept", PromiseResolved,
354 "reject", PromiseRejected, 353 "reject", PromiseRejected,
355 "all", PromiseAll, 354 "all", PromiseAll,
356 "race", PromiseOne, 355 "race", PromiseOne,
357 "resolve", PromiseCast 356 "resolve", PromiseCast
358 ]); 357 ]);
359 InstallFunctions($Promise.prototype, DONT_ENUM, [ 358 InstallFunctions($Promise.prototype, DONT_ENUM, [
360 "chain", PromiseChain, 359 "chain", PromiseChain,
361 "then", PromiseThen, 360 "then", PromiseThen,
362 "catch", PromiseCatch 361 "catch", PromiseCatch
363 ]); 362 ]);
364 363
365 })(); 364 })();
OLDNEW
« no previous file with comments | « src/objects-printer.cc ('k') | src/runtime/runtime.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698