Search in sources :

Example 41 with Jump

use of com.github.anba.es6draft.compiler.assembler.Jump in project es6draft by anba.

the class FunctionCodeGenerator method returnResultOrThis.

/**
     * Generate bytecode for:
     * 
     * <pre>
     * if (tailCall &amp;&amp; result instanceof TailCallInvocation) {
     *     return ((TailCallInvocation) result).toConstructTailCall(thisArgument);
     * }
     * if (Type.isObject(result)) {
     *     return Type.objectValue(result);
     * }
     * return thisArgument;
     * </pre>
     * 
     * @param thisArgument
     *            the variable which holds the thisArgument
     * @param tailCall
     *            {@code true} if the constructor function contains a tail-call
     * @param mv
     *            the instruction visitor
     */
private void returnResultOrThis(Variable<ScriptObject> thisArgument, boolean tailCall, InstructionVisitor mv) {
    if (tailCall) {
        Jump noTailCall = new Jump();
        mv.dup();
        mv.instanceOf(Types.TailCallInvocation);
        mv.ifeq(noTailCall);
        {
            mv.checkcast(Types.TailCallInvocation);
            mv.load(thisArgument);
            mv.invoke(Methods.TailCallInvocation_toConstructTailCall);
            mv._return();
        }
        mv.mark(noTailCall);
    }
    Jump noResult = new Jump();
    mv.dup();
    mv.instanceOf(Types.ScriptObject);
    mv.ifeq(noResult);
    {
        mv.checkcast(Types.ScriptObject);
        mv._return();
    }
    mv.mark(noResult);
    mv.pop();
    mv.load(thisArgument);
    mv._return();
}
Also used : Jump(com.github.anba.es6draft.compiler.assembler.Jump)

Example 42 with Jump

use of com.github.anba.es6draft.compiler.assembler.Jump in project es6draft by anba.

the class StatementGenerator method visitTryFinally.

/**
     * 13.15.8 Runtime Semantics: Evaluation<br>
     * 
     * <code>try-finally</code>
     * 
     * @param node
     *            the try-statement
     * @param mv
     *            the code visitor
     * @return the completion value
     */
private Completion visitTryFinally(TryStatement node, CodeVisitor mv) {
    TryCatchLabel startFinally = new TryCatchLabel(), endFinally = new TryCatchLabel();
    TryCatchLabel handlerFinally = new TryCatchLabel();
    TryCatchLabel handlerFinallyStackOverflow = new TryCatchLabel();
    Jump noException = new Jump();
    mv.enterVariableScope();
    Variable<LexicalEnvironment<?>> savedEnv = saveEnvironment(mv);
    MutableValue<Object> completion = mv.enterFinallyScoped(node);
    /* step 1 */
    // Emit try-block
    mv.mark(startFinally);
    Completion tryResult = emitTryBlock(node, noException, mv);
    mv.mark(endFinally);
    // Restore temporary abrupt targets
    List<TempLabel> tempLabels = mv.exitFinallyScoped();
    /* step 2 */
    // Emit finally-block
    Completion finallyResult = emitFinallyBlock(node, savedEnv, completion, tryResult, Completion.Abrupt, handlerFinally, handlerFinallyStackOverflow, noException, tempLabels, mv);
    mv.exitVariableScope();
    mv.tryCatch(startFinally, endFinally, handlerFinally, Types.ScriptException);
    mv.tryCatch(startFinally, endFinally, handlerFinallyStackOverflow, Types.Error);
    /* steps 3-6 */
    return finallyResult.then(tryResult);
}
Also used : LexicalEnvironment(com.github.anba.es6draft.runtime.LexicalEnvironment) TryCatchLabel(com.github.anba.es6draft.compiler.assembler.TryCatchLabel) ScriptObject(com.github.anba.es6draft.runtime.types.ScriptObject) FunctionObject(com.github.anba.es6draft.runtime.types.builtins.FunctionObject) Jump(com.github.anba.es6draft.compiler.assembler.Jump) TempLabel(com.github.anba.es6draft.compiler.Labels.TempLabel)

Example 43 with Jump

use of com.github.anba.es6draft.compiler.assembler.Jump in project es6draft by anba.

the class StatementGenerator method visitTryCatch.

/**
     * 13.15.8 Runtime Semantics: Evaluation<br>
     * 
     * <code>try-catch</code>
     * 
     * @param node
     *            the try-statement
     * @param mv
     *            the code visitor
     * @return the completion value
     */
private Completion visitTryCatch(TryStatement node, CodeVisitor mv) {
    TryCatchLabel startCatch = new TryCatchLabel(), endCatch = new TryCatchLabel();
    TryCatchLabel handlerCatch = new TryCatchLabel();
    TryCatchLabel handlerCatchStackOverflow = new TryCatchLabel();
    Jump exceptionHandled = new Jump();
    mv.enterVariableScope();
    Variable<LexicalEnvironment<?>> savedEnv = saveEnvironment(mv);
    /* step 1 */
    // Emit try-block
    mv.mark(startCatch);
    Completion tryResult = emitTryBlock(node, exceptionHandled, mv);
    mv.mark(endCatch);
    /* step 2 */
    // Emit catch-block
    Completion catchResult = emitCatchBlock(node, savedEnv, handlerCatch, handlerCatchStackOverflow, mv);
    /* step 3 */
    if (!tryResult.isAbrupt()) {
        mv.mark(exceptionHandled);
    }
    mv.exitVariableScope();
    mv.tryCatch(startCatch, endCatch, handlerCatch, Types.ScriptException);
    mv.tryCatch(startCatch, endCatch, handlerCatchStackOverflow, Types.Error);
    /* steps 4-6 */
    return tryResult.select(catchResult);
}
Also used : LexicalEnvironment(com.github.anba.es6draft.runtime.LexicalEnvironment) TryCatchLabel(com.github.anba.es6draft.compiler.assembler.TryCatchLabel) Jump(com.github.anba.es6draft.compiler.assembler.Jump)

Example 44 with Jump

use of com.github.anba.es6draft.compiler.assembler.Jump in project es6draft by anba.

the class SwitchStatementGenerator method emitCharSwitch.

/**
     * <h3>char-switch</h3>
     * 
     * <pre>
     * switch (v) {
     * case "a": ...
     * case "b": ...
     * }
     * 
     * var $v = v;
     * if (typeof $v == 'string' {@literal &&} length($v) == 1) {
     *   tableswitch|lookupswitch(charCodeAt($v, 0)) {
     *     charCodeAt("a", 0): goto L1
     *     charCodeAt("b", 0): goto L2
     *   }
     *   L1: ...
     *   L2: ...
     * }
     * </pre>
     * 
     * @param clauses
     *            the switch clauses
     * @param labels
     *            the labels for each switch clause
     * @param defaultClause
     *            the label for the default clause
     * @param lblExit
     *            the exit label
     * @param switchValue
     *            the variable which holds the switch value
     * @param mv
     *            the code visitor
     */
private void emitCharSwitch(List<SwitchClause> clauses, Jump[] labels, Jump defaultClause, Jump lblExit, Variable<?> switchValue, CodeVisitor mv) {
    Jump switchDefault = defaultClause != null ? defaultClause : lblExit;
    if (switchValue.getType().equals(Types.CharSequence)) {
        // test for char: value is character (string with only one character)
        mv.load(switchValue);
        mv.invoke(Methods.CharSequence_length);
        mv.iconst(1);
        mv.ificmpne(switchDefault);
        mv.load(switchValue);
        mv.iconst(0);
        mv.invoke(Methods.CharSequence_charAt);
    // mv.cast(Type.CHAR_TYPE, Type.INT_TYPE);
    } else {
        assert switchValue.getType().equals(Types.Object);
        // test for char: type is java.lang.CharSequence
        mv.load(switchValue);
        mv.instanceOf(Types.CharSequence);
        mv.ifeq(switchDefault);
        // test for char: value is character (string with only one character)
        mv.enterVariableScope();
        Variable<CharSequence> switchValueChar = mv.newVariable("switchValueChar", CharSequence.class);
        mv.load(switchValue);
        mv.checkcast(Types.CharSequence);
        mv.dup();
        mv.store(switchValueChar);
        mv.invoke(Methods.CharSequence_length);
        mv.iconst(1);
        mv.ificmpne(switchDefault);
        mv.load(switchValueChar);
        mv.iconst(0);
        mv.invoke(Methods.CharSequence_charAt);
        // mv.cast(Type.CHAR_TYPE, Type.INT_TYPE);
        mv.exitVariableScope();
    }
    // emit tableswitch or lookupswitch
    long[] entries = charSwitchEntries(clauses, defaultClause != null);
    switchInstruction(switchDefault, labels, entries, mv);
}
Also used : Jump(com.github.anba.es6draft.compiler.assembler.Jump)

Example 45 with Jump

use of com.github.anba.es6draft.compiler.assembler.Jump in project es6draft by anba.

the class SwitchStatementGenerator method emitStringSwitch.

/**
     * <h3>String-switch</h3>
     * 
     * <pre>
     * switch (v) {
     * case "key1": ...
     * case "key2": ...
     * }
     * 
     * var $v = v;
     * if (typeof $v == 'string') {
     *   lookupswitch(hashCode($v)) {
     *     hashCode("key1"): goto L1
     *     hashCode("key2"): goto L2
     *   }
     *   L1: if (equals($v, "key1")) ...
     *   L2: if (equals($v, "key2")) ...
     * }
     * </pre>
     * 
     * @param clauses
     *            the switch clauses
     * @param labels
     *            the labels for each switch clause
     * @param defaultClause
     *            the label for the default clause
     * @param lblExit
     *            the exit label
     * @param switchValue
     *            the variable which holds the switch value
     * @param mv
     *            the code visitor
     */
private void emitStringSwitch(List<SwitchClause> clauses, Jump[] labels, Jump defaultClause, Jump lblExit, Variable<?> switchValue, CodeVisitor mv) {
    Jump switchDefault = defaultClause != null ? defaultClause : lblExit;
    mv.enterVariableScope();
    Variable<String> switchValueString = mv.newVariable("switchValueString", String.class);
    if (switchValue.getType().equals(Types.CharSequence)) {
        mv.load(switchValue);
        mv.invoke(Methods.CharSequence_toString);
        mv.dup();
        mv.store(switchValueString);
        mv.invoke(Methods.String_hashCode);
    } else {
        assert switchValue.getType().equals(Types.Object);
        // test for string: type is java.lang.CharSequence
        mv.load(switchValue);
        mv.instanceOf(Types.CharSequence);
        mv.ifeq(switchDefault);
        mv.load(switchValue);
        mv.checkcast(Types.CharSequence);
        mv.invoke(Methods.CharSequence_toString);
        mv.dup();
        mv.store(switchValueString);
        mv.invoke(Methods.String_hashCode);
    }
    long[] entries = stringSwitchEntries(clauses, defaultClause != null);
    int distinctValues = distinctValues(entries);
    Jump[] switchLabels = new Jump[distinctValues];
    int[] switchKeys = new int[distinctValues];
    for (int i = 0, j = 0, lastValue = 0, length = entries.length; i < length; ++i) {
        int value = Value(entries[i]);
        if (i == 0 || value != lastValue) {
            switchLabels[j] = new Jump();
            switchKeys[j] = value;
            j += 1;
        }
        lastValue = value;
    }
    // emit lookupswitch
    mv.lookupswitch(switchDefault, switchKeys, switchLabels);
    // add String.equals() calls
    for (int i = 0, j = 0, lastValue = 0, length = entries.length; i < length; ++i) {
        int value = Value(entries[i]);
        int index = Index(entries[i]);
        if (i == 0 || value != lastValue) {
            if (i != 0) {
                mv.goTo(switchDefault);
            }
            mv.mark(switchLabels[j++]);
        }
        String string = ((StringLiteral) clauses.get(index).getExpression()).getValue();
        mv.load(switchValueString);
        mv.aconst(string);
        mv.invoke(Methods.String_equals);
        mv.ifne(labels[index]);
        lastValue = value;
    }
    mv.goTo(switchDefault);
    mv.exitVariableScope();
}
Also used : StringLiteral(com.github.anba.es6draft.ast.StringLiteral) Jump(com.github.anba.es6draft.compiler.assembler.Jump)

Aggregations

Jump (com.github.anba.es6draft.compiler.assembler.Jump)46 LexicalEnvironment (com.github.anba.es6draft.runtime.LexicalEnvironment)14 Name (com.github.anba.es6draft.ast.scope.Name)10 MethodName (com.github.anba.es6draft.compiler.assembler.MethodName)9 DeclarativeEnvironmentRecord (com.github.anba.es6draft.runtime.DeclarativeEnvironmentRecord)9 ScriptObject (com.github.anba.es6draft.runtime.types.ScriptObject)8 TryCatchLabel (com.github.anba.es6draft.compiler.assembler.TryCatchLabel)7 GlobalEnvironmentRecord (com.github.anba.es6draft.runtime.GlobalEnvironmentRecord)7 FunctionObject (com.github.anba.es6draft.runtime.types.builtins.FunctionObject)7 ScriptName (com.github.anba.es6draft.compiler.CodeGenerator.ScriptName)6 BreakLabel (com.github.anba.es6draft.compiler.Labels.BreakLabel)6 TempLabel (com.github.anba.es6draft.compiler.Labels.TempLabel)6 Variable (com.github.anba.es6draft.compiler.assembler.Variable)6 EnvironmentRecord (com.github.anba.es6draft.runtime.EnvironmentRecord)6 ContinueLabel (com.github.anba.es6draft.compiler.Labels.ContinueLabel)5 Completion (com.github.anba.es6draft.compiler.StatementGenerator.Completion)5 BlockScope (com.github.anba.es6draft.ast.scope.BlockScope)4 FunctionDeclaration (com.github.anba.es6draft.ast.FunctionDeclaration)3 HoistableDeclaration (com.github.anba.es6draft.ast.HoistableDeclaration)3 ExecutionContext (com.github.anba.es6draft.runtime.ExecutionContext)3