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::dispatch_field() { 127 // no '(', just one (field) type 128 _index = 0; 129 _parameter_index = 0; 130 parse_type(); 131 check_signature_end(); 132 } 133 134 135 void SignatureIterator::iterate_parameters() { 136 // Parse parameters 137 _index = 0; 138 _parameter_index = 0; 139 expect('('); 140 while (_signature->char_at(_index) != ')') _parameter_index += parse_type(); 141 expect(')'); 142 _parameter_index = 0; 143 } 144 145 // Optimized version of iterate_parameters when fingerprint is known 146 void SignatureIterator::iterate_parameters( uint64_t fingerprint ) { 147 uint64_t saved_fingerprint = fingerprint; 148 149 // Check for too many arguments 150 if (fingerprint == (uint64_t)CONST64(-1)) { 151 SignatureIterator::iterate_parameters(); 152 return; 153 } 154 155 assert(fingerprint, "Fingerprint should not be 0"); 156 157 _parameter_index = 0; 158 fingerprint = fingerprint >> (static_feature_size + result_feature_size); 159 while ( 1 ) { 160 switch ( fingerprint & parameter_feature_mask ) { 161 case bool_parm: 162 do_bool(); 163 _parameter_index += T_BOOLEAN_size; 164 break; 165 case byte_parm: 166 do_byte(); 167 _parameter_index += T_BYTE_size; 168 break; 169 case char_parm: 170 do_char(); 171 _parameter_index += T_CHAR_size; 172 break; 173 case short_parm: 174 do_short(); 175 _parameter_index += T_SHORT_size; 176 break; 177 case int_parm: 178 do_int(); 179 _parameter_index += T_INT_size; 180 break; 181 case obj_parm: 182 do_object(0, 0); 183 _parameter_index += T_OBJECT_size; 184 break; 185 case long_parm: 186 do_long(); 187 _parameter_index += T_LONG_size; 188 break; 189 case float_parm: 190 do_float(); 191 _parameter_index += T_FLOAT_size; 192 break; 193 case double_parm: 194 do_double(); 195 _parameter_index += T_DOUBLE_size; 196 break; 197 case done_parm: 198 return; 199 break; 200 default: 201 tty->print_cr("*** parameter is " UINT64_FORMAT, fingerprint & parameter_feature_mask); 202 tty->print_cr("*** fingerprint is " PTR64_FORMAT, saved_fingerprint); 203 ShouldNotReachHere(); 204 break; 205 } 206 fingerprint >>= parameter_feature_size; 207 } 208 _parameter_index = 0; 209 } 210 211 212 void SignatureIterator::iterate_returntype() { 213 // Ignore parameters 214 _index = 0; 215 expect('('); 216 Symbol* sig = _signature; 217 // Need to skip over each type in the signature's argument list until a 218 // closing ')' is found., then get the return type. We cannot just scan 219 // for the first ')' because ')' is a legal character in a type name. 220 while (sig->char_at(_index) != ')') { 221 switch(sig->char_at(_index)) { 222 case 'B': 223 case 'C': 224 case 'D': 225 case 'F': 226 case 'I': 227 case 'J': 228 case 'S': 229 case 'Z': 230 case 'V': 231 { 232 _index++; 233 } 234 break; 235 case 'L': 236 { 237 while (sig->char_at(_index++) != ';') ; 238 } 239 break; 240 case '[': 241 { 242 int begin = ++_index; 243 while (sig->char_at(_index) == '[') { 244 _index++; 245 } 246 if (sig->char_at(_index) == 'L') { 247 while (sig->char_at(_index++) != ';') ; 248 } else { 249 _index++; 250 } 251 } 252 break; 253 default: 254 ShouldNotReachHere(); 255 break; 256 } 257 } 258 expect(')'); 259 // Parse return type 260 _parameter_index = -1; 261 parse_type(); 262 check_signature_end(); 263 _parameter_index = 0; 264 } 265 266 267 void SignatureIterator::iterate() { 268 // Parse parameters 269 _parameter_index = 0; 270 _index = 0; 271 expect('('); 272 while (_signature->char_at(_index) != ')') _parameter_index += parse_type(); 273 expect(')'); 274 // Parse return type 275 _parameter_index = -1; 276 parse_type(); 277 check_signature_end(); 278 _parameter_index = 0; 279 } 280 281 282 // Implementation of SignatureStream 283 SignatureStream::SignatureStream(Symbol* signature, bool is_method) : 284 _signature(signature), _at_return_type(false) { 285 _begin = _end = (is_method ? 1 : 0); // skip first '(' in method signatures 286 _names = new GrowableArray<Symbol*>(10); 287 next(); 288 } 289 290 SignatureStream::~SignatureStream() { 291 // decrement refcount for names created during signature parsing 292 for (int i = 0; i < _names->length(); i++) { 293 _names->at(i)->decrement_refcount(); 294 } 295 } 296 297 bool SignatureStream::is_done() const { 298 return _end > _signature->utf8_length(); 299 } 300 301 302 void SignatureStream::next_non_primitive(int t) { 303 switch (t) { 304 case 'L': { 305 _type = T_OBJECT; 306 Symbol* sig = _signature; 307 while (sig->char_at(_end++) != ';'); 308 break; 309 } 310 case '[': { 311 _type = T_ARRAY; 312 Symbol* sig = _signature; 313 char c = sig->char_at(_end); 314 while ('0' <= c && c <= '9') c = sig->char_at(_end++); 315 while (sig->char_at(_end) == '[') { 316 _end++; 317 c = sig->char_at(_end); 318 while ('0' <= c && c <= '9') c = sig->char_at(_end++); 319 } 320 switch(sig->char_at(_end)) { 321 case 'B': 322 case 'C': 323 case 'D': 324 case 'F': 325 case 'I': 326 case 'J': 327 case 'S': 328 case 'Z':_end++; break; 329 default: { 330 while (sig->char_at(_end++) != ';'); 331 break; 332 } 333 } 334 break; 335 } 336 case ')': _end++; next(); _at_return_type = true; break; 337 default : ShouldNotReachHere(); 338 } 339 } 340 341 342 bool SignatureStream::is_object() const { 343 return _type == T_OBJECT 344 || _type == T_ARRAY; 345 } 346 347 bool SignatureStream::is_array() const { 348 return _type == T_ARRAY; 349 } 350 351 Symbol* SignatureStream::as_symbol(TRAPS) { 352 // Create a symbol from for string _begin _end 353 int begin = _begin; 354 int end = _end; 355 356 if ( _signature->char_at(_begin) == 'L' 357 && _signature->char_at(_end-1) == ';') { 358 begin++; 359 end--; 360 } 361 362 // Save names for cleaning up reference count at the end of 363 // SignatureStream scope. 364 Symbol* name = SymbolTable::new_symbol(_signature, begin, end, CHECK_NULL); 365 _names->push(name); // save new symbol for decrementing later 366 return name; 367 } 368 369 Klass* SignatureStream::as_klass(Handle class_loader, Handle protection_domain, 370 FailureMode failure_mode, TRAPS) { 371 if (!is_object()) return NULL; 372 Symbol* name = as_symbol(CHECK_NULL); 373 if (failure_mode == ReturnNull) { 374 return SystemDictionary::resolve_or_null(name, class_loader, protection_domain, THREAD); 375 } else { 376 bool throw_error = (failure_mode == NCDFError); 377 return SystemDictionary::resolve_or_fail(name, class_loader, protection_domain, throw_error, THREAD); 378 } 379 } 380 381 oop SignatureStream::as_java_mirror(Handle class_loader, Handle protection_domain, 382 FailureMode failure_mode, TRAPS) { 383 if (!is_object()) 384 return Universe::java_mirror(type()); 385 Klass* klass = as_klass(class_loader, protection_domain, failure_mode, CHECK_NULL); 386 if (klass == NULL) return NULL; 387 return klass->java_mirror(); 388 } 389 390 Symbol* SignatureStream::as_symbol_or_null() { 391 // Create a symbol from for string _begin _end 392 ResourceMark rm; 393 394 int begin = _begin; 395 int end = _end; 396 397 if ( _signature->char_at(_begin) == 'L' 398 && _signature->char_at(_end-1) == ';') { 399 begin++; 400 end--; 401 } 402 403 char* buffer = NEW_RESOURCE_ARRAY(char, end - begin); 404 for (int index = begin; index < end; index++) { 405 buffer[index - begin] = _signature->char_at(index); 406 } 407 Symbol* result = SymbolTable::probe(buffer, end - begin); 408 return result; 409 } 410 411 int SignatureStream::reference_parameter_count() { 412 int args_count = 0; 413 for ( ; !at_return_type(); next()) { 414 if (is_object()) { 415 args_count++; 416 } 417 } 418 return args_count; 419 } 420 421 bool SignatureVerifier::is_valid_signature(Symbol* sig) { 422 const char* signature = (const char*)sig->bytes(); 423 ssize_t len = sig->utf8_length(); 424 if (signature == NULL || signature[0] == '\0' || len < 1) { 425 return false; 426 } else if (signature[0] == '(') { 427 return is_valid_method_signature(sig); 428 } else { 429 return is_valid_type_signature(sig); 430 } 431 } 432 433 bool SignatureVerifier::is_valid_method_signature(Symbol* sig) { 434 const char* method_sig = (const char*)sig->bytes(); 435 ssize_t len = sig->utf8_length(); 436 ssize_t index = 0; 437 if (method_sig != NULL && len > 1 && method_sig[index] == '(') { 438 ++index; 439 while (index < len && method_sig[index] != ')') { 440 ssize_t res = is_valid_type(&method_sig[index], len - index); 441 if (res == -1) { 442 return false; 443 } else { 444 index += res; 445 } 446 } 447 if (index < len && method_sig[index] == ')') { 448 // check the return type 449 ++index; 450 return (is_valid_type(&method_sig[index], len - index) == (len - index)); 451 } 452 } 453 return false; 454 } 455 456 bool SignatureVerifier::is_valid_type_signature(Symbol* sig) { 457 const char* type_sig = (const char*)sig->bytes(); 458 ssize_t len = sig->utf8_length(); 459 return (type_sig != NULL && len >= 1 && 460 (is_valid_type(type_sig, len) == len)); 461 } 462 463 // Checks to see if the type (not to go beyond 'limit') refers to a valid type. 464 // Returns -1 if it is not, or the index of the next character that is not part 465 // of the type. The type encoding may end before 'limit' and that's ok. 466 ssize_t SignatureVerifier::is_valid_type(const char* type, ssize_t limit) { 467 ssize_t index = 0; 468 469 // Iterate over any number of array dimensions 470 while (index < limit && type[index] == '[') ++index; 471 if (index >= limit) { 472 return -1; 473 } 474 switch (type[index]) { 475 case 'B': case 'C': case 'D': case 'F': case 'I': 476 case 'J': case 'S': case 'Z': case 'V': 477 return index + 1; 478 case 'L': 479 for (index = index + 1; index < limit; ++index) { 480 char c = type[index]; 481 if (c == ';') { 482 return index + 1; 483 } 484 if (invalid_name_char(c)) { 485 return -1; 486 } 487 } 488 // fall through 489 default: ; // fall through 490 } 491 return -1; 492 } 493 494 bool SignatureVerifier::invalid_name_char(char c) { 495 switch (c) { 496 case '\0': case '.': case ';': case '[': 497 return true; 498 default: 499 return false; 500 } 501 }