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;
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()) {
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
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
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 }
|
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 "oops/valueKlass.hpp"
35 #include "runtime/signature.hpp"
36
37 // Implementation of SignatureIterator
38
39 // Signature syntax:
40 //
41 // Signature = "(" {Parameter} ")" ReturnType.
42 // Parameter = FieldType.
43 // ReturnType = FieldType | "V".
44 // FieldType = "B" | "C" | "D" | "F" | "I" | "J" | "S" | "Z" | "L" ClassName ";" | "Q" ValueClassName ";" | "[" FieldType.
45 // ClassName = string.
46
47
48 SignatureIterator::SignatureIterator(Symbol* signature) {
49 _signature = signature;
50 _parameter_index = 0;
51 }
52
53 void SignatureIterator::expect(char c) {
54 if (_signature->char_at(_index) != c) fatal("expecting %c", c);
55 _index++;
56 }
57
58 int SignatureIterator::parse_type() {
59 // Note: This function could be simplified by using "return T_XXX_size;"
60 // instead of the assignment and the break statements. However, it
61 // seems that the product build for win32_i486 with MS VC++ 6.0 doesn't
62 // work (stack underflow for some tests) - this seems to be a VC++ 6.0
63 // compiler bug (was problem - gri 4/27/2000).
64 int size = -1;
73 _index++; size = T_FLOAT_size ; break;
74 case 'I': do_int (); if (_parameter_index < 0 ) _return_type = T_INT;
75 _index++; size = T_INT_size ; break;
76 case 'J': do_long (); if (_parameter_index < 0 ) _return_type = T_LONG;
77 _index++; size = T_LONG_size ; break;
78 case 'S': do_short (); if (_parameter_index < 0 ) _return_type = T_SHORT;
79 _index++; size = T_SHORT_size ; break;
80 case 'Z': do_bool (); if (_parameter_index < 0 ) _return_type = T_BOOLEAN;
81 _index++; size = T_BOOLEAN_size; break;
82 case 'V': do_void (); if (_parameter_index < 0 ) _return_type = T_VOID;
83 _index++; size = T_VOID_size; ; break;
84 case 'L':
85 { int begin = ++_index;
86 Symbol* sig = _signature;
87 while (sig->char_at(_index++) != ';') ;
88 do_object(begin, _index);
89 }
90 if (_parameter_index < 0 ) _return_type = T_OBJECT;
91 size = T_OBJECT_size;
92 break;
93 case 'Q':
94 { int begin = ++_index;
95 Symbol* sig = _signature;
96 while (sig->char_at(_index++) != ';') ;
97 do_valuetype(begin, _index);
98 }
99 if (_parameter_index < 0 ) _return_type = T_VALUETYPE;
100 size = T_VALUETYPE_size;
101 break;
102 case '[':
103 { int begin = ++_index;
104 Symbol* sig = _signature;
105 while (sig->char_at(_index) == '[') {
106 _index++;
107 }
108 if (sig->char_at(_index) == 'L' || sig->char_at(_index) == 'Q') {
109 while (sig->char_at(_index++) != ';') ;
110 } else {
111 _index++;
112 }
113 do_array(begin, _index);
114 if (_parameter_index < 0 ) _return_type = T_ARRAY;
115 }
116 size = T_ARRAY_size;
117 break;
118 default:
119 ShouldNotReachHere();
120 break;
121 }
122 assert(size >= 0, "size must be set");
123 return size;
124 }
125
126
127 void SignatureIterator::check_signature_end() {
128 if (_index < _signature->utf8_length()) {
225 expect('(');
226 Symbol* sig = _signature;
227 // Need to skip over each type in the signature's argument list until a
228 // closing ')' is found., then get the return type. We cannot just scan
229 // for the first ')' because ')' is a legal character in a type name.
230 while (sig->char_at(_index) != ')') {
231 switch(sig->char_at(_index)) {
232 case 'B':
233 case 'C':
234 case 'D':
235 case 'F':
236 case 'I':
237 case 'J':
238 case 'S':
239 case 'Z':
240 case 'V':
241 {
242 _index++;
243 }
244 break;
245 case 'Q':
246 case 'L':
247 {
248 while (sig->char_at(_index++) != ';') ;
249 }
250 break;
251 case '[':
252 {
253 int begin = ++_index;
254 while (sig->char_at(_index) == '[') {
255 _index++;
256 }
257 if (sig->char_at(_index) == 'L' || sig->char_at(_index) == 'Q' ) {
258 while (sig->char_at(_index++) != ';') ;
259 } else {
260 _index++;
261 }
262 }
263 break;
264 default:
265 ShouldNotReachHere();
266 break;
267 }
268 }
269 expect(')');
270 // Parse return type
271 _parameter_index = -1;
272 parse_type();
273 check_signature_end();
274 _parameter_index = 0;
275 }
276
277
301 SignatureStream::~SignatureStream() {
302 // decrement refcount for names created during signature parsing
303 for (int i = 0; i < _names->length(); i++) {
304 _names->at(i)->decrement_refcount();
305 }
306 }
307
308 bool SignatureStream::is_done() const {
309 return _end > _signature->utf8_length();
310 }
311
312
313 void SignatureStream::next_non_primitive(int t) {
314 switch (t) {
315 case 'L': {
316 _type = T_OBJECT;
317 Symbol* sig = _signature;
318 while (sig->char_at(_end++) != ';');
319 break;
320 }
321 case 'Q': {
322 _type = T_VALUETYPE;
323 Symbol* sig = _signature;
324 while (sig->char_at(_end++) != ';');
325 break;
326 }
327 case '[': {
328 _type = T_ARRAY;
329 Symbol* sig = _signature;
330 char c = sig->char_at(_end);
331 while ('0' <= c && c <= '9') c = sig->char_at(_end++);
332 while (sig->char_at(_end) == '[') {
333 _end++;
334 c = sig->char_at(_end);
335 while ('0' <= c && c <= '9') c = sig->char_at(_end++);
336 }
337 switch(sig->char_at(_end)) {
338 case 'B':
339 case 'C':
340 case 'D':
341 case 'F':
342 case 'I':
343 case 'J':
344 case 'S':
345 case 'Z':_end++; break;
346 default: {
347 while (sig->char_at(_end++) != ';');
348 break;
349 }
350 }
351 break;
352 }
353 case ')': _end++; next(); _at_return_type = true; break;
354 default : ShouldNotReachHere();
355 }
356 }
357
358
359 bool SignatureStream::is_object() const {
360 return _type == T_OBJECT
361 || _type == T_ARRAY
362 || _type == T_VALUETYPE;
363 }
364
365 bool SignatureStream::is_array() const {
366 return _type == T_ARRAY;
367 }
368
369 Symbol* SignatureStream::as_symbol(TRAPS) {
370 // Create a symbol from for string _begin _end
371 int begin = _begin;
372 int end = _end;
373
374 if (_type == T_OBJECT || _type == T_VALUETYPE) {
375 begin++;
376 end--;
377 if (begin == end) {
378 return vmSymbols::java_lang_Object();
379 }
380 }
381
382 // Save names for cleaning up reference count at the end of
383 // SignatureStream scope.
384 Symbol* name = SymbolTable::new_symbol(_signature, begin, end, CHECK_NULL);
385 _names->push(name); // save new symbol for decrementing later
386 return name;
387 }
388
389 Klass* SignatureStream::as_klass(Handle class_loader, Handle protection_domain,
390 FailureMode failure_mode, TRAPS) {
391 if (!is_object()) return NULL;
392 Symbol* name = as_symbol(CHECK_NULL);
393 if (failure_mode == ReturnNull) {
394 return SystemDictionary::resolve_or_null(name, class_loader, protection_domain, THREAD);
395 } else {
396 bool throw_error = (failure_mode == NCDFError);
397 return SystemDictionary::resolve_or_fail(name, class_loader, protection_domain, throw_error, THREAD);
398 }
399 }
400
401 oop SignatureStream::as_java_mirror(Handle class_loader, Handle protection_domain,
402 FailureMode failure_mode, TRAPS) {
403 if (!is_object())
404 return Universe::java_mirror(type());
405 Klass* klass = as_klass(class_loader, protection_domain, failure_mode, CHECK_NULL);
406 if (klass == NULL) return NULL;
407 return _type == T_VALUETYPE ? ValueKlass::cast(InstanceKlass::cast(klass))->value_mirror() : klass->java_mirror();
408 }
409
410 Symbol* SignatureStream::as_symbol_or_null() {
411 // Create a symbol from for string _begin _end
412 ResourceMark rm;
413
414 int begin = _begin;
415 int end = _end;
416
417 if (_type == T_OBJECT || _type == T_VALUETYPE) {
418 begin++;
419 end--;
420 if (begin == end) {
421 return vmSymbols::java_lang_Object();
422 }
423 }
424
425 char* buffer = NEW_RESOURCE_ARRAY(char, end - begin);
426 for (int index = begin; index < end; index++) {
427 buffer[index - begin] = _signature->char_at(index);
428 }
429 Symbol* result = SymbolTable::probe(buffer, end - begin);
430 return result;
431 }
432
433 int SignatureStream::reference_parameter_count() {
434 int args_count = 0;
435 for ( ; !at_return_type(); next()) {
436 if (is_object()) {
437 args_count++;
438 }
439 }
440 return args_count;
441 }
442
480 ssize_t len = sig->utf8_length();
481 return (type_sig != NULL && len >= 1 &&
482 (is_valid_type(type_sig, len) == len));
483 }
484
485 // Checks to see if the type (not to go beyond 'limit') refers to a valid type.
486 // Returns -1 if it is not, or the index of the next character that is not part
487 // of the type. The type encoding may end before 'limit' and that's ok.
488 ssize_t SignatureVerifier::is_valid_type(const char* type, ssize_t limit) {
489 ssize_t index = 0;
490
491 // Iterate over any number of array dimensions
492 while (index < limit && type[index] == '[') ++index;
493 if (index >= limit) {
494 return -1;
495 }
496 switch (type[index]) {
497 case 'B': case 'C': case 'D': case 'F': case 'I':
498 case 'J': case 'S': case 'Z': case 'V':
499 return index + 1;
500 case 'Q': // fall through
501 case 'L':
502 for (index = index + 1; index < limit; ++index) {
503 char c = type[index];
504 if (c == ';') {
505 return index + 1;
506 }
507 if (invalid_name_char(c)) {
508 return -1;
509 }
510 }
511 // fall through
512 default: ; // fall through
513 }
514 return -1;
515 }
516
517 bool SignatureVerifier::invalid_name_char(char c) {
518 switch (c) {
519 case '\0': case '.': case ';': case '[':
520 return true;
521 default:
522 return false;
523 }
524 }
525
526 // Adds an argument to the signature
527 void SigEntry::add_entry(GrowableArray<SigEntry>* sig, BasicType bt, int offset) {
528 sig->append(SigEntry(bt, offset));
529 if (bt == T_LONG || bt == T_DOUBLE) {
530 sig->append(SigEntry(T_VOID, offset)); // Longs and doubles take two stack slots
531 }
532 }
533
534 // Inserts a reserved argument at position 'i'
535 void SigEntry::insert_reserved_entry(GrowableArray<SigEntry>* sig, int i, BasicType bt) {
536 if (bt == T_OBJECT || bt == T_ARRAY || bt == T_VALUETYPE) {
537 // Treat this as INT to not confuse the GC
538 bt = T_INT;
539 } else if (bt == T_LONG || bt == T_DOUBLE) {
540 // Longs and doubles take two stack slots
541 sig->insert_before(i, SigEntry(T_VOID, SigEntry::ReservedOffset));
542 }
543 sig->insert_before(i, SigEntry(bt, SigEntry::ReservedOffset));
544 }
545
546 // Returns true if the argument at index 'i' is a reserved argument
547 bool SigEntry::is_reserved_entry(const GrowableArray<SigEntry>* sig, int i) {
548 return sig->at(i)._offset == SigEntry::ReservedOffset;
549 }
550
551 // Returns true if the argument at index 'i' is not a value type delimiter
552 bool SigEntry::skip_value_delimiters(const GrowableArray<SigEntry>* sig, int i) {
553 return (sig->at(i)._bt != T_VALUETYPE &&
554 (sig->at(i)._bt != T_VOID || sig->at(i-1)._bt == T_LONG || sig->at(i-1)._bt == T_DOUBLE));
555 }
556
557 // Fill basic type array from signature array
558 int SigEntry::fill_sig_bt(const GrowableArray<SigEntry>* sig, BasicType* sig_bt) {
559 int count = 0;
560 for (int i = 0; i < sig->length(); i++) {
561 if (skip_value_delimiters(sig, i)) {
562 sig_bt[count++] = sig->at(i)._bt;
563 }
564 }
565 return count;
566 }
567
568 // Create a temporary symbol from the signature array
569 TempNewSymbol SigEntry::create_symbol(const GrowableArray<SigEntry>* sig) {
570 ResourceMark rm;
571 int length = sig->length();
572 char* sig_str = NEW_RESOURCE_ARRAY(char, 2*length + 3);
573 int idx = 0;
574 sig_str[idx++] = '(';
575 for (int i = 0; i < length; i++) {
576 BasicType bt = sig->at(i)._bt;
577 if (bt == T_VALUETYPE || bt == T_VOID) {
578 // Ignore
579 } else {
580 if (bt == T_ARRAY) {
581 bt = T_OBJECT; // We don't know the element type, treat as Object
582 }
583 sig_str[idx++] = type2char(bt);
584 if (bt == T_OBJECT) {
585 sig_str[idx++] = ';';
586 }
587 }
588 }
589 sig_str[idx++] = ')';
590 sig_str[idx++] = '\0';
591 return SymbolTable::new_symbol(sig_str, Thread::current());
592 }
593
594 // Increment signature iterator (skips value type delimiters and T_VOID) and check if next entry is reserved
595 bool SigEntry::next_is_reserved(ExtendedSignature& sig, BasicType& bt, bool can_be_void) {
596 assert(can_be_void || bt != T_VOID, "should never see void");
597 if (sig.at_end() || (can_be_void && type2size[bt] == 2 && (*sig)._offset != SigEntry::ReservedOffset)) {
598 // Don't increment at the end or at a T_LONG/T_DOUBLE which will be followed by a (skipped) T_VOID
599 return false;
600 }
601 assert(bt == T_VOID || type2wfield[bt] == type2wfield[(*sig)._bt], "inconsistent signature");
602 ++sig;
603 if (!sig.at_end() && (*sig)._offset == SigEntry::ReservedOffset) {
604 bt = (*sig)._bt;
605 return true;
606 }
607 return false;
608 }
|