12.10 with statement

2010-05-23

WithStatement :
with ( Expression ) Statement

The with statement adds an object environment record for the object returned by Expression to the lexical environment of the current execution context. After executing the Statement, it restores the original lexical environment. The Statement uses an augmented lexical environment.

Code: (Meta Ecma)
function evaluate(with ( Expression ) Statement) {
var val = evaluate(Expression);
var obj = ToObject(GetValue(val));
var rec = global.arrRunningExecutionContexts[global.arrRunningExecutionContexts.length-1];
var oldEnv = rec.LexicalEnvironment;
var newEnv = NewObjectEnvironment(obj, oldEnv);
newEnv.provideThis = true;
rec.LexicalEnvironment = newEnv;
// execute Statement, trap throws to restore env
try {
var C = evaluate(Statement);
} catch(E) {
var C = Completion(throw, V, undefined);
}
// first restore env (regardless of result)
rec.LexicalEnvironment = oldEnv;
// now return result of Statement
return C;
}

Note that if Statement throws an error with a target (not done in the spec) or a type that's not 'throw' (not sure how that's even possible), this does not propagate since the algorithm above creates a new Completion object when a throw occurs.

The with statement ALWAYS restores the old environment record before completing, regardless of what happens and even in the event of an error. It should be transparent in this regard though, throwing an error further and passing on the result.

As 12.10.1 says, the with statement is not allowed in strict mode.