Skip to content

Commit 8f39dbc

Browse files
committedMay 26, 2019
Fixes #1326
1 parent 12154ad commit 8f39dbc

File tree

4 files changed

+22
-2
lines changed

4 files changed

+22
-2
lines changed
 

‎.jshintrc

+2
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,9 @@
8888
"CALLBACK_PROMISE_OFFSET": false,
8989
"CALLBACK_RECEIVER_OFFSET": false,
9090
"CALLBACK_SIZE": false,
91+
"ASYNC_GUARANTEE_SHIFT": false,
9192
"NO_STATE": false,
93+
"NO_ASYNC_GUARANTEE": false,
9294
"RETURNED_NON_UNDEFINED": false,
9395
"IS_ASYNC_GUARANTEED": false,
9496
"IS_FOLLOWING": false,

‎src/constants.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,11 @@ CONSTANT(CALLBACK_PROMISE_OFFSET, 2);
2828
CONSTANT(CALLBACK_RECEIVER_OFFSET, 3);
2929
CONSTANT(CALLBACK_SIZE, 4);
3030
//Layout for ._bitField
31-
//[RR]RO GWFN CTBH IUDE LLLL LLLL LLLL LLLL
31+
//[RR]XO GWFN CTBH IUDE LLLL LLLL LLLL LLLL
3232
//[RR] = [Reserved] (Both bits are either on or off to represent
3333
// 1 bit due to 31-bit integers in 32-bit v8)
3434
//R = [Reserved]
35+
//X = noAsyncGuarantee
3536
//O = returnedNonUndefined
3637
//G = isAsyncGuaranteed
3738
//W = isFollowing (The promise that is being followed is not stored explicitly)
@@ -46,7 +47,9 @@ CONSTANT(CALLBACK_SIZE, 4);
4647
//D = isDisposable
4748
//E = isCancelled
4849
//L = Length, 16 bit unsigned
50+
CONSTANT(ASYNC_GUARANTEE_SHIFT, 2)
4951
CONSTANT(NO_STATE, 0x0|0);
52+
CONSTANT(NO_ASYNC_GUARANTEE, 0x20000000|0);
5053
CONSTANT(RETURNED_NON_UNDEFINED, 0x10000000|0);
5154
CONSTANT(IS_ASYNC_GUARANTEED, 0x8000000|0);
5255
CONSTANT(IS_FOLLOWING, 0x4000000|0);

‎src/promise.js

+9-1
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,15 @@ Promise.prototype._setWillBeCancelled = function() {
360360

361361
Promise.prototype._setAsyncGuaranteed = function() {
362362
if (async.hasCustomScheduler()) return;
363-
this._bitField = this._bitField | IS_ASYNC_GUARANTEED;
363+
var bitField = this._bitField;
364+
this._bitField = bitField |
365+
(((bitField & NO_ASYNC_GUARANTEE) >> ASYNC_GUARANTEE_SHIFT) ^
366+
IS_ASYNC_GUARANTEED);
367+
};
368+
369+
Promise.prototype._setNoAsyncGuarantee = function() {
370+
this._bitField = (this._bitField | NO_ASYNC_GUARANTEE) &
371+
(~IS_ASYNC_GUARANTEED);
364372
};
365373

366374
Promise.prototype._receiverAt = function (index) {

‎src/reduce.js

+7
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,14 @@ ReductionPromiseArray.prototype._iterate = function (values) {
110110
length: length,
111111
array: this
112112
};
113+
113114
value = value._then(gotAccum, undefined, undefined, ctx, undefined);
115+
116+
// Too many promises chained with asyncGuaranteed will result in
117+
// stack overflow. Break up long chains to reset stack.
118+
if ((i & 127) === 0) {
119+
value._setNoAsyncGuarantee();
120+
}
114121
}
115122
}
116123

0 commit comments

Comments
 (0)
Please sign in to comment.