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

Side by Side Diff: src/js/promise.js

Issue 2396763002: [promises] dont create resolving closures in PromiseThen (Closed)
Patch Set: add comment back Created 4 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
« no previous file with comments | « no previous file | no next file » | 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 (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 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 } 162 }
163 PromiseSet(promise, status, value); 163 PromiseSet(promise, status, value);
164 } 164 }
165 } 165 }
166 166
167 function PromiseHandle(value, handler, deferred) { 167 function PromiseHandle(value, handler, deferred) {
168 var debug_is_active = DEBUG_IS_ACTIVE; 168 var debug_is_active = DEBUG_IS_ACTIVE;
169 try { 169 try {
170 if (debug_is_active) %DebugPushPromise(deferred.promise); 170 if (debug_is_active) %DebugPushPromise(deferred.promise);
171 var result = handler(value); 171 var result = handler(value);
172 deferred.resolve(result); 172 if (deferred.resolve) { deferred.resolve(result); }
173 else { ResolvePromise(deferred.promise, result); }
173 } %catch (exception) { // Natives syntax to mark this catch block. 174 } %catch (exception) { // Natives syntax to mark this catch block.
174 try { deferred.reject(exception); } catch (e) { } 175 try {
176 if (deferred.reject) { deferred.reject(exception); }
177 else { RejectPromise(deferred.promise, exception, false); }
178 } catch (e) { }
175 } finally { 179 } finally {
176 if (debug_is_active) %DebugPopPromise(); 180 if (debug_is_active) %DebugPopPromise();
177 } 181 }
178 } 182 }
179 183
180 function PromiseEnqueue(value, tasks, deferreds, status) { 184 function PromiseEnqueue(value, tasks, deferreds, status) {
181 var id, name, instrumenting = DEBUG_IS_ACTIVE; 185 var id, name, instrumenting = DEBUG_IS_ACTIVE;
182 %EnqueueMicrotask(function() { 186 %EnqueueMicrotask(function() {
183 if (instrumenting) { 187 if (instrumenting) {
184 %DebugAsyncTaskEvent({ type: "willHandle", id: id, name: name }); 188 %DebugAsyncTaskEvent({ type: "willHandle", id: id, name: name });
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
362 366
363 // Export to bindings 367 // Export to bindings
364 function DoRejectPromise(promise, reason) { 368 function DoRejectPromise(promise, reason) {
365 return RejectPromise(promise, reason, true); 369 return RejectPromise(promise, reason, true);
366 } 370 }
367 371
368 // ES#sec-newpromisecapability 372 // ES#sec-newpromisecapability
369 // NewPromiseCapability ( C ) 373 // NewPromiseCapability ( C )
370 function NewPromiseCapability(C, debugEvent) { 374 function NewPromiseCapability(C, debugEvent) {
371 if (C === GlobalPromise) { 375 if (C === GlobalPromise) {
372 // Optimized case, avoid extra closure.
373 var promise = PromiseCreate();
374 var callbacks = CreateResolvingFunctions(promise, debugEvent);
375 return { 376 return {
376 promise: promise, 377 promise: PromiseCreate(),
377 resolve: callbacks.resolve, 378 resolve: false,
378 reject: callbacks.reject 379 reject: false,
379 }; 380 };
380 } 381 }
381 382
382 var result = {promise: UNDEFINED, resolve: UNDEFINED, reject: UNDEFINED }; 383 var result = {promise: UNDEFINED, resolve: UNDEFINED, reject: UNDEFINED };
383 result.promise = new C((resolve, reject) => { 384 result.promise = new C((resolve, reject) => {
384 if (!IS_UNDEFINED(result.resolve) || !IS_UNDEFINED(result.reject)) 385 if (!IS_UNDEFINED(result.resolve) || !IS_UNDEFINED(result.reject))
385 throw %make_type_error(kPromiseExecutorAlreadyInvoked); 386 throw %make_type_error(kPromiseExecutorAlreadyInvoked);
386 result.resolve = resolve; 387 result.resolve = resolve;
387 result.reject = reject; 388 result.reject = reject;
388 }); 389 });
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
467 // Combinators. 468 // Combinators.
468 469
469 // ES#sec-promise.resolve 470 // ES#sec-promise.resolve
470 // Promise.resolve ( x ) 471 // Promise.resolve ( x )
471 function PromiseResolve(x) { 472 function PromiseResolve(x) {
472 if (!IS_RECEIVER(this)) { 473 if (!IS_RECEIVER(this)) {
473 throw %make_type_error(kCalledOnNonObject, PromiseResolve); 474 throw %make_type_error(kCalledOnNonObject, PromiseResolve);
474 } 475 }
475 if (IsPromise(x) && x.constructor === this) return x; 476 if (IsPromise(x) && x.constructor === this) return x;
476 477
477 // Avoid creating resolving functions. 478 // debugEvent is not so meaningful here as it will be resolved
479 var promiseCapability = NewPromiseCapability(this, true);
480
478 if (this === GlobalPromise) { 481 if (this === GlobalPromise) {
479 var promise = PromiseCreate(); 482 ResolvePromise(promiseCapability.promise, x);
480 var resolveResult = ResolvePromise(promise, x); 483 } else {
481 return promise; 484 %_Call(promiseCapability.resolve, UNDEFINED, x);
482 } 485 }
483 486
484 // debugEvent is not so meaningful here as it will be resolved
485 var promiseCapability = NewPromiseCapability(this, true);
486 var resolveResult = %_Call(promiseCapability.resolve, UNDEFINED, x);
487 return promiseCapability.promise; 487 return promiseCapability.promise;
488 } 488 }
489 489
490 // ES#sec-promise.all 490 // ES#sec-promise.all
491 // Promise.all ( iterable ) 491 // Promise.all ( iterable )
492 function PromiseAll(iterable) { 492 function PromiseAll(iterable) {
493 if (!IS_RECEIVER(this)) { 493 if (!IS_RECEIVER(this)) {
494 throw %make_type_error(kCalledOnNonObject, "Promise.all"); 494 throw %make_type_error(kCalledOnNonObject, "Promise.all");
495 } 495 }
496 496
497 // false debugEvent so that forwarding the rejection through all does not 497 // false debugEvent so that forwarding the rejection through all does not
498 // trigger redundant ExceptionEvents 498 // trigger redundant ExceptionEvents
499 var deferred = NewPromiseCapability(this, false); 499 var deferred = NewPromiseCapability(this, false);
500 if (this === GlobalPromise) {
501 var callbacks = CreateResolvingFunctions(deferred.promise, false);
502 deferred.resolve = callbacks.resolve;
503 deferred.reject = callbacks.reject;
504 }
500 var resolutions = new InternalArray(); 505 var resolutions = new InternalArray();
501 var count; 506 var count;
502 507
503 // For catch prediction, don't treat the .then calls as handling it; 508 // For catch prediction, don't treat the .then calls as handling it;
504 // instead, recurse outwards. 509 // instead, recurse outwards.
505 var instrumenting = DEBUG_IS_ACTIVE; 510 var instrumenting = DEBUG_IS_ACTIVE;
506 if (instrumenting) { 511 if (instrumenting) {
507 SET_PRIVATE(deferred.reject, promiseForwardingHandlerSymbol, true); 512 SET_PRIVATE(deferred.reject, promiseForwardingHandlerSymbol, true);
508 } 513 }
509 514
510 function CreateResolveElementFunction(index, values, promiseCapability) { 515 function CreateResolveElementFunction(index, values, promiseCapability) {
511 var alreadyCalled = false; 516 var alreadyCalled = false;
512 return (x) => { 517 return function(x) {
513 if (alreadyCalled === true) return; 518 if (alreadyCalled === true) return;
514 alreadyCalled = true; 519 alreadyCalled = true;
515 values[index] = x; 520 values[index] = x;
516 if (--count === 0) { 521 if (--count === 0) {
517 var valuesArray = []; 522 var valuesArray = [];
518 %MoveArrayContents(values, valuesArray); 523 %MoveArrayContents(values, valuesArray);
519 %_Call(promiseCapability.resolve, UNDEFINED, valuesArray); 524 %_Call(promiseCapability.resolve, UNDEFINED, valuesArray);
520 } 525 }
521 }; 526 };
522 } 527 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
554 // ES#sec-promise.race 559 // ES#sec-promise.race
555 // Promise.race ( iterable ) 560 // Promise.race ( iterable )
556 function PromiseRace(iterable) { 561 function PromiseRace(iterable) {
557 if (!IS_RECEIVER(this)) { 562 if (!IS_RECEIVER(this)) {
558 throw %make_type_error(kCalledOnNonObject, PromiseRace); 563 throw %make_type_error(kCalledOnNonObject, PromiseRace);
559 } 564 }
560 565
561 // false debugEvent so that forwarding the rejection through race does not 566 // false debugEvent so that forwarding the rejection through race does not
562 // trigger redundant ExceptionEvents 567 // trigger redundant ExceptionEvents
563 var deferred = NewPromiseCapability(this, false); 568 var deferred = NewPromiseCapability(this, false);
569 if (this === GlobalPromise) {
570 var callbacks = CreateResolvingFunctions(deferred.promise, false);
adamk 2016/10/05 20:18:09 Ah, I didn't realize some callers need the callbac
571 deferred.resolve = callbacks.resolve;
572 deferred.reject = callbacks.reject;
573 }
564 574
565 // For catch prediction, don't treat the .then calls as handling it; 575 // For catch prediction, don't treat the .then calls as handling it;
566 // instead, recurse outwards. 576 // instead, recurse outwards.
567 var instrumenting = DEBUG_IS_ACTIVE; 577 var instrumenting = DEBUG_IS_ACTIVE;
568 if (instrumenting) { 578 if (instrumenting) {
569 SET_PRIVATE(deferred.reject, promiseForwardingHandlerSymbol, true); 579 SET_PRIVATE(deferred.reject, promiseForwardingHandlerSymbol, true);
570 } 580 }
571 581
572 try { 582 try {
573 for (var value of iterable) { 583 for (var value of iterable) {
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
696 to.PromiseNextMicrotaskID = PromiseNextMicrotaskID; 706 to.PromiseNextMicrotaskID = PromiseNextMicrotaskID;
697 707
698 to.GlobalPromise = GlobalPromise; 708 to.GlobalPromise = GlobalPromise;
699 to.NewPromiseCapability = NewPromiseCapability; 709 to.NewPromiseCapability = NewPromiseCapability;
700 to.PerformPromiseThen = PerformPromiseThen; 710 to.PerformPromiseThen = PerformPromiseThen;
701 to.ResolvePromise = ResolvePromise; 711 to.ResolvePromise = ResolvePromise;
702 to.RejectPromise = RejectPromise; 712 to.RejectPromise = RejectPromise;
703 }); 713 });
704 714
705 }) 715 })
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698