001: package org.hansel;
002:
003: import java.lang.reflect.Constructor;
004:
005: import org.hansel.probes.ACmpBranchProbe;
006: import org.hansel.probes.BinaryBranchProbe;
007: import org.hansel.probes.BranchProbe;
008: import org.hansel.probes.EQComparator;
009: import org.hansel.probes.ExceptionProbe;
010: import org.hansel.probes.GEComparator;
011: import org.hansel.probes.GTComparator;
012: import org.hansel.probes.IntComparator;
013: import org.hansel.probes.LEComparator;
014: import org.hansel.probes.LTComparator;
015: import org.hansel.probes.MethodProbe;
016: import org.hansel.probes.NEComparator;
017: import org.hansel.probes.NullCmpBranchProbe;
018: import org.hansel.probes.SelectProbe;
019: import org.hansel.probes.UnaryBranchProbe;
020: import org.objectweb.asm.Label;
021: import org.objectweb.asm.Opcodes;
022:
023: public class ProbeFactory {
024: private final static Class[] BRANCH_CLASS_ARGS = { ProbeData.class,
025: IntComparator.class };
026:
027: private final static BranchClassEntry[] BRANCH_CLASSES = {
028: new BranchClassEntry(Opcodes.IFEQ, UnaryBranchProbe.class,
029: new EQComparator()),
030: new BranchClassEntry(Opcodes.IFNE, UnaryBranchProbe.class,
031: new NEComparator()),
032: new BranchClassEntry(Opcodes.IFGE, UnaryBranchProbe.class,
033: new GEComparator()),
034: new BranchClassEntry(Opcodes.IFGT, UnaryBranchProbe.class,
035: new GTComparator()),
036: new BranchClassEntry(Opcodes.IFLE, UnaryBranchProbe.class,
037: new LEComparator()),
038: new BranchClassEntry(Opcodes.IFLT, UnaryBranchProbe.class,
039: new LTComparator()),
040:
041: new BranchClassEntry(Opcodes.IF_ICMPEQ,
042: BinaryBranchProbe.class, new EQComparator()),
043: new BranchClassEntry(Opcodes.IF_ICMPNE,
044: BinaryBranchProbe.class, new NEComparator()),
045: new BranchClassEntry(Opcodes.IF_ICMPGE,
046: BinaryBranchProbe.class, new GEComparator()),
047: new BranchClassEntry(Opcodes.IF_ICMPGT,
048: BinaryBranchProbe.class, new GTComparator()),
049: new BranchClassEntry(Opcodes.IF_ICMPLE,
050: BinaryBranchProbe.class, new LEComparator()),
051: new BranchClassEntry(Opcodes.IF_ICMPLT,
052: BinaryBranchProbe.class, new LTComparator()), };
053:
054: public static MethodProbe createMethodProbe(ProbeData pd) {
055: MethodProbe cached = (MethodProbe) ProbeTable.getProbeTable()
056: .getCached(pd);
057: if (cached != null) {
058: return cached;
059: }
060:
061: return new MethodProbe(pd);
062: }
063:
064: public static ExceptionProbe createExceptionProbe(ProbeData pd,
065: Probe mp) {
066: ExceptionProbe cached = (ExceptionProbe) ProbeTable
067: .getProbeTable().getCached(pd);
068: if (cached != null) {
069: return cached;
070: }
071:
072: return new ExceptionProbe(mp, pd);
073: }
074:
075: public static SelectProbe createSelectProbe(ProbeData pd,
076: Label dflt, int[] keys, Label[] labels) {
077: SelectProbe cached = (SelectProbe) ProbeTable.getProbeTable()
078: .getCached(pd);
079: if (cached != null) {
080: return cached;
081: }
082:
083: return new SelectProbe(pd, dflt, keys, labels);
084: }
085:
086: public static SelectProbe createSelectProbe(ProbeData pd, int min,
087: int max, Label dflt, Label labels[]) {
088: SelectProbe cached = (SelectProbe) ProbeTable.getProbeTable()
089: .getCached(pd);
090: if (cached != null) {
091: return cached;
092: }
093:
094: return new SelectProbe(pd, min, max, dflt, labels);
095: }
096:
097: public static BranchProbe createBranchProbe(ProbeData pd, int opcode) {
098:
099: BranchProbe cached = (BranchProbe) ProbeTable.getProbeTable()
100: .getCached(pd);
101: if (cached != null) {
102: return cached;
103: }
104:
105: for (int i = 0; i < BRANCH_CLASSES.length; i++) {
106: if (opcode == BRANCH_CLASSES[i].getBranchOpcode()) {
107: return BRANCH_CLASSES[i].createProbe(pd);
108: }
109: }
110:
111: if (opcode == Opcodes.IF_ACMPEQ) {
112: return new ACmpBranchProbe(pd, true);
113: } else if (opcode == Opcodes.IF_ACMPNE) {
114: return new ACmpBranchProbe(pd, false);
115: } else if (opcode == Opcodes.IFNONNULL) {
116: return new NullCmpBranchProbe(pd, false);
117: } else if (opcode == Opcodes.IFNULL) {
118: return new NullCmpBranchProbe(pd, true);
119: }
120:
121: throw new UnsupportedOperationException(
122: "Unknown branch opcode:" + opcode);
123: }
124:
125: private static class BranchClassEntry {
126: private int opcode;
127: private Class probeClazz;
128: private IntComparator cmp;
129:
130: public BranchClassEntry(int opcode, Class probeClazz,
131: IntComparator cmp) {
132: this .opcode = opcode;
133: this .probeClazz = probeClazz;
134: this .cmp = cmp;
135: }
136:
137: public int getBranchOpcode() {
138: return opcode;
139: }
140:
141: public BranchProbe createProbe(ProbeData pd) {
142: try {
143: Constructor constr = probeClazz
144: .getConstructor(BRANCH_CLASS_ARGS);
145: return (BranchProbe) constr.newInstance(new Object[] {
146: pd, cmp });
147: } catch (Exception e) {
148: // Should not happen ...
149: e.printStackTrace();
150: return null;
151: }
152: }
153: }
154: }
|