use of com.github.anba.es6draft.compiler.assembler.Variable in project es6draft by anba.
the class DefaultCodeGenerator method returnAfterResume.
private void returnAfterResume(CodeVisitor mv) {
Jump isReturn = new Jump();
mv.dup();
mv.instanceOf(Types.ReturnValue);
mv.ifeq(isReturn);
{
mv.checkcast(Types.ReturnValue);
mv.invoke(Methods.ReturnValue_getValue);
if (mv.getStackSize() == 1) {
mv.returnCompletion();
} else {
mv.enterVariableScope();
Variable<Object> returnValue = mv.newVariable("returnValue", Object.class);
mv.store(returnValue);
mv.popStack();
mv.returnCompletion(returnValue);
mv.exitVariableScope();
}
}
mv.mark(isReturn);
}
use of com.github.anba.es6draft.compiler.assembler.Variable in project es6draft by anba.
the class DefaultCodeGenerator method delegatedYield.
/**
* 14.4 Generator Function Definitions
* <p>
* 14.4.14 Runtime Semantics: Evaluation
* <ul>
* <li>YieldExpression : yield * AssignmentExpression
* </ul>
* <p>
* stack: [value] {@literal ->} [value']
*
* @param node
* the expression node
* @param mv
* the code visitor
*/
protected final void delegatedYield(Expression node, CodeVisitor mv) {
if (!mv.isAsync()) {
delegatedYield(node, (iterator, received) -> {
IteratorNext(node, iterator, received, mv);
}, (iterator, received) -> {
mv.loadExecutionContext();
mv.load(iterator);
mv.load(received);
mv.checkcast(Types.ScriptException);
mv.invoke(Methods.ScriptRuntime_yieldThrowCompletion);
}, (iterator, received) -> {
mv.loadExecutionContext();
mv.load(iterator);
mv.load(received);
mv.checkcast(Types.ReturnValue);
mv.invoke(Methods.ScriptRuntime_yieldReturnCompletion);
}, mv);
} else {
delegatedYield(node, (iterator, received) -> {
IteratorNext(node, iterator, received, mv);
await(node, mv);
// FIXME: spec bug - missing type check
requireObjectResult(node, "next", mv);
}, (iterator, received) -> {
mv.enterVariableScope();
Variable<Callable> throwMethod = mv.newVariable("throwMethod", Callable.class);
GetMethod(node, iterator, "throw", mv);
mv.store(throwMethod);
Jump noThrow = new Jump(), nextYield = new Jump();
mv.load(throwMethod);
mv.ifnull(noThrow);
{
InvokeMethod(node, mv, throwMethod, iterator, __ -> {
mv.load(received);
mv.checkcast(Types.ScriptException);
mv.invoke(Methods.ScriptException_getValue);
});
await(node, mv);
requireObjectResult(node, "throw", mv);
mv.goTo(nextYield);
}
mv.mark(noThrow);
{
asyncIteratorClose(node, iterator, mv);
reportPropertyNotCallable(node, "throw", mv);
mv.athrow();
}
mv.mark(nextYield);
mv.exitVariableScope();
}, (iterator, received) -> {
mv.enterVariableScope();
Variable<Callable> returnMethod = mv.newVariable("returnMethod", Callable.class);
GetMethod(node, iterator, "return", mv);
mv.store(returnMethod);
Jump noReturn = new Jump(), nextYield = new Jump();
mv.load(returnMethod);
mv.ifnull(noReturn);
{
InvokeMethod(node, mv, returnMethod, iterator, __ -> {
mv.load(received);
mv.checkcast(Types.ReturnValue);
mv.invoke(Methods.ReturnValue_getValue);
});
await(node, mv);
requireObjectResult(node, "return", mv);
mv.goTo(nextYield);
}
mv.mark(noReturn);
{
mv.anull();
}
mv.mark(nextYield);
mv.exitVariableScope();
}, mv);
}
}
use of com.github.anba.es6draft.compiler.assembler.Variable 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<ScriptObject> iterator = mv.newVariable("iter", ScriptObject.class);
// stack: [Iterator] -> []
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);
await(node, 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);
IteratorNext(node, iterator, mv);
await(node, mv);
// FIXME: spec bug - missing type check after await
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.assembler.Variable in project es6draft by anba.
the class StatementGenerator method ForInOfBodyEvaluationInner.
private <FORSTATEMENT extends IterationStatement & ForIterationNode> Completion ForInOfBodyEvaluationInner(FORSTATEMENT node, Variable<Object> nextValue, CodeVisitor mv) {
BlockScope scope = node.getScope();
Node lhs = node.getHead();
/* steps 5.f-j */
if (lhs instanceof Expression) {
/* steps 5.f, 5.h-j */
LeftHandSideExpression lhsExpr = (LeftHandSideExpression) lhs;
if (!(lhsExpr instanceof AssignmentPattern)) {
ReferenceOp<LeftHandSideExpression> op = ReferenceOp.of(lhsExpr);
/* step 5.f.i.1 */
// stack: [] -> [<ref>]
ValType ref = op.reference(lhsExpr, mv, codegen);
/* steps 5.h.i, 5.h.iii */
// stack: [<ref>] -> []
mv.load(nextValue);
op.putValue(lhsExpr, ref, ValType.Any, mv);
} else {
/* step 5.i.i */
mv.load(nextValue);
DestructuringAssignment(codegen, (AssignmentPattern) lhs, mv);
}
} else if (lhs instanceof VariableStatement) {
/* steps 5.f, 5.h-j */
Binding binding = forVarDeclarationBinding((VariableStatement) lhs);
if (binding instanceof BindingIdentifier) {
BindingIdentifier bindingId = (BindingIdentifier) binding;
/* step 5.f.i.1 */
// 13.7.5.14 Runtime Semantics: Evaluation
IdReferenceOp op = IdReferenceOp.of(bindingId);
op.resolveBinding(bindingId, mv);
/* steps 5.h.i, 5.h.iii */
// stack: [<ref>] -> []
mv.load(nextValue);
op.putValue(bindingId, ValType.Any, mv);
} else {
/* step 5.i.ii */
mv.load(nextValue);
BindingInitialization(codegen, (BindingPattern) binding, mv);
}
} else {
/* step 5.g-j */
Binding binding = forDeclarationBinding((LexicalDeclaration) lhs);
Variable<DeclarativeEnvironmentRecord> envRec = null;
if (scope.isPresent()) {
mv.enterVariableScope();
envRec = mv.newVariable("envRec", DeclarativeEnvironmentRecord.class);
newDeclarativeEnvironment(scope, mv);
getEnvRec(envRec, mv);
BindingInstantiation(envRec, (LexicalDeclaration) lhs, mv);
pushLexicalEnvironment(mv);
}
mv.enterScope(node);
/* step 5.h */
if (binding instanceof BindingIdentifier) {
/* step 5.h.ii */
BindingIdentifier bindingId = (BindingIdentifier) binding;
Name name = bindingId.getName();
BindingOp<DeclarativeEnvironmentRecord> op = BindingOp.of(envRec, name);
op.initializeBinding(envRec, name, nextValue, mv);
} else {
/* step 5.i.iii */
// 13.7.5.9 Runtime Semantics: BindingInitialization
BindingInitialization(codegen, envRec, (BindingPattern) binding, nextValue, mv);
}
if (scope.isPresent()) {
mv.exitVariableScope();
}
}
/* step 5.k */
Completion result = node.getStatement().accept(this, mv);
/* step 5.l */
if (lhs instanceof LexicalDeclaration) {
mv.exitScope();
if (scope.isPresent() && !result.isAbrupt()) {
popLexicalEnvironment(mv);
}
}
return result;
}
use of com.github.anba.es6draft.compiler.assembler.Variable in project es6draft by anba.
the class StatementGenerator method ForInOfBodyEvaluation.
/**
* 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 ForInOfBodyEvaluation(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<?>> iterator = mv.newVariable("iter", ScriptIterator.class).uncheckedCast();
// stack: [Iterator] -> []
mv.store(iterator);
Variable<Object> nextValue = mv.newVariable("nextValue", Object.class);
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);
mv.load(iterator);
mv.lineInfo(node);
mv.invoke(Methods.Iterator_next);
mv.store(nextValue);
/* steps 5.f-l */
{
mv.enterIteration(node, lblBreak, lblContinue);
mv.enterWrapped();
new IterationGenerator<FORSTATEMENT>(codegen) {
@Override
protected Completion iterationBody(FORSTATEMENT node, Variable<ScriptIterator<?>> 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);
}
}.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(iterator);
mv.lineInfo(node);
mv.invoke(Methods.Iterator_hasNext);
mv.ifne(enter);
/* steps 5.m-n */
if (lblBreak.isTarget()) {
mv.mark(lblBreak);
restoreEnvironment(savedEnv, mv);
}
mv.exitVariableScope();
return Completion.Normal;
}
Aggregations