Skip to content

Commit

Permalink
Fixes #1326
Browse files Browse the repository at this point in the history
  • Loading branch information
petkaantonov committed May 26, 2019
1 parent 12154ad commit 8f39dbc
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 2 deletions.
2 changes: 2 additions & 0 deletions .jshintrc
Expand Up @@ -88,7 +88,9 @@
"CALLBACK_PROMISE_OFFSET": false,
"CALLBACK_RECEIVER_OFFSET": false,
"CALLBACK_SIZE": false,
"ASYNC_GUARANTEE_SHIFT": false,
"NO_STATE": false,
"NO_ASYNC_GUARANTEE": false,
"RETURNED_NON_UNDEFINED": false,
"IS_ASYNC_GUARANTEED": false,
"IS_FOLLOWING": false,
Expand Down
5 changes: 4 additions & 1 deletion src/constants.js
Expand Up @@ -28,10 +28,11 @@ CONSTANT(CALLBACK_PROMISE_OFFSET, 2);
CONSTANT(CALLBACK_RECEIVER_OFFSET, 3);
CONSTANT(CALLBACK_SIZE, 4);
//Layout for ._bitField
//[RR]RO GWFN CTBH IUDE LLLL LLLL LLLL LLLL
//[RR]XO GWFN CTBH IUDE LLLL LLLL LLLL LLLL
//[RR] = [Reserved] (Both bits are either on or off to represent
// 1 bit due to 31-bit integers in 32-bit v8)
//R = [Reserved]
//X = noAsyncGuarantee
//O = returnedNonUndefined
//G = isAsyncGuaranteed
//W = isFollowing (The promise that is being followed is not stored explicitly)
Expand All @@ -46,7 +47,9 @@ CONSTANT(CALLBACK_SIZE, 4);
//D = isDisposable
//E = isCancelled
//L = Length, 16 bit unsigned
CONSTANT(ASYNC_GUARANTEE_SHIFT, 2)
CONSTANT(NO_STATE, 0x0|0);
CONSTANT(NO_ASYNC_GUARANTEE, 0x20000000|0);
CONSTANT(RETURNED_NON_UNDEFINED, 0x10000000|0);
CONSTANT(IS_ASYNC_GUARANTEED, 0x8000000|0);
CONSTANT(IS_FOLLOWING, 0x4000000|0);
Expand Down
10 changes: 9 additions & 1 deletion src/promise.js
Expand Up @@ -360,7 +360,15 @@ Promise.prototype._setWillBeCancelled = function() {

Promise.prototype._setAsyncGuaranteed = function() {
if (async.hasCustomScheduler()) return;
this._bitField = this._bitField | IS_ASYNC_GUARANTEED;
var bitField = this._bitField;
this._bitField = bitField |
(((bitField & NO_ASYNC_GUARANTEE) >> ASYNC_GUARANTEE_SHIFT) ^
IS_ASYNC_GUARANTEED);
};

Promise.prototype._setNoAsyncGuarantee = function() {
this._bitField = (this._bitField | NO_ASYNC_GUARANTEE) &
(~IS_ASYNC_GUARANTEED);
};

Promise.prototype._receiverAt = function (index) {
Expand Down
7 changes: 7 additions & 0 deletions src/reduce.js
Expand Up @@ -110,7 +110,14 @@ ReductionPromiseArray.prototype._iterate = function (values) {
length: length,
array: this
};

value = value._then(gotAccum, undefined, undefined, ctx, undefined);

// Too many promises chained with asyncGuaranteed will result in
// stack overflow. Break up long chains to reset stack.
if ((i & 127) === 0) {
value._setNoAsyncGuarantee();
}
}
}

Expand Down

0 comments on commit 8f39dbc

Please sign in to comment.