Mercurial > hg > graal-jvmci-8
annotate src/share/vm/runtime/signature.cpp @ 7588:f9eb431c3efe
8006005: Fix constant pool index validation and alignment trap for method parameter reflection
Summary: This patch addresses an alignment trap due to the storage format of method parameters data in constMethod. It also adds code to validate constant pool indexes for method parameters data.
Reviewed-by: jrose, dholmes
Contributed-by: eric.mccorkle@oracle.com
author | coleenp |
---|---|
date | Mon, 14 Jan 2013 11:01:39 -0500 |
parents | 070d523b96a7 |
children | d13d7aba8c12 |
rev | line source |
---|---|
0 | 1 /* |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2426
diff
changeset
|
2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. |
0 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1513
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1513
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1513
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "classfile/symbolTable.hpp" | |
27 #include "classfile/systemDictionary.hpp" | |
28 #include "memory/oopFactory.hpp" | |
29 #include "oops/instanceKlass.hpp" | |
30 #include "oops/oop.inline.hpp" | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
31 #include "oops/symbol.hpp" |
1972 | 32 #include "oops/typeArrayKlass.hpp" |
33 #include "runtime/signature.hpp" | |
0 | 34 |
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 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
47 SignatureIterator::SignatureIterator(Symbol* signature) { |
0 | 48 _signature = signature; |
49 _parameter_index = 0; | |
50 } | |
51 | |
52 void SignatureIterator::expect(char c) { | |
1490
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
0
diff
changeset
|
53 if (_signature->byte_at(_index) != c) fatal(err_msg("expecting %c", c)); |
0 | 54 _index++; |
55 } | |
56 | |
57 | |
58 void SignatureIterator::skip_optional_size() { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
59 Symbol* sig = _signature; |
0 | 60 char c = sig->byte_at(_index); |
61 while ('0' <= c && c <= '9') c = sig->byte_at(++_index); | |
62 } | |
63 | |
64 | |
65 int SignatureIterator::parse_type() { | |
66 // Note: This function could be simplified by using "return T_XXX_size;" | |
67 // instead of the assignment and the break statements. However, it | |
68 // seems that the product build for win32_i486 with MS VC++ 6.0 doesn't | |
69 // work (stack underflow for some tests) - this seems to be a VC++ 6.0 | |
70 // compiler bug (was problem - gri 4/27/2000). | |
71 int size = -1; | |
72 switch(_signature->byte_at(_index)) { | |
73 case 'B': do_byte (); if (_parameter_index < 0 ) _return_type = T_BYTE; | |
74 _index++; size = T_BYTE_size ; break; | |
75 case 'C': do_char (); if (_parameter_index < 0 ) _return_type = T_CHAR; | |
76 _index++; size = T_CHAR_size ; break; | |
77 case 'D': do_double(); if (_parameter_index < 0 ) _return_type = T_DOUBLE; | |
78 _index++; size = T_DOUBLE_size ; break; | |
79 case 'F': do_float (); if (_parameter_index < 0 ) _return_type = T_FLOAT; | |
80 _index++; size = T_FLOAT_size ; break; | |
81 case 'I': do_int (); if (_parameter_index < 0 ) _return_type = T_INT; | |
82 _index++; size = T_INT_size ; break; | |
83 case 'J': do_long (); if (_parameter_index < 0 ) _return_type = T_LONG; | |
84 _index++; size = T_LONG_size ; break; | |
85 case 'S': do_short (); if (_parameter_index < 0 ) _return_type = T_SHORT; | |
86 _index++; size = T_SHORT_size ; break; | |
87 case 'Z': do_bool (); if (_parameter_index < 0 ) _return_type = T_BOOLEAN; | |
88 _index++; size = T_BOOLEAN_size; break; | |
89 case 'V': do_void (); if (_parameter_index < 0 ) _return_type = T_VOID; | |
90 _index++; size = T_VOID_size; ; break; | |
91 case 'L': | |
92 { int begin = ++_index; | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
93 Symbol* sig = _signature; |
0 | 94 while (sig->byte_at(_index++) != ';') ; |
95 do_object(begin, _index); | |
96 } | |
97 if (_parameter_index < 0 ) _return_type = T_OBJECT; | |
98 size = T_OBJECT_size; | |
99 break; | |
100 case '[': | |
101 { int begin = ++_index; | |
102 skip_optional_size(); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
103 Symbol* sig = _signature; |
0 | 104 while (sig->byte_at(_index) == '[') { |
105 _index++; | |
106 skip_optional_size(); | |
107 } | |
108 if (sig->byte_at(_index) == 'L') { | |
109 while (sig->byte_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()) { | |
129 tty->print_cr("too many chars in signature"); | |
130 _signature->print_value_on(tty); | |
131 tty->print_cr(" @ %d", _index); | |
132 } | |
133 } | |
134 | |
135 | |
136 void SignatureIterator::dispatch_field() { | |
137 // no '(', just one (field) type | |
138 _index = 0; | |
139 _parameter_index = 0; | |
140 parse_type(); | |
141 check_signature_end(); | |
142 } | |
143 | |
144 | |
145 void SignatureIterator::iterate_parameters() { | |
146 // Parse parameters | |
147 _index = 0; | |
148 _parameter_index = 0; | |
149 expect('('); | |
150 while (_signature->byte_at(_index) != ')') _parameter_index += parse_type(); | |
151 expect(')'); | |
152 _parameter_index = 0; | |
153 } | |
154 | |
155 // Optimized version of iterat_parameters when fingerprint is known | |
156 void SignatureIterator::iterate_parameters( uint64_t fingerprint ) { | |
157 uint64_t saved_fingerprint = fingerprint; | |
158 | |
159 // Check for too many arguments | |
160 if ( fingerprint == UCONST64(-1) ) { | |
161 SignatureIterator::iterate_parameters(); | |
162 return; | |
163 } | |
164 | |
165 assert(fingerprint, "Fingerprint should not be 0"); | |
166 | |
167 _parameter_index = 0; | |
168 fingerprint = fingerprint >> (static_feature_size + result_feature_size); | |
169 while ( 1 ) { | |
170 switch ( fingerprint & parameter_feature_mask ) { | |
171 case bool_parm: | |
172 do_bool(); | |
173 _parameter_index += T_BOOLEAN_size; | |
174 break; | |
175 case byte_parm: | |
176 do_byte(); | |
177 _parameter_index += T_BYTE_size; | |
178 break; | |
179 case char_parm: | |
180 do_char(); | |
181 _parameter_index += T_CHAR_size; | |
182 break; | |
183 case short_parm: | |
184 do_short(); | |
185 _parameter_index += T_SHORT_size; | |
186 break; | |
187 case int_parm: | |
188 do_int(); | |
189 _parameter_index += T_INT_size; | |
190 break; | |
191 case obj_parm: | |
192 do_object(0, 0); | |
193 _parameter_index += T_OBJECT_size; | |
194 break; | |
195 case long_parm: | |
196 do_long(); | |
197 _parameter_index += T_LONG_size; | |
198 break; | |
199 case float_parm: | |
200 do_float(); | |
201 _parameter_index += T_FLOAT_size; | |
202 break; | |
203 case double_parm: | |
204 do_double(); | |
205 _parameter_index += T_DOUBLE_size; | |
206 break; | |
207 case done_parm: | |
208 return; | |
209 break; | |
210 default: | |
211 tty->print_cr("*** parameter is %d", fingerprint & parameter_feature_mask); | |
212 tty->print_cr("*** fingerprint is " PTR64_FORMAT, saved_fingerprint); | |
213 ShouldNotReachHere(); | |
214 break; | |
215 } | |
216 fingerprint >>= parameter_feature_size; | |
217 } | |
218 _parameter_index = 0; | |
219 } | |
220 | |
221 | |
222 void SignatureIterator::iterate_returntype() { | |
223 // Ignore parameters | |
224 _index = 0; | |
225 expect('('); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
226 Symbol* sig = _signature; |
0 | 227 while (sig->byte_at(_index) != ')') _index++; |
228 expect(')'); | |
229 // Parse return type | |
230 _parameter_index = -1; | |
231 parse_type(); | |
232 check_signature_end(); | |
233 _parameter_index = 0; | |
234 } | |
235 | |
236 | |
237 void SignatureIterator::iterate() { | |
238 // Parse parameters | |
239 _parameter_index = 0; | |
240 _index = 0; | |
241 expect('('); | |
242 while (_signature->byte_at(_index) != ')') _parameter_index += parse_type(); | |
243 expect(')'); | |
244 // Parse return type | |
245 _parameter_index = -1; | |
246 parse_type(); | |
247 check_signature_end(); | |
248 _parameter_index = 0; | |
249 } | |
250 | |
251 | |
252 // Implementation of SignatureStream | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
253 SignatureStream::SignatureStream(Symbol* signature, bool is_method) : |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
254 _signature(signature), _at_return_type(false) { |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
255 _begin = _end = (is_method ? 1 : 0); // skip first '(' in method signatures |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
256 _names = new GrowableArray<Symbol*>(10); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
257 next(); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
258 } |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
259 |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
260 SignatureStream::~SignatureStream() { |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
261 // decrement refcount for names created during signature parsing |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
262 for (int i = 0; i < _names->length(); i++) { |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
263 _names->at(i)->decrement_refcount(); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
264 } |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
265 } |
0 | 266 |
267 bool SignatureStream::is_done() const { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
268 return _end > _signature->utf8_length(); |
0 | 269 } |
270 | |
271 | |
272 void SignatureStream::next_non_primitive(int t) { | |
273 switch (t) { | |
274 case 'L': { | |
275 _type = T_OBJECT; | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
276 Symbol* sig = _signature; |
0 | 277 while (sig->byte_at(_end++) != ';'); |
278 break; | |
279 } | |
280 case '[': { | |
281 _type = T_ARRAY; | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
282 Symbol* sig = _signature; |
0 | 283 char c = sig->byte_at(_end); |
284 while ('0' <= c && c <= '9') c = sig->byte_at(_end++); | |
285 while (sig->byte_at(_end) == '[') { | |
286 _end++; | |
287 c = sig->byte_at(_end); | |
288 while ('0' <= c && c <= '9') c = sig->byte_at(_end++); | |
289 } | |
290 switch(sig->byte_at(_end)) { | |
291 case 'B': | |
292 case 'C': | |
293 case 'D': | |
294 case 'F': | |
295 case 'I': | |
296 case 'J': | |
297 case 'S': | |
298 case 'Z':_end++; break; | |
299 default: { | |
300 while (sig->byte_at(_end++) != ';'); | |
301 break; | |
302 } | |
303 } | |
304 break; | |
305 } | |
306 case ')': _end++; next(); _at_return_type = true; break; | |
307 default : ShouldNotReachHere(); | |
308 } | |
309 } | |
310 | |
311 | |
312 bool SignatureStream::is_object() const { | |
313 return _type == T_OBJECT | |
314 || _type == T_ARRAY; | |
315 } | |
316 | |
317 bool SignatureStream::is_array() const { | |
318 return _type == T_ARRAY; | |
319 } | |
320 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
321 Symbol* SignatureStream::as_symbol(TRAPS) { |
0 | 322 // Create a symbol from for string _begin _end |
323 int begin = _begin; | |
324 int end = _end; | |
325 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
326 if ( _signature->byte_at(_begin) == 'L' |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
327 && _signature->byte_at(_end-1) == ';') { |
0 | 328 begin++; |
329 end--; | |
330 } | |
331 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
332 // Save names for cleaning up reference count at the end of |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
333 // SignatureStream scope. |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
334 Symbol* name = SymbolTable::new_symbol(_signature, begin, end, CHECK_NULL); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
335 _names->push(name); // save new symbol for decrementing later |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
336 return name; |
0 | 337 } |
338 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2426
diff
changeset
|
339 Klass* SignatureStream::as_klass(Handle class_loader, Handle protection_domain, |
1508
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
0
diff
changeset
|
340 FailureMode failure_mode, TRAPS) { |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
0
diff
changeset
|
341 if (!is_object()) return NULL; |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
342 Symbol* name = as_symbol(CHECK_NULL); |
1508
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
0
diff
changeset
|
343 if (failure_mode == ReturnNull) { |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
0
diff
changeset
|
344 return SystemDictionary::resolve_or_null(name, class_loader, protection_domain, THREAD); |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
0
diff
changeset
|
345 } else { |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
0
diff
changeset
|
346 bool throw_error = (failure_mode == NCDFError); |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
0
diff
changeset
|
347 return SystemDictionary::resolve_or_fail(name, class_loader, protection_domain, throw_error, THREAD); |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
0
diff
changeset
|
348 } |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
0
diff
changeset
|
349 } |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
0
diff
changeset
|
350 |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
0
diff
changeset
|
351 oop SignatureStream::as_java_mirror(Handle class_loader, Handle protection_domain, |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
0
diff
changeset
|
352 FailureMode failure_mode, TRAPS) { |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
0
diff
changeset
|
353 if (!is_object()) |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
0
diff
changeset
|
354 return Universe::java_mirror(type()); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
2426
diff
changeset
|
355 Klass* klass = as_klass(class_loader, protection_domain, failure_mode, CHECK_NULL); |
1508
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
0
diff
changeset
|
356 if (klass == NULL) return NULL; |
6983 | 357 return klass->java_mirror(); |
1508
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
0
diff
changeset
|
358 } |
0 | 359 |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
360 Symbol* SignatureStream::as_symbol_or_null() { |
0 | 361 // Create a symbol from for string _begin _end |
362 ResourceMark rm; | |
363 | |
364 int begin = _begin; | |
365 int end = _end; | |
366 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
367 if ( _signature->byte_at(_begin) == 'L' |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
368 && _signature->byte_at(_end-1) == ';') { |
0 | 369 begin++; |
370 end--; | |
371 } | |
372 | |
373 char* buffer = NEW_RESOURCE_ARRAY(char, end - begin); | |
374 for (int index = begin; index < end; index++) { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
375 buffer[index - begin] = _signature->byte_at(index); |
0 | 376 } |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
377 Symbol* result = SymbolTable::probe(buffer, end - begin); |
0 | 378 return result; |
379 } | |
380 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
381 bool SignatureVerifier::is_valid_signature(Symbol* sig) { |
0 | 382 const char* signature = (const char*)sig->bytes(); |
383 ssize_t len = sig->utf8_length(); | |
384 if (signature == NULL || signature[0] == '\0' || len < 1) { | |
385 return false; | |
386 } else if (signature[0] == '(') { | |
387 return is_valid_method_signature(sig); | |
388 } else { | |
389 return is_valid_type_signature(sig); | |
390 } | |
391 } | |
392 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
393 bool SignatureVerifier::is_valid_method_signature(Symbol* sig) { |
0 | 394 const char* method_sig = (const char*)sig->bytes(); |
395 ssize_t len = sig->utf8_length(); | |
396 ssize_t index = 0; | |
397 if (method_sig != NULL && len > 1 && method_sig[index] == '(') { | |
398 ++index; | |
399 while (index < len && method_sig[index] != ')') { | |
400 ssize_t res = is_valid_type(&method_sig[index], len - index); | |
401 if (res == -1) { | |
402 return false; | |
403 } else { | |
404 index += res; | |
405 } | |
406 } | |
407 if (index < len && method_sig[index] == ')') { | |
408 // check the return type | |
409 ++index; | |
410 return (is_valid_type(&method_sig[index], len - index) == (len - index)); | |
411 } | |
412 } | |
413 return false; | |
414 } | |
415 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
416 bool SignatureVerifier::is_valid_type_signature(Symbol* sig) { |
0 | 417 const char* type_sig = (const char*)sig->bytes(); |
418 ssize_t len = sig->utf8_length(); | |
419 return (type_sig != NULL && len >= 1 && | |
420 (is_valid_type(type_sig, len) == len)); | |
421 } | |
422 | |
423 // Checks to see if the type (not to go beyond 'limit') refers to a valid type. | |
424 // Returns -1 if it is not, or the index of the next character that is not part | |
425 // of the type. The type encoding may end before 'limit' and that's ok. | |
426 ssize_t SignatureVerifier::is_valid_type(const char* type, ssize_t limit) { | |
427 ssize_t index = 0; | |
428 | |
429 // Iterate over any number of array dimensions | |
430 while (index < limit && type[index] == '[') ++index; | |
431 if (index >= limit) { | |
432 return -1; | |
433 } | |
434 switch (type[index]) { | |
435 case 'B': case 'C': case 'D': case 'F': case 'I': | |
436 case 'J': case 'S': case 'Z': case 'V': | |
437 return index + 1; | |
438 case 'L': | |
439 for (index = index + 1; index < limit; ++index) { | |
440 char c = type[index]; | |
441 if (c == ';') { | |
442 return index + 1; | |
443 } | |
444 if (invalid_name_char(c)) { | |
445 return -1; | |
446 } | |
447 } | |
448 // fall through | |
449 default: ; // fall through | |
450 } | |
451 return -1; | |
452 } | |
453 | |
454 bool SignatureVerifier::invalid_name_char(char c) { | |
455 switch (c) { | |
456 case '\0': case '.': case ';': case '[': | |
457 return true; | |
458 default: | |
459 return false; | |
460 } | |
461 } |