Skip to content

Commit

Permalink
Fix memory leak
Browse files Browse the repository at this point in the history
Fixes the memory described at
promises-aplus/promises-spec#179
  • Loading branch information
petkaantonov committed Dec 28, 2014
1 parent 3e4bbe3 commit 8c1edaf
Show file tree
Hide file tree
Showing 15 changed files with 445 additions and 269 deletions.
2 changes: 1 addition & 1 deletion src/cancel.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Promise.prototype._cancel = function (reason) {
ASSERT(promiseToReject.isCancellable());
this._unsetCancellable();
promiseToReject._attachExtraTrace(reason);
promiseToReject._rejectUnchecked(reason);
promiseToReject._target()._rejectUnchecked(reason);
};

Promise.prototype.cancel = function (reason) {
Expand Down
5 changes: 1 addition & 4 deletions src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ CONSTANT(CALLBACK_PROMISE_OFFSET, 3);
CONSTANT(CALLBACK_RECEIVER_OFFSET, 4);
CONSTANT(CALLBACK_SIZE, 5);
//Layout for ._bitField
//QQWF NCTR BPHS UDLL LLLL LLLL LLLL LLLL
//QQWF NCTR B[R]HS UDLL LLLL LLLL LLLL LLLL
//Q = isSettlePromisesQueued (Both bits are either on or off to represent
// 1 bit due to 31-bit integers in 32-bit v8)
//W = isFollowing (The promise that is being followed is not stored explicitly)
Expand All @@ -36,8 +36,6 @@ CONSTANT(CALLBACK_SIZE, 5);
//C = isCancellable
//T = isFinal (used for .done() implementation)
//B = isBound
//P = isProxied (optimization when .then listeners on a promise are
// just respective fate sealers on some other promise)
//H = isRejectionUnhandled
//S = isCarryingStackTrace
//U = isUnhanldedRejectionNotified
Expand All @@ -52,7 +50,6 @@ CONSTANT(IS_REJECTED, 0x8000000|0);
CONSTANT(IS_CANCELLABLE, 0x4000000|0);
CONSTANT(IS_FINAL, 0x2000000|0);
CONSTANT(IS_BOUND, 0x800000|0);
CONSTANT(IS_PROXIED, 0x400000|0);
CONSTANT(IS_REJECTION_UNHANDLED, 0x200000|0);
CONSTANT(IS_CARRYING_STACK_TRACE, 0x100000|0);
CONSTANT(IS_UNHANDLED_REJECTION_NOTIFIED, 0x80000|0);
Expand Down
2 changes: 2 additions & 0 deletions src/finally.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ function finallyHandler(reasonOrValue) {
if (ret !== undefined) {
var maybePromise = tryConvertToPromise(ret, undefined);
if (maybePromise instanceof Promise) {
maybePromise = maybePromise._target();
return promisedFinally(maybePromise, reasonOrValue,
promise.isFulfilled());
}
Expand Down Expand Up @@ -70,6 +71,7 @@ function tapHandler(value) {
if (ret !== undefined) {
var maybePromise = tryConvertToPromise(ret, undefined);
if (maybePromise instanceof Promise) {
maybePromise = maybePromise._target();
return promisedFinally(maybePromise, value, true);
}
}
Expand Down
9 changes: 5 additions & 4 deletions src/join.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,15 @@ Promise.join = function () {
for (var i = 0; i < last; ++i) {
var maybePromise = tryConvertToPromise(arguments[i], undefined);
if (maybePromise instanceof Promise) {
if (maybePromise.isPending()) {
maybePromise = maybePromise._target();
if (maybePromise._isPending()) {
maybePromise._then(callbacks[i], reject,
undefined, ret, holder);
} else if (maybePromise.isFulfilled()) {
} else if (maybePromise._isFulfilled()) {
callbacks[i].call(ret,
maybePromise._settledValue, holder);
maybePromise._value(), holder);
} else {
ret._reject(maybePromise._settledValue);
ret._reject(maybePromise._reason());
maybePromise._unsetRejectionIsUnhandled();
}
} else {
Expand Down
9 changes: 5 additions & 4 deletions src/map.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,16 @@ MappingPromiseArray.prototype._promiseFulfilled = function (value, index) {
// anymore), the marker PENDING is put at that index
var maybePromise = tryConvertToPromise(ret, this._promise);
if (maybePromise instanceof Promise) {
if (maybePromise.isPending()) {
maybePromise = maybePromise._target();
if (maybePromise._isPending()) {
if (limit >= 1) this._inFlight++;
values[index] = PENDING;
return maybePromise._proxyPromiseArray(this, index);
} else if (maybePromise.isFulfilled()) {
ret = maybePromise._settledValue;
} else if (maybePromise._isFulfilled()) {
ret = maybePromise._value();
} else {
maybePromise._unsetRejectionIsUnhandled();
return this._reject(maybePromise._settledValue);
return this._reject(maybePromise._reason());
}
}
values[index] = ret;
Expand Down
6 changes: 2 additions & 4 deletions src/progress.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Promise.prototype.progressed = function (handler) {

Promise.prototype._progress = function (progressValue) {
if (this._isFollowingOrFulfilledOrRejected()) return;
this._progressUnchecked(progressValue);
this._target()._progressUnchecked(progressValue);

};

Expand Down Expand Up @@ -67,7 +67,7 @@ Promise.prototype._doProgressWith = function (progression) {


Promise.prototype._progressUnchecked = function (progressValue) {
if (!this.isPending()) return;
ASSERT(!this._isFollowingOrFulfilledOrRejected());
var len = this._length();
var progress = this._progress;
for (var i = 0; i < len; i++) {
Expand All @@ -79,8 +79,6 @@ Promise.prototype._progressUnchecked = function (progressValue) {
var receiver = this._receiverAt(i);
if (typeof handler === "function") {
handler.call(receiver, progressValue, promise);
} else if (receiver instanceof Promise && receiver._isProxied()) {
receiver._progressUnchecked(progressValue);
} else if (receiver instanceof PromiseArray &&
!receiver._isResolved()) {
receiver._promiseProgressed(progressValue, promise);
Expand Down
Loading

0 comments on commit 8c1edaf

Please sign in to comment.