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