Package de.scoopgmbh.copper.instrument

Source Code of de.scoopgmbh.copper.instrument.TryCatchBlockHandler

/*
* Copyright 2002-2013 SCOOP Software GmbH
*
* Licensed 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 de.scoopgmbh.copper.instrument;

import java.util.HashSet;
import java.util.List;

import org.objectweb.asm.Label;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FrameNode;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.InsnNode;
import org.objectweb.asm.tree.JumpInsnNode;
import org.objectweb.asm.tree.LabelNode;
import org.objectweb.asm.tree.LineNumberNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.TryCatchBlockNode;
import org.objectweb.asm.tree.TypeInsnNode;
import org.objectweb.asm.tree.VarInsnNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import de.scoopgmbh.copper.InterruptException;

/**
* Adds "if (e instanceof InterruptException) throw (InterruptException)e;" to each catch block.
* This prevent COPPERs InterruptExceptions thrown by the COPPER wait calls to be handled in the exception handlers.
*
* @author austermann
*
*/
public class TryCatchBlockHandler {
 
  private static final Logger logger = LoggerFactory.getLogger(TryCatchBlockHandler.class);
 
  private static final String INTERRUPT_EXCEPTION_NAME = InterruptException.class.getName().replace('.', '/');
 
  @SuppressWarnings("unchecked")
  public void instrument(ClassNode cn) {
    //if (1 == 1) return;
   
    for (MethodNode m : (List<MethodNode>)cn.methods) {
      if (!m.exceptions.contains(INTERRUPT_EXCEPTION_NAME) || m.tryCatchBlocks.isEmpty()) {
        continue;
      }
      logger.info("Instrument "+cn.name+"."+m.name);
      HashSet<Label> labels = new HashSet<Label>();
      for (TryCatchBlockNode catchNode : (List<TryCatchBlockNode>)m.tryCatchBlocks) {
        if (labels.contains(catchNode.handler.getLabel())) {
          // some handlers share their handling code - check it out to prevent double instrumentation
          logger.info("skipping node");
          continue;
        }
        labels.add(catchNode.handler.getLabel());
       
        LabelNode labelNode = catchNode.handler;
        AbstractInsnNode lineNumberNode = labelNode.getNext() instanceof LineNumberNode ? labelNode.getNext() : labelNode;
        FrameNode frameNode = (FrameNode) lineNumberNode.getNext();
        VarInsnNode varInsnNode = (VarInsnNode) frameNode.getNext();
        AbstractInsnNode insertPoint = varInsnNode;
       
        if (catchNode.type == null) {
          // this is probably a finally block;
          if (insertPoint.getNext() != null && insertPoint.getNext() instanceof LabelNode) {
            insertPoint = insertPoint.getNext();
          }
        }
       
        LabelNode labelNode4ifeg = new LabelNode();
        InsnList newCode = new InsnList();
        newCode.add(new VarInsnNode(Opcodes.ALOAD, varInsnNode.var));
        newCode.add(new TypeInsnNode(Opcodes.INSTANCEOF, INTERRUPT_EXCEPTION_NAME));
        newCode.add(new JumpInsnNode(Opcodes.IFEQ, labelNode4ifeg));
        newCode.add(new VarInsnNode(Opcodes.ALOAD, varInsnNode.var));
        newCode.add(new TypeInsnNode(Opcodes.CHECKCAST, INTERRUPT_EXCEPTION_NAME));
        newCode.add(new InsnNode(Opcodes.ATHROW));
        newCode.add(labelNode4ifeg);
        m.instructions.insert(insertPoint, newCode);
      }
    }
  }
}
TOP

Related Classes of de.scoopgmbh.copper.instrument.TryCatchBlockHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.