Object Arrays for Argument Passing

Ok, during the last day and a bit, I changed my completely working implementation of passing method arguments. Before, there was one argument in the predicate method for each argument in the method that was annotated. That limited the applicability of the annotations. Now I pass an Object[] array that can be empty, contain one element, or however many. The coolest thing is that it automatically takes care of the subtyping problem.

Here are rewritten predicates and annotations from the last post:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
public class TCSample14 {
    public static class CheckSynchronized {
        public static boolean check(
          Object thisObject, Object args[], int value) {
            if (value>=args.length) return false;
            return ThreadCheckPredicates.checkMonitorOwned(args[value]);
        }
        public static boolean checkNot(
          Object thisObject, Object args[], int value) {
            if (value>=args.length) return false;
            return !ThreadCheckPredicates.checkMonitorOwned(args[value]);
        }
    }

    @PredicateLink(
      value=CheckSynchronized.class,
      arguments=true)
    public static interface OnlySynchronized {
        int value() default 0;
    }

    @PredicateLink(
      value=CheckSynchronized.class,
      method="checkNot",
      arguments=true)
    public static interface NotSynchronized {
        int value() default 0;
    }

    public static void main(String[] args) {
        TCSample14 o = new TCSample14();
        System.out.println("main!");
        o.succeeds();
        o.fails();
        System.out.println("end main!");
    }

    // these invariants all succeed
    void succeeds() {
        String o1 = "foo";
        String o2 = "bar";
        notUnary(o1);
        synchronized(o1) {
            unary(o1);
            binary1st(o1,o2);
            notBinary2nd(o1,o2);
        }
        synchronized(o2) {
            notBinary1st(o1,o2);
            binary2nd(o1,o2);
        }
    }

    @OnlySynchronized(0)
    void unary(Object o1) {
        System.out.println("unary!");
    }

    @OnlySynchronized(0)
    void binary1st(Object o1, Object o2) {
        System.out.println("binary1st");
    }

    @OnlySynchronized(1)
    void binary2nd(Object o1, Object o2) {
        System.out.println("binary2nd");
    }

    // these invariants all fail
    private void fails() {
        String o1 = "foo";
        String o2 = "bar";
        unary(o1);
        synchronized(o1) {
            notUnary(o1);
            notBinary1st(o1,o2);
            binary2nd(o1,o2);
        }
        synchronized(o2) {
            binary1st(o1,o2);
            notBinary2nd(o1,o2);
        }
    }

    @NotSynchronized(0)
    void notUnary(Object o1) {
        System.out.println("notUnary!");
    }

    @NotSynchronized(0)
    void notBinary1st(Object o1, Object o2) {
        System.out.println("notBinary1st");
    }

    @NotSynchronized(1)
    void notBinary2nd(Object o1, Object o2) {
        System.out.println("notBinary2nd");
    }
}

Now I think this is pretty cool. It even auto-boxes primitive types to their boxed types. Now I’m just running some more tests, and then it’s time to sleep.

PS: Whatever happened to Beer Bike today?

Share

About Mathias

Software development engineer. Principal developer of DrJava. Recent Ph.D. graduate from the Department of Computer Science at Rice University.
This entry was posted in Concurrent Unit Testing. Bookmark the permalink.

Leave a Reply