langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java
changeset 15385 ee1eebe7e210
parent 14949 45f43822bbde
child 16801 e2de240b437f
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java	Wed Jan 23 20:57:40 2013 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java	Wed Jan 23 13:27:24 2013 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1924,17 +1924,70 @@
                 if (length < Character.MAX_VALUE) {
                     v.length = length;
                     putVar(v);
+                    fillLocalVarPosition(v);
                 }
             }
         }
         state.defined.excl(adr);
     }
 
+    private void fillLocalVarPosition(LocalVar lv) {
+        if (lv == null || lv.sym == null
+                || lv.sym.annotations.isTypesEmpty())
+            return;
+        for (Attribute.TypeCompound ta : lv.sym.getRawTypeAttributes()) {
+            TypeAnnotationPosition p = ta.position;
+            p.lvarOffset = new int[] { (int)lv.start_pc };
+            p.lvarLength = new int[] { (int)lv.length };
+            p.lvarIndex = new int[] { (int)lv.reg };
+            p.isValidOffset = true;
+        }
+    }
+
+    // Method to be called after compressCatchTable to
+    // fill in the exception table index for type
+    // annotations on exception parameters.
+    public void fillExceptionParameterPositions() {
+        for (int i = 0; i < varBufferSize; ++i) {
+            LocalVar lv = varBuffer[i];
+            if (lv == null || lv.sym == null
+                    || lv.sym.annotations.isTypesEmpty()
+                    || !lv.sym.isExceptionParameter())
+                return;
+
+            int exidx = findExceptionIndex(lv);
+
+            for (Attribute.TypeCompound ta : lv.sym.getRawTypeAttributes()) {
+                TypeAnnotationPosition p = ta.position;
+                p.exception_index = exidx;
+            }
+        }
+    }
+
+    private int findExceptionIndex(LocalVar lv) {
+        List<char[]> iter = catchInfo.toList();
+        int len = catchInfo.length();
+        for (int i = 0; i < len; ++i) {
+            char[] catchEntry = iter.head;
+            iter = iter.tail;
+            char handlerpc = catchEntry[2];
+            if (lv.start_pc == handlerpc + 1) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
     /** Put a live variable range into the buffer to be output to the
      *  class file.
      */
     void putVar(LocalVar var) {
-        if (!varDebugInfo) return;
+        // Keep local variables if
+        // 1) we need them for debug information
+        // 2) it is an exception type and it contains type annotations
+        if (!varDebugInfo &&
+                (!var.sym.isExceptionParameter() ||
+                var.sym.annotations.isTypesEmpty())) return;
         if ((var.sym.flags() & Flags.SYNTHETIC) != 0) return;
         if (varBuffer == null)
             varBuffer = new LocalVar[20];