[Jsr308-statements] statement ranges

Eugene Kuleshov eu at javatx.org
Wed Apr 18 08:09:36 EDT 2007


Trevor Harmon wrote:
>>> Faking statement annotations by putting blocks around everything is
>>> so awkward and error-prone that I hardly think there would be any
>>> gain at all.
>> I am sympathetic to this point of view, particularly because I think 
>> it may
>> be awkward (but I'm not yet sure how it will work out in practice, 
>> and it
>> turn out that a block annotation will be simpler), but what would be
>> error-prone about it?  Are you worried that people will forget?  The
>> compiler will immediately warn in that case.
> I don't see how the compiler could do anything. Eugene once gave an 
> example of why using blocks as statement annotations is error-prone:
>
> https://lists.csail.mit.edu/pipermail/jsr308/2007-February/000104.html
>
> Note that his example code is perfectly legal according to the Option 
> 2 grammar, so there'd be no compiler warning.
  Trevor, the example I used there has an extra block around loop.

@Loopcount(100) {
     for(...) {
        ...
     }
  }
 
  However Option 2 is actually suggesting to use loop's own block, which 
won't be affected by that issue:

     for(...) @Loopcount(100) {
        ...
     }

  There is actually one thing to worry about. We need to specify how 
those blocks will be mapped to the bytecode. For example, consider the 
following method:

35  private void boo1() {
36    int a = 1;
37    @Ann1 for (int i = 0;
38          i < 100;
39          i++) @Ann2 {
40      int b = 1;
41      boo();
42    }
43  }

  Now, question is how ranges should look like for annotations Ann1 and 
Ann2?

  Live range of variable a is close to outer scope of the for loop and 
live range of variable b is close to the inner scope. There is also live 
range of variable i which is between ranges for a and b.
 
  private boo1() : void
    LOCALVARIABLE this A L0 L8 0
    LOCALVARIABLE a int L1 L8 1
    LOCALVARIABLE i int L2 L7 2
    LOCALVARIABLE b int L5 L6 3

   L0 (0)    LINENUMBER 36  // int a = 1;
    ICONST_1
    ISTORE 1: a

   L1 (3)    LINENUMBER 37  // for (int i = 0;
    ICONST_0
    ISTORE 2: i
   L2 (6)    LINENUMBER 38  // i < 100;
    GOTO L3

   L4 (8)    LINENUMBER 40  // int b = 1;
    ICONST_1
    ISTORE 3: b
   L5 (11)    LINENUMBER 41  // boo();
    INVOKESTATIC A.boo() : void
   L6 (15)    LINENUMBER 39  //  i++) {
    IINC 2: i 1
   L3 (17)    LINENUMBER 38  // i < 100;
    ILOAD 2: i
    BIPUSH 100
    IF_ICMPLT L4

   L7 (21)    LINENUMBER 43  // } method end
    RETURN
   L8 (23)

  For comparison we can also look at the ranges of try/catch blocks. For 
example:

45  private void boo2() {
46    try {
47      for (int i = 0;
48      i < 100;
49      i++) {
50        try {
51          boo();
52        } catch(RuntimeException ex) {
53          throw ex;
54        }
55      }
56    } catch(Error ex) {
57       throw ex;
58    }
59  }

  Which look like this in the bytecode:

  // access flags 2
  private boo2() : void
    LOCALVARIABLE this A L3 L12 0
    LOCALVARIABLE i int L6 L4 1
    LOCALVARIABLE ex1 RuntimeException L9 L8 2
    LOCALVARIABLE ex2 Error L11 L10 1

    TRYCATCHBLOCK L0 L1 L2 RuntimeException
    TRYCATCHBLOCK L3 L4 L5 Error

   L3 (0)    LINENUMBER 47  // for (int i = 0;   // begin try for Error ex2
    ICONST_0
    ISTORE 1: i
   L6 (3)    LINENUMBER 48  // i < 100;
    GOTO L7

   L0 (5)    LINENUMBER 51  // boo();  // begin try for RuntimeException ex1
    INVOKESTATIC A.boo() : void
   L1 (9)  // end of try for RuntimeException ex1
    GOTO L8

   L2 (11)    LINENUMBER 52  // } catch(RuntimeException ex1) {
    ASTORE 2: ex1
   L9 (13)    LINENUMBER 53  // throw ex1;
    ALOAD 2: ex1
    ATHROW

   L8 (16)    LINENUMBER 49 // i++) {
    IINC 1: i 1
   L7 (18)    LINENUMBER 48  // i < 100;
    ILOAD 1: i
    BIPUSH 100
    IF_ICMPLT L0

   L4 (22)   // end of try for Error ex2
    GOTO L10

   L5 (24)    LINENUMBER 56  // } catch(Error ex2) {
    ASTORE 1: ex2
   L11 (26)    LINENUMBER 57  // throw ex2
    ALOAD 1: ex2
    ATHROW

   L10 (29)    LINENUMBER 59  // } method end
    RETURN
   L12 (31)

>> It might be good to elucidate the argument a bit, because I don't 
>> think the above will convince any
>> skeptics.  And this:
>>> It wouldn't even be worth the effort of putting forth a 
>>> specification, IMHO.
>> definitely won't!
> I wasn't expecting to win over anyone; I'm just saying that if the 
> spec starts heading in that direction, I'll no longer have any 
> interest in participating.
  Hmm. What is this about? It seems like I missed an email or two...

  regards,
  Eugene





More information about the JSR308-statements mailing list