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