12.14 try statement

2010-05-23

TryStatement :
try Block catch
try Block Finally
try Block Catch Finally

Catch :
catch ( Identifier ) Block

Finally :
finally Block

The try-catch Statements allow you to trap any errors or throw Statements. Whenever code within a try block throws an error, the code in catch will be executed, rather than exiting the program right there and then.

Whenever a catch clause catches an exception, its Identifier (the argument to catch) is said to be bound to that exception.

Note that catch creates a new scope, like function does. Probably because the catch Identifier needed to be bound.

Code: (Meta Ecma)
function evaluate(try Block Catch) {
var B = evaluate(Block);
if (B.type != 'throw') return B;
return evaluate(Catch, B); // B is param
}


Code: (Meta Ecma)
function evaluate(try Block Finally) {
var B = evaluate(Block);
var F = evaluate(Finally);
// if the finally block threw no error, return whatever the result of the try was
if (F.type == 'normal') return B;
// otherwise return the result of evaluating F
return F;
}


Code: (Meta Ecma)
function evaluate(try Block Catch Finally) {
var B = evaluate(Block);
if (B.type == 'throw') var C = evaluate(Catch, B);
else var C = B;
var F = evaluate(Finally);
// if the finally block threw no error, return whatever the result of the try was
if (F.type == 'normal') return C;
// otherwise return the result of evaluating F
return F;
}

The next function is called with parameter C (result of calling the try Block).

Code: (Meta Ecma)
function evaluate(catch ( Identifier ) Block, C) {
var rec = global.arrRunningExecutionContexts[global.arrRunningExecutionContexts.length-1];
var oldEnv = rec.LexicalEnvironment;
var catchEnv = NewDeclarativeEnvironment(oldEnv);
catchEnv.CreateMutableBinding(Identifier);
catchEnv.SetMutableBinding(Identifier, C, false); // "strict argument is immaterial"
rec.LexicalEnvironment = catchEnv;
var B = evaluate(Block);
rec.LexicalEnvironment = oldEnv;
return B;
}


Code: (Meta Ecma)
function evaluate(finally Block) {
return evaluate(Block);
}