1 /* 2 * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 package sun.jvm.hotspot.runtime; 26 27 import sun.jvm.hotspot.oops.*; 28 29 /** <P> SignatureIterators iterate over a Java signature (or parts of it). 30 (Syntax according to: "The Java Virtual Machine Specification" by 31 Tim Lindholm & Frank Yellin; section 4.3 Descriptors; p. 89ff.) </P> 32 33 <P> Example: Iterating over 34 <PRE> 35 ([Lfoo;D)I 36 0123456789 37 </PRE> 38 39 using </P> 40 41 <PRE> 42 iterateParameters() calls: do_array(2, 7); do_double(); 43 iterateReturntype() calls: do_int(); 44 iterate() calls: do_array(2, 7); do_double(); do_int(); 45 46 is_returnType() is: false ; false ; true 47 </PRE> 48 */ 49 50 public abstract class SignatureIterator { 51 protected Symbol _signature; // the signature to iterate over 52 protected int _index; // the current character index (only valid during iteration) 53 protected int _parameter_index; // the current parameter index (0 outside iteration phase) 54 expect(char c)55 protected void expect(char c) { 56 if (_signature.getByteAt(_index) != (byte) c) { 57 throw new RuntimeException("expecting '" + c + "'"); 58 } 59 _index++; 60 } skipOptionalSize()61 protected void skipOptionalSize() { 62 byte c = _signature.getByteAt(_index); 63 while ('0' <= c && c <= '9') { 64 c = _signature.getByteAt(++_index); 65 } 66 } 67 // returns the parameter size in words (0 for void) parseType()68 protected int parseType() { 69 switch(_signature.getByteAt(_index)) { 70 case 'B': doByte (); _index++; return BasicTypeSize.getTByteSize(); 71 case 'C': doChar (); _index++; return BasicTypeSize.getTCharSize(); 72 case 'D': doDouble(); _index++; return BasicTypeSize.getTDoubleSize(); 73 case 'F': doFloat (); _index++; return BasicTypeSize.getTFloatSize(); 74 case 'I': doInt (); _index++; return BasicTypeSize.getTIntSize(); 75 case 'J': doLong (); _index++; return BasicTypeSize.getTLongSize(); 76 case 'S': doShort (); _index++; return BasicTypeSize.getTShortSize(); 77 case 'Z': doBool (); _index++; return BasicTypeSize.getTBooleanSize(); 78 case 'V': 79 { 80 if (!isReturnType()) { 81 throw new RuntimeException("illegal parameter type V (void)"); 82 } 83 84 doVoid(); _index++; 85 return BasicTypeSize.getTVoidSize(); 86 } 87 case 'L': 88 { 89 int begin = ++_index; 90 while (_signature.getByteAt(_index++) != ';') ; 91 doObject(begin, _index); 92 return BasicTypeSize.getTObjectSize(); 93 } 94 case '[': 95 { 96 int begin = ++_index; 97 skipOptionalSize(); 98 while (_signature.getByteAt(_index) == '[') { 99 _index++; 100 skipOptionalSize(); 101 } 102 if (_signature.getByteAt(_index) == 'L') { 103 while (_signature.getByteAt(_index++) != ';') ; 104 } else { 105 _index++; 106 } 107 doArray(begin, _index); 108 return BasicTypeSize.getTArraySize(); 109 } 110 } 111 throw new RuntimeException("Should not reach here: char " + (char)_signature.getByteAt(_index) + " @ " + _index + " in " + _signature.asString()); 112 } checkSignatureEnd()113 protected void checkSignatureEnd() { 114 if (_index < _signature.getLength()) { 115 System.err.println("too many chars in signature"); 116 _signature.printValueOn(System.err); 117 System.err.println(" @ " + _index); 118 } 119 } 120 SignatureIterator(Symbol signature)121 public SignatureIterator(Symbol signature) { 122 _signature = signature; 123 _parameter_index = 0; 124 } 125 126 // 127 // Iteration 128 // 129 130 // dispatches once for field signatures dispatchField()131 public void dispatchField() { 132 // no '(', just one (field) type 133 _index = 0; 134 _parameter_index = 0; 135 parseType(); 136 checkSignatureEnd(); 137 } 138 139 // iterates over parameters only iterateParameters()140 public void iterateParameters() { 141 // Parse parameters 142 _index = 0; 143 _parameter_index = 0; 144 expect('('); 145 while (_signature.getByteAt(_index) != ')') { 146 _parameter_index += parseType(); 147 } 148 expect(')'); 149 _parameter_index = 0; // so isReturnType() is false outside iteration 150 } 151 152 // iterates over returntype only iterateReturntype()153 public void iterateReturntype() { 154 // Ignore parameters 155 _index = 0; 156 expect('('); 157 while (_signature.getByteAt(_index) != ')') { 158 _index++; 159 } 160 expect(')'); 161 // Parse return type 162 _parameter_index = -1; 163 parseType(); 164 checkSignatureEnd(); 165 _parameter_index = 0; // so isReturnType() is false outside iteration 166 } 167 168 // iterates over whole signature iterate()169 public void iterate() { 170 // Parse parameters 171 _index = 0; 172 _parameter_index = 0; 173 expect('('); 174 while (_signature.getByteAt(_index) != ')') { 175 _parameter_index += parseType(); 176 } 177 expect(')'); 178 // Parse return type 179 _parameter_index = -1; 180 parseType(); 181 checkSignatureEnd(); 182 _parameter_index = 0; // so isReturnType() is false outside iteration 183 } 184 185 // Returns the word index of the current parameter; returns a negative value at the return type parameterIndex()186 public int parameterIndex() { return _parameter_index; } isReturnType()187 public boolean isReturnType() { return (parameterIndex() < 0); } 188 189 // Basic types doBool()190 public abstract void doBool (); doChar()191 public abstract void doChar (); doFloat()192 public abstract void doFloat (); doDouble()193 public abstract void doDouble(); doByte()194 public abstract void doByte (); doShort()195 public abstract void doShort (); doInt()196 public abstract void doInt (); doLong()197 public abstract void doLong (); doVoid()198 public abstract void doVoid (); 199 200 // Object types (begin indexes the first character of the entry, end 201 // indexes the first character after the entry) doObject(int begin, int end)202 public abstract void doObject(int begin, int end); doArray(int begin, int end)203 public abstract void doArray (int begin, int end); 204 } 205