26 #include "classfile/symbolTable.hpp" |
26 #include "classfile/symbolTable.hpp" |
27 #include "classfile/systemDictionary.hpp" |
27 #include "classfile/systemDictionary.hpp" |
28 #include "memory/oopFactory.hpp" |
28 #include "memory/oopFactory.hpp" |
29 #include "oops/instanceKlass.hpp" |
29 #include "oops/instanceKlass.hpp" |
30 #include "oops/oop.inline.hpp" |
30 #include "oops/oop.inline.hpp" |
31 #include "oops/symbolOop.hpp" |
31 #include "oops/symbol.hpp" |
32 #include "oops/typeArrayKlass.hpp" |
32 #include "oops/typeArrayKlass.hpp" |
33 #include "runtime/signature.hpp" |
33 #include "runtime/signature.hpp" |
34 |
34 |
35 |
35 |
36 // Implementation of SignatureIterator |
36 // Implementation of SignatureIterator |
42 // ReturnType = FieldType | "V". |
42 // ReturnType = FieldType | "V". |
43 // FieldType = "B" | "C" | "D" | "F" | "I" | "J" | "S" | "Z" | "L" ClassName ";" | "[" FieldType. |
43 // FieldType = "B" | "C" | "D" | "F" | "I" | "J" | "S" | "Z" | "L" ClassName ";" | "[" FieldType. |
44 // ClassName = string. |
44 // ClassName = string. |
45 |
45 |
46 |
46 |
47 SignatureIterator::SignatureIterator(symbolHandle signature) { |
47 SignatureIterator::SignatureIterator(Symbol* signature) { |
48 assert(signature->is_symbol(), "not a symbol"); |
|
49 _signature = signature; |
48 _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; |
49 _parameter_index = 0; |
64 } |
50 } |
65 |
51 |
66 void SignatureIterator::expect(char c) { |
52 void SignatureIterator::expect(char c) { |
67 if (_signature->byte_at(_index) != c) fatal(err_msg("expecting %c", c)); |
53 if (_signature->byte_at(_index) != c) fatal(err_msg("expecting %c", c)); |
68 _index++; |
54 _index++; |
69 } |
55 } |
70 |
56 |
71 |
57 |
72 void SignatureIterator::skip_optional_size() { |
58 void SignatureIterator::skip_optional_size() { |
73 symbolOop sig = _signature(); |
59 Symbol* sig = _signature; |
74 char c = sig->byte_at(_index); |
60 char c = sig->byte_at(_index); |
75 while ('0' <= c && c <= '9') c = sig->byte_at(++_index); |
61 while ('0' <= c && c <= '9') c = sig->byte_at(++_index); |
76 } |
62 } |
77 |
63 |
78 |
64 |
102 _index++; size = T_BOOLEAN_size; break; |
88 _index++; size = T_BOOLEAN_size; break; |
103 case 'V': do_void (); if (_parameter_index < 0 ) _return_type = T_VOID; |
89 case 'V': do_void (); if (_parameter_index < 0 ) _return_type = T_VOID; |
104 _index++; size = T_VOID_size; ; break; |
90 _index++; size = T_VOID_size; ; break; |
105 case 'L': |
91 case 'L': |
106 { int begin = ++_index; |
92 { int begin = ++_index; |
107 symbolOop sig = _signature(); |
93 Symbol* sig = _signature; |
108 while (sig->byte_at(_index++) != ';') ; |
94 while (sig->byte_at(_index++) != ';') ; |
109 do_object(begin, _index); |
95 do_object(begin, _index); |
110 } |
96 } |
111 if (_parameter_index < 0 ) _return_type = T_OBJECT; |
97 if (_parameter_index < 0 ) _return_type = T_OBJECT; |
112 size = T_OBJECT_size; |
98 size = T_OBJECT_size; |
113 break; |
99 break; |
114 case '[': |
100 case '[': |
115 { int begin = ++_index; |
101 { int begin = ++_index; |
116 skip_optional_size(); |
102 skip_optional_size(); |
117 symbolOop sig = _signature(); |
103 Symbol* sig = _signature; |
118 while (sig->byte_at(_index) == '[') { |
104 while (sig->byte_at(_index) == '[') { |
119 _index++; |
105 _index++; |
120 skip_optional_size(); |
106 skip_optional_size(); |
121 } |
107 } |
122 if (sig->byte_at(_index) == 'L') { |
108 if (sig->byte_at(_index) == 'L') { |
262 _parameter_index = 0; |
248 _parameter_index = 0; |
263 } |
249 } |
264 |
250 |
265 |
251 |
266 // Implementation of SignatureStream |
252 // Implementation of SignatureStream |
|
253 SignatureStream::SignatureStream(Symbol* signature, bool is_method) : |
|
254 _signature(signature), _at_return_type(false) { |
|
255 _begin = _end = (is_method ? 1 : 0); // skip first '(' in method signatures |
|
256 _names = new GrowableArray<Symbol*>(10); |
|
257 next(); |
|
258 } |
|
259 |
|
260 SignatureStream::~SignatureStream() { |
|
261 // decrement refcount for names created during signature parsing |
|
262 for (int i = 0; i < _names->length(); i++) { |
|
263 _names->at(i)->decrement_refcount(); |
|
264 } |
|
265 } |
267 |
266 |
268 bool SignatureStream::is_done() const { |
267 bool SignatureStream::is_done() const { |
269 return _end > _signature()->utf8_length(); |
268 return _end > _signature->utf8_length(); |
270 } |
269 } |
271 |
270 |
272 |
271 |
273 void SignatureStream::next_non_primitive(int t) { |
272 void SignatureStream::next_non_primitive(int t) { |
274 switch (t) { |
273 switch (t) { |
275 case 'L': { |
274 case 'L': { |
276 _type = T_OBJECT; |
275 _type = T_OBJECT; |
277 symbolOop sig = _signature(); |
276 Symbol* sig = _signature; |
278 while (sig->byte_at(_end++) != ';'); |
277 while (sig->byte_at(_end++) != ';'); |
279 break; |
278 break; |
280 } |
279 } |
281 case '[': { |
280 case '[': { |
282 _type = T_ARRAY; |
281 _type = T_ARRAY; |
283 symbolOop sig = _signature(); |
282 Symbol* sig = _signature; |
284 char c = sig->byte_at(_end); |
283 char c = sig->byte_at(_end); |
285 while ('0' <= c && c <= '9') c = sig->byte_at(_end++); |
284 while ('0' <= c && c <= '9') c = sig->byte_at(_end++); |
286 while (sig->byte_at(_end) == '[') { |
285 while (sig->byte_at(_end) == '[') { |
287 _end++; |
286 _end++; |
288 c = sig->byte_at(_end); |
287 c = sig->byte_at(_end); |
317 |
316 |
318 bool SignatureStream::is_array() const { |
317 bool SignatureStream::is_array() const { |
319 return _type == T_ARRAY; |
318 return _type == T_ARRAY; |
320 } |
319 } |
321 |
320 |
322 symbolOop SignatureStream::as_symbol(TRAPS) { |
321 Symbol* SignatureStream::as_symbol(TRAPS) { |
323 // Create a symbol from for string _begin _end |
322 // Create a symbol from for string _begin _end |
324 int begin = _begin; |
323 int begin = _begin; |
325 int end = _end; |
324 int end = _end; |
326 |
325 |
327 if ( _signature()->byte_at(_begin) == 'L' |
326 if ( _signature->byte_at(_begin) == 'L' |
328 && _signature()->byte_at(_end-1) == ';') { |
327 && _signature->byte_at(_end-1) == ';') { |
329 begin++; |
328 begin++; |
330 end--; |
329 end--; |
331 } |
330 } |
332 |
331 |
333 symbolOop result = oopFactory::new_symbol(_signature, begin, end, CHECK_NULL); |
332 // Save names for cleaning up reference count at the end of |
334 return result; |
333 // SignatureStream scope. |
|
334 Symbol* name = SymbolTable::new_symbol(_signature, begin, end, CHECK_NULL); |
|
335 _names->push(name); // save new symbol for decrementing later |
|
336 return name; |
335 } |
337 } |
336 |
338 |
337 klassOop SignatureStream::as_klass(Handle class_loader, Handle protection_domain, |
339 klassOop SignatureStream::as_klass(Handle class_loader, Handle protection_domain, |
338 FailureMode failure_mode, TRAPS) { |
340 FailureMode failure_mode, TRAPS) { |
339 if (!is_object()) return NULL; |
341 if (!is_object()) return NULL; |
340 symbolOop name = as_symbol(CHECK_NULL); |
342 Symbol* name = as_symbol(CHECK_NULL); |
341 if (failure_mode == ReturnNull) { |
343 if (failure_mode == ReturnNull) { |
342 return SystemDictionary::resolve_or_null(name, class_loader, protection_domain, THREAD); |
344 return SystemDictionary::resolve_or_null(name, class_loader, protection_domain, THREAD); |
343 } else { |
345 } else { |
344 bool throw_error = (failure_mode == NCDFError); |
346 bool throw_error = (failure_mode == NCDFError); |
345 return SystemDictionary::resolve_or_fail(name, class_loader, protection_domain, throw_error, THREAD); |
347 return SystemDictionary::resolve_or_fail(name, class_loader, protection_domain, throw_error, THREAD); |
353 klassOop klass = as_klass(class_loader, protection_domain, failure_mode, CHECK_NULL); |
355 klassOop klass = as_klass(class_loader, protection_domain, failure_mode, CHECK_NULL); |
354 if (klass == NULL) return NULL; |
356 if (klass == NULL) return NULL; |
355 return Klass::cast(klass)->java_mirror(); |
357 return Klass::cast(klass)->java_mirror(); |
356 } |
358 } |
357 |
359 |
358 symbolOop SignatureStream::as_symbol_or_null() { |
360 Symbol* SignatureStream::as_symbol_or_null() { |
359 // Create a symbol from for string _begin _end |
361 // Create a symbol from for string _begin _end |
360 ResourceMark rm; |
362 ResourceMark rm; |
361 |
363 |
362 int begin = _begin; |
364 int begin = _begin; |
363 int end = _end; |
365 int end = _end; |
364 |
366 |
365 if ( _signature()->byte_at(_begin) == 'L' |
367 if ( _signature->byte_at(_begin) == 'L' |
366 && _signature()->byte_at(_end-1) == ';') { |
368 && _signature->byte_at(_end-1) == ';') { |
367 begin++; |
369 begin++; |
368 end--; |
370 end--; |
369 } |
371 } |
370 |
372 |
371 char* buffer = NEW_RESOURCE_ARRAY(char, end - begin); |
373 char* buffer = NEW_RESOURCE_ARRAY(char, end - begin); |
372 for (int index = begin; index < end; index++) { |
374 for (int index = begin; index < end; index++) { |
373 buffer[index - begin] = _signature()->byte_at(index); |
375 buffer[index - begin] = _signature->byte_at(index); |
374 } |
376 } |
375 symbolOop result = SymbolTable::probe(buffer, end - begin); |
377 Symbol* result = SymbolTable::probe(buffer, end - begin); |
376 return result; |
378 return result; |
377 } |
379 } |
378 |
380 |
379 bool SignatureVerifier::is_valid_signature(symbolHandle sig) { |
381 bool SignatureVerifier::is_valid_signature(Symbol* sig) { |
380 const char* signature = (const char*)sig->bytes(); |
382 const char* signature = (const char*)sig->bytes(); |
381 ssize_t len = sig->utf8_length(); |
383 ssize_t len = sig->utf8_length(); |
382 if (signature == NULL || signature[0] == '\0' || len < 1) { |
384 if (signature == NULL || signature[0] == '\0' || len < 1) { |
383 return false; |
385 return false; |
384 } else if (signature[0] == '(') { |
386 } else if (signature[0] == '(') { |
386 } else { |
388 } else { |
387 return is_valid_type_signature(sig); |
389 return is_valid_type_signature(sig); |
388 } |
390 } |
389 } |
391 } |
390 |
392 |
391 bool SignatureVerifier::is_valid_method_signature(symbolHandle sig) { |
393 bool SignatureVerifier::is_valid_method_signature(Symbol* sig) { |
392 const char* method_sig = (const char*)sig->bytes(); |
394 const char* method_sig = (const char*)sig->bytes(); |
393 ssize_t len = sig->utf8_length(); |
395 ssize_t len = sig->utf8_length(); |
394 ssize_t index = 0; |
396 ssize_t index = 0; |
395 if (method_sig != NULL && len > 1 && method_sig[index] == '(') { |
397 if (method_sig != NULL && len > 1 && method_sig[index] == '(') { |
396 ++index; |
398 ++index; |
409 } |
411 } |
410 } |
412 } |
411 return false; |
413 return false; |
412 } |
414 } |
413 |
415 |
414 bool SignatureVerifier::is_valid_type_signature(symbolHandle sig) { |
416 bool SignatureVerifier::is_valid_type_signature(Symbol* sig) { |
415 const char* type_sig = (const char*)sig->bytes(); |
417 const char* type_sig = (const char*)sig->bytes(); |
416 ssize_t len = sig->utf8_length(); |
418 ssize_t len = sig->utf8_length(); |
417 return (type_sig != NULL && len >= 1 && |
419 return (type_sig != NULL && len >= 1 && |
418 (is_valid_type(type_sig, len) == len)); |
420 (is_valid_type(type_sig, len) == len)); |
419 } |
421 } |