use of com.github.anba.es6draft.compiler.StatementGenerator.Completion 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.compiler.StatementGenerator.Completion in project es6draft by anba.
the class ComprehensionGenerator method visit.
/**
* Runtime Semantics: ComprehensionComponentEvaluation
* <p>
* ComprehensionFor : for ( ForBinding of AssignmentExpression )
*/
@Override
public Void visit(ComprehensionFor node, CodeVisitor mv) {
Jump lblTest = new Jump(), lblLoop = new Jump();
Variable<ScriptIterator<?>> iter = iterators.next();
/* steps 1-2 */
expressionBoxed(node.getExpression(), mv);
/* steps 3-4 */
mv.loadExecutionContext();
mv.lineInfo(node.getExpression());
mv.invoke(Methods.ScriptRuntime_iterate);
mv.store(iter);
/* step 5 (not applicable) */
/* step 6 */
mv.nonDestructiveGoTo(lblTest);
/* steps 6.d-e */
mv.mark(lblLoop);
mv.load(iter);
mv.lineInfo(node);
mv.invoke(Methods.Iterator_next);
/* steps 6.f-j */
BlockScope scope = node.getScope();
if (scope.isPresent()) {
mv.enterVariableScope();
Variable<LexicalEnvironment<DeclarativeEnvironmentRecord>> env = mv.newVariable("env", LexicalEnvironment.class).uncheckedCast();
Variable<DeclarativeEnvironmentRecord> envRec = mv.newVariable("envRec", DeclarativeEnvironmentRecord.class);
// stack: [nextValue] -> []
Variable<Object> nextValue = mv.newVariable("nextValue", Object.class);
mv.store(nextValue);
newDeclarativeEnvironment(scope, mv);
mv.store(env);
getEnvRec(env, envRec, mv);
for (Name name : BoundNames(node.getBinding())) {
BindingOp<DeclarativeEnvironmentRecord> op = BindingOp.of(envRec, name);
op.createMutableBinding(envRec, name, false, mv);
}
BindingInitialization(codegen, envRec, node.getBinding(), nextValue, mv);
mv.load(env);
pushLexicalEnvironment(mv);
mv.exitVariableScope();
} else {
// stack: [nextValue] -> []
mv.pop();
}
/* step 6.k */
mv.enterScope(node);
new IterationGenerator<ComprehensionFor>(codegen) {
@Override
protected Completion iterationBody(ComprehensionFor node, Variable<ScriptIterator<?>> iterator, CodeVisitor mv) {
elements.next().accept(ComprehensionGenerator.this, mv);
return Completion.Normal;
}
@Override
protected MutableValue<Object> enterIteration(ComprehensionFor node, CodeVisitor mv) {
return mv.enterIteration();
}
@Override
protected List<TempLabel> exitIteration(ComprehensionFor node, CodeVisitor mv) {
return mv.exitIteration();
}
}.generate(node, iter, mv);
mv.exitScope();
/* steps 6.l-m */
if (scope.isPresent()) {
popLexicalEnvironment(mv);
}
/* steps 6.a-c */
mv.mark(lblTest);
mv.load(iter);
mv.lineInfo(node);
mv.invoke(Methods.Iterator_hasNext);
mv.ifne(lblLoop);
return null;
}
use of com.github.anba.es6draft.compiler.StatementGenerator.Completion in project es6draft by anba.
the class CodeGenerator method compile.
Entry<MethodName, LabelState> compile(DoExpression node, CodeVisitor mv) {
if (!isCompiled(node)) {
if (!isEnabled(Compiler.Option.NoCompletion)) {
CompletionValueVisitor.performCompletion(node);
}
MethodCode method = newMethod(mv.getTopLevelNode(), node);
DoExpressionCodeVisitor body = new DoExpressionCodeVisitor(node, method, mv);
body.lineInfo(node);
// force line-number entry
body.nop();
body.begin();
GeneratorState generatorState = null;
if (node.hasYieldOrAwait()) {
generatorState = body.generatorPrologue();
}
body.labelPrologue();
Completion result = statement(node.getStatement(), body);
if (!result.isAbrupt()) {
// fall-thru, return `0`.
body.iconst(0);
body._return();
}
LabelState labelState = body.labelEpilogue(result);
if (generatorState != null) {
body.generatorEpilogue(generatorState);
}
body.end();
doExpressionCompletions.put(node, labelState);
}
return new SimpleImmutableEntry<>(methodDesc(node), doExpressionCompletions.get(node));
}
use of com.github.anba.es6draft.compiler.StatementGenerator.Completion in project es6draft by anba.
the class CodeGenerator method scriptBody.
private void scriptBody(Script node) {
MethodCode method = newMethod(node, ScriptName.Code);
ScriptCodeVisitor body = new ScriptCodeVisitor(method, node);
body.lineInfo(node);
body.begin();
body.loadUndefined();
body.storeCompletionValue(ValType.Undefined);
body.enterScope(node);
Completion result = statements(node.getStatements(), body);
body.exitScope();
if (!result.isAbrupt()) {
body.loadCompletionValue();
body._return();
}
body.end();
}
use of com.github.anba.es6draft.compiler.StatementGenerator.Completion in project es6draft by anba.
the class CodeGenerator method functionBody.
private boolean functionBody(FunctionNode node) {
MethodCode method = newMethod(node, FunctionName.Code);
FunctionCodeVisitor body = new FunctionCodeVisitor(method, node);
body.lineInfo(node);
body.begin();
body.enterFunction(node);
Completion result = statements(node.getStatements(), body);
body.exitFunction();
if (!result.isAbrupt()) {
// fall-thru, return undefined from function
body.loadUndefined();
body._return();
}
body.end();
return body.hasTailCalls();
}
Aggregations