use of com.github.anba.es6draft.compiler.CodeVisitor.LabelState 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.CodeVisitor.LabelState in project es6draft by anba.
the class StatementGenerator method visit.
@Override
public Completion visit(StatementListMethod node, CodeVisitor mv) {
Entry<MethodName, LabelState> entry = codegen.compile(node, mv);
MethodName method = entry.getKey();
LabelState labelState = entry.getValue();
boolean hasCompletion = labelState.hasReturn() || (mv.hasCompletion() && node.hasCompletionValue());
boolean hasResume = node.hasResumePoint();
boolean hasTarget = hasResume || labelState.hasTargetInstruction();
mv.enterVariableScope();
Value<Object[]> completion;
if (hasCompletion) {
Variable<Object[]> completionVar = mv.newVariable("completion", Object[].class);
mv.anewarray(1, Types.Object);
mv.store(completionVar);
if (mv.hasCompletion()) {
mv.astore(completionVar, 0, mv.completionValue());
}
completion = completionVar;
} else {
completion = mv.anullValue();
}
MutableValue<Integer> target = hasTarget ? mv.newVariable("target", int.class) : new PopStoreValue<>();
// stack: [] -> []
// 0 = hint for stacktraces to omit this frame
mv.lineInfo(0);
if (hasResume) {
mv.callWithSuspendInt(method, target, completion);
} else {
mv.callWithResult(method, target, completion);
}
Value<Object> completionValue = mv.arrayElement(completion, 0, Object.class);
if (node.hasCompletionValue()) {
mv.storeCompletionValue(completionValue);
}
mv.labelSwitch(labelState, target, completionValue, false);
mv.exitVariableScope();
return labelState.completion;
}
use of com.github.anba.es6draft.compiler.CodeVisitor.LabelState in project es6draft by anba.
the class DefaultCodeGenerator method outlined.
/**
* Compiles an outlined method.
*
* @param mv
* the code visitor
* @param compiler
* the compiler function
* @return the outlined-call object
*/
protected final <VISITOR extends OutlinedCodeVisitor> OutlinedCall outlined(VISITOR mv, Function<VISITOR, Completion> compiler) {
mv.lineInfo(mv.getNode());
// force line-number entry
mv.nop();
mv.begin();
GeneratorState generatorState = null;
if (mv.hasResume()) {
generatorState = mv.generatorPrologue();
}
mv.labelPrologue();
Completion result = compiler.apply(mv);
if (!result.isAbrupt()) {
// fall-thru, return `0`.
mv.iconst(0);
mv._return();
}
LabelState labelState = mv.labelEpilogue(result, mv.hasResume());
if (generatorState != null) {
mv.generatorEpilogue(generatorState);
}
mv.end();
return new OutlinedCall(mv.getMethod().name(), labelState);
}
use of com.github.anba.es6draft.compiler.CodeVisitor.LabelState in project es6draft by anba.
the class CodeGenerator method compile.
Entry<MethodName, LabelState> compile(StatementListMethod node, CodeVisitor mv) {
if (!isCompiled(node)) {
MethodCode method = newMethod(mv.getTopLevelNode(), node);
StatementListMethodCodeVisitor body = new StatementListMethodCodeVisitor(node, method, mv);
body.lineInfo(node);
// force line-number entry
body.nop();
body.begin();
GeneratorState generatorState = null;
if (node.hasResumePoint()) {
generatorState = body.generatorPrologue();
}
body.labelPrologue();
Completion result = statements(node.getStatements(), 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();
statementCompletions.put(node, labelState);
}
return new SimpleImmutableEntry<>(methodDesc(node), statementCompletions.get(node));
}
Aggregations