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

org.apache.commons.javaflow.bytecode.transformation.asm.MonitoringFrame Maven / Gradle / Ivy

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.commons.javaflow.bytecode.transformation.asm;

import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.analysis.AnalyzerException;
import org.objectweb.asm.tree.analysis.Frame;
import org.objectweb.asm.tree.analysis.Interpreter;
import org.objectweb.asm.tree.analysis.Value;

import java.util.LinkedList;
import java.util.List;

public final class MonitoringFrame extends Frame {

    // keeps track of monitored locals
    private List monitored;

    public MonitoringFrame(Frame arg0) {
        super(arg0);
    }

    public MonitoringFrame(int arg0, int arg1) {
        super(arg0, arg1);
        monitored = new LinkedList();
    }

    public void execute(AbstractInsnNode insn, Interpreter interpreter)
            throws AnalyzerException {

        boolean never = false;
        if (never) {
            super.execute(insn, interpreter);
            return;
        }

        int insnOpcode = insn.getOpcode();

        if (insnOpcode == Opcodes.MONITORENTER || insnOpcode == Opcodes.MONITOREXIT) {
            Value pop = pop();
            interpreter.unaryOperation(insn, pop);

            int local = -1;
            for (int i = 0; i < getLocals(); i++) {
                if (getLocal(i) == pop) local = i;
            }

            if (local > -1) {
                if (insnOpcode == Opcodes.MONITORENTER) {
                    monitorEnter(local);
                } else {
                    monitorExit(local);
                }
            }

        } else {
            super.execute(insn, interpreter);
        }
    }

    public Frame init(Frame frame) {
        super.init(frame);
        if (frame instanceof MonitoringFrame) {
            monitored = new LinkedList(MonitoringFrame.class.cast(frame).monitored);
        } else {
            monitored = new LinkedList();
        }
        return this;
    }

    public int[] getMonitored() {
        int[] res = new int[monitored.size()];
        for (int i = 0; i < monitored.size(); i++) {
            res[i] = monitored.get(i);
        }
        return res;
    }

    public void monitorEnter(int local) {
        monitored.add(new Integer(local));
    }

    public void monitorExit(int local) {
        int index = monitored.lastIndexOf(local);
        if (index == -1) {
            // throw new IllegalStateException("Monitor Exit never entered");
        } else {
            monitored.remove(index);
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy