Search in sources :

Example 1 with Completion

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;
}
Also used : Completion(com.github.anba.es6draft.compiler.StatementGenerator.Completion) IterationKind(com.github.anba.es6draft.ast.LegacyComprehensionFor.IterationKind) LegacyComprehensionFor(com.github.anba.es6draft.ast.LegacyComprehensionFor) MutableValue(com.github.anba.es6draft.compiler.assembler.MutableValue) ArrayList(java.util.ArrayList) List(java.util.List) Jump(com.github.anba.es6draft.compiler.assembler.Jump) ScriptIterator(com.github.anba.es6draft.runtime.internal.ScriptIterator)

Example 2 with Completion

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;
}
Also used : LegacyComprehensionFor(com.github.anba.es6draft.ast.LegacyComprehensionFor) ComprehensionFor(com.github.anba.es6draft.ast.ComprehensionFor) MutableValue(com.github.anba.es6draft.compiler.assembler.MutableValue) Jump(com.github.anba.es6draft.compiler.assembler.Jump) ScriptIterator(com.github.anba.es6draft.runtime.internal.ScriptIterator) MethodName(com.github.anba.es6draft.compiler.assembler.MethodName) Name(com.github.anba.es6draft.ast.scope.Name) Completion(com.github.anba.es6draft.compiler.StatementGenerator.Completion) LexicalEnvironment(com.github.anba.es6draft.runtime.LexicalEnvironment) BlockScope(com.github.anba.es6draft.ast.scope.BlockScope) ArrayList(java.util.ArrayList) List(java.util.List) DeclarativeEnvironmentRecord(com.github.anba.es6draft.runtime.DeclarativeEnvironmentRecord)

Example 3 with Completion

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));
}
Also used : Completion(com.github.anba.es6draft.compiler.StatementGenerator.Completion) SimpleImmutableEntry(java.util.AbstractMap.SimpleImmutableEntry) LabelState(com.github.anba.es6draft.compiler.CodeVisitor.LabelState) MethodCode(com.github.anba.es6draft.compiler.assembler.Code.MethodCode) GeneratorState(com.github.anba.es6draft.compiler.CodeVisitor.GeneratorState)

Example 4 with Completion

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();
}
Also used : Completion(com.github.anba.es6draft.compiler.StatementGenerator.Completion) MethodCode(com.github.anba.es6draft.compiler.assembler.Code.MethodCode)

Example 5 with Completion

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();
}
Also used : Completion(com.github.anba.es6draft.compiler.StatementGenerator.Completion) MethodCode(com.github.anba.es6draft.compiler.assembler.Code.MethodCode)

Aggregations

Completion (com.github.anba.es6draft.compiler.StatementGenerator.Completion)11 MethodCode (com.github.anba.es6draft.compiler.assembler.Code.MethodCode)6 Jump (com.github.anba.es6draft.compiler.assembler.Jump)5 GeneratorState (com.github.anba.es6draft.compiler.CodeVisitor.GeneratorState)3 LegacyComprehensionFor (com.github.anba.es6draft.ast.LegacyComprehensionFor)2 BlockScope (com.github.anba.es6draft.ast.scope.BlockScope)2 LabelState (com.github.anba.es6draft.compiler.CodeVisitor.LabelState)2 MutableValue (com.github.anba.es6draft.compiler.assembler.MutableValue)2 LexicalEnvironment (com.github.anba.es6draft.runtime.LexicalEnvironment)2 ScriptIterator (com.github.anba.es6draft.runtime.internal.ScriptIterator)2 SimpleImmutableEntry (java.util.AbstractMap.SimpleImmutableEntry)2 ArrayList (java.util.ArrayList)2 List (java.util.List)2 ComprehensionFor (com.github.anba.es6draft.ast.ComprehensionFor)1 IterationKind (com.github.anba.es6draft.ast.LegacyComprehensionFor.IterationKind)1 SwitchClause (com.github.anba.es6draft.ast.SwitchClause)1 Name (com.github.anba.es6draft.ast.scope.Name)1 BreakLabel (com.github.anba.es6draft.compiler.Labels.BreakLabel)1 TempLabel (com.github.anba.es6draft.compiler.Labels.TempLabel)1 MethodName (com.github.anba.es6draft.compiler.assembler.MethodName)1