1 /* 2 * Copyright (c) 1997, 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 #include "precompiled.hpp" 26 #include "classfile/symbolTable.hpp" 27 #include "classfile/systemDictionary.hpp" 28 #include "memory/oopFactory.hpp" 29 #include "oops/instanceKlass.hpp" 30 #include "oops/oop.inline.hpp" 31 #include "oops/symbolOop.hpp" 32 #include "oops/typeArrayKlass.hpp" 33 #include "runtime/signature.hpp" 34 35 36 // Implementation of SignatureIterator 37 38 // Signature syntax: 39 // 40 // Signature = "(" {Parameter} ")" ReturnType. 41 // Parameter = FieldType. 42 // ReturnType = FieldType | "V". 43 // FieldType = "B" | "C" | "D" | "F" | "I" | "J" | "S" | "Z" | "L" ClassName ";" | "[" FieldType. 44 // ClassName = string. 45 46 47 SignatureIterator::SignatureIterator(symbolHandle signature) { 48 assert(signature->is_symbol(), "not a symbol"); 49 _signature = signature; 50 _parameter_index = 0; 51 } 52 53 // Overloaded version called without handle 54 SignatureIterator::SignatureIterator(symbolOop signature) { 55 symbolHandle sh(Thread::current(), signature); 56 _signature = sh; 57 _parameter_index = 0; 58 } 59 60 SignatureIterator::SignatureIterator(Thread *thread, symbolOop signature) { 61 symbolHandle sh(thread, signature); 62 _signature = sh; 63 _parameter_index = 0; 64 } 65 66 void SignatureIterator::expect(char c) { 67 if (_signature->byte_at(_index) != c) fatal(err_msg("expecting %c", c)); 68 _index++; 69 } 70 71 72 void SignatureIterator::skip_optional_size() { 73 symbolOop sig = _signature(); 74 char c = sig->byte_at(_index); 75 while ('0' <= c && c <= '9') c = sig->byte_at(++_index); 76 } 77 78 79 int SignatureIterator::parse_type() { 80 // Note: This function could be simplified by using "return T_XXX_size;" 81 // instead of the assignment and the break statements. However, it 82 // seems that the product build for win32_i486 with MS VC++ 6.0 doesn't 83 // work (stack underflow for some tests) - this seems to be a VC++ 6.0 84 // compiler bug (was problem - gri 4/27/2000). 85 int size = -1; 86 switch(_signature->byte_at(_index)) { 87 case 'B': do_byte (); if (_parameter_index < 0 ) _return_type = T_BYTE; 88 _index++; size = T_BYTE_size ; break; 89 case 'C': do_char (); if (_parameter_index < 0 ) _return_type = T_CHAR; 90 _index++; size = T_CHAR_size ; break; 91 case 'D': do_double(); if (_parameter_index < 0 ) _return_type = T_DOUBLE; 92 _index++; size = T_DOUBLE_size ; break; 93 case 'F': do_float (); if (_parameter_index < 0 ) _return_type = T_FLOAT; 94 _index++; size = T_FLOAT_size ; break; 95 case 'I': do_int (); if (_parameter_index < 0 ) _return_type = T_INT; 96 _index++; size = T_INT_size ; break; 97 case 'J': do_long (); if (_parameter_index < 0 ) _return_type = T_LONG; 98 _index++; size = T_LONG_size ; break; 99 case 'S': do_short (); if (_parameter_index < 0 ) _return_type = T_SHORT; 100 _index++; size = T_SHORT_size ; break; 101 case 'Z': do_bool (); if (_parameter_index < 0 ) _return_type = T_BOOLEAN; 102 _index++; size = T_BOOLEAN_size; break; 103 case 'V': do_void (); if (_parameter_index < 0 ) _return_type = T_VOID; 104 _index++; size = T_VOID_size; ; break; 105 case 'L': 106 { int begin = ++_index; 107 symbolOop sig = _signature(); 108 while (sig->byte_at(_index++) != ';') ; 109 do_object(begin, _index); 110 } 111 if (_parameter_index < 0 ) _return_type = T_OBJECT; 112 size = T_OBJECT_size; 113 break; 114 case '[': 115 { int begin = ++_index; 116 skip_optional_size(); 117 symbolOop sig = _signature(); 118 while (sig->byte_at(_index) == '[') { 119 _index++; 120 skip_optional_size(); 121 } 122 if (sig->byte_at(_index) == 'L') { 123 while (sig->byte_at(_index++) != ';') ; 124 } else { 125 _index++; 126 } 127 do_array(begin, _index); 128 if (_parameter_index < 0 ) _return_type = T_ARRAY; 129 } 130 size = T_ARRAY_size; 131 break; 132 default: 133 ShouldNotReachHere(); 134 break; 135 } 136 assert(size >= 0, "size must be set"); 137 return size; 138 } 139 140 141 void SignatureIterator::check_signature_end() { 142 if (_index < _signature->utf8_length()) { 143 tty->print_cr("too many chars in signature"); 144 _signature->print_value_on(tty); 145 tty->print_cr(" @ %d", _index); 146 } 147 } 148 149 150 void SignatureIterator::dispatch_field() { 151 // no '(', just one (field) type 152 _index = 0; 153 _parameter_index = 0; 154 parse_type(); 155 check_signature_end(); 156 } 157 158 159 void SignatureIterator::iterate_parameters() { 160 // Parse parameters 161 _index = 0; 162 _parameter_index = 0; 163 expect('('); 164 while (_signature->byte_at(_index) != ')') _parameter_index += parse_type(); 165 expect(')'); 166 _parameter_index = 0; 167 } 168 169 // Optimized version of iterat_parameters when fingerprint is known 170 void SignatureIterator::iterate_parameters( uint64_t fingerprint ) { 171 uint64_t saved_fingerprint = fingerprint; 172 173 // Check for too many arguments 174 if ( fingerprint == UCONST64(-1) ) { 175 SignatureIterator::iterate_parameters(); 176 return; 177 } 178 179 assert(fingerprint, "Fingerprint should not be 0"); 180 181 _parameter_index = 0; 182 fingerprint = fingerprint >> (static_feature_size + result_feature_size); 183 while ( 1 ) { 184 switch ( fingerprint & parameter_feature_mask ) { 185 case bool_parm: 186 do_bool(); 187 _parameter_index += T_BOOLEAN_size; 188 break; 189 case byte_parm: 190 do_byte(); 191 _parameter_index += T_BYTE_size; 192 break; 193 case char_parm: 194 do_char(); 195 _parameter_index += T_CHAR_size; 196 break; 197 case short_parm: 198 do_short(); 199 _parameter_index += T_SHORT_size; 200 break; 201 case int_parm: 202 do_int(); 203 _parameter_index += T_INT_size; 204 break; 205 case obj_parm: 206 do_object(0, 0); 207 _parameter_index += T_OBJECT_size; 208 break; 209 case long_parm: 210 do_long(); 211 _parameter_index += T_LONG_size; 212 break; 213 case float_parm: 214 do_float(); 215 _parameter_index += T_FLOAT_size; 216 break; 217 case double_parm: 218 do_double(); 219 _parameter_index += T_DOUBLE_size; 220 break; 221 case done_parm: 222 return; 223 break; 224 default: 225 tty->print_cr("*** parameter is %d", fingerprint & parameter_feature_mask); 226 tty->print_cr("*** fingerprint is " PTR64_FORMAT, saved_fingerprint); 227 ShouldNotReachHere(); 228 break; 229 } 230 fingerprint >>= parameter_feature_size; 231 } 232 _parameter_index = 0; 233 } 234 235 236 void SignatureIterator::iterate_returntype() { 237 // Ignore parameters 238 _index = 0; 239 expect('('); 240 symbolOop sig = _signature(); 241 while (sig->byte_at(_index) != ')') _index++; 242 expect(')'); 243 // Parse return type 244 _parameter_index = -1; 245 parse_type(); 246 check_signature_end(); 247 _parameter_index = 0; 248 } 249 250 251 void SignatureIterator::iterate() { 252 // Parse parameters 253 _parameter_index = 0; 254 _index = 0; 255 expect('('); 256 while (_signature->byte_at(_index) != ')') _parameter_index += parse_type(); 257 expect(')'); 258 // Parse return type 259 _parameter_index = -1; 260 parse_type(); 261 check_signature_end(); 262 _parameter_index = 0; 263 } 264 265 266 // Implementation of SignatureStream 267 268 bool SignatureStream::is_done() const { 269 return _end > _signature()->utf8_length(); 270 } 271 272 273 void SignatureStream::next_non_primitive(int t) { 274 switch (t) { 275 case 'L': { 276 _type = T_OBJECT; 277 symbolOop sig = _signature(); 278 while (sig->byte_at(_end++) != ';'); 279 break; 280 } 281 case '[': { 282 _type = T_ARRAY; 283 symbolOop sig = _signature(); 284 char c = sig->byte_at(_end); 285 while ('0' <= c && c <= '9') c = sig->byte_at(_end++); 286 while (sig->byte_at(_end) == '[') { 287 _end++; 288 c = sig->byte_at(_end); 289 while ('0' <= c && c <= '9') c = sig->byte_at(_end++); 290 } 291 switch(sig->byte_at(_end)) { 292 case 'B': 293 case 'C': 294 case 'D': 295 case 'F': 296 case 'I': 297 case 'J': 298 case 'S': 299 case 'Z':_end++; break; 300 default: { 301 while (sig->byte_at(_end++) != ';'); 302 break; 303 } 304 } 305 break; 306 } 307 case ')': _end++; next(); _at_return_type = true; break; 308 default : ShouldNotReachHere(); 309 } 310 } 311 312 313 bool SignatureStream::is_object() const { 314 return _type == T_OBJECT 315 || _type == T_ARRAY; 316 } 317 318 bool SignatureStream::is_array() const { 319 return _type == T_ARRAY; 320 } 321 322 symbolOop SignatureStream::as_symbol(TRAPS) { 323 // Create a symbol from for string _begin _end 324 int begin = _begin; 325 int end = _end; 326 327 if ( _signature()->byte_at(_begin) == 'L' 328 && _signature()->byte_at(_end-1) == ';') { 329 begin++; 330 end--; 331 } 332 333 symbolOop result = oopFactory::new_symbol(_signature, begin, end, CHECK_NULL); 334 return result; 335 } 336 337 klassOop SignatureStream::as_klass(Handle class_loader, Handle protection_domain, 338 FailureMode failure_mode, TRAPS) { 339 if (!is_object()) return NULL; 340 symbolOop name = as_symbol(CHECK_NULL); 341 if (failure_mode == ReturnNull) { 342 return SystemDictionary::resolve_or_null(name, class_loader, protection_domain, THREAD); 343 } else { 344 bool throw_error = (failure_mode == NCDFError); 345 return SystemDictionary::resolve_or_fail(name, class_loader, protection_domain, throw_error, THREAD); 346 } 347 } 348 349 oop SignatureStream::as_java_mirror(Handle class_loader, Handle protection_domain, 350 FailureMode failure_mode, TRAPS) { 351 if (!is_object()) 352 return Universe::java_mirror(type()); 353 klassOop klass = as_klass(class_loader, protection_domain, failure_mode, CHECK_NULL); 354 if (klass == NULL) return NULL; 355 return Klass::cast(klass)->java_mirror(); 356 } 357 358 symbolOop SignatureStream::as_symbol_or_null() { 359 // Create a symbol from for string _begin _end 360 ResourceMark rm; 361 362 int begin = _begin; 363 int end = _end; 364 365 if ( _signature()->byte_at(_begin) == 'L' 366 && _signature()->byte_at(_end-1) == ';') { 367 begin++; 368 end--; 369 } 370 371 char* buffer = NEW_RESOURCE_ARRAY(char, end - begin); 372 for (int index = begin; index < end; index++) { 373 buffer[index - begin] = _signature()->byte_at(index); 374 } 375 symbolOop result = SymbolTable::probe(buffer, end - begin); 376 return result; 377 } 378 379 bool SignatureVerifier::is_valid_signature(symbolHandle sig) { 380 const char* signature = (const char*)sig->bytes(); 381 ssize_t len = sig->utf8_length(); 382 if (signature == NULL || signature[0] == '\0' || len < 1) { 383 return false; 384 } else if (signature[0] == '(') { 385 return is_valid_method_signature(sig); 386 } else { 387 return is_valid_type_signature(sig); 388 } 389 } 390 391 bool SignatureVerifier::is_valid_method_signature(symbolHandle sig) { 392 const char* method_sig = (const char*)sig->bytes(); 393 ssize_t len = sig->utf8_length(); 394 ssize_t index = 0; 395 if (method_sig != NULL && len > 1 && method_sig[index] == '(') { 396 ++index; 397 while (index < len && method_sig[index] != ')') { 398 ssize_t res = is_valid_type(&method_sig[index], len - index); 399 if (res == -1) { 400 return false; 401 } else { 402 index += res; 403 } 404 } 405 if (index < len && method_sig[index] == ')') { 406 // check the return type 407 ++index; 408 return (is_valid_type(&method_sig[index], len - index) == (len - index)); 409 } 410 } 411 return false; 412 } 413 414 bool SignatureVerifier::is_valid_type_signature(symbolHandle sig) { 415 const char* type_sig = (const char*)sig->bytes(); 416 ssize_t len = sig->utf8_length(); 417 return (type_sig != NULL && len >= 1 && 418 (is_valid_type(type_sig, len) == len)); 419 } 420 421 // Checks to see if the type (not to go beyond 'limit') refers to a valid type. 422 // Returns -1 if it is not, or the index of the next character that is not part 423 // of the type. The type encoding may end before 'limit' and that's ok. 424 ssize_t SignatureVerifier::is_valid_type(const char* type, ssize_t limit) { 425 ssize_t index = 0; 426 427 // Iterate over any number of array dimensions 428 while (index < limit && type[index] == '[') ++index; 429 if (index >= limit) { 430 return -1; 431 } 432 switch (type[index]) { 433 case 'B': case 'C': case 'D': case 'F': case 'I': 434 case 'J': case 'S': case 'Z': case 'V': 435 return index + 1; 436 case 'L': 437 for (index = index + 1; index < limit; ++index) { 438 char c = type[index]; 439 if (c == ';') { 440 return index + 1; 441 } 442 if (invalid_name_char(c)) { 443 return -1; 444 } 445 } 446 // fall through 447 default: ; // fall through 448 } 449 return -1; 450 } 451 452 bool SignatureVerifier::invalid_name_char(char c) { 453 switch (c) { 454 case '\0': case '.': case ';': case '[': 455 return true; 456 default: 457 return false; 458 } 459 }