use of com.github.anba.es6draft.compiler.Labels.TempLabel in project es6draft by anba.
the class StatementGenerator method emitFinallyBlock.
private Completion emitFinallyBlock(TryStatement node, Variable<LexicalEnvironment<?>> savedEnv, Value<Object> completion, Completion tryResult, Completion catchResult, TryCatchLabel handlerFinally, TryCatchLabel handlerFinallyStackOverflow, Jump noException, List<TempLabel> tempLabels, CodeVisitor mv) {
BlockStatement finallyBlock = node.getFinallyBlock();
assert finallyBlock != null;
// various finally blocks (1 - 4)
// (1) finally block for abrupt throw completions within 'try-catch'
mv.enterVariableScope();
Variable<Throwable> throwable = mv.newVariable("throwable", Throwable.class);
mv.catchHandler(handlerFinallyStackOverflow, Types.Error);
mv.invoke(Methods.ErrorOperations_stackOverflowError);
mv.catchHandler(handlerFinally, Types.ScriptException);
mv.store(throwable);
restoreEnvironment(savedEnv, mv);
Completion finallyResult = finallyBlock.accept(this, mv);
if (!finallyResult.isAbrupt()) {
mv.load(throwable);
mv.athrow();
}
mv.exitVariableScope();
// (2) finally block if 'try' did not complete abruptly
// (3) finally block if 'catch' did not complete abruptly
Jump exceptionHandled = null;
if (!tryResult.isAbrupt() || !catchResult.isAbrupt()) {
mv.mark(noException);
finallyBlock.accept(this, mv);
if (!finallyResult.isAbrupt()) {
if (node.hasCompletionValue()) {
mv.storeCompletionValue(completion);
}
if (!tempLabels.isEmpty()) {
exceptionHandled = new Jump();
mv.goTo(exceptionHandled);
}
}
}
// (4) finally blocks for other abrupt completion (return, break, continue)
for (TempLabel temp : tempLabels) {
if (temp.isTarget()) {
mv.mark(temp);
restoreEnvironment(savedEnv, mv);
finallyBlock.accept(this, mv);
if (!finallyResult.isAbrupt()) {
if (node.hasCompletionValue()) {
mv.storeCompletionValue(completion);
}
mv.goTo(temp, completion);
}
}
}
if (exceptionHandled != null) {
mv.mark(exceptionHandled);
}
return finallyResult;
}
use of com.github.anba.es6draft.compiler.Labels.TempLabel in project es6draft by anba.
the class StatementGenerator method visitTryCatchFinally.
/**
* 13.15.8 Runtime Semantics: Evaluation<br>
*
* <code>try-catch-finally</code>
*
* @param node
* the try-statement
* @param mv
* the code visitor
* @return the completion value
*/
private Completion visitTryCatchFinally(TryStatement node, CodeVisitor mv) {
TryCatchLabel startCatchFinally = new TryCatchLabel();
TryCatchLabel endCatch = new TryCatchLabel(), handlerCatch = new TryCatchLabel();
TryCatchLabel endFinally = new TryCatchLabel(), handlerFinally = new TryCatchLabel();
TryCatchLabel handlerCatchStackOverflow = new TryCatchLabel();
TryCatchLabel handlerFinallyStackOverflow = new TryCatchLabel();
Jump noException = new Jump();
mv.enterVariableScope();
Variable<LexicalEnvironment<?>> savedEnv = saveEnvironment(mv);
MutableValue<Object> completion = mv.enterFinallyScoped(node);
/* step 1 */
// Emit try-block
mv.mark(startCatchFinally);
Completion tryResult = emitTryBlock(node, noException, mv);
mv.mark(endCatch);
/* steps 2-3 */
// Emit catch-block
Completion catchResult = emitCatchBlock(node, savedEnv, handlerCatch, handlerCatchStackOverflow, mv);
if (!catchResult.isAbrupt()) {
mv.goTo(noException);
}
mv.mark(endFinally);
// Restore temporary abrupt targets
List<TempLabel> tempLabels = mv.exitFinallyScoped();
/* step 4 */
// Emit finally-block
Completion finallyResult = emitFinallyBlock(node, savedEnv, completion, tryResult, catchResult, handlerFinally, handlerFinallyStackOverflow, noException, tempLabels, mv);
mv.exitVariableScope();
mv.tryCatch(startCatchFinally, endCatch, handlerCatch, Types.ScriptException);
mv.tryCatch(startCatchFinally, endCatch, handlerCatchStackOverflow, Types.Error);
mv.tryCatch(startCatchFinally, endFinally, handlerFinally, Types.ScriptException);
mv.tryCatch(startCatchFinally, endFinally, handlerFinallyStackOverflow, Types.Error);
/* steps 5-8 */
return finallyResult.then(tryResult.select(catchResult));
}
use of com.github.anba.es6draft.compiler.Labels.TempLabel in project es6draft by anba.
the class StatementGenerator method AsyncForInOfBodyEvaluation.
/**
* 13.7.5.13 Runtime Semantics: ForIn/OfBodyEvaluation (lhs, stmt, iterator, lhsKind, labelSet)
* <p>
* stack: [Iterator] {@literal ->} []
*
* @param <FORSTATEMENT>
* the for-statement node type
* @param node
* the for-statement node
* @param mv
* the code visitor
* @return the completion value
*/
private <FORSTATEMENT extends IterationStatement & ForIterationNode> Completion AsyncForInOfBodyEvaluation(FORSTATEMENT node, CodeVisitor mv) {
assert mv.getStackSize() == 1;
ContinueLabel lblContinue = new ContinueLabel();
BreakLabel lblBreak = new BreakLabel();
Jump enter = new Jump(), test = new Jump();
mv.enterVariableScope();
Variable<ScriptIterator<?>> iterRec = mv.newVariable("iterRec", ScriptIterator.class).uncheckedCast();
Variable<ScriptObject> iterator = mv.newVariable("iter", ScriptObject.class);
// stack: [Iterator] -> []
mv.store(iterRec);
mv.load(iterRec);
mv.invoke(Methods.ScriptIterator_getScriptObject);
mv.store(iterator);
Variable<ScriptObject> nextResult = mv.newVariable("nextResult", ScriptObject.class);
mv.anull();
mv.store(nextResult);
Variable<Object> nextValue = mv.newVariable("nextValue", Object.class);
mv.anull();
mv.store(nextValue);
Variable<LexicalEnvironment<?>> savedEnv = saveEnvironment(node, mv);
/* step 2 */
if (node.hasCompletionValue()) {
mv.storeUndefinedAsCompletionValue();
}
/* steps 3-4 (not applicable) */
/* step 5 (repeat loop) */
mv.nonDestructiveGoTo(test);
/* steps 5.d-e */
mv.mark(enter);
IteratorValue(node, nextResult, mv);
mv.store(nextValue);
/* steps 5.f-l */
{
mv.enterIteration(node, lblBreak, lblContinue);
mv.enterWrapped();
new AbstractIterationGenerator<FORSTATEMENT, ScriptObject>(codegen) {
@Override
protected Completion iterationBody(FORSTATEMENT node, Variable<ScriptObject> iterator, CodeVisitor mv) {
return ForInOfBodyEvaluationInner(node, nextValue, mv);
}
@Override
protected MutableValue<Object> enterIteration(FORSTATEMENT node, CodeVisitor mv) {
return mv.enterIterationBody(node);
}
@Override
protected List<TempLabel> exitIteration(FORSTATEMENT node, CodeVisitor mv) {
return mv.exitIterationBody(node);
}
@Override
protected void IteratorClose(FORSTATEMENT node, Variable<ScriptObject> iterator, Variable<? extends Throwable> throwable, CodeVisitor mv) {
asyncIteratorClose(node, iterator, throwable, mv);
}
@Override
protected void IteratorClose(FORSTATEMENT node, Variable<ScriptObject> iterator, CodeVisitor mv) {
asyncIteratorClose(node, iterator, mv);
}
}.generate(node, iterator, test, mv);
mv.exitWrapped();
mv.exitIteration(node);
}
/* steps 5.m-n */
if (lblContinue.isTarget()) {
mv.mark(lblContinue);
restoreEnvironment(savedEnv, mv);
}
/* steps 5.a-c */
mv.mark(test);
mv.load(iterRec);
mv.invoke(Methods.ScriptIterator_nextIterResult);
await(node, mv);
requireObjectResult(node, "next", mv);
mv.store(nextResult);
IteratorComplete(node, nextResult, mv);
mv.ifeq(enter);
/* steps 5.m-n */
if (lblBreak.isTarget()) {
mv.mark(lblBreak);
restoreEnvironment(savedEnv, mv);
}
mv.exitVariableScope();
return Completion.Normal;
}
use of com.github.anba.es6draft.compiler.Labels.TempLabel in project es6draft by anba.
the class AbstractIterationGenerator method emitReturnHandler.
private void emitReturnHandler(NODE node, Variable<ITERATOR> iterator, Value<Object> completion, List<TempLabel> tempLabels, CodeVisitor mv) {
// (1) Intercept return instructions
for (TempLabel temp : tempLabels) {
if (temp.isTarget()) {
mv.mark(temp);
IteratorClose(node, iterator, mv);
mv.goTo(temp, completion);
}
}
}
use of com.github.anba.es6draft.compiler.Labels.TempLabel in project es6draft by anba.
the class AbstractIterationGenerator method generate.
/**
* Emit code for the wrapped iteration.
*
* @param node
* the ast node
* @param iterator
* the iterator variable
* @param target
* the target label
* @param mv
* the code visitor
* @return the completion value
*/
public final Completion generate(NODE node, Variable<ITERATOR> iterator, Jump target, CodeVisitor mv) {
TryCatchLabel startIteration = new TryCatchLabel(), endIteration = new TryCatchLabel();
TryCatchLabel handlerCatch = new TryCatchLabel();
TryCatchLabel handlerCatchStackOverflow = null;
if (codegen.isEnabled(Compiler.Option.IterationCatchStackOverflow)) {
handlerCatchStackOverflow = new TryCatchLabel();
}
boolean hasTarget = target != null;
if (!hasTarget) {
target = new Jump();
}
mv.enterVariableScope();
MutableValue<Object> completion = enterIteration(node, mv);
// Emit loop body
mv.mark(startIteration);
Completion loopBodyResult = iterationBody(node, iterator, mv);
if (!loopBodyResult.isAbrupt()) {
mv.goTo(target);
}
mv.mark(endIteration);
// Restore temporary abrupt targets
List<TempLabel> tempLabels = exitIteration(node, mv);
// Emit throw handler
emitThrowHandler(node, iterator, handlerCatch, handlerCatchStackOverflow, mv);
// Emit return handler
emitReturnHandler(node, iterator, completion, tempLabels, mv);
mv.exitVariableScope();
mv.tryCatch(startIteration, endIteration, handlerCatch, Types.ScriptException);
if (handlerCatchStackOverflow != null) {
mv.tryCatch(startIteration, endIteration, handlerCatchStackOverflow, Types.Error);
}
if (!hasTarget) {
mv.mark(target);
epilogue(node, iterator, mv);
}
return loopBodyResult;
}
Aggregations