1 package jp.sourceforge.stigmata.birthmarks.wsp;
3 import java.util.ArrayList;
4 import java.util.HashMap;
8 import jp.sourceforge.stigmata.Birthmark;
9 import jp.sourceforge.stigmata.BirthmarkContext;
10 import jp.sourceforge.stigmata.BirthmarkElement;
11 import jp.sourceforge.stigmata.ExtractionUnit;
12 import jp.sourceforge.stigmata.birthmarks.ASMBirthmarkExtractor;
13 import jp.sourceforge.stigmata.birthmarks.BirthmarkExtractVisitor;
14 import jp.sourceforge.stigmata.cflib.BirthmarkElementBuilder;
15 import jp.sourceforge.stigmata.cflib.LabelOpcode;
16 import jp.sourceforge.stigmata.cflib.Opcode;
17 import jp.sourceforge.stigmata.cflib.OpcodeExtractVisitor;
18 import jp.sourceforge.stigmata.spi.BirthmarkService;
20 import org.objectweb.asm.ClassWriter;
21 import org.objectweb.asm.Label;
25 * @author Haruaki Tamada
27 public class StackPatternBasedBirthmarkExtractor
28 extends ASMBirthmarkExtractor{
29 public StackPatternBasedBirthmarkExtractor(BirthmarkService service){
34 public BirthmarkExtractVisitor createExtractVisitor(
35 ClassWriter writer, Birthmark birthmark,
36 BirthmarkContext context){
38 return new OpcodeExtractVisitor(
39 writer, birthmark, context, new WSPBirthmarkElementBuilder()
44 public ExtractionUnit[] getAcceptableUnits(){
45 return new ExtractionUnit[] {
50 private static class WSPBirthmarkElementBuilder
51 implements BirthmarkElementBuilder{
53 public BirthmarkElement[] buildElements(List<Opcode> opcodes,
54 BirthmarkContext context){
55 List<CurrentDepth> pattern = buildStackPattern(opcodes, context);
56 List<BirthmarkElement> elements =
57 new ArrayList<BirthmarkElement>();
59 List<CurrentDepth> subPattern = new ArrayList<CurrentDepth>();
60 for(CurrentDepth depth: pattern){
61 subPattern.add(depth);
62 if(depth.getDepth() == 0){
64 new StackPatternBasedBirthmarkElement(
66 new CurrentDepth[subPattern.size()]
74 new StackPatternBasedBirthmarkElement(
75 subPattern.toArray(new CurrentDepth[subPattern.size()])
79 return elements.toArray(new BirthmarkElement[elements.size()]);
82 @SuppressWarnings("unchecked")
83 private List<CurrentDepth> buildStackPattern(List<Opcode> opcodes,
84 BirthmarkContext context){
85 Map<Label, Integer> tableMap = new HashMap<Label, Integer>();
86 List<CurrentDepth> pattern = new ArrayList<CurrentDepth>();
87 Map<Integer, Integer> weights =
88 (Map<Integer, Integer>)context.getProperty(
89 "birthmarks.wsp.weights"
93 Integer forwardedStatus = null;
94 for(Opcode opcode: opcodes){
95 if(opcode.getCategory() == Opcode.Category.TARGETER){
97 tableMap.get(((LabelOpcode)opcode).getLabel());
100 WSPOpcode wspOpcode = new WSPOpcode(
101 opcode, weights.get(opcode.getOpcode())
103 if(forwardedStatus == null){
104 currentDepth += opcode.getAct();
107 currentDepth = forwardedStatus + opcode.getAct();
109 forwardedStatus = null;
111 pattern.add(new CurrentDepth(currentDepth, wspOpcode));
112 if(opcode.getCategory() == Opcode.Category.BRANCH){
113 for(Label label: opcode.getLabels()){
114 tableMap.put(label, currentDepth);
124 public BirthmarkElement buildElement(String value){
125 return new StackPatternBasedBirthmarkElement(value);