340 /** Base class for any attributed object (Class, Field, Method, Code). |
340 /** Base class for any attributed object (Class, Field, Method, Code). |
341 * Flags are included because they are used to help transmit the |
341 * Flags are included because they are used to help transmit the |
342 * presence of attributes. That is, flags are a mix of modifier |
342 * presence of attributes. That is, flags are a mix of modifier |
343 * bits and attribute indicators. |
343 * bits and attribute indicators. |
344 */ |
344 */ |
345 public static abstract |
345 public abstract static |
346 class Holder { |
346 class Holder { |
347 |
347 |
348 // We need this abstract method to interpret embedded CP refs. |
348 // We need this abstract method to interpret embedded CP refs. |
349 protected abstract Entry[] getCPMap(); |
349 protected abstract Entry[] getCPMap(); |
350 |
350 |
459 } |
459 } |
460 } |
460 } |
461 |
461 |
462 // Lightweight interface to hide details of band structure. |
462 // Lightweight interface to hide details of band structure. |
463 // Also used for testing. |
463 // Also used for testing. |
464 public static abstract |
464 public abstract static |
465 class ValueStream { |
465 class ValueStream { |
466 public int getInt(int bandIndex) { throw undef(); } |
466 public int getInt(int bandIndex) { throw undef(); } |
467 public void putInt(int bandIndex, int value) { throw undef(); } |
467 public void putInt(int bandIndex, int value) { throw undef(); } |
468 public Entry getRef(int bandIndex) { throw undef(); } |
468 public Entry getRef(int bandIndex) { throw undef(); } |
469 public void putRef(int bandIndex, Entry ref) { throw undef(); } |
469 public void putRef(int bandIndex, Entry ref) { throw undef(); } |
665 } |
665 } |
666 |
666 |
667 public boolean hasCallables() { |
667 public boolean hasCallables() { |
668 return (elems.length > 0 && elems[0].kind == EK_CBLE); |
668 return (elems.length > 0 && elems[0].kind == EK_CBLE); |
669 } |
669 } |
670 static private final Element[] noElems = {}; |
670 private static final Element[] noElems = {}; |
671 public Element[] getCallables() { |
671 public Element[] getCallables() { |
672 if (hasCallables()) { |
672 if (hasCallables()) { |
673 Element[] nelems = Arrays.copyOf(elems, elems.length); |
673 Element[] nelems = Arrays.copyOf(elems, elems.length); |
674 return nelems; |
674 return nelems; |
675 } else |
675 } else |
781 * Removes blanks and control chars. |
781 * Removes blanks and control chars. |
782 * Removes '#' comments (to end of line). |
782 * Removes '#' comments (to end of line). |
783 * Replaces '\c' by the decimal code of the character c. |
783 * Replaces '\c' by the decimal code of the character c. |
784 * Replaces '0xNNN' by the decimal code of the hex number NNN. |
784 * Replaces '0xNNN' by the decimal code of the hex number NNN. |
785 */ |
785 */ |
786 static public |
786 public static |
787 String normalizeLayoutString(String layout) { |
787 String normalizeLayoutString(String layout) { |
788 StringBuilder buf = new StringBuilder(); |
788 StringBuilder buf = new StringBuilder(); |
789 for (int i = 0, len = layout.length(); i < len; ) { |
789 for (int i = 0, len = layout.length(); i < len; ) { |
790 char ch = layout.charAt(i++); |
790 char ch = layout.charAt(i++); |
791 if (ch <= ' ') { |
791 if (ch <= ' ') { |
1137 } |
1137 } |
1138 String[] res = new String[bodies.size()]; |
1138 String[] res = new String[bodies.size()]; |
1139 bodies.toArray(res); |
1139 bodies.toArray(res); |
1140 return res; |
1140 return res; |
1141 } |
1141 } |
1142 static private |
1142 private static |
1143 int skipBody(String layout, int i) { |
1143 int skipBody(String layout, int i) { |
1144 assert(layout.charAt(i-1) == '['); |
1144 assert(layout.charAt(i-1) == '['); |
1145 if (layout.charAt(i) == ']') |
1145 if (layout.charAt(i) == ']') |
1146 // No empty bodies, please. |
1146 // No empty bodies, please. |
1147 return -i; |
1147 return -i; |
1154 } |
1154 } |
1155 --i; // get before bracket |
1155 --i; // get before bracket |
1156 assert(layout.charAt(i) == ']'); |
1156 assert(layout.charAt(i) == ']'); |
1157 return i; // return closing bracket |
1157 return i; // return closing bracket |
1158 } |
1158 } |
1159 static private |
1159 private static |
1160 int tokenizeUInt(Layout.Element e, String layout, int i) { |
1160 int tokenizeUInt(Layout.Element e, String layout, int i) { |
1161 switch (layout.charAt(i++)) { |
1161 switch (layout.charAt(i++)) { |
1162 case 'V': e.len = 0; break; |
1162 case 'V': e.len = 0; break; |
1163 case 'B': e.len = 1; break; |
1163 case 'B': e.len = 1; break; |
1164 case 'H': e.len = 2; break; |
1164 case 'H': e.len = 2; break; |
1165 case 'I': e.len = 4; break; |
1165 case 'I': e.len = 4; break; |
1166 default: return -i; |
1166 default: return -i; |
1167 } |
1167 } |
1168 return i; |
1168 return i; |
1169 } |
1169 } |
1170 static private |
1170 private static |
1171 int tokenizeSInt(Layout.Element e, String layout, int i) { |
1171 int tokenizeSInt(Layout.Element e, String layout, int i) { |
1172 if (layout.charAt(i) == 'S') { |
1172 if (layout.charAt(i) == 'S') { |
1173 e.flags |= EF_SIGN; |
1173 e.flags |= EF_SIGN; |
1174 ++i; |
1174 ++i; |
1175 } |
1175 } |
1176 return tokenizeUInt(e, layout, i); |
1176 return tokenizeUInt(e, layout, i); |
1177 } |
1177 } |
1178 |
1178 |
1179 static private |
1179 private static |
1180 boolean isDigit(char c) { |
1180 boolean isDigit(char c) { |
1181 return c >= '0' && c <= '9'; |
1181 return c >= '0' && c <= '9'; |
1182 } |
1182 } |
1183 |
1183 |
1184 /** Find an occurrence of hyphen '-' between two numerals. */ |
1184 /** Find an occurrence of hyphen '-' between two numerals. */ |
1381 return ce; |
1381 return ce; |
1382 } |
1382 } |
1383 return e.body[lastj]; |
1383 return e.body[lastj]; |
1384 } |
1384 } |
1385 |
1385 |
1386 static private |
1386 private static |
1387 int parseInt(Layout.Element e, byte[] bytes, int pos, int[] buf) { |
1387 int parseInt(Layout.Element e, byte[] bytes, int pos, int[] buf) { |
1388 int value = 0; |
1388 int value = 0; |
1389 int loBits = e.len * 8; |
1389 int loBits = e.len * 8; |
1390 // Read in big-endian order: |
1390 // Read in big-endian order: |
1391 for (int bitPos = loBits; (bitPos -= 8) >= 0; ) { |
1391 for (int bitPos = loBits; (bitPos -= 8) >= 0; ) { |