Search in sources :

Example 1 with Variable

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);
}
Also used : Variable(com.github.anba.es6draft.compiler.assembler.Variable) ScriptObject(com.github.anba.es6draft.runtime.types.ScriptObject) OrdinaryObject(com.github.anba.es6draft.runtime.types.builtins.OrdinaryObject) Jump(com.github.anba.es6draft.compiler.assembler.Jump)

Example 2 with Variable

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);
    }
}
Also used : ModuleEnvironmentRecord(com.github.anba.es6draft.runtime.ModuleEnvironmentRecord) ConstructorMethod(com.github.anba.es6draft.semantics.StaticSemantics.ConstructorMethod) Undefined(com.github.anba.es6draft.runtime.types.Undefined) TryCatchLabel(com.github.anba.es6draft.compiler.assembler.TryCatchLabel) ArrayList(java.util.ArrayList) ModuleScope(com.github.anba.es6draft.ast.scope.ModuleScope) Variable(com.github.anba.es6draft.compiler.assembler.Variable) Type(com.github.anba.es6draft.compiler.assembler.Type) ScriptObject(com.github.anba.es6draft.runtime.types.ScriptObject) WithScope(com.github.anba.es6draft.ast.scope.WithScope) Null(com.github.anba.es6draft.runtime.types.Null) Reference(com.github.anba.es6draft.runtime.types.Reference) Scope(com.github.anba.es6draft.ast.scope.Scope) EnvironmentRecord(com.github.anba.es6draft.runtime.EnvironmentRecord) BiConsumer(java.util.function.BiConsumer) OrdinaryConstructorFunction(com.github.anba.es6draft.runtime.types.builtins.OrdinaryConstructorFunction) EnumSet(java.util.EnumSet) ScriptException(com.github.anba.es6draft.runtime.internal.ScriptException) LexicalEnvironment(com.github.anba.es6draft.runtime.LexicalEnvironment) Jump(com.github.anba.es6draft.compiler.assembler.Jump) GlobalEnvironmentRecord(com.github.anba.es6draft.runtime.GlobalEnvironmentRecord) HasDecorators(com.github.anba.es6draft.semantics.StaticSemantics.HasDecorators) MethodName(com.github.anba.es6draft.compiler.assembler.MethodName) ObjectEnvironmentRecord(com.github.anba.es6draft.runtime.ObjectEnvironmentRecord) Consumer(java.util.function.Consumer) com.github.anba.es6draft.ast(com.github.anba.es6draft.ast) BlockScope(com.github.anba.es6draft.ast.scope.BlockScope) List(java.util.List) Name(com.github.anba.es6draft.ast.scope.Name) Callable(com.github.anba.es6draft.runtime.types.Callable) FieldName(com.github.anba.es6draft.compiler.assembler.FieldName) ClassPropertyEvaluation(com.github.anba.es6draft.compiler.ClassPropertyGenerator.ClassPropertyEvaluation) OrdinaryObject(com.github.anba.es6draft.runtime.types.builtins.OrdinaryObject) Value(com.github.anba.es6draft.compiler.assembler.Value) Abrupt(com.github.anba.es6draft.ast.AbruptNode.Abrupt) ScriptScope(com.github.anba.es6draft.ast.scope.ScriptScope) DeclarativeEnvironmentRecord(com.github.anba.es6draft.runtime.DeclarativeEnvironmentRecord) Bootstrap(com.github.anba.es6draft.runtime.internal.Bootstrap) Jump(com.github.anba.es6draft.compiler.assembler.Jump) Callable(com.github.anba.es6draft.runtime.types.Callable)

Example 3 with Variable

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;
}
Also used : ScriptObject(com.github.anba.es6draft.runtime.types.ScriptObject) Variable(com.github.anba.es6draft.compiler.assembler.Variable) Jump(com.github.anba.es6draft.compiler.assembler.Jump) TempLabel(com.github.anba.es6draft.compiler.Labels.TempLabel) ContinueLabel(com.github.anba.es6draft.compiler.Labels.ContinueLabel) LexicalEnvironment(com.github.anba.es6draft.runtime.LexicalEnvironment) ScriptObject(com.github.anba.es6draft.runtime.types.ScriptObject) FunctionObject(com.github.anba.es6draft.runtime.types.builtins.FunctionObject) BreakLabel(com.github.anba.es6draft.compiler.Labels.BreakLabel)

Example 4 with Variable

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;
}
Also used : Variable(com.github.anba.es6draft.compiler.assembler.Variable) InitializeBoundName(com.github.anba.es6draft.compiler.BindingInitializationGenerator.InitializeBoundName) MethodName(com.github.anba.es6draft.compiler.assembler.MethodName) Name(com.github.anba.es6draft.ast.scope.Name) BlockScope(com.github.anba.es6draft.ast.scope.BlockScope)

Example 5 with Variable

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;
}
Also used : Variable(com.github.anba.es6draft.compiler.assembler.Variable) Jump(com.github.anba.es6draft.compiler.assembler.Jump) TempLabel(com.github.anba.es6draft.compiler.Labels.TempLabel) ScriptIterator(com.github.anba.es6draft.runtime.internal.ScriptIterator) ContinueLabel(com.github.anba.es6draft.compiler.Labels.ContinueLabel) LexicalEnvironment(com.github.anba.es6draft.runtime.LexicalEnvironment) ScriptObject(com.github.anba.es6draft.runtime.types.ScriptObject) FunctionObject(com.github.anba.es6draft.runtime.types.builtins.FunctionObject) BreakLabel(com.github.anba.es6draft.compiler.Labels.BreakLabel)

Aggregations

Variable (com.github.anba.es6draft.compiler.assembler.Variable)9 Jump (com.github.anba.es6draft.compiler.assembler.Jump)6 ScriptObject (com.github.anba.es6draft.runtime.types.ScriptObject)5 BlockScope (com.github.anba.es6draft.ast.scope.BlockScope)3 Name (com.github.anba.es6draft.ast.scope.Name)3 MethodName (com.github.anba.es6draft.compiler.assembler.MethodName)3 LexicalEnvironment (com.github.anba.es6draft.runtime.LexicalEnvironment)3 FunctionObject (com.github.anba.es6draft.runtime.types.builtins.FunctionObject)3 InitializeBoundName (com.github.anba.es6draft.compiler.BindingInitializationGenerator.InitializeBoundName)2 BreakLabel (com.github.anba.es6draft.compiler.Labels.BreakLabel)2 ContinueLabel (com.github.anba.es6draft.compiler.Labels.ContinueLabel)2 TempLabel (com.github.anba.es6draft.compiler.Labels.TempLabel)2 TryCatchLabel (com.github.anba.es6draft.compiler.assembler.TryCatchLabel)2 ScriptException (com.github.anba.es6draft.runtime.internal.ScriptException)2 ScriptIterator (com.github.anba.es6draft.runtime.internal.ScriptIterator)2 OrdinaryObject (com.github.anba.es6draft.runtime.types.builtins.OrdinaryObject)2 ArrayList (java.util.ArrayList)2 com.github.anba.es6draft.ast (com.github.anba.es6draft.ast)1 Abrupt (com.github.anba.es6draft.ast.AbruptNode.Abrupt)1 ComprehensionFor (com.github.anba.es6draft.ast.ComprehensionFor)1