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);
}
}
}
}
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);
}
Aggregations