1 package jp.sourceforge.stigmata.birthmarks.wsp;
7 import java.util.ArrayList;
8 import java.util.HashMap;
9 import java.util.Iterator;
10 import java.util.List;
13 import jp.sourceforge.stigmata.Birthmark;
14 import jp.sourceforge.stigmata.BirthmarkContext;
15 import jp.sourceforge.stigmata.BirthmarkElement;
16 import jp.sourceforge.stigmata.ExtractionUnit;
17 import jp.sourceforge.stigmata.birthmarks.ASMBirthmarkExtractor;
18 import jp.sourceforge.stigmata.birthmarks.BirthmarkElementBuilder;
19 import jp.sourceforge.stigmata.birthmarks.BirthmarkExtractVisitor;
20 import jp.sourceforge.stigmata.birthmarks.LabelOpcode;
21 import jp.sourceforge.stigmata.birthmarks.Opcode;
22 import jp.sourceforge.stigmata.birthmarks.OpcodeExtractVisitor;
23 import jp.sourceforge.stigmata.spi.BirthmarkSpi;
25 import org.objectweb.asm.ClassWriter;
26 import org.objectweb.asm.Label;
30 * @author Haruaki Tamada
33 public class StackPatternBasedBirthmarkExtractor extends ASMBirthmarkExtractor{
34 public StackPatternBasedBirthmarkExtractor(BirthmarkSpi service){
39 public BirthmarkExtractVisitor createExtractVisitor(ClassWriter writer, Birthmark birthmark, BirthmarkContext context){
40 return new OpcodeExtractVisitor(writer, birthmark, context, new WSPBirthmarkElementBuilder());
44 public ExtractionUnit[] getAcceptableUnits(){
45 return new ExtractionUnit[] {
50 private static class WSPBirthmarkElementBuilder implements BirthmarkElementBuilder{
51 public BirthmarkElement[] buildElements(List<Opcode> opcodes, BirthmarkContext context){
52 List<CurrentDepth> pattern = buildStackPattern(opcodes, context);
53 List<BirthmarkElement> elements = new ArrayList<BirthmarkElement>();
55 List<CurrentDepth> subPattern = new ArrayList<CurrentDepth>();
56 for(CurrentDepth depth: pattern){
57 subPattern.add(depth);
58 if(depth.getDepth() == 0){
59 elements.add(new StackPatternBasedBirthmarkElement(subPattern.toArray(new CurrentDepth[subPattern.size()])));
63 elements.add(new StackPatternBasedBirthmarkElement(subPattern.toArray(new CurrentDepth[subPattern.size()])));
65 return elements.toArray(new BirthmarkElement[elements.size()]);
68 @SuppressWarnings("unchecked")
69 private List<CurrentDepth> buildStackPattern(List<Opcode> opcodes, BirthmarkContext context){
70 Map<Label, Integer> tableMap = new HashMap<Label, Integer>();
71 List<CurrentDepth> pattern = new ArrayList<CurrentDepth>();
72 Map<Integer, Integer> weights = (Map<Integer, Integer>)context.getProperty("birthmarks.wsp.weights");
75 Integer forwardedStatus = null;
76 for(Opcode opcode: opcodes){
77 if(opcode.getCategory() == Opcode.Category.TARGETER){
78 forwardedStatus = tableMap.get(((LabelOpcode)opcode).getLabel());
81 WSPOpcode wspOpcode = new WSPOpcode(opcode, weights.get(opcode.getOpcode()));
82 if(forwardedStatus == null){
83 currentDepth += opcode.getAct();
86 currentDepth = forwardedStatus + opcode.getAct();
88 forwardedStatus = null;
90 pattern.add(new CurrentDepth(currentDepth, wspOpcode));
91 if(opcode.getCategory() == Opcode.Category.BRANCH){
92 for(Iterator<Label> i = opcode.labels(); i.hasNext(); ){
93 Label label = i.next();
94 tableMap.put(label, currentDepth);