src/share/vm/runtime/signature.cpp

Thu, 24 May 2018 19:24:53 +0800

author
aoqi
date
Thu, 24 May 2018 19:24:53 +0800
changeset 8861
2a33b32dd03c
parent 8604
04d83ba48607
permissions
-rw-r--r--

#7046 Disable the compilation when branch offset is beyond short branch
Contributed-by: fujie, aoqi

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

mercurial