1 package jp.sourceforge.stigmata.birthmarks.wsp;
7 import java.util.ArrayList;
8 import java.util.HashMap;
12 import jp.sourceforge.stigmata.Birthmark;
13 import jp.sourceforge.stigmata.BirthmarkContext;
14 import jp.sourceforge.stigmata.BirthmarkElement;
15 import jp.sourceforge.stigmata.ExtractionUnit;
16 import jp.sourceforge.stigmata.birthmarks.ASMBirthmarkExtractor;
17 import jp.sourceforge.stigmata.birthmarks.BirthmarkElementBuilder;
18 import jp.sourceforge.stigmata.birthmarks.BirthmarkExtractVisitor;
19 import jp.sourceforge.stigmata.birthmarks.LabelOpcode;
20 import jp.sourceforge.stigmata.birthmarks.Opcode;
21 import jp.sourceforge.stigmata.birthmarks.OpcodeExtractVisitor;
22 import jp.sourceforge.stigmata.spi.BirthmarkSpi;
24 import org.objectweb.asm.ClassVisitor;
25 import org.objectweb.asm.Label;
29 * @author Haruaki Tamada
32 public class StackPatternBasedBirthmarkExtractor extends ASMBirthmarkExtractor{
33 public StackPatternBasedBirthmarkExtractor(BirthmarkSpi service){
38 public BirthmarkExtractVisitor createExtractVisitor(ClassVisitor visitor, Birthmark birthmark, BirthmarkContext context){
39 return new OpcodeExtractVisitor(visitor, birthmark, context, new WSPBirthmarkElementBuilder());
43 public ExtractionUnit[] getAcceptableUnits(){
44 return new ExtractionUnit[] {
49 private static class WSPBirthmarkElementBuilder implements BirthmarkElementBuilder{
50 public BirthmarkElement[] buildElements(List<Opcode> opcodes, BirthmarkContext context){
51 List<CurrentDepth> pattern = buildStackPattern(opcodes, context);
52 List<BirthmarkElement> elements = new ArrayList<BirthmarkElement>();
54 List<CurrentDepth> subPattern = new ArrayList<CurrentDepth>();
55 for(CurrentDepth depth: pattern){
56 subPattern.add(depth);
57 if(depth.getDepth() == 0){
58 elements.add(new StackPatternBasedBirthmarkElement(subPattern.toArray(new CurrentDepth[subPattern.size()])));
62 elements.add(new StackPatternBasedBirthmarkElement(subPattern.toArray(new CurrentDepth[subPattern.size()])));
64 return elements.toArray(new BirthmarkElement[elements.size()]);
67 @SuppressWarnings("unchecked")
68 private List<CurrentDepth> buildStackPattern(List<Opcode> opcodes, BirthmarkContext context){
69 Map<Label, Integer> tableMap = new HashMap<Label, Integer>();
70 List<CurrentDepth> pattern = new ArrayList<CurrentDepth>();
71 Map<Integer, Integer> weights = (Map<Integer, Integer>)context.getProperty("birthmarks.wsp.weights");
74 Integer forwardedStatus = null;
75 for(Opcode opcode: opcodes){
76 if(opcode.getCategory() == Opcode.Category.TARGETER){
77 forwardedStatus = tableMap.get(((LabelOpcode)opcode).getLabel());
80 WSPOpcode wspOpcode = new WSPOpcode(opcode, weights.get(opcode.getOpcode()));
81 if(forwardedStatus == null){
82 currentDepth += opcode.getAct();
85 currentDepth = forwardedStatus + opcode.getAct();
87 forwardedStatus = null;
89 pattern.add(new CurrentDepth(currentDepth, wspOpcode));
90 if(opcode.getCategory() == Opcode.Category.BRANCH){
91 for(Label label: opcode.getLabels()){
92 tableMap.put(label, currentDepth);