use of com.github.anba.es6draft.ast.LegacyComprehensionFor in project es6draft by anba.
the class ComprehensionGenerator method visit.
/**
* Runtime Semantics: ComprehensionComponentEvaluation
* <p>
* ComprehensionFor : for ( ForBinding of AssignmentExpression )
*/
@Override
public Void visit(LegacyComprehensionFor node, CodeVisitor mv) {
Jump lblTest = new Jump(), lblLoop = new Jump(), lblFail = new Jump();
Variable<ScriptIterator<?>> iter = iterators.next();
ValType type = expressionBoxed(node.getExpression(), mv);
if (type != ValType.Object) {
// fail-safe behaviour for null/undefined values in legacy comprehensions
Jump loopstart = new Jump();
mv.dup();
isUndefinedOrNull(mv);
mv.ifeq(loopstart);
mv.pop();
mv.goTo(lblFail);
mv.mark(loopstart);
}
IterationKind iterationKind = node.getIterationKind();
if (iterationKind == IterationKind.Enumerate || iterationKind == IterationKind.EnumerateValues) {
// legacy generator mode, both, for-in and for-each, perform Iterate on generators
Jump l0 = new Jump(), l1 = new Jump();
mv.dup();
mv.instanceOf(Types.GeneratorObject);
mv.ifeq(l0);
mv.dup();
mv.checkcast(Types.GeneratorObject);
mv.invoke(Methods.GeneratorObject_isLegacyGenerator);
mv.ifeq(l0);
mv.loadExecutionContext();
mv.lineInfo(node.getExpression());
mv.invoke(Methods.ScriptRuntime_iterate);
mv.goTo(l1);
mv.mark(l0);
mv.loadExecutionContext();
mv.lineInfo(node.getExpression());
if (iterationKind == IterationKind.Enumerate) {
mv.invoke(Methods.ScriptRuntime_enumerate);
} else {
mv.invoke(Methods.ScriptRuntime_enumerateValues);
}
mv.mark(l1);
} else {
assert iterationKind == IterationKind.Iterate;
mv.loadExecutionContext();
mv.lineInfo(node.getExpression());
mv.invoke(Methods.ScriptRuntime_iterate);
}
mv.store(iter);
mv.nonDestructiveGoTo(lblTest);
mv.mark(lblLoop);
mv.load(iter);
mv.lineInfo(node);
mv.invoke(Methods.Iterator_next);
new IterationGenerator<LegacyComprehensionFor>(codegen) {
@Override
protected Completion iterationBody(LegacyComprehensionFor node, Variable<ScriptIterator<?>> iterator, CodeVisitor mv) {
// stack: [nextValue] -> []
BindingInitialization(codegen, node.getBinding(), mv);
elements.next().accept(ComprehensionGenerator.this, mv);
return Completion.Normal;
}
@Override
protected MutableValue<Object> enterIteration(LegacyComprehensionFor node, CodeVisitor mv) {
return mv.enterIteration();
}
@Override
protected List<TempLabel> exitIteration(LegacyComprehensionFor node, CodeVisitor mv) {
return mv.exitIteration();
}
}.generate(node, iter, mv);
mv.mark(lblTest);
mv.load(iter);
mv.lineInfo(node);
mv.invoke(Methods.Iterator_hasNext);
mv.ifne(lblLoop);
mv.mark(lblFail);
return null;
}
use of com.github.anba.es6draft.ast.LegacyComprehensionFor in project es6draft by anba.
the class ComprehensionGenerator method visit.
/**
* Runtime Semantics: ComprehensionEvaluation
*/
@Override
public Void visit(Comprehension node, CodeVisitor mv) {
ArrayList<Node> list = new ArrayList<>(node.getList().size() + 1);
list.addAll(node.getList());
list.add(node.getExpression());
elements = list.iterator();
// Create variables early so they'll appear next to each other in the local variable map.
ArrayList<Variable<ScriptIterator<?>>> iters = new ArrayList<>();
for (ComprehensionQualifier e : node.getList()) {
if (e instanceof ComprehensionFor || e instanceof LegacyComprehensionFor) {
Variable<ScriptIterator<?>> iter = mv.newVariable("iter", ScriptIterator.class).uncheckedCast();
iters.add(iter);
}
}
iterators = iters.iterator();
// Start generating code.
elements.next().accept(this, mv);
return null;
}
Aggregations