Skip to content

Commit

Permalink
Merge pull request #11547 from stefanpenner/revert-ios-6.0.x-double-f…
Browse files Browse the repository at this point in the history
…inally-on-error

Revert "Fixes: Safari's 'double finally on error bug'"
  • Loading branch information
rwjblue committed Jun 26, 2015
2 parents 6130fa6 + 7847cc4 commit 9c919ca
Show file tree
Hide file tree
Showing 8 changed files with 38 additions and 467 deletions.
33 changes: 16 additions & 17 deletions packages/ember-metal/lib/events.js
Expand Up @@ -10,7 +10,6 @@
import Ember from 'ember-metal/core';
import {
meta as metaFor,
tryFinally,
apply,
applyStr
} from 'ember-metal/utils';
Expand Down Expand Up @@ -221,10 +220,13 @@ export function suspendListener(obj, eventName, target, method, callback) {
actions[actionIndex+2] |= SUSPENDED; // mark the action as suspended
}

function tryable() { return callback.call(target); }
function finalizer() { if (actionIndex !== -1) { actions[actionIndex+2] &= ~SUSPENDED; } }

return tryFinally(tryable, finalizer);
try {
return callback.call(target);
} finally {
if (actionIndex !== -1) {
actions[actionIndex+2] &= ~SUSPENDED;
}
}
}

/**
Expand All @@ -248,12 +250,11 @@ export function suspendListeners(obj, eventNames, target, method, callback) {

var suspendedActions = [];
var actionsList = [];
var eventName, actions, i, l;

for (i=0, l=eventNames.length; i<l; i++) {
eventName = eventNames[i];
actions = actionsFor(obj, eventName);
var actionIndex = indexOf(actions, target, method);
for (let i=0, l=eventNames.length; i<l; i++) {
let eventName = eventNames[i];
let actions = actionsFor(obj, eventName);
let actionIndex = indexOf(actions, target, method);

if (actionIndex !== -1) {
actions[actionIndex+2] |= SUSPENDED;
Expand All @@ -262,16 +263,14 @@ export function suspendListeners(obj, eventNames, target, method, callback) {
}
}

function tryable() { return callback.call(target); }

function finalizer() {
for (var i = 0, l = suspendedActions.length; i < l; i++) {
var actionIndex = suspendedActions[i];
try {
return callback.call(target);
} finally {
for (let i = 0, l = suspendedActions.length; i < l; i++) {
let actionIndex = suspendedActions[i];
actionsList[i][actionIndex+2] &= ~SUSPENDED;
}
}

return tryFinally(tryable, finalizer);
}

/**
Expand Down
25 changes: 14 additions & 11 deletions packages/ember-metal/lib/instrumentation.js
@@ -1,5 +1,4 @@
import Ember from 'ember-metal/core';
import { tryCatchFinally } from 'ember-metal/utils';

/**
The purpose of the Ember Instrumentation module is
Expand Down Expand Up @@ -97,22 +96,26 @@ export function instrument(name, _payload, callback, binding) {
return callback.call(binding);
}
var payload = _payload || {};
var finalizer = _instrumentStart(name, function () {
return payload;
});
var finalizer = _instrumentStart(name, () => payload);

if (finalizer) {
var tryable = function _instrumenTryable() {
return callback.call(binding);
};
var catchable = function _instrumentCatchable(e) {
payload.exception = e;
};
return tryCatchFinally(tryable, catchable, finalizer);
return withFinalizer(callback, finalizer, payload, binding);
} else {
return callback.call(binding);
}
}

function withFinalizer(callback, finalizer, payload, binding) {
try {
return callback.call(binding);
} catch(e) {
payload.exception = e;
return payload;
} finally {
return finalizer();
}
}

// private for now
export function _instrumentStart(name, _payload) {
var listeners = cache[name];
Expand Down
1 change: 0 additions & 1 deletion packages/ember-metal/lib/main.js
Expand Up @@ -241,7 +241,6 @@ Ember.tryCatchFinally = deprecatedTryCatchFinally;
Ember.makeArray = makeArray;
Ember.canInvoke = canInvoke;
Ember.tryInvoke = tryInvoke;
Ember.tryFinally = deprecatedTryFinally;
Ember.wrap = wrap;
Ember.apply = apply;
Ember.applyStr = applyStr;
Expand Down
9 changes: 6 additions & 3 deletions packages/ember-metal/lib/property_events.js
@@ -1,6 +1,5 @@
import {
guidFor,
tryFinally
guidFor
} from 'ember-metal/utils';
import {
sendEvent,
Expand Down Expand Up @@ -276,7 +275,11 @@ function endPropertyChanges() {
*/
function changeProperties(callback, binding) {
beginPropertyChanges();
tryFinally(callback, endPropertyChanges, binding);
try {
callback.call(binding);
} finally {
endPropertyChanges.call(binding);
}
}

function notifyBeforeObservers(obj, keyName) {
Expand Down
3 changes: 1 addition & 2 deletions packages/ember-metal/lib/run_loop.js
Expand Up @@ -62,8 +62,7 @@ var backburner = new Backburner(['sync', 'actions', 'destroy'], {
@return {Object} return value from invoking the passed function.
@public
*/
export default run;
function run() {
export default function run() {
return backburner.run(...arguments);
}

Expand Down
180 changes: 1 addition & 179 deletions packages/ember-metal/lib/utils.js
Expand Up @@ -539,180 +539,6 @@ export function tryInvoke(obj, methodName, args) {
}
}

// https://github.com/emberjs/ember.js/pull/1617
var needsFinallyFix = (function() {
var count = 0;
try {
// jscs:disable
try {
} finally {
count++;
throw new Error('needsFinallyFixTest');
}
// jscs:enable
} catch (e) {}

return count !== 1;
})();

/**
Provides try/finally functionality, while working
around Safari's double finally bug.
```javascript
var tryable = function() {
someResource.lock();
runCallback(); // May throw error.
};
var finalizer = function() {
someResource.unlock();
};
Ember.tryFinally(tryable, finalizer);
```
@method tryFinally
@deprecated Use JavaScript's native try/finally
@for Ember
@param {Function} tryable The function to run the try callback
@param {Function} finalizer The function to run the finally callback
@param {Object} [binding] The optional calling object. Defaults to 'this'
@return {*} The return value is the that of the finalizer,
unless that value is undefined, in which case it is the return value
of the tryable
@private
*/

var tryFinally;
if (needsFinallyFix) {
tryFinally = function(tryable, finalizer, binding) {
var result, finalResult, finalError;

binding = binding || this;

try {
result = tryable.call(binding);
} finally {
try {
finalResult = finalizer.call(binding);
} catch (e) {
finalError = e;
}
}

if (finalError) { throw finalError; }

return (finalResult === undefined) ? result : finalResult;
};
} else {
tryFinally = function(tryable, finalizer, binding) {
var result, finalResult;

binding = binding || this;

try {
result = tryable.call(binding);
} finally {
finalResult = finalizer.call(binding);
}

return (finalResult === undefined) ? result : finalResult;
};
}

var deprecatedTryFinally = function() {
Ember.deprecate('tryFinally is deprecated. Please use JavaScript\'s native try/finally.', false);
return tryFinally.apply(this, arguments);
};

/**
Provides try/catch/finally functionality, while working
around Safari's double finally bug.
```javascript
var tryable = function() {
for (i = 0, l = listeners.length; i < l; i++) {
listener = listeners[i];
beforeValues[i] = listener.before(name, time(), payload);
}
return callback.call(binding);
};
var catchable = function(e) {
payload = payload || {};
payload.exception = e;
};
var finalizer = function() {
for (i = 0, l = listeners.length; i < l; i++) {
listener = listeners[i];
listener.after(name, time(), payload, beforeValues[i]);
}
};
Ember.tryCatchFinally(tryable, catchable, finalizer);
```
@method tryCatchFinally
@deprecated Use JavaScript's native try/catch/finally instead
@for Ember
@param {Function} tryable The function to run the try callback
@param {Function} catchable The function to run the catchable callback
@param {Function} finalizer The function to run the finally callback
@param {Object} [binding] The optional calling object. Defaults to 'this'
@return {*} The return value is the that of the finalizer,
unless that value is undefined, in which case it is the return value
of the tryable.
@private
*/
var tryCatchFinally;
if (needsFinallyFix) {
tryCatchFinally = function(tryable, catchable, finalizer, binding) {
var result, finalResult, finalError;

binding = binding || this;

try {
result = tryable.call(binding);
} catch(error) {
result = catchable.call(binding, error);
} finally {
try {
finalResult = finalizer.call(binding);
} catch (e) {
finalError = e;
}
}

if (finalError) { throw finalError; }

return (finalResult === undefined) ? result : finalResult;
};
} else {
tryCatchFinally = function(tryable, catchable, finalizer, binding) {
var result, finalResult;

binding = binding || this;

try {
result = tryable.call(binding);
} catch(error) {
result = catchable.call(binding, error);
} finally {
finalResult = finalizer.call(binding);
}

return (finalResult === undefined) ? result : finalResult;
};
}

var deprecatedTryCatchFinally = function() {
Ember.deprecate('tryCatchFinally is deprecated. Please use JavaScript\'s native try/catch/finally.', false);
return tryCatchFinally.apply(this, arguments);
};

// ........................................
// TYPING & ARRAY MESSAGING
//
Expand Down Expand Up @@ -846,9 +672,5 @@ export {
EMPTY_META,
meta,
makeArray,
tryCatchFinally,
deprecatedTryCatchFinally,
canInvoke,
tryFinally,
deprecatedTryFinally
canInvoke
};

0 comments on commit 9c919ca

Please sign in to comment.