Search in sources :

Example 6 with Flow

use of org.apache.tapestry5.func.Flow in project tapestry-5 by apache.

the class ExceptionReportWriterImpl method writeReport.

@Override
public void writeReport(final PrintWriter writer, ExceptionAnalysis analysis) {
    writer.printf("EXCEPTION STACK:%n%n");
    // Figure out what all the property names are so that we can set the width of the column that lists
    // property names.
    Flow<String> propertyNames = F.flow(analysis.getExceptionInfos()).mapcat(EXCEPTION_INFO_TO_PROPERTY_NAMES).append("Exception", "Message");
    PropertyWriter pw = newPropertyWriter(writer, propertyNames);
    boolean first = true;
    for (ExceptionInfo info : analysis.getExceptionInfos()) {
        if (first) {
            writer.println();
            first = false;
        }
        pw.write("Exception", info.getClassName());
        pw.write("Message", info.getMessage());
        for (String name : info.getPropertyNames()) {
            pw.write(name, info.getProperty(name));
        }
        if (!info.getStackTrace().isEmpty()) {
            writer.printf("%n  Stack trace:%n%n");
            for (StackTraceElement e : info.getStackTrace()) {
                writer.printf("  - %s%n", e.toString());
            }
        }
        writer.println();
    }
    Request request = requestGlobals.getRequest();
    if (request != null) {
        // New PropertyWriter based on the lengths of parameter names and header names, and a sample of
        // the literal keys.
        pw = newPropertyWriter(writer, F.flow(request.getParameterNames()).concat(request.getHeaderNames()).append("serverName", "removeHost"));
        writer.printf("REQUEST:%n%nBasic Information:%n%n");
        List<String> flags = CollectionFactory.newList();
        if (request.isXHR()) {
            flags.add("XHR");
        }
        if (request.isRequestedSessionIdValid()) {
            flags.add("requestedSessionIdValid");
        }
        if (request.isSecure()) {
            flags.add("secure");
        }
        pw.write("contextPath", contextPath);
        if (!flags.isEmpty()) {
            pw.write("flags", InternalUtils.joinSorted(flags));
        }
        pw.write("method", request.getMethod());
        pw.write("path", request.getPath());
        pw.write("locale", request.getLocale());
        pw.write("serverName", request.getServerName());
        pw.write("remoteHost", request.getRemoteHost());
        writer.printf("%nHeaders:%n%n");
        for (String name : request.getHeaderNames()) {
            pw.write(name, request.getHeader(name));
        }
        if (!request.getParameterNames().isEmpty()) {
            writer.printf("%nParameters:%n");
            for (String name : request.getParameterNames()) {
                // TODO: Support multi-value parameters
                pw.write(name, request.getParameters(name));
            }
        }
        Session session = request.getSession(false);
        if (session != null) {
            pw = newPropertyWriter(writer, session.getAttributeNames());
            writer.printf("%nSESSION:%n%n");
            for (String name : session.getAttributeNames()) {
                pw.write(name, session.getAttribute(name));
            }
        }
    }
    writer.printf("%nSYSTEM INFORMATION:");
    Runtime runtime = Runtime.getRuntime();
    writer.printf("%n%nMemory:%n  %,15d bytes free%n  %,15d bytes total%n  %,15d bytes max%n", runtime.freeMemory(), runtime.totalMemory(), runtime.maxMemory());
    Thread[] threads = TapestryInternalUtils.getAllThreads();
    int maxThreadNameLength = 0;
    for (Thread t : threads) {
        maxThreadNameLength = Math.max(maxThreadNameLength, t.getName().length());
    }
    String format = "%n%s %" + maxThreadNameLength + "s %s";
    writer.printf("%n%,d Threads:", threads.length);
    for (Thread t : threads) {
        writer.printf(format, Thread.currentThread() == t ? "*" : " ", t.getName(), t.getState().name());
        if (t.isDaemon()) {
            writer.write(", daemon");
        }
        if (!t.isAlive()) {
            writer.write(", NOT alive");
        }
        if (t.isInterrupted()) {
            writer.write(", interrupted");
        }
        if (t.getPriority() != Thread.NORM_PRIORITY) {
            writer.printf(", priority %d", t.getPriority());
        }
    }
    // Finish the final line.
    writer.println();
}
Also used : Request(org.apache.tapestry5.http.services.Request) ExceptionInfo(org.apache.tapestry5.ioc.services.ExceptionInfo) Session(org.apache.tapestry5.http.services.Session)

Example 7 with Flow

use of org.apache.tapestry5.func.Flow in project tapestry-5 by apache.

the class PageCatalog method onRecomputeTotals.

public void onRecomputeTotals() {
    totals = new PageCatalogTotals();
    Flow<Page> pages = F.flow(getPages());
    totals.loadedPages = pages.count();
    totals.definedPages = getPageNames().size();
    totals.uniquePageNames = pages.map(new Mapper<Page, String>() {

        public String map(Page element) {
            return element.getName();
        }
    }).toSet().size();
    totals.components = pages.reduce(new Reducer<Integer, Page>() {

        public Integer reduce(Integer accumulator, Page element) {
            return accumulator + element.getStats().componentCount;
        }
    }, 0);
    Set<String> selectorIds = pages.map(new Mapper<Page, String>() {

        public String map(Page element) {
            return element.getSelector().toShortString();
        }
    }).toSet();
    totals.selectors = InternalUtils.joinSorted(selectorIds);
}
Also used : PageCatalogTotals(org.apache.tapestry5.internal.PageCatalogTotals) Page(org.apache.tapestry5.internal.structure.Page)

Example 8 with Flow

use of org.apache.tapestry5.func.Flow in project tapestry-5 by apache.

the class BasicTypeCoercions method provideBasicTypeCoercions.

/**
 * Provides the basic type coercions to a {@link MappedConfiguration} instance.
 */
public static void provideBasicTypeCoercions(MappedConfiguration<CoercionTuple.Key, CoercionTuple> configuration) {
    add(configuration, Object.class, String.class, new Coercion<Object, String>() {

        @Override
        public String coerce(Object input) {
            return input.toString();
        }
    });
    add(configuration, Object.class, Boolean.class, new Coercion<Object, Boolean>() {

        @Override
        public Boolean coerce(Object input) {
            return input != null;
        }
    });
    add(configuration, String.class, Double.class, new Coercion<String, Double>() {

        @Override
        public Double coerce(String input) {
            return Double.valueOf(input);
        }
    });
    // String to BigDecimal is important, as String->Double->BigDecimal would lose
    // precision.
    add(configuration, String.class, BigDecimal.class, new Coercion<String, BigDecimal>() {

        @Override
        public BigDecimal coerce(String input) {
            return new BigDecimal(input);
        }
    });
    add(configuration, BigDecimal.class, Double.class, new Coercion<BigDecimal, Double>() {

        @Override
        public Double coerce(BigDecimal input) {
            return input.doubleValue();
        }
    });
    add(configuration, String.class, BigInteger.class, new Coercion<String, BigInteger>() {

        @Override
        public BigInteger coerce(String input) {
            return new BigInteger(input);
        }
    });
    add(configuration, String.class, Long.class, new Coercion<String, Long>() {

        @Override
        public Long coerce(String input) {
            return Long.valueOf(input);
        }
    });
    add(configuration, String.class, Integer.class, Integer::valueOf);
    add(configuration, Long.class, Byte.class, new Coercion<Long, Byte>() {

        @Override
        public Byte coerce(Long input) {
            return input.byteValue();
        }
    });
    add(configuration, Long.class, Short.class, new Coercion<Long, Short>() {

        @Override
        public Short coerce(Long input) {
            return input.shortValue();
        }
    });
    add(configuration, Long.class, Integer.class, new Coercion<Long, Integer>() {

        @Override
        public Integer coerce(Long input) {
            return input.intValue();
        }
    });
    add(configuration, Number.class, Long.class, new Coercion<Number, Long>() {

        @Override
        public Long coerce(Number input) {
            return input.longValue();
        }
    });
    add(configuration, Double.class, Float.class, new Coercion<Double, Float>() {

        @Override
        public Float coerce(Double input) {
            return input.floatValue();
        }
    });
    add(configuration, Long.class, Double.class, new Coercion<Long, Double>() {

        @Override
        public Double coerce(Long input) {
            return input.doubleValue();
        }
    });
    add(configuration, String.class, Boolean.class, new Coercion<String, Boolean>() {

        @Override
        public Boolean coerce(String input) {
            String trimmed = input == null ? "" : input.trim();
            if (trimmed.equalsIgnoreCase("false") || trimmed.length() == 0)
                return false;
            return true;
        }
    });
    add(configuration, Number.class, Boolean.class, new Coercion<Number, Boolean>() {

        @Override
        public Boolean coerce(Number input) {
            return input.longValue() != 0;
        }
    });
    add(configuration, Void.class, Boolean.class, new Coercion<Void, Boolean>() {

        @Override
        public Boolean coerce(Void input) {
            return false;
        }
    });
    add(configuration, Collection.class, Boolean.class, new Coercion<Collection, Boolean>() {

        @Override
        public Boolean coerce(Collection input) {
            return !input.isEmpty();
        }
    });
    add(configuration, Object.class, List.class, new Coercion<Object, List>() {

        @Override
        public List coerce(Object input) {
            return Collections.singletonList(input);
        }
    });
    add(configuration, Object[].class, List.class, new Coercion<Object[], List>() {

        @Override
        public List coerce(Object[] input) {
            return Arrays.asList(input);
        }
    });
    add(configuration, Object[].class, Boolean.class, new Coercion<Object[], Boolean>() {

        @Override
        public Boolean coerce(Object[] input) {
            return input != null && input.length > 0;
        }
    });
    add(configuration, Float.class, Double.class, new Coercion<Float, Double>() {

        @Override
        public Double coerce(Float input) {
            return input.doubleValue();
        }
    });
    Coercion primitiveArrayCoercion = new Coercion<Object, List>() {

        @Override
        public List<Object> coerce(Object input) {
            int length = Array.getLength(input);
            Object[] array = new Object[length];
            for (int i = 0; i < length; i++) {
                array[i] = Array.get(input, i);
            }
            return Arrays.asList(array);
        }
    };
    add(configuration, byte[].class, List.class, primitiveArrayCoercion);
    add(configuration, short[].class, List.class, primitiveArrayCoercion);
    add(configuration, int[].class, List.class, primitiveArrayCoercion);
    add(configuration, long[].class, List.class, primitiveArrayCoercion);
    add(configuration, float[].class, List.class, primitiveArrayCoercion);
    add(configuration, double[].class, List.class, primitiveArrayCoercion);
    add(configuration, char[].class, List.class, primitiveArrayCoercion);
    add(configuration, boolean[].class, List.class, primitiveArrayCoercion);
    add(configuration, String.class, File.class, new Coercion<String, File>() {

        @Override
        public File coerce(String input) {
            return new File(input);
        }
    });
    add(configuration, String.class, TimeInterval.class, new Coercion<String, TimeInterval>() {

        @Override
        public TimeInterval coerce(String input) {
            return new TimeInterval(input);
        }
    });
    add(configuration, TimeInterval.class, Long.class, new Coercion<TimeInterval, Long>() {

        @Override
        public Long coerce(TimeInterval input) {
            return input.milliseconds();
        }
    });
    add(configuration, Object.class, Object[].class, new Coercion<Object, Object[]>() {

        @Override
        public Object[] coerce(Object input) {
            return new Object[] { input };
        }
    });
    add(configuration, Collection.class, Object[].class, new Coercion<Collection, Object[]>() {

        @Override
        public Object[] coerce(Collection input) {
            return input.toArray();
        }
    });
    CoercionTuple<Flow, List> flowToListCoercion = CoercionTuple.create(Flow.class, List.class, Flow::toList);
    configuration.add(flowToListCoercion.getKey(), flowToListCoercion);
    CoercionTuple<Flow, Boolean> flowToBooleanCoercion = CoercionTuple.create(Flow.class, Boolean.class, (i) -> !i.isEmpty());
    configuration.add(flowToBooleanCoercion.getKey(), flowToBooleanCoercion);
}
Also used : List(java.util.List) BigInteger(java.math.BigInteger) Collection(java.util.Collection) File(java.io.File) TimeInterval(org.apache.tapestry5.commons.util.TimeInterval) BigDecimal(java.math.BigDecimal) StringToEnumCoercion(org.apache.tapestry5.commons.util.StringToEnumCoercion) Coercion(org.apache.tapestry5.commons.services.Coercion) Flow(org.apache.tapestry5.func.Flow) BigInteger(java.math.BigInteger)

Example 9 with Flow

use of org.apache.tapestry5.func.Flow in project tapestry-5 by apache.

the class JSRInlinerAdapter method findReachableInsns.

/**
 * Finds the instructions that are reachable from the given instruction, without following any JSR
 * instruction nor any exception handler. For this the control flow graph is visited with a depth
 * first search.
 *
 * @param insnIndex the index of an instruction of the subroutine.
 * @param subroutineInsns where the indices of the instructions of the subroutine must be stored.
 * @param visitedInsns the indices of the instructions that have been visited so far (including in
 *     previous calls to this method). This bitset is updated by this method each time a new
 *     instruction is visited. It is used to make sure each instruction is visited at most once.
 */
private void findReachableInsns(final int insnIndex, final BitSet subroutineInsns, final BitSet visitedInsns) {
    int currentInsnIndex = insnIndex;
    // return or not from a JSR, but this is more complicated).
    while (currentInsnIndex < instructions.size()) {
        // Visit each instruction at most once.
        if (subroutineInsns.get(currentInsnIndex)) {
            return;
        }
        subroutineInsns.set(currentInsnIndex);
        // Check if this instruction has already been visited by another subroutine.
        if (visitedInsns.get(currentInsnIndex)) {
            sharedSubroutineInsns.set(currentInsnIndex);
        }
        visitedInsns.set(currentInsnIndex);
        AbstractInsnNode currentInsnNode = instructions.get(currentInsnIndex);
        if (currentInsnNode.getType() == AbstractInsnNode.JUMP_INSN && currentInsnNode.getOpcode() != JSR) {
            // Don't follow JSR instructions in the control flow graph.
            JumpInsnNode jumpInsnNode = (JumpInsnNode) currentInsnNode;
            findReachableInsns(instructions.indexOf(jumpInsnNode.label), subroutineInsns, visitedInsns);
        } else if (currentInsnNode.getType() == AbstractInsnNode.TABLESWITCH_INSN) {
            TableSwitchInsnNode tableSwitchInsnNode = (TableSwitchInsnNode) currentInsnNode;
            findReachableInsns(instructions.indexOf(tableSwitchInsnNode.dflt), subroutineInsns, visitedInsns);
            for (LabelNode labelNode : tableSwitchInsnNode.labels) {
                findReachableInsns(instructions.indexOf(labelNode), subroutineInsns, visitedInsns);
            }
        } else if (currentInsnNode.getType() == AbstractInsnNode.LOOKUPSWITCH_INSN) {
            LookupSwitchInsnNode lookupSwitchInsnNode = (LookupSwitchInsnNode) currentInsnNode;
            findReachableInsns(instructions.indexOf(lookupSwitchInsnNode.dflt), subroutineInsns, visitedInsns);
            for (LabelNode labelNode : lookupSwitchInsnNode.labels) {
                findReachableInsns(instructions.indexOf(labelNode), subroutineInsns, visitedInsns);
            }
        }
        // Check if this instruction falls through to the next instruction; if not, return.
        switch(instructions.get(currentInsnIndex).getOpcode()) {
            case GOTO:
            case RET:
            case TABLESWITCH:
            case LOOKUPSWITCH:
            case IRETURN:
            case LRETURN:
            case FRETURN:
            case DRETURN:
            case ARETURN:
            case RETURN:
            case ATHROW:
                // Note: this either returns from this subroutine, or from a parent subroutine.
                return;
            default:
                // Go to the next instruction.
                currentInsnIndex++;
                break;
        }
    }
}
Also used : LabelNode(org.apache.tapestry5.internal.plastic.asm.tree.LabelNode) TableSwitchInsnNode(org.apache.tapestry5.internal.plastic.asm.tree.TableSwitchInsnNode) JumpInsnNode(org.apache.tapestry5.internal.plastic.asm.tree.JumpInsnNode) LookupSwitchInsnNode(org.apache.tapestry5.internal.plastic.asm.tree.LookupSwitchInsnNode) AbstractInsnNode(org.apache.tapestry5.internal.plastic.asm.tree.AbstractInsnNode)

Example 10 with Flow

use of org.apache.tapestry5.func.Flow in project tapestry-5 by apache.

the class Analyzer method analyze.

/**
 * Analyzes the given method.
 *
 * @param owner the internal name of the class to which 'method' belongs.
 * @param method the method to be analyzed. The maxStack and maxLocals fields must have correct
 *     values.
 * @return the symbolic state of the execution stack frame at each bytecode instruction of the
 *     method. The size of the returned array is equal to the number of instructions (and labels)
 *     of the method. A given frame is {@literal null} if and only if the corresponding
 *     instruction cannot be reached (dead code).
 * @throws AnalyzerException if a problem occurs during the analysis.
 */
@SuppressWarnings("unchecked")
public Frame<V>[] analyze(final String owner, final MethodNode method) throws AnalyzerException {
    if ((method.access & (ACC_ABSTRACT | ACC_NATIVE)) != 0) {
        frames = (Frame<V>[]) new Frame<?>[0];
        return frames;
    }
    insnList = method.instructions;
    insnListSize = insnList.size();
    handlers = (List<TryCatchBlockNode>[]) new List<?>[insnListSize];
    frames = (Frame<V>[]) new Frame<?>[insnListSize];
    subroutines = new Subroutine[insnListSize];
    inInstructionsToProcess = new boolean[insnListSize];
    instructionsToProcess = new int[insnListSize];
    numInstructionsToProcess = 0;
    // fact that execution can flow from this instruction to the exception handler.
    for (int i = 0; i < method.tryCatchBlocks.size(); ++i) {
        TryCatchBlockNode tryCatchBlock = method.tryCatchBlocks.get(i);
        int startIndex = insnList.indexOf(tryCatchBlock.start);
        int endIndex = insnList.indexOf(tryCatchBlock.end);
        for (int j = startIndex; j < endIndex; ++j) {
            List<TryCatchBlockNode> insnHandlers = handlers[j];
            if (insnHandlers == null) {
                insnHandlers = new ArrayList<>();
                handlers[j] = insnHandlers;
            }
            insnHandlers.add(tryCatchBlock);
        }
    }
    // For each instruction, compute the subroutine to which it belongs.
    // Follow the main 'subroutine', and collect the jsr instructions to nested subroutines.
    Subroutine main = new Subroutine(null, method.maxLocals, null);
    List<AbstractInsnNode> jsrInsns = new ArrayList<>();
    findSubroutine(0, main, jsrInsns);
    // Follow the nested subroutines, and collect their own nested subroutines, until all
    // subroutines are found.
    Map<LabelNode, Subroutine> jsrSubroutines = new HashMap<>();
    while (!jsrInsns.isEmpty()) {
        JumpInsnNode jsrInsn = (JumpInsnNode) jsrInsns.remove(0);
        Subroutine subroutine = jsrSubroutines.get(jsrInsn.label);
        if (subroutine == null) {
            subroutine = new Subroutine(jsrInsn.label, method.maxLocals, jsrInsn);
            jsrSubroutines.put(jsrInsn.label, subroutine);
            findSubroutine(insnList.indexOf(jsrInsn.label), subroutine, jsrInsns);
        } else {
            subroutine.callers.add(jsrInsn);
        }
    }
    // intermediate step above to find the real ones).
    for (int i = 0; i < insnListSize; ++i) {
        if (subroutines[i] != null && subroutines[i].start == null) {
            subroutines[i] = null;
        }
    }
    // Initializes the data structures for the control flow analysis.
    Frame<V> currentFrame = computeInitialFrame(owner, method);
    merge(0, currentFrame, null);
    init(owner, method);
    // Control flow analysis.
    while (numInstructionsToProcess > 0) {
        // Get and remove one instruction from the list of instructions to process.
        int insnIndex = instructionsToProcess[--numInstructionsToProcess];
        Frame<V> oldFrame = frames[insnIndex];
        Subroutine subroutine = subroutines[insnIndex];
        inInstructionsToProcess[insnIndex] = false;
        // Simulate the execution of this instruction.
        AbstractInsnNode insnNode = null;
        try {
            insnNode = method.instructions.get(insnIndex);
            int insnOpcode = insnNode.getOpcode();
            int insnType = insnNode.getType();
            if (insnType == AbstractInsnNode.LABEL || insnType == AbstractInsnNode.LINE || insnType == AbstractInsnNode.FRAME) {
                merge(insnIndex + 1, oldFrame, subroutine);
                newControlFlowEdge(insnIndex, insnIndex + 1);
            } else {
                currentFrame.init(oldFrame).execute(insnNode, interpreter);
                subroutine = subroutine == null ? null : new Subroutine(subroutine);
                if (insnNode instanceof JumpInsnNode) {
                    JumpInsnNode jumpInsn = (JumpInsnNode) insnNode;
                    if (insnOpcode != GOTO && insnOpcode != JSR) {
                        currentFrame.initJumpTarget(insnOpcode, /* target = */
                        null);
                        merge(insnIndex + 1, currentFrame, subroutine);
                        newControlFlowEdge(insnIndex, insnIndex + 1);
                    }
                    int jumpInsnIndex = insnList.indexOf(jumpInsn.label);
                    currentFrame.initJumpTarget(insnOpcode, jumpInsn.label);
                    if (insnOpcode == JSR) {
                        merge(jumpInsnIndex, currentFrame, new Subroutine(jumpInsn.label, method.maxLocals, jumpInsn));
                    } else {
                        merge(jumpInsnIndex, currentFrame, subroutine);
                    }
                    newControlFlowEdge(insnIndex, jumpInsnIndex);
                } else if (insnNode instanceof LookupSwitchInsnNode) {
                    LookupSwitchInsnNode lookupSwitchInsn = (LookupSwitchInsnNode) insnNode;
                    int targetInsnIndex = insnList.indexOf(lookupSwitchInsn.dflt);
                    currentFrame.initJumpTarget(insnOpcode, lookupSwitchInsn.dflt);
                    merge(targetInsnIndex, currentFrame, subroutine);
                    newControlFlowEdge(insnIndex, targetInsnIndex);
                    for (int i = 0; i < lookupSwitchInsn.labels.size(); ++i) {
                        LabelNode label = lookupSwitchInsn.labels.get(i);
                        targetInsnIndex = insnList.indexOf(label);
                        currentFrame.initJumpTarget(insnOpcode, label);
                        merge(targetInsnIndex, currentFrame, subroutine);
                        newControlFlowEdge(insnIndex, targetInsnIndex);
                    }
                } else if (insnNode instanceof TableSwitchInsnNode) {
                    TableSwitchInsnNode tableSwitchInsn = (TableSwitchInsnNode) insnNode;
                    int targetInsnIndex = insnList.indexOf(tableSwitchInsn.dflt);
                    currentFrame.initJumpTarget(insnOpcode, tableSwitchInsn.dflt);
                    merge(targetInsnIndex, currentFrame, subroutine);
                    newControlFlowEdge(insnIndex, targetInsnIndex);
                    for (int i = 0; i < tableSwitchInsn.labels.size(); ++i) {
                        LabelNode label = tableSwitchInsn.labels.get(i);
                        currentFrame.initJumpTarget(insnOpcode, label);
                        targetInsnIndex = insnList.indexOf(label);
                        merge(targetInsnIndex, currentFrame, subroutine);
                        newControlFlowEdge(insnIndex, targetInsnIndex);
                    }
                } else if (insnOpcode == RET) {
                    if (subroutine == null) {
                        throw new AnalyzerException(insnNode, "RET instruction outside of a subroutine");
                    }
                    for (int i = 0; i < subroutine.callers.size(); ++i) {
                        JumpInsnNode caller = subroutine.callers.get(i);
                        int jsrInsnIndex = insnList.indexOf(caller);
                        if (frames[jsrInsnIndex] != null) {
                            merge(jsrInsnIndex + 1, frames[jsrInsnIndex], currentFrame, subroutines[jsrInsnIndex], subroutine.localsUsed);
                            newControlFlowEdge(insnIndex, jsrInsnIndex + 1);
                        }
                    }
                } else if (insnOpcode != ATHROW && (insnOpcode < IRETURN || insnOpcode > RETURN)) {
                    if (subroutine != null) {
                        if (insnNode instanceof VarInsnNode) {
                            int var = ((VarInsnNode) insnNode).var;
                            subroutine.localsUsed[var] = true;
                            if (insnOpcode == LLOAD || insnOpcode == DLOAD || insnOpcode == LSTORE || insnOpcode == DSTORE) {
                                subroutine.localsUsed[var + 1] = true;
                            }
                        } else if (insnNode instanceof IincInsnNode) {
                            int var = ((IincInsnNode) insnNode).var;
                            subroutine.localsUsed[var] = true;
                        }
                    }
                    merge(insnIndex + 1, currentFrame, subroutine);
                    newControlFlowEdge(insnIndex, insnIndex + 1);
                }
            }
            List<TryCatchBlockNode> insnHandlers = handlers[insnIndex];
            if (insnHandlers != null) {
                for (TryCatchBlockNode tryCatchBlock : insnHandlers) {
                    Type catchType;
                    if (tryCatchBlock.type == null) {
                        catchType = Type.getObjectType("java/lang/Throwable");
                    } else {
                        catchType = Type.getObjectType(tryCatchBlock.type);
                    }
                    if (newControlFlowExceptionEdge(insnIndex, tryCatchBlock)) {
                        Frame<V> handler = newFrame(oldFrame);
                        handler.clearStack();
                        handler.push(interpreter.newExceptionValue(tryCatchBlock, handler, catchType));
                        merge(insnList.indexOf(tryCatchBlock.handler), handler, subroutine);
                    }
                }
            }
        } catch (AnalyzerException e) {
            throw new AnalyzerException(e.node, "Error at instruction " + insnIndex + ": " + e.getMessage(), e);
        } catch (RuntimeException e) {
            // DontCheck(IllegalCatch): can't be fixed, for backward compatibility.
            throw new AnalyzerException(insnNode, "Error at instruction " + insnIndex + ": " + e.getMessage(), e);
        }
    }
    return frames;
}
Also used : LabelNode(org.apache.tapestry5.internal.plastic.asm.tree.LabelNode) TryCatchBlockNode(org.apache.tapestry5.internal.plastic.asm.tree.TryCatchBlockNode) TableSwitchInsnNode(org.apache.tapestry5.internal.plastic.asm.tree.TableSwitchInsnNode) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) AbstractInsnNode(org.apache.tapestry5.internal.plastic.asm.tree.AbstractInsnNode) Type(org.apache.tapestry5.internal.plastic.asm.Type) JumpInsnNode(org.apache.tapestry5.internal.plastic.asm.tree.JumpInsnNode) IincInsnNode(org.apache.tapestry5.internal.plastic.asm.tree.IincInsnNode) ArrayList(java.util.ArrayList) InsnList(org.apache.tapestry5.internal.plastic.asm.tree.InsnList) List(java.util.List) LookupSwitchInsnNode(org.apache.tapestry5.internal.plastic.asm.tree.LookupSwitchInsnNode) VarInsnNode(org.apache.tapestry5.internal.plastic.asm.tree.VarInsnNode)

Aggregations

AbstractInsnNode (org.apache.tapestry5.internal.plastic.asm.tree.AbstractInsnNode)4 JumpInsnNode (org.apache.tapestry5.internal.plastic.asm.tree.JumpInsnNode)4 LabelNode (org.apache.tapestry5.internal.plastic.asm.tree.LabelNode)4 LookupSwitchInsnNode (org.apache.tapestry5.internal.plastic.asm.tree.LookupSwitchInsnNode)4 TableSwitchInsnNode (org.apache.tapestry5.internal.plastic.asm.tree.TableSwitchInsnNode)4 TryCatchBlockNode (org.apache.tapestry5.internal.plastic.asm.tree.TryCatchBlockNode)4 ArrayList (java.util.ArrayList)2 List (java.util.List)2 JSONArray (org.apache.tapestry5.json.JSONArray)2 File (java.io.File)1 BigDecimal (java.math.BigDecimal)1 BigInteger (java.math.BigInteger)1 BitSet (java.util.BitSet)1 Collection (java.util.Collection)1 HashMap (java.util.HashMap)1 OnEvent (org.apache.tapestry5.annotations.OnEvent)1 Coercion (org.apache.tapestry5.commons.services.Coercion)1 StringToEnumCoercion (org.apache.tapestry5.commons.util.StringToEnumCoercion)1 TimeInterval (org.apache.tapestry5.commons.util.TimeInterval)1 PublishServerSideEvents (org.apache.tapestry5.corelib.mixins.PublishServerSideEvents)1