All Downloads are FREE. Search and download functionalities are using the official Maven repository.

mockit.asm.exceptionHandling.ExceptionHandling Maven / Gradle / Ivy

package mockit.asm.exceptionHandling;

import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.Nullable;

import java.util.ArrayList;
import java.util.List;

import mockit.asm.constantPool.ConstantPoolGeneration;
import mockit.asm.controlFlow.Edge;
import mockit.asm.controlFlow.FrameTypeMask;
import mockit.asm.controlFlow.Label;
import mockit.asm.util.ByteVector;

import org.checkerframework.checker.index.qual.NonNegative;

public final class ExceptionHandling {
    @NonNull
    private final List handlers;
    @NonNull
    private final ConstantPoolGeneration cp;

    public ExceptionHandling(@NonNull ConstantPoolGeneration cp) {
        handlers = new ArrayList<>();
        this.cp = cp;
    }

    public void addHandler(@NonNull Label start, @NonNull Label end, @NonNull Label handler, @Nullable String type) {
        int handlerType = type == null ? 0 : cp.newClass(type);
        handlers.add(new ExceptionHandler(start, end, handler, type, handlerType));
    }

    public void completeControlFlowGraphWithExceptionHandlerBlocksFromComputedFrames() {
        for (ExceptionHandler exceptionHandler : handlers) {
            Label handler = exceptionHandler.handler.getFirst();
            Label start = exceptionHandler.start.getFirst();
            Label end = exceptionHandler.end.getFirst();

            // Computes the kind of the edges to 'handler'.
            String catchType = exceptionHandler.getCatchTypeDesc();
            int kindOfEdge = FrameTypeMask.OBJECT | cp.addNormalType(catchType);

            // 'handler' is an exception handler.
            handler.markAsTarget();

            addHandlerLabelAsSuccessor(kindOfEdge, handler, start, end);
        }
    }

    public void completeControlFlowGraphWithExceptionHandlerBlocks() {
        for (ExceptionHandler exceptionHandler : handlers) {
            addHandlerLabelAsSuccessor(Edge.EXCEPTION, exceptionHandler.handler, exceptionHandler.start,
                    exceptionHandler.end);
        }
    }

    // Adds 'handler' as a successor of labels between 'start' and 'end'.
    private static void addHandlerLabelAsSuccessor(int kindOfEdge, @NonNull Label handler, @NonNull Label start,
            @NonNull Label end) {
        while (start != end) {
            Edge edge = new Edge(kindOfEdge, handler);
            // noinspection ConstantConditions
            start = start.setSuccessors(edge);
        }
    }

    public boolean hasHandlers() {
        return !handlers.isEmpty();
    }

    @NonNegative
    public int getSize() {
        return 8 * handlers.size();
    }

    public void put(@NonNull ByteVector out) {
        out.putShort(handlers.size());

        for (ExceptionHandler exceptionHandler : handlers) {
            exceptionHandler.put(out);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy