Skip to content

Commit

Permalink
Merge pull request #539 from tildeio/remove-try-catch-avoidance
Browse files Browse the repository at this point in the history
Remove try/catch avoidance, as modern runtimes should not longer need…
  • Loading branch information
stefanpenner committed Jun 6, 2019
2 parents 92aff41 + 98fe2e8 commit 2b8fd20
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 86 deletions.
61 changes: 21 additions & 40 deletions lib/rsvp/-internal.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,38 +20,17 @@ export const PENDING = void 0;
export const FULFILLED = 1;
export const REJECTED = 2;

export const TRY_CATCH_ERROR = { error: null };

export function getThen(promise) {
function tryThen(then, value, fulfillmentHandler, rejectionHandler) {
try {
return promise.then;
} catch(error) {
TRY_CATCH_ERROR.error = error;
return TRY_CATCH_ERROR;
}
}

let tryCatchCallback;
function tryCatcher() {
try {
let target = tryCatchCallback;
tryCatchCallback = null;
return target.apply(this, arguments);
then.call(value, fulfillmentHandler, rejectionHandler);
} catch(e) {
TRY_CATCH_ERROR.error = e;
return TRY_CATCH_ERROR;
return e;
}
}

export function tryCatch(fn) {
tryCatchCallback = fn;
return tryCatcher;
}

function handleForeignThenable(promise, thenable, then) {
config.async(promise => {
let sealed = false;
let result = tryCatch(then).call(
let error = tryThen(then,
thenable,
value => {
if (sealed) { return; }
Expand All @@ -70,14 +49,10 @@ function handleForeignThenable(promise, thenable, then) {
},
'Settle: ' + (promise._label || ' unknown promise')
);

if (!sealed && result === TRY_CATCH_ERROR) {
if (!sealed && error) {
sealed = true;
let error = TRY_CATCH_ERROR.error;
TRY_CATCH_ERROR.error = null;
reject(promise, error);
}

}, promise);
}

Expand Down Expand Up @@ -106,10 +81,6 @@ export function handleMaybeThenable(promise, maybeThenable, then) {

if (isOwnThenable) {
handleOwnThenable(promise, maybeThenable);
} else if (then === TRY_CATCH_ERROR) {
let error = TRY_CATCH_ERROR.error
TRY_CATCH_ERROR.error = null;
reject(promise, error);
} else if (typeof then === 'function') {
handleForeignThenable(promise, maybeThenable, then);
} else {
Expand All @@ -121,7 +92,14 @@ export function resolve(promise, value) {
if (promise === value) {
fulfill(promise, value);
} else if (objectOrFunction(value)) {
handleMaybeThenable(promise, value, getThen(value));
let then;
try {
then = value.then;
} catch (error) {
reject(promise, error);
return;
}
handleMaybeThenable(promise, value, then);
} else {
fulfill(promise, value);
}
Expand Down Expand Up @@ -200,10 +178,15 @@ export function publish(promise) {

export function invokeCallback(state, promise, callback, result) {
let hasCallback = typeof callback === 'function';
let value;
let value, succeeded = true, error;

if (hasCallback) {
value = tryCatch(callback)(result);
try {
value = callback(result)
} catch (e) {
succeeded = false;
error = e;
}
} else {
value = result;
}
Expand All @@ -212,9 +195,7 @@ export function invokeCallback(state, promise, callback, result) {
// noop
} else if (value === promise) {
reject(promise, withOwnPromise());
} else if (value === TRY_CATCH_ERROR) {
let error = TRY_CATCH_ERROR.error;
TRY_CATCH_ERROR.error = null; // release
} else if (succeeded === false) {
reject(promise, error);
} else if (hasCallback) {
resolve(promise, value);
Expand Down
17 changes: 13 additions & 4 deletions lib/rsvp/enumerator.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
FULFILLED,
REJECTED,
PENDING,
getThen
} from './-internal';

import { default as OwnPromise } from './promise';
Expand Down Expand Up @@ -57,7 +56,13 @@ export default class Enumerator {
let c = this._instanceConstructor;

if (this._isUsingOwnResolve) {
let then = getThen(entry);
let then, error, succeeded = true;
try {
then = entry.then;
} catch (e) {
succeeded = false;
error = e;
}

if (then === ownThen && entry._state !== PENDING) {
entry._onError = null;
Expand All @@ -66,8 +71,12 @@ export default class Enumerator {
this._settledAt(FULFILLED, i, entry, firstPass);
} else if (this._isUsingOwnPromise) {
let promise = new c(noop);
handleMaybeThenable(promise, entry, then);
this._willSettleAt(promise, i, firstPass);
if (succeeded === false) {
reject(promise, error);
} else {
handleMaybeThenable(promise, entry, then);
this._willSettleAt(promise, i, firstPass);
}
} else {
this._willSettleAt(new c(resolve => resolve(entry)), i, firstPass);
}
Expand Down
14 changes: 8 additions & 6 deletions lib/rsvp/filter.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import Promise from './promise';
import { MapEnumerator } from './map';
import {
tryCatch,
fulfill,
TRY_CATCH_ERROR,
REJECTED
} from './-internal';

Expand All @@ -22,10 +20,14 @@ class FilterEnumerator extends MapEnumerator {
_setResultAt(state, i, value, firstPass) {
if (firstPass) {
this._result[i] = value;
let val = tryCatch(this._mapFn)(value, i);
if (val === TRY_CATCH_ERROR) {
this._settledAt(REJECTED, i, val.error, false);
} else {
let val, succeeded = true;
try {
val = this._mapFn(value, i);
} catch (error) {
succeeded = false;
this._settledAt(REJECTED, i, error, false);
}
if (succeeded) {
this._eachEntry(val, i, false);
}
} else {
Expand Down
12 changes: 4 additions & 8 deletions lib/rsvp/map.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ import {
default as Enumerator
} from './enumerator';
import {
tryCatch,
TRY_CATCH_ERROR,
REJECTED
} from './-internal';

Expand All @@ -25,18 +23,16 @@ export class MapEnumerator extends Enumerator {

_setResultAt(state, i, value, firstPass) {
if (firstPass) {
let val = tryCatch(this._mapFn)(value, i);
if (val === TRY_CATCH_ERROR) {
this._settledAt(REJECTED, i, val.error, false);
} else {
this._eachEntry(val, i, false);
try {
this._eachEntry(this._mapFn(value, i), i, false);
} catch (error) {
this._settledAt(REJECTED, i, error, false);
}
} else {
this._remaining--;
this._result[i] = value;
}
}

}


Expand Down
49 changes: 21 additions & 28 deletions lib/rsvp/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@ import {
noop,
resolve,
reject,
getThen,
tryCatch,
TRY_CATCH_ERROR
} from './-internal';

function makeObject(_, argumentNames) {
Expand Down Expand Up @@ -179,17 +176,26 @@ export default function denodeify(nodeFunc, options) {

for (let i = 0; i < l; ++i) {
let arg = arguments[i];
let then;

// TODO: this code really needs to be cleaned up
if (!promiseInput) {
// TODO: clean this up
promiseInput = needsPromiseInput(arg);
if (promiseInput === TRY_CATCH_ERROR) {
let error = TRY_CATCH_ERROR.error;
TRY_CATCH_ERROR.error = null;
let p = new Promise(noop);
reject(p, error);
return p;
} else if (promiseInput && promiseInput !== true) {
if (arg !== null && typeof arg === 'object') {
if (arg.constructor === Promise) {
promiseInput = true;
} else {
try {
promiseInput = arg.then;
} catch(error) {
let p = new Promise(noop);
reject(p, error);
return p;
}
}
} else {
promiseInput = false;
}
if (promiseInput && promiseInput !== true) {
arg = wrapThenable(promiseInput, arg);
}
}
Expand Down Expand Up @@ -225,10 +231,9 @@ export default function denodeify(nodeFunc, options) {
}

function handleValueInput(promise, args, nodeFunc, self) {
let result = tryCatch(nodeFunc).apply(self, args);
if (result === TRY_CATCH_ERROR) {
let error = TRY_CATCH_ERROR.error;
TRY_CATCH_ERROR.error = null;
try {
nodeFunc.apply(self, args);
} catch (error) {
reject(promise, error);
}
return promise;
Expand All @@ -238,15 +243,3 @@ function handlePromiseInput(promise, args, nodeFunc, self){
return Promise.all(args)
.then(args => handleValueInput(promise, args, nodeFunc, self));
}

function needsPromiseInput(arg) {
if (arg !== null && typeof arg === 'object') {
if (arg.constructor === Promise) {
return true;
} else {
return getThen(arg);
}
} else {
return false;
}
}

0 comments on commit 2b8fd20

Please sign in to comment.