Search in sources :

Example 1 with FlowControlFinal

use of lucee.transformer.bytecode.statement.FlowControlFinal in project Lucee by lucee.

the class ASMUtil method getAncestorFCStatement.

private static FlowControl getAncestorFCStatement(Statement stat, List<FlowControlFinal> finallyLabels, int flowType, String label) {
    Statement parent = stat;
    FlowControlFinal fcf;
    while (true) {
        parent = parent.getParent();
        if (parent == null)
            return null;
        if (((flowType == FlowControl.RETRY && parent instanceof FlowControlRetry) || (flowType == FlowControl.CONTINUE && parent instanceof FlowControlContinue) || (flowType == FlowControl.BREAK && parent instanceof FlowControlBreak)) && labelMatch((FlowControl) parent, label)) {
            if (parent instanceof ScriptBody) {
                List<FlowControlFinal> _finallyLabels = finallyLabels == null ? null : new ArrayList<FlowControlFinal>();
                FlowControl scriptBodyParent = getAncestorFCStatement(parent, _finallyLabels, flowType, label);
                if (scriptBodyParent != null) {
                    if (finallyLabels != null) {
                        Iterator<FlowControlFinal> it = _finallyLabels.iterator();
                        while (it.hasNext()) {
                            finallyLabels.add(it.next());
                        }
                    }
                    return scriptBodyParent;
                }
                return (FlowControl) parent;
            }
            return (FlowControl) parent;
        }
        // only if not last
        if (finallyLabels != null) {
            fcf = parent.getFlowControlFinal();
            if (fcf != null) {
                finallyLabels.add(fcf);
            }
        }
    }
}
Also used : FlowControlContinue(lucee.transformer.bytecode.statement.FlowControlContinue) FlowControl(lucee.transformer.bytecode.statement.FlowControl) Statement(lucee.transformer.bytecode.Statement) ScriptBody(lucee.transformer.bytecode.ScriptBody) FlowControlFinal(lucee.transformer.bytecode.statement.FlowControlFinal) FlowControlBreak(lucee.transformer.bytecode.statement.FlowControlBreak) FlowControlRetry(lucee.transformer.bytecode.statement.FlowControlRetry)

Example 2 with FlowControlFinal

use of lucee.transformer.bytecode.statement.FlowControlFinal in project Lucee by lucee.

the class ASMUtil method leadFlow.

public static void leadFlow(BytecodeContext bc, Statement stat, int flowType, String label) throws TransformerException {
    List<FlowControlFinal> finallyLabels = new ArrayList<FlowControlFinal>();
    FlowControl fc;
    String name;
    if (FlowControl.BREAK == flowType) {
        fc = ASMUtil.getAncestorBreakFCStatement(stat, finallyLabels, label);
        name = "break";
    } else if (FlowControl.CONTINUE == flowType) {
        fc = ASMUtil.getAncestorContinueFCStatement(stat, finallyLabels, label);
        name = "continue";
    } else {
        fc = ASMUtil.getAncestorRetryFCStatement(stat, finallyLabels, label);
        name = "retry";
    }
    if (fc == null)
        throw new TransformerException(name + " must be inside a loop (for,while,do-while,<cfloop>,<cfwhile> ...)", stat.getStart());
    GeneratorAdapter adapter = bc.getAdapter();
    Label end;
    if (FlowControl.BREAK == flowType)
        end = ((FlowControlBreak) fc).getBreakLabel();
    else if (FlowControl.CONTINUE == flowType)
        end = ((FlowControlContinue) fc).getContinueLabel();
    else
        end = ((FlowControlRetry) fc).getRetryLabel();
    // first jump to all final labels
    FlowControlFinal[] arr = finallyLabels.toArray(new FlowControlFinal[finallyLabels.size()]);
    if (arr.length > 0) {
        FlowControlFinal fcf;
        for (int i = 0; i < arr.length; i++) {
            fcf = arr[i];
            // first
            if (i == 0) {
                adapter.visitJumpInsn(Opcodes.GOTO, fcf.getFinalEntryLabel());
            }
            // last
            if (arr.length == i + 1)
                fcf.setAfterFinalGOTOLabel(end);
            else
                fcf.setAfterFinalGOTOLabel(arr[i + 1].getFinalEntryLabel());
        }
    } else
        bc.getAdapter().visitJumpInsn(Opcodes.GOTO, end);
}
Also used : FlowControl(lucee.transformer.bytecode.statement.FlowControl) FlowControlFinal(lucee.transformer.bytecode.statement.FlowControlFinal) ArrayList(java.util.ArrayList) Label(org.objectweb.asm.Label) GeneratorAdapter(org.objectweb.asm.commons.GeneratorAdapter) VariableString(lucee.transformer.bytecode.expression.var.VariableString) LitString(lucee.transformer.expression.literal.LitString) ExprString(lucee.transformer.expression.ExprString) FlowControlBreak(lucee.transformer.bytecode.statement.FlowControlBreak) TransformerException(lucee.transformer.TransformerException) lucee.aprint(lucee.aprint)

Aggregations

FlowControl (lucee.transformer.bytecode.statement.FlowControl)2 FlowControlBreak (lucee.transformer.bytecode.statement.FlowControlBreak)2 FlowControlFinal (lucee.transformer.bytecode.statement.FlowControlFinal)2 ArrayList (java.util.ArrayList)1 lucee.aprint (lucee.aprint)1 TransformerException (lucee.transformer.TransformerException)1 ScriptBody (lucee.transformer.bytecode.ScriptBody)1 Statement (lucee.transformer.bytecode.Statement)1 VariableString (lucee.transformer.bytecode.expression.var.VariableString)1 FlowControlContinue (lucee.transformer.bytecode.statement.FlowControlContinue)1 FlowControlRetry (lucee.transformer.bytecode.statement.FlowControlRetry)1 ExprString (lucee.transformer.expression.ExprString)1 LitString (lucee.transformer.expression.literal.LitString)1 Label (org.objectweb.asm.Label)1 GeneratorAdapter (org.objectweb.asm.commons.GeneratorAdapter)1