Line data Source code
1 : /* src/vm/resolve.cpp - resolving classes/interfaces/fields/methods
2 :
3 : Copyright (C) 1996-2014
4 : CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 :
6 : This file is part of CACAO.
7 :
8 : This program is free software; you can redistribute it and/or
9 : modify it under the terms of the GNU General Public License as
10 : published by the Free Software Foundation; either version 2, or (at
11 : your option) any later version.
12 :
13 : This program is distributed in the hope that it will be useful, but
14 : WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 : General Public License for more details.
17 :
18 : You should have received a copy of the GNU General Public License
19 : along with this program; if not, write to the Free Software
20 : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 : 02110-1301, USA.
22 :
23 : */
24 :
25 :
26 : #include "vm/resolve.hpp"
27 : #include <assert.h> // for assert
28 : #include <stdint.h> // for int32_t
29 : #include "config.h" // for ENABLE_VERIFIER
30 : #include "mm/dumpmemory.hpp" // for DNEW
31 : #include "mm/memory.hpp"
32 : #include "toolbox/buffer.hpp" // for Buffer
33 : #include "vm/access.hpp" // for access_is_accessible_member, etc
34 : #include "vm/class.hpp" // for classinfo, etc
35 : #include "vm/classcache.hpp" // for classcache_add_constraint, etc
36 : #include "vm/descriptor.hpp" // for typedesc, methoddesc, etc
37 : #include "vm/exceptions.hpp"
38 : #include "vm/field.hpp" // for fieldinfo
39 : #include "vm/global.hpp" // for Type::TYPE_ADR, etc
40 : #include "vm/globals.hpp"
41 : #include "vm/jit/builtin.hpp" // for builtin_instanceof
42 : #include "vm/jit/ir/icmd.hpp" // for ::ICMD_GETFIELD, etc
43 : #include "vm/jit/ir/instruction.hpp" // for instruction, etc
44 : #include "vm/jit/jit.hpp"
45 : #include "vm/jit/reg.hpp" // for varinfo
46 : #include "vm/jit/verify/typeinfo.hpp" // for typeinfo_t, etc
47 : #include "vm/linker.hpp" // for link_class
48 : #include "vm/loader.hpp" // for load_class_from_classloader
49 : #include "vm/method.hpp" // for methodinfo
50 : #include "vm/options.hpp" // for opt_verify
51 : #include "vm/primitive.hpp" // for Primitive
52 : #include "vm/types.hpp" // for s4
53 :
54 : struct jitdata;
55 :
56 :
57 : /******************************************************************************/
58 : /* DEBUG HELPERS */
59 : /******************************************************************************/
60 :
61 : /*#define RESOLVE_VERBOSE*/
62 :
63 : /* resolve_handle_pending_exception ********************************************
64 :
65 : Convert a pending ClassNotFoundException into a
66 : NoClassDefFoundError if requested.
67 :
68 : See: hotspot/src/share/vm/classfile/systemDictionary.cpp
69 : (handle_resolution_exception)
70 :
71 : ARGUMENTS:
72 : classname .... name of the class currently resolved
73 : throwError ... if true throw a NoClassDefFoundError instead of
74 : a ClassNotFoundException
75 :
76 : *******************************************************************************/
77 :
78 15 : void resolve_handle_pending_exception(bool throwError)
79 : {
80 : java_handle_t *e;
81 :
82 : /* Get the current exception. */
83 :
84 15 : e = exceptions_get_exception();
85 :
86 15 : if (e != NULL) {
87 15 : if (throwError == true) {
88 : /* Convert ClassNotFoundException to
89 : NoClassDefFoundError. */
90 :
91 15 : if (builtin_instanceof(e, class_java_lang_ClassNotFoundException)) {
92 : /* Clear exception, because we are calling Java code
93 : again. */
94 :
95 3 : exceptions_clear_exception();
96 :
97 : /* create new error */
98 :
99 3 : exceptions_throw_noclassdeffounderror_cause(e);
100 : }
101 : else {
102 12 : return;
103 : }
104 : }
105 : else {
106 : /* An exception conversion was not requested. Simply
107 : return. */
108 :
109 0 : return;
110 : }
111 : }
112 : }
113 :
114 :
115 : /******************************************************************************/
116 : /* CLASS RESOLUTION */
117 : /******************************************************************************/
118 :
119 : /* resolve_class_from_name *****************************************************
120 :
121 : Resolve a symbolic class reference
122 :
123 : IN:
124 : referer..........the class containing the reference
125 : refmethod........the method from which resolution was triggered
126 : (may be NULL if not applicable)
127 : classname........class name to resolve
128 : mode.............mode of resolution:
129 : resolveLazy...only resolve if it does not
130 : require loading classes
131 : resolveEager..load classes if necessary
132 : checkaccess......if true, access rights to the class are checked
133 : link.............if true, guarantee that the returned class, if any,
134 : has been linked
135 :
136 : OUT:
137 : *result..........set to result of resolution, or to NULL if
138 : the reference has not been resolved
139 : In the case of an exception, *result is
140 : guaranteed to be set to NULL.
141 :
142 : RETURN VALUE:
143 : true.............everything ok
144 : (*result may still be NULL for resolveLazy)
145 : false............an exception has been thrown
146 :
147 : NOTE:
148 : The returned class is *not* guaranteed to be linked!
149 : (It is guaranteed to be loaded, though.)
150 :
151 : *******************************************************************************/
152 :
153 882668 : bool resolve_class_from_name(classinfo *referer,
154 : methodinfo *refmethod,
155 : Utf8String classname,
156 : resolve_mode_t mode,
157 : bool checkaccess,
158 : bool link,
159 : classinfo **result)
160 : {
161 : classinfo *cls;
162 : const char *utf_ptr;
163 : int len;
164 :
165 882668 : assert(result);
166 882668 : assert(referer);
167 882668 : assert(classname);
168 882668 : assert(mode == resolveLazy || mode == resolveEager);
169 :
170 882668 : *result = NULL;
171 :
172 : #ifdef RESOLVE_VERBOSE
173 : printf("resolve_class_from_name(");
174 : utf_fprint_printable_ascii(stdout,referer->name);
175 : printf(",%p,",(void*)referer->classloader);
176 : utf_fprint_printable_ascii(stdout,classname);
177 : printf(",%d,%d)\n",(int)checkaccess,(int)link);
178 : #endif
179 :
180 : /* lookup if this class has already been loaded */
181 :
182 882668 : cls = classcache_lookup(referer->classloader, classname);
183 :
184 : #ifdef RESOLVE_VERBOSE
185 : printf(" lookup result: %p\n",(void*)cls);
186 : #endif
187 :
188 882668 : if (!cls) {
189 : /* resolve array types */
190 :
191 252188 : if (classname[0] == '[') {
192 7540 : utf_ptr = classname.begin() + 1;
193 7540 : len = classname.size() - 1;
194 :
195 : /* classname is an array type name */
196 :
197 7540 : switch (*utf_ptr) {
198 : case 'L':
199 6962 : utf_ptr++;
200 6962 : len -= 2;
201 : /* FALLTHROUGH */
202 : case '[':
203 : /* the component type is a reference type */
204 : /* resolve the component type */
205 7201 : if (!resolve_class_from_name(referer,refmethod,
206 : Utf8String::from_utf8(utf_ptr,len),
207 : mode,checkaccess,link,&cls))
208 0 : return false; /* exception */
209 7201 : if (!cls) {
210 4320 : assert(mode == resolveLazy);
211 4320 : return true; /* be lazy */
212 : }
213 : /* create the array class */
214 2881 : cls = class_array_of(cls,false);
215 2881 : if (!cls)
216 0 : return false; /* exception */
217 : }
218 : }
219 : else {
220 : /* the class has not been loaded, yet */
221 244648 : if (mode == resolveLazy)
222 215415 : return true; /* be lazy */
223 : }
224 :
225 : #ifdef RESOLVE_VERBOSE
226 : printf(" loading...\n");
227 : #endif
228 :
229 : /* load the class */
230 :
231 32453 : if (cls == NULL) {
232 29572 : cls = load_class_from_classloader(classname, referer->classloader);
233 :
234 29572 : if (cls == NULL)
235 28 : return false;
236 : }
237 : }
238 :
239 : /* the class is now loaded */
240 662905 : assert(cls);
241 662905 : assert(cls->state & CLASS_LOADED);
242 :
243 : #ifdef RESOLVE_VERBOSE
244 : printf(" checking access rights...\n");
245 : #endif
246 :
247 : /* check access rights of referer to refered class */
248 :
249 662905 : if (checkaccess && !access_is_accessible_class(referer,cls)) {
250 0 : Buffer<> buf;
251 :
252 : Utf8String u = buf.write("class is not accessible (")
253 : .write_slash_to_dot(cls->name)
254 : .write(" from ")
255 : .write_slash_to_dot(referer->name)
256 : .write(")")
257 0 : .utf8_str();
258 :
259 0 : exceptions_throw_illegalaccessexception(u);
260 0 : return false; /* exception */
261 : }
262 :
263 : /* link the class if necessary */
264 662905 : if (link) {
265 603877 : if (!(cls->state & CLASS_LINKED))
266 19894 : if (!link_class(cls))
267 0 : return false; /* exception */
268 :
269 603877 : assert(cls->state & CLASS_LINKED);
270 : }
271 :
272 : /* resolution succeeds */
273 : #ifdef RESOLVE_VERBOSE
274 : printf(" success.\n");
275 : #endif
276 662905 : *result = cls;
277 662905 : return true;
278 : }
279 :
280 : /* resolve_classref ************************************************************
281 :
282 : Resolve a symbolic class reference
283 :
284 : IN:
285 : refmethod........the method from which resolution was triggered
286 : (may be NULL if not applicable)
287 : ref..............class reference
288 : mode.............mode of resolution:
289 : resolveLazy...only resolve if it does not
290 : require loading classes
291 : resolveEager..load classes if necessary
292 : checkaccess......if true, access rights to the class are checked
293 : link.............if true, guarantee that the returned class, if any,
294 : has been linked
295 :
296 : OUT:
297 : *result..........set to result of resolution, or to NULL if
298 : the reference has not been resolved
299 : In the case of an exception, *result is
300 : guaranteed to be set to NULL.
301 :
302 : RETURN VALUE:
303 : true.............everything ok
304 : (*result may still be NULL for resolveLazy)
305 : false............an exception has been thrown
306 :
307 : *******************************************************************************/
308 :
309 115612 : bool resolve_classref(methodinfo *refmethod,
310 : constant_classref *ref,
311 : resolve_mode_t mode,
312 : bool checkaccess,
313 : bool link,
314 : classinfo **result)
315 : {
316 115612 : return resolve_classref_or_classinfo(refmethod,to_classref_or_classinfo(ref),mode,checkaccess,link,result);
317 : }
318 :
319 : /* resolve_classref_or_classinfo ***********************************************
320 :
321 : Resolve a symbolic class reference if necessary
322 :
323 : NOTE: If given, refmethod->clazz is used as the referring class.
324 : Otherwise, cls.ref->referer is used.
325 :
326 : IN:
327 : refmethod........the method from which resolution was triggered
328 : (may be NULL if not applicable)
329 : cls..............class reference or classinfo
330 : mode.............mode of resolution:
331 : resolveLazy...only resolve if it does not
332 : require loading classes
333 : resolveEager..load classes if necessary
334 : checkaccess......if true, access rights to the class are checked
335 : link.............if true, guarantee that the returned class, if any,
336 : has been linked
337 :
338 : OUT:
339 : *result..........set to result of resolution, or to NULL if
340 : the reference has not been resolved
341 : In the case of an exception, *result is
342 : guaranteed to be set to NULL.
343 :
344 : RETURN VALUE:
345 : true.............everything ok
346 : (*result may still be NULL for resolveLazy)
347 : false............an exception has been thrown
348 :
349 : *******************************************************************************/
350 :
351 706438 : bool resolve_classref_or_classinfo(methodinfo *refmethod,
352 : classref_or_classinfo cls,
353 : resolve_mode_t mode,
354 : bool checkaccess,
355 : bool link,
356 : classinfo **result)
357 : {
358 : classinfo *c;
359 : classinfo *referer;
360 :
361 706438 : assert(cls.any);
362 706438 : assert(mode == resolveEager || mode == resolveLazy);
363 706438 : assert(result);
364 :
365 : #ifdef RESOLVE_VERBOSE
366 : printf("resolve_classref_or_classinfo(");
367 : utf_fprint_printable_ascii(stdout, CLASSREF_OR_CLASSINFO_NAME(cls));
368 : printf(",%i,%i,%i)\n",mode,(int)checkaccess,(int)link);
369 : #endif
370 :
371 706438 : *result = NULL;
372 :
373 706438 : if (cls.is_classref()) {
374 : /* we must resolve this reference */
375 :
376 : /* determine which class to use as the referer */
377 :
378 : /* Common cases are refmethod == NULL or both referring classes */
379 : /* being the same, so the referer usually is cls.ref->referer. */
380 : /* There is one important case where it is not: When we do a */
381 : /* deferred assignability check to a formal argument of a method, */
382 : /* we must use refmethod->clazz (the caller's class) to resolve */
383 : /* the type of the formal argument. */
384 :
385 580616 : referer = (refmethod) ? refmethod->clazz : cls.ref->referer;
386 :
387 580616 : if (!resolve_class_from_name(referer, refmethod, cls.ref->name,
388 : mode, checkaccess, link, &c))
389 25 : goto return_exception;
390 :
391 : } else {
392 : /* cls has already been resolved */
393 125822 : c = cls.cls;
394 125822 : assert(c->state & CLASS_LOADED);
395 : }
396 706413 : assert(c || (mode == resolveLazy));
397 :
398 706413 : if (!c)
399 138154 : return true; /* be lazy */
400 :
401 568259 : assert(c);
402 568259 : assert(c->state & CLASS_LOADED);
403 :
404 568259 : if (link) {
405 509333 : if (!(c->state & CLASS_LINKED))
406 0 : if (!link_class(c))
407 0 : goto return_exception;
408 :
409 509333 : assert(c->state & CLASS_LINKED);
410 : }
411 :
412 : /* succeeded */
413 568259 : *result = c;
414 568259 : return true;
415 :
416 : return_exception:
417 25 : *result = NULL;
418 25 : return false;
419 : }
420 :
421 :
422 : /* resolve_classref_or_classinfo_eager *****************************************
423 :
424 : Resolve a symbolic class reference eagerly if necessary.
425 : No attempt is made to link the class.
426 :
427 : IN:
428 : cls..............class reference or classinfo
429 : checkaccess......if true, access rights to the class are checked
430 :
431 : RETURN VALUE:
432 : classinfo *......the resolved class
433 : NULL.............an exception has been thrown
434 :
435 : *******************************************************************************/
436 :
437 56108 : classinfo *resolve_classref_or_classinfo_eager(classref_or_classinfo cls,
438 : bool checkaccess)
439 : {
440 : classinfo *c;
441 :
442 56108 : if (!resolve_classref_or_classinfo(NULL, cls, resolveEager, checkaccess, false, &c))
443 2 : return NULL;
444 :
445 56106 : return c;
446 : }
447 :
448 :
449 : /* resolve_class_from_typedesc *************************************************
450 :
451 : Return a classinfo * for the given type descriptor
452 :
453 : IN:
454 : d................type descriptor
455 : checkaccess......if true, access rights to the class are checked
456 : link.............if true, guarantee that the returned class, if any,
457 : has been linked
458 : OUT:
459 : *result..........set to result of resolution, or to NULL if
460 : the reference has not been resolved
461 : In the case of an exception, *result is
462 : guaranteed to be set to NULL.
463 :
464 : RETURN VALUE:
465 : true.............everything ok
466 : false............an exception has been thrown
467 :
468 : NOTE:
469 : This function always resolves eagerly.
470 :
471 : *******************************************************************************/
472 :
473 1910 : bool resolve_class_from_typedesc(typedesc *d, bool checkaccess, bool link, classinfo **result)
474 : {
475 : classinfo *cls;
476 :
477 1910 : assert(d);
478 1910 : assert(result);
479 :
480 1910 : *result = NULL;
481 :
482 : #ifdef RESOLVE_VERBOSE
483 : printf("resolve_class_from_typedesc(");
484 : descriptor_debug_print_typedesc(stdout,d);
485 : printf(",%i,%i)\n",(int)checkaccess,(int)link);
486 : #endif
487 :
488 1910 : if (d->type == TYPE_ADR) {
489 : /* a reference type */
490 1517 : assert(d->classref);
491 1517 : if (!resolve_classref_or_classinfo(NULL,to_classref_or_classinfo(d->classref),
492 : resolveEager,checkaccess,link,&cls))
493 0 : return false; /* exception */
494 : }
495 : else {
496 : /* a primitive type */
497 :
498 393 : cls = Primitive::get_class_by_type(d->primitivetype);
499 :
500 393 : assert(cls->state & CLASS_LOADED);
501 :
502 393 : if (!(cls->state & CLASS_LINKED))
503 0 : if (!link_class(cls))
504 0 : return false; /* exception */
505 : }
506 :
507 1910 : assert(cls);
508 1910 : assert(cls->state & CLASS_LOADED);
509 1910 : assert(!link || (cls->state & CLASS_LINKED));
510 :
511 : #ifdef RESOLVE_VERBOSE
512 : printf(" result = ");utf_fprint_printable_ascii(stdout,cls->name);printf("\n");
513 : #endif
514 :
515 1910 : *result = cls;
516 1910 : return true;
517 : }
518 :
519 : /******************************************************************************/
520 : /* SUBTYPE SET CHECKS */
521 : /******************************************************************************/
522 :
523 : /* resolve_subtype_check *******************************************************
524 :
525 : Resolve the given types lazily and perform a subtype check
526 :
527 : IN:
528 : refmethod........the method triggering the resolution
529 : subtype..........checked to be a subtype of supertype
530 : supertype........the super type to check agaings
531 : mode.............mode of resolution:
532 : resolveLazy...only resolve if it does not
533 : require loading classes
534 : resolveEager..load classes if necessary
535 : error............which type of exception to throw if
536 : the test fails. May be:
537 : resolveLinkageError, or
538 : resolveIllegalAccessError
539 : IMPORTANT: If error==resolveIllegalAccessError,
540 : then array types are not checked.
541 :
542 : RETURN VALUE:
543 : resolveSucceeded.....the check succeeded
544 : resolveDeferred......the check could not be performed due to
545 : unresolved types. (This can only happen for
546 : mode == resolveLazy.)
547 : resolveFailed........the check failed, an exception has been thrown.
548 :
549 : NOTE:
550 : The types are resolved first, so any
551 : exception which may occurr during resolution may
552 : be thrown by this function.
553 :
554 : *******************************************************************************/
555 :
556 : #if defined(ENABLE_VERIFIER)
557 55839 : static resolve_result_t resolve_subtype_check(methodinfo *refmethod,
558 : classref_or_classinfo subtype,
559 : classref_or_classinfo supertype,
560 : resolve_mode_t mode,
561 : resolve_err_t error)
562 : {
563 : classinfo *subclass;
564 : typeinfo_t subti;
565 : typecheck_result r;
566 :
567 55839 : assert(refmethod);
568 55839 : assert(subtype.any);
569 55839 : assert(supertype.any);
570 55839 : assert(mode == resolveLazy || mode == resolveEager);
571 55839 : assert(error == resolveLinkageError || error == resolveIllegalAccessError);
572 :
573 : /* resolve the subtype */
574 :
575 55839 : if (!resolve_classref_or_classinfo(refmethod,subtype,mode,false,true,&subclass)) {
576 : /* the subclass could not be resolved. therefore we are sure that */
577 : /* no instances of this subclass will ever exist -> skip this test */
578 : /* XXX this assumes that class loading has invariant results (as in JVM spec) */
579 22 : exceptions_clear_exception();
580 22 : return resolveSucceeded;
581 : }
582 55817 : if (!subclass)
583 7829 : return resolveDeferred; /* be lazy */
584 :
585 47988 : assert(subclass->state & CLASS_LINKED);
586 :
587 : /* do not check access to protected members of arrays */
588 :
589 47988 : if (error == resolveIllegalAccessError && subclass->name[0] == '[') {
590 0 : return resolveSucceeded;
591 : }
592 :
593 : /* perform the subtype check */
594 :
595 47988 : subti.init_class(subclass);
596 : check_again:
597 47988 : r = subti.is_assignable_to_class(supertype);
598 47988 : if (r == typecheck_FAIL)
599 0 : return resolveFailed; /* failed, exception is already set */
600 :
601 47988 : if (r == typecheck_MAYBE) {
602 3291 : assert(supertype.is_classref());
603 3291 : if (mode == resolveEager) {
604 0 : if (!resolve_classref_or_classinfo(refmethod,supertype,
605 : resolveEager,false,true,
606 : &supertype.cls))
607 : {
608 0 : return resolveFailed;
609 : }
610 0 : assert(supertype.cls);
611 0 : goto check_again;
612 : }
613 :
614 3291 : return resolveDeferred; /* be lazy */
615 : }
616 :
617 44697 : if (!r) {
618 : /* sub class relationship is false */
619 :
620 : #if defined(RESOLVE_VERBOSE)
621 : printf("SUBTYPE CHECK FAILED!\n");
622 : #endif
623 5 : Buffer<> buf;
624 :
625 5 : if (error == resolveIllegalAccessError)
626 0 : buf.write("illegal access to protected member (");
627 : else
628 5 : buf.write("subtype constraint violated (");
629 :
630 : buf.write_slash_to_dot(subclass->name)
631 : .write(" is not a subclass of ")
632 : .write_slash_to_dot(CLASSREF_OR_CLASSINFO_NAME(supertype))
633 5 : .write(')');
634 :
635 5 : if (error == resolveIllegalAccessError)
636 0 : exceptions_throw_illegalaccessexception(buf.utf8_str());
637 : else
638 5 : exceptions_throw_linkageerror(buf.c_str(), NULL);
639 :
640 5 : return resolveFailed; /* exception */
641 : }
642 :
643 : /* everything ok */
644 :
645 44692 : return resolveSucceeded;
646 : }
647 : #endif /* defined(ENABLE_VERIFIER) */
648 :
649 : /* resolve_lazy_subtype_checks *************************************************
650 :
651 : Resolve the types to check lazily and perform subtype checks
652 :
653 : IN:
654 : refmethod........the method triggering the resolution
655 : subtinfo.........the typeinfo containing the subtypes
656 : supertype........the supertype to test againgst
657 : mode.............mode of resolution:
658 : resolveLazy...only resolve if it does not
659 : require loading classes
660 : resolveEager..load classes if necessary
661 : error............which type of exception to throw if
662 : the test fails. May be:
663 : resolveLinkageError, or
664 : resolveIllegalAccessError
665 : IMPORTANT: If error==resolveIllegalAccessError,
666 : then array types in the set are skipped.
667 :
668 : RETURN VALUE:
669 : resolveSucceeded.....the check succeeded
670 : resolveDeferred......the check could not be performed due to
671 : unresolved types
672 : resolveFailed........the check failed, an exception has been thrown.
673 :
674 : NOTE:
675 : The references in the set are resolved first, so any
676 : exception which may occurr during resolution may
677 : be thrown by this function.
678 :
679 : *******************************************************************************/
680 :
681 : #if defined(ENABLE_VERIFIER)
682 535567 : static resolve_result_t resolve_lazy_subtype_checks(methodinfo *refmethod,
683 : typeinfo_t *subtinfo,
684 : classref_or_classinfo supertype,
685 : resolve_err_t error)
686 : {
687 : int count;
688 : int i;
689 : resolve_result_t result;
690 :
691 535567 : assert(refmethod);
692 535567 : assert(subtinfo);
693 535567 : assert(supertype.any);
694 535567 : assert(error == resolveLinkageError || error == resolveIllegalAccessError);
695 :
696 : /* returnAddresses are illegal here */
697 :
698 535567 : if (subtinfo->is_primitive()) {
699 : exceptions_throw_verifyerror(refmethod,
700 0 : "Invalid use of returnAddress");
701 0 : return resolveFailed;
702 : }
703 :
704 : /* uninitialized objects are illegal here */
705 :
706 535567 : if (subtinfo->is_newobject()) {
707 : exceptions_throw_verifyerror(refmethod,
708 0 : "Invalid use of uninitialized object");
709 0 : return resolveFailed;
710 : }
711 :
712 : /* the nulltype is always assignable */
713 :
714 535567 : if (subtinfo->is_nulltype())
715 8528 : return resolveSucceeded;
716 :
717 : /* every type is assignable to (BOOTSTRAP)java.lang.Object */
718 :
719 527039 : if (supertype.cls == class_java_lang_Object
720 : || (CLASSREF_OR_CLASSINFO_NAME(supertype) == utf8::java_lang_Object
721 : && refmethod->clazz->classloader == NULL))
722 : {
723 41362 : return resolveSucceeded;
724 : }
725 :
726 485677 : if (subtinfo->merged) {
727 :
728 : /* for a merged type we have to do a series of checks */
729 :
730 357 : count = subtinfo->merged->count;
731 687 : for (i=0; i<count; ++i) {
732 687 : classref_or_classinfo c = subtinfo->merged->list[i];
733 687 : if (subtinfo->dimension > 0) {
734 : /* a merge of array types */
735 : /* the merged list contains the possible _element_ types, */
736 : /* so we have to create array types with these elements. */
737 0 : if (c.is_classref()) {
738 0 : c.ref = class_get_classref_multiarray_of(subtinfo->dimension,c.ref);
739 : }
740 : else {
741 0 : c.cls = class_multiarray_of(subtinfo->dimension,c.cls,false);
742 : }
743 : }
744 :
745 : /* do the subtype check against the type c */
746 :
747 687 : result = resolve_subtype_check(refmethod,c,supertype,resolveLazy,error);
748 687 : if (result != resolveSucceeded)
749 357 : return result;
750 : }
751 : }
752 : else {
753 :
754 : /* a single type, this is the common case, hopefully */
755 :
756 485320 : if (CLASSREF_OR_CLASSINFO_NAME(subtinfo->typeclass)
757 : == CLASSREF_OR_CLASSINFO_NAME(supertype))
758 : {
759 : /* the class names are the same */
760 : /* equality is guaranteed by the loading constraints */
761 444955 : return resolveSucceeded;
762 : }
763 : else {
764 :
765 : /* some other type name, try to perform the check lazily */
766 :
767 : return resolve_subtype_check(refmethod,
768 : subtinfo->typeclass,supertype,
769 : resolveLazy,
770 40365 : error);
771 : }
772 : }
773 :
774 : /* everything ok */
775 0 : return resolveSucceeded;
776 : }
777 : #endif /* defined(ENABLE_VERIFIER) */
778 :
779 : /* resolve_and_check_subtype_set ***********************************************
780 :
781 : Resolve the references in the given set and test subtype relationships
782 :
783 : IN:
784 : refmethod........the method triggering the resolution
785 : ref..............a set of class/interface references
786 : (may be empty)
787 : typeref..........the type to test against the set
788 : mode.............mode of resolution:
789 : resolveLazy...only resolve if it does not
790 : require loading classes
791 : resolveEager..load classes if necessary
792 : error............which type of exception to throw if
793 : the test fails. May be:
794 : resolveLinkageError, or
795 : resolveIllegalAccessError
796 : IMPORTANT: If error==resolveIllegalAccessError,
797 : then array types in the set are skipped.
798 :
799 : RETURN VALUE:
800 : resolveSucceeded.....the check succeeded
801 : resolveDeferred......the check could not be performed due to
802 : unresolved types. (This can only happen if
803 : mode == resolveLazy.)
804 : resolveFailed........the check failed, an exception has been thrown.
805 :
806 : NOTE:
807 : The references in the set are resolved first, so any
808 : exception which may occurr during resolution may
809 : be thrown by this function.
810 :
811 : *******************************************************************************/
812 :
813 : #if defined(ENABLE_VERIFIER)
814 59049 : static resolve_result_t resolve_and_check_subtype_set(methodinfo *refmethod,
815 : unresolved_subtype_set *ref,
816 : classref_or_classinfo typeref,
817 : resolve_mode_t mode,
818 : resolve_err_t error)
819 : {
820 : classref_or_classinfo *setp;
821 : resolve_result_t checkresult;
822 :
823 59049 : assert(refmethod);
824 59049 : assert(ref);
825 59049 : assert(typeref.any);
826 59049 : assert(mode == resolveLazy || mode == resolveEager);
827 59049 : assert(error == resolveLinkageError || error == resolveIllegalAccessError);
828 :
829 : #if defined(RESOLVE_VERBOSE)
830 : printf("resolve_and_check_subtype_set:\n");
831 : unresolved_subtype_set_debug_dump(ref, stdout);
832 : if (typeref.is_classref())
833 : class_classref_println(typeref.ref);
834 : else
835 : class_println(typeref.cls);
836 : #endif
837 :
838 59049 : setp = ref->subtyperefs;
839 :
840 : /* an empty set of tests always succeeds */
841 59049 : if (!setp || !setp->any) {
842 45589 : return resolveSucceeded;
843 : }
844 :
845 : /* first resolve the type if necessary */
846 13460 : if (!resolve_classref_or_classinfo(refmethod,typeref,mode,false,true,&(typeref.cls)))
847 0 : return resolveFailed; /* exception */
848 13460 : if (!typeref.cls)
849 0 : return resolveDeferred; /* be lazy */
850 :
851 13460 : assert(typeref.cls->state & CLASS_LINKED);
852 :
853 : /* iterate over the set members */
854 :
855 28242 : for (; setp->any; ++setp) {
856 14787 : checkresult = resolve_subtype_check(refmethod,*setp,typeref,mode,error);
857 : #if defined(RESOLVE_VERBOSE)
858 : if (checkresult != resolveSucceeded)
859 : printf("SUBTYPE CHECK FAILED!\n");
860 : #endif
861 14787 : if (checkresult != resolveSucceeded)
862 5 : return checkresult;
863 : }
864 :
865 : /* check succeeds */
866 13455 : return resolveSucceeded;
867 : }
868 : #endif /* defined(ENABLE_VERIFIER) */
869 :
870 : /******************************************************************************/
871 : /* CLASS RESOLUTION */
872 : /******************************************************************************/
873 :
874 : /* resolve_class ***************************************************************
875 :
876 : Resolve an unresolved class reference. The class is also linked.
877 :
878 : IN:
879 : ref..............struct containing the reference
880 : mode.............mode of resolution:
881 : resolveLazy...only resolve if it does not
882 : require loading classes
883 : resolveEager..load classes if necessary
884 : checkaccess......if true, access rights to the class are checked
885 :
886 : OUT:
887 : *result..........set to the result of resolution, or to NULL if
888 : the reference has not been resolved
889 : In the case of an exception, *result is
890 : guaranteed to be set to NULL.
891 :
892 : RETURN VALUE:
893 : true.............everything ok
894 : (*result may still be NULL for resolveLazy)
895 : false............an exception has been thrown
896 :
897 : *******************************************************************************/
898 :
899 : #ifdef ENABLE_VERIFIER
900 2990 : bool resolve_class(unresolved_class *ref,
901 : resolve_mode_t mode,
902 : bool checkaccess,
903 : classinfo **result)
904 : {
905 : classinfo *cls;
906 : resolve_result_t checkresult;
907 :
908 2990 : assert(ref);
909 2990 : assert(result);
910 2990 : assert(mode == resolveLazy || mode == resolveEager);
911 :
912 2990 : *result = NULL;
913 :
914 : #ifdef RESOLVE_VERBOSE
915 : unresolved_class_debug_dump(ref,stdout);
916 : #endif
917 :
918 : /* first we must resolve the class */
919 2990 : if (!resolve_classref(ref->referermethod,
920 : ref->classref,mode,checkaccess,true,&cls))
921 : {
922 : /* the class reference could not be resolved */
923 0 : return false; /* exception */
924 : }
925 2990 : if (!cls)
926 0 : return true; /* be lazy */
927 :
928 2990 : assert(cls);
929 2990 : assert((cls->state & CLASS_LOADED) && (cls->state & CLASS_LINKED));
930 :
931 : /* now we check the subtype constraints */
932 :
933 : checkresult = resolve_and_check_subtype_set(ref->referermethod,
934 : &(ref->subtypeconstraints),
935 : to_classref_or_classinfo(cls),
936 : mode,
937 2990 : resolveLinkageError);
938 2990 : if (checkresult != resolveSucceeded)
939 3 : return (bool) checkresult;
940 :
941 : /* succeed */
942 2987 : *result = cls;
943 2987 : return true;
944 : }
945 : #endif /* ENABLE_VERIFIER */
946 :
947 : /* resolve_classref_eager ******************************************************
948 :
949 : Resolve an unresolved class reference eagerly. The class is also linked and
950 : access rights to the class are checked.
951 :
952 : IN:
953 : ref..............constant_classref to the class
954 :
955 : RETURN VALUE:
956 : classinfo * to the class, or
957 : NULL if an exception has been thrown
958 :
959 : *******************************************************************************/
960 :
961 15398 : classinfo * resolve_classref_eager(constant_classref *ref)
962 : {
963 : classinfo *c;
964 :
965 15398 : if (!resolve_classref(NULL,ref,resolveEager,true,true,&c))
966 1 : return NULL;
967 :
968 15397 : return c;
969 : }
970 :
971 : /* resolve_classref_eager_nonabstract ******************************************
972 :
973 : Resolve an unresolved class reference eagerly. The class is also linked and
974 : access rights to the class are checked. A check is performed that the class
975 : is not abstract.
976 :
977 : IN:
978 : ref..............constant_classref to the class
979 :
980 : RETURN VALUE:
981 : classinfo * to the class, or
982 : NULL if an exception has been thrown
983 :
984 : *******************************************************************************/
985 :
986 0 : classinfo * resolve_classref_eager_nonabstract(constant_classref *ref)
987 : {
988 : classinfo *c;
989 :
990 0 : if (!resolve_classref(NULL,ref,resolveEager,true,true,&c))
991 0 : return NULL;
992 :
993 : /* ensure that the class is not abstract */
994 :
995 0 : if (c->flags & ACC_ABSTRACT) {
996 0 : exceptions_throw_verifyerror(NULL,"creating instance of abstract class");
997 0 : return NULL;
998 : }
999 :
1000 0 : return c;
1001 : }
1002 :
1003 : /* resolve_class_eager *********************************************************
1004 :
1005 : Resolve an unresolved class reference eagerly. The class is also linked and
1006 : access rights to the class are checked.
1007 :
1008 : IN:
1009 : ref..............struct containing the reference
1010 :
1011 : RETURN VALUE:
1012 : classinfo * to the class, or
1013 : NULL if an exception has been thrown
1014 :
1015 : *******************************************************************************/
1016 :
1017 : #ifdef ENABLE_VERIFIER
1018 0 : classinfo * resolve_class_eager(unresolved_class *ref)
1019 : {
1020 : classinfo *c;
1021 :
1022 0 : if (!resolve_class(ref,resolveEager,true,&c))
1023 0 : return NULL;
1024 :
1025 0 : return c;
1026 : }
1027 : #endif /* ENABLE_VERIFIER */
1028 :
1029 : /* resolve_class_eager_no_access_check *****************************************
1030 :
1031 : Resolve an unresolved class reference eagerly. The class is also linked.
1032 : Access rights are _not_ checked.
1033 :
1034 : IN:
1035 : ref..............struct containing the reference
1036 :
1037 : RETURN VALUE:
1038 : classinfo * to the class, or
1039 : NULL if an exception has been thrown
1040 :
1041 : *******************************************************************************/
1042 :
1043 : #ifdef ENABLE_VERIFIER
1044 2990 : classinfo * resolve_class_eager_no_access_check(unresolved_class *ref)
1045 : {
1046 : classinfo *c;
1047 :
1048 2990 : if (!resolve_class(ref, resolveEager, false, &c))
1049 3 : return NULL;
1050 :
1051 2987 : return c;
1052 : }
1053 : #endif /* ENABLE_VERIFIER */
1054 :
1055 : /******************************************************************************/
1056 : /* FIELD RESOLUTION */
1057 : /******************************************************************************/
1058 :
1059 : /* resolve_field_verifier_checks *******************************************
1060 :
1061 : Do the verifier checks necessary after field has been resolved.
1062 :
1063 : IN:
1064 : refmethod........the method containing the reference
1065 : fieldref.........the field reference
1066 : container........the class where the field was found
1067 : fi...............the fieldinfo of the resolved field
1068 : instanceti.......instance typeinfo, if available
1069 : valueti..........value typeinfo, if available
1070 : isstatic.........true if this is a *STATIC* instruction
1071 : isput............true if this is a PUT* instruction
1072 :
1073 : RETURN VALUE:
1074 : resolveSucceeded....everything ok
1075 : resolveDeferred.....tests could not be done, have been deferred
1076 : resolveFailed.......exception has been thrown
1077 :
1078 : *******************************************************************************/
1079 :
1080 : #if defined(ENABLE_VERIFIER)
1081 224523 : resolve_result_t resolve_field_verifier_checks(methodinfo *refmethod,
1082 : constant_FMIref *fieldref,
1083 : classinfo *container,
1084 : fieldinfo *fi,
1085 : typeinfo_t *instanceti,
1086 : typeinfo_t *valueti,
1087 : bool isstatic,
1088 : bool isput)
1089 : {
1090 : classinfo *declarer;
1091 : classinfo *referer;
1092 : resolve_result_t result;
1093 : constant_classref *fieldtyperef;
1094 :
1095 224523 : assert(refmethod);
1096 224523 : assert(fieldref);
1097 224523 : assert(container);
1098 224523 : assert(fi);
1099 :
1100 : /* get the classinfos and the field type */
1101 :
1102 224523 : referer = refmethod->clazz;
1103 224523 : assert(referer);
1104 :
1105 224523 : declarer = fi->clazz;
1106 224523 : assert(declarer);
1107 224523 : assert(referer->state & CLASS_LINKED);
1108 :
1109 224523 : fieldtyperef = fieldref->parseddesc.fd->classref;
1110 :
1111 : /* check static */
1112 :
1113 : #if true != 1
1114 : #error This code assumes that `true` is `1`. Otherwise, use the ternary operator below.
1115 : #endif
1116 :
1117 224523 : if (((fi->flags & ACC_STATIC) != 0) != isstatic) {
1118 : /* a static field is accessed via an instance, or vice versa */
1119 : exceptions_throw_incompatibleclasschangeerror(declarer,
1120 : (fi->flags & ACC_STATIC)
1121 : ? "static field accessed via instance"
1122 0 : : "instance field accessed without instance");
1123 :
1124 0 : return resolveFailed;
1125 : }
1126 :
1127 : /* check access rights */
1128 :
1129 224523 : if (!access_is_accessible_member(referer,declarer,fi->flags)) {
1130 0 : Buffer<> buf(64);
1131 :
1132 : Utf8String u = buf.write("field is not accessible (")
1133 : .write_slash_to_dot(declarer->name)
1134 : .write(".")
1135 : .write(fi->name)
1136 : .write(" from ")
1137 : .write_slash_to_dot(referer->name)
1138 : .write(")")
1139 0 : .utf8_str();
1140 :
1141 0 : exceptions_throw_illegalaccessexception(u);
1142 :
1143 0 : return resolveFailed; /* exception */
1144 : }
1145 :
1146 : /* for non-static methods we have to check the constraints on the */
1147 : /* instance type */
1148 :
1149 224523 : if (instanceti) {
1150 : typeinfo_t *insttip;
1151 : typeinfo_t tinfo;
1152 :
1153 : /* The instanceslot must contain a reference to a non-array type */
1154 :
1155 152771 : if (!instanceti->is_reference()) {
1156 0 : exceptions_throw_verifyerror(refmethod, "illegal instruction: field access on non-reference");
1157 0 : return resolveFailed;
1158 : }
1159 152771 : if (instanceti->is_array()) {
1160 0 : exceptions_throw_verifyerror(refmethod, "illegal instruction: field access on array");
1161 0 : return resolveFailed;
1162 : }
1163 :
1164 152771 : if (isput && instanceti->is_newobject())
1165 : {
1166 : /* The instruction writes a field in an uninitialized object. */
1167 : /* This is only allowed when a field of an uninitialized 'this' object is */
1168 : /* written inside an initialization method */
1169 :
1170 : classinfo *initclass;
1171 1502 : instruction *ins = instanceti->newobject_instruction();
1172 :
1173 1502 : if (ins != NULL) {
1174 0 : exceptions_throw_verifyerror(refmethod, "accessing field of uninitialized object");
1175 0 : return resolveFailed;
1176 : }
1177 :
1178 : /* XXX check that class of field == refmethod->clazz */
1179 1502 : initclass = referer; /* XXX classrefs */
1180 1502 : assert(initclass->state & CLASS_LINKED);
1181 :
1182 1502 : tinfo.init_class(initclass);
1183 1502 : insttip = &tinfo;
1184 : }
1185 : else {
1186 151269 : insttip = instanceti;
1187 : }
1188 :
1189 : result = resolve_lazy_subtype_checks(refmethod,
1190 : insttip,
1191 : to_classref_or_classinfo(container),
1192 152771 : resolveLinkageError);
1193 152771 : if (result != resolveSucceeded)
1194 144 : return result;
1195 :
1196 : /* check protected access */
1197 :
1198 152627 : if (((fi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer))
1199 : {
1200 : result = resolve_lazy_subtype_checks(refmethod,
1201 : instanceti,
1202 : to_classref_or_classinfo(referer),
1203 172 : resolveIllegalAccessError);
1204 172 : if (result != resolveSucceeded)
1205 0 : return result;
1206 : }
1207 :
1208 : }
1209 :
1210 : /* for PUT* instructions we have to check the constraints on the value type */
1211 :
1212 224379 : if (valueti) {
1213 48516 : assert(fieldtyperef);
1214 :
1215 : /* check subtype constraints */
1216 : result = resolve_lazy_subtype_checks(refmethod,
1217 : valueti,
1218 : to_classref_or_classinfo(fieldtyperef),
1219 48516 : resolveLinkageError);
1220 :
1221 48516 : if (result != resolveSucceeded)
1222 1610 : return result;
1223 : }
1224 :
1225 : /* impose loading constraint on field type */
1226 :
1227 222769 : if (fi->type == TYPE_ADR) {
1228 149367 : assert(fieldtyperef);
1229 149367 : if (!classcache_add_constraint(declarer->classloader,
1230 : referer->classloader,
1231 : fieldtyperef->name))
1232 0 : return resolveFailed;
1233 : }
1234 :
1235 : /* XXX impose loading constraint on instance? */
1236 :
1237 : /* everything ok */
1238 222769 : return resolveSucceeded;
1239 : }
1240 : #endif /* defined(ENABLE_VERIFIER) */
1241 :
1242 : /* resolve_field_lazy **********************************************************
1243 :
1244 : Resolve an unresolved field reference lazily
1245 :
1246 : NOTE: This function does NOT do any verification checks. In case of a
1247 : successful resolution, you must call resolve_field_verifier_checks
1248 : in order to perform the necessary checks!
1249 :
1250 : IN:
1251 : refmethod........the referer method
1252 : fieldref.........the field reference
1253 :
1254 : RETURN VALUE:
1255 : resolveSucceeded.....the reference has been resolved
1256 : resolveDeferred......the resolving could not be performed lazily
1257 : resolveFailed........resolving failed, an exception has been thrown.
1258 :
1259 : *******************************************************************************/
1260 :
1261 225545 : resolve_result_t resolve_field_lazy(methodinfo *refmethod,
1262 : constant_FMIref *fieldref)
1263 : {
1264 : classinfo *referer;
1265 : classinfo *container;
1266 : fieldinfo *fi;
1267 :
1268 225545 : assert(refmethod);
1269 :
1270 : /* the class containing the reference */
1271 :
1272 225545 : referer = refmethod->clazz;
1273 225545 : assert(referer);
1274 :
1275 : /* check if the field itself is already resolved */
1276 :
1277 225545 : if (fieldref->is_resolved())
1278 140766 : return resolveSucceeded;
1279 :
1280 : /* first we must resolve the class containg the field */
1281 :
1282 : /* XXX can/may lazyResolving trigger linking? */
1283 :
1284 84779 : if (!resolve_class_from_name(referer, refmethod,
1285 : fieldref->p.classref->name, resolveLazy, true, true, &container))
1286 : {
1287 : /* the class reference could not be resolved */
1288 0 : return resolveFailed; /* exception */
1289 : }
1290 84779 : if (!container)
1291 19840 : return resolveDeferred; /* be lazy */
1292 :
1293 64939 : assert(container->state & CLASS_LINKED);
1294 :
1295 : /* now we must find the declaration of the field in `container`
1296 : * or one of its superclasses */
1297 :
1298 : fi = class_resolvefield(container,
1299 : fieldref->name, fieldref->descriptor,
1300 64939 : referer);
1301 64939 : if (!fi) {
1302 : /* The field does not exist. But since we were called lazily, */
1303 : /* this error must not be reported now. (It will be reported */
1304 : /* if eager resolving of this field is ever tried.) */
1305 :
1306 2 : exceptions_clear_exception();
1307 2 : return resolveDeferred; /* be lazy */
1308 : }
1309 :
1310 : /* cache the result of the resolution */
1311 :
1312 64937 : fieldref->p.field = fi;
1313 :
1314 : /* everything ok */
1315 64937 : return resolveSucceeded;
1316 : }
1317 :
1318 : /* resolve_field ***************************************************************
1319 :
1320 : Resolve an unresolved field reference
1321 :
1322 : IN:
1323 : ref..............struct containing the reference
1324 : mode.............mode of resolution:
1325 : resolveLazy...only resolve if it does not
1326 : require loading classes
1327 : resolveEager..load classes if necessary
1328 :
1329 : OUT:
1330 : *result..........set to the result of resolution, or to NULL if
1331 : the reference has not been resolved
1332 : In the case of an exception, *result is
1333 : guaranteed to be set to NULL.
1334 :
1335 : RETURN VALUE:
1336 : true.............everything ok
1337 : (*result may still be NULL for resolveLazy)
1338 : false............an exception has been thrown
1339 :
1340 : *******************************************************************************/
1341 :
1342 18822 : bool resolve_field(unresolved_field *ref,
1343 : resolve_mode_t mode,
1344 : fieldinfo **result)
1345 : {
1346 : classinfo *referer;
1347 : classinfo *container;
1348 : fieldinfo *fi;
1349 :
1350 18822 : assert(ref);
1351 18822 : assert(result);
1352 18822 : assert(mode == resolveLazy || mode == resolveEager);
1353 :
1354 18822 : *result = NULL;
1355 :
1356 : #ifdef RESOLVE_VERBOSE
1357 : unresolved_field_debug_dump(ref,stdout);
1358 : #endif
1359 :
1360 : /* the class containing the reference */
1361 :
1362 18822 : referer = ref->referermethod->clazz;
1363 18822 : assert(referer);
1364 :
1365 : /* check if the field itself is already resolved */
1366 18822 : if (ref->fieldref->is_resolved()) {
1367 16102 : fi = ref->fieldref->p.field;
1368 16102 : container = fi->clazz;
1369 16102 : goto resolved_the_field;
1370 : }
1371 :
1372 : /* first we must resolve the class containg the field */
1373 2720 : if (!resolve_class_from_name(referer,ref->referermethod,
1374 : ref->fieldref->p.classref->name,mode,true,true,&container))
1375 : {
1376 : /* the class reference could not be resolved */
1377 0 : return false; /* exception */
1378 : }
1379 2720 : if (!container)
1380 0 : return true; /* be lazy */
1381 :
1382 2720 : assert(container);
1383 2720 : assert(container->state & CLASS_LOADED);
1384 2720 : assert(container->state & CLASS_LINKED);
1385 :
1386 : /* now we must find the declaration of the field in `container`
1387 : * or one of its superclasses */
1388 :
1389 : #ifdef RESOLVE_VERBOSE
1390 : printf(" resolving field in class...\n");
1391 : #endif
1392 :
1393 : fi = class_resolvefield(container,
1394 : ref->fieldref->name,ref->fieldref->descriptor,
1395 2720 : referer);
1396 2720 : if (!fi) {
1397 2 : if (mode == resolveLazy) {
1398 : /* The field does not exist. But since we were called lazily, */
1399 : /* this error must not be reported now. (It will be reported */
1400 : /* if eager resolving of this field is ever tried.) */
1401 :
1402 0 : exceptions_clear_exception();
1403 0 : return true; /* be lazy */
1404 : }
1405 :
1406 2 : return false; /* exception */
1407 : }
1408 :
1409 : /* cache the result of the resolution */
1410 2718 : ref->fieldref->p.field = fi;
1411 :
1412 : resolved_the_field:
1413 :
1414 : #ifdef ENABLE_VERIFIER
1415 : /* Checking opt_verify is ok here, because the NULL iptr guarantees */
1416 : /* that no missing parts of an instruction will be accessed. */
1417 18820 : if (opt_verify) {
1418 : resolve_result_t checkresult = resolve_field_verifier_checks(
1419 : ref->referermethod,
1420 : ref->fieldref,
1421 : container,
1422 : fi,
1423 : NULL, /* instanceti, handled by constraints below */
1424 : NULL, /* valueti, handled by constraints below */
1425 : (ref->flags & RESOLVE_STATIC) != 0, /* isstatic */
1426 18820 : (ref->flags & RESOLVE_PUTFIELD) != 0 /* isput */);
1427 :
1428 18820 : if (checkresult != resolveSucceeded)
1429 0 : return (bool) checkresult;
1430 :
1431 18820 : classinfo *declarer = fi->clazz;
1432 18820 : assert(declarer);
1433 18820 : assert(declarer->state & CLASS_LOADED);
1434 18820 : assert(declarer->state & CLASS_LINKED);
1435 :
1436 : /* for non-static accesses we have to check the constraints on the */
1437 : /* instance type */
1438 :
1439 18820 : if (!(ref->flags & RESOLVE_STATIC)) {
1440 : checkresult = resolve_and_check_subtype_set(ref->referermethod,
1441 : &(ref->instancetypes),
1442 : to_classref_or_classinfo(container),
1443 650 : mode, resolveLinkageError);
1444 650 : if (checkresult != resolveSucceeded)
1445 0 : return (bool) checkresult;
1446 : }
1447 :
1448 18820 : constant_classref *fieldtyperef = ref->fieldref->parseddesc.fd->classref;
1449 :
1450 : /* for PUT* instructions we have to check the constraints on the value type */
1451 18820 : if (((ref->flags & RESOLVE_PUTFIELD) != 0) && fi->type == TYPE_ADR) {
1452 1587 : assert(fieldtyperef);
1453 1587 : if (!SUBTYPESET_IS_EMPTY(ref->valueconstraints)) {
1454 : /* check subtype constraints */
1455 : checkresult = resolve_and_check_subtype_set(ref->referermethod,
1456 : &(ref->valueconstraints),
1457 : to_classref_or_classinfo(fieldtyperef),
1458 1561 : mode, resolveLinkageError);
1459 1561 : if (checkresult != resolveSucceeded)
1460 0 : return (bool) checkresult;
1461 : }
1462 : }
1463 :
1464 : /* check protected access */
1465 18820 : if (((fi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer)) {
1466 : checkresult = resolve_and_check_subtype_set(ref->referermethod,
1467 : &(ref->instancetypes),
1468 : to_classref_or_classinfo(referer),
1469 : mode,
1470 0 : resolveIllegalAccessError);
1471 0 : if (checkresult != resolveSucceeded)
1472 0 : return (bool) checkresult;
1473 : }
1474 :
1475 : }
1476 : #endif /* ENABLE_VERIFIER */
1477 :
1478 : /* succeed */
1479 18820 : *result = fi;
1480 :
1481 18820 : return true;
1482 : }
1483 :
1484 : /* resolve_field_eager *********************************************************
1485 :
1486 : Resolve an unresolved field reference eagerly.
1487 :
1488 : IN:
1489 : ref..............struct containing the reference
1490 :
1491 : RETURN VALUE:
1492 : fieldinfo * to the field, or
1493 : NULL if an exception has been thrown
1494 :
1495 : *******************************************************************************/
1496 :
1497 18822 : fieldinfo * resolve_field_eager(unresolved_field *ref)
1498 : {
1499 : fieldinfo *fi;
1500 :
1501 18822 : if (!resolve_field(ref,resolveEager,&fi))
1502 2 : return NULL;
1503 :
1504 18820 : return fi;
1505 : }
1506 :
1507 : /******************************************************************************/
1508 : /* METHOD RESOLUTION */
1509 : /******************************************************************************/
1510 :
1511 : /* resolve_method_invokespecial_lookup *****************************************
1512 :
1513 : Do the special lookup for methods invoked by INVOKESPECIAL
1514 :
1515 : IN:
1516 : refmethod........the method containing the reference
1517 : mi...............the methodinfo of the resolved method
1518 :
1519 : RETURN VALUE:
1520 : a methodinfo *...the result of the lookup,
1521 : NULL.............an exception has been thrown
1522 :
1523 : *******************************************************************************/
1524 :
1525 53296 : methodinfo * resolve_method_invokespecial_lookup(methodinfo *refmethod,
1526 : methodinfo *mi)
1527 : {
1528 : classinfo *declarer;
1529 : classinfo *referer;
1530 :
1531 53296 : assert(refmethod);
1532 53296 : assert(mi);
1533 :
1534 : /* get referer and declarer classes */
1535 :
1536 53296 : referer = refmethod->clazz;
1537 53296 : assert(referer);
1538 :
1539 53296 : declarer = mi->clazz;
1540 53296 : assert(declarer);
1541 53296 : assert(referer->state & CLASS_LINKED);
1542 :
1543 : /* checks for INVOKESPECIAL: */
1544 : /* for <init> and methods of the current class we don't need any */
1545 : /* special checks. Otherwise we must verify that the called method */
1546 : /* belongs to a super class of the current class */
1547 :
1548 53296 : if ((referer != declarer) && (mi->name != utf8::init)) {
1549 : /* check that declarer is a super class of the current class */
1550 :
1551 1255 : if (!class_issubclass(referer,declarer)) {
1552 : exceptions_throw_verifyerror(refmethod,
1553 0 : "INVOKESPECIAL calling non-super class method");
1554 0 : return NULL;
1555 : }
1556 :
1557 : /* if the referer has ACC_SUPER set, we must do the special */
1558 : /* lookup starting with the direct super class of referer */
1559 :
1560 1255 : if ((referer->flags & ACC_SUPER) != 0) {
1561 : mi = class_resolvemethod(referer->super,
1562 : mi->name,
1563 1255 : mi->descriptor);
1564 :
1565 1255 : if (mi == NULL) {
1566 : /* the spec calls for an AbstractMethodError in this case */
1567 :
1568 0 : exceptions_throw_abstractmethoderror();
1569 :
1570 0 : return NULL;
1571 : }
1572 : }
1573 : }
1574 :
1575 : /* everything ok */
1576 53296 : return mi;
1577 : }
1578 :
1579 : /* resolve_method_verifier_checks ******************************************
1580 :
1581 : Do the verifier checks necessary after a method has been resolved.
1582 :
1583 : IN:
1584 : refmethod........the method containing the reference
1585 : methodref........the method reference
1586 : mi...............the methodinfo of the resolved method
1587 : invokestatic.....true if the method is invoked by INVOKESTATIC
1588 :
1589 : RETURN VALUE:
1590 : resolveSucceeded....everything ok
1591 : resolveDeferred.....tests could not be done, have been deferred
1592 : resolveFailed.......exception has been thrown
1593 :
1594 : *******************************************************************************/
1595 :
1596 : #if defined(ENABLE_VERIFIER)
1597 265894 : resolve_result_t resolve_method_verifier_checks(methodinfo *refmethod,
1598 : constant_FMIref *methodref,
1599 : methodinfo *mi,
1600 : bool invokestatic)
1601 : {
1602 : classinfo *declarer;
1603 : classinfo *referer;
1604 :
1605 265894 : assert(refmethod);
1606 265894 : assert(methodref);
1607 265894 : assert(mi);
1608 :
1609 : #ifdef RESOLVE_VERBOSE
1610 : printf("resolve_method_verifier_checks\n");
1611 : printf(" flags: %02x\n",mi->flags);
1612 : #endif
1613 :
1614 : /* get the classinfos and the method descriptor */
1615 :
1616 265894 : referer = refmethod->clazz;
1617 265894 : assert(referer);
1618 :
1619 265894 : declarer = mi->clazz;
1620 265894 : assert(declarer);
1621 :
1622 : /* check static */
1623 :
1624 265894 : if (((mi->flags & ACC_STATIC) != 0) != (invokestatic != false)) {
1625 : /* a static method is accessed via an instance, or vice versa */
1626 : exceptions_throw_incompatibleclasschangeerror(declarer,
1627 : (mi->flags & ACC_STATIC)
1628 : ? "static method called via instance"
1629 0 : : "instance method called without instance");
1630 :
1631 0 : return resolveFailed;
1632 : }
1633 :
1634 : /* check access rights */
1635 :
1636 265894 : if (!access_is_accessible_member(referer,declarer,mi->flags)) {
1637 : /* XXX clean this up. this should be in exceptions.c */
1638 :
1639 0 : Buffer<> buf(64);
1640 :
1641 : Utf8String u = buf.write("method is not accessible (")
1642 : .write_slash_to_dot(declarer->name)
1643 : .write(".")
1644 : .write(mi->name)
1645 : .write(mi->descriptor)
1646 : .write(" from ")
1647 : .write_slash_to_dot(referer->name)
1648 : .write(")")
1649 0 : .utf8_str();
1650 :
1651 0 : exceptions_throw_illegalaccessexception(u);
1652 0 : return resolveFailed; /* exception */
1653 : }
1654 :
1655 : /* everything ok */
1656 :
1657 265894 : return resolveSucceeded;
1658 : }
1659 : #endif /* defined(ENABLE_VERIFIER) */
1660 :
1661 :
1662 : /* resolve_method_instance_type_checks *****************************************
1663 :
1664 : Check the instance type of a method invocation.
1665 :
1666 : IN:
1667 : refmethod........the method containing the reference
1668 : mi...............the methodinfo of the resolved method
1669 : instanceti.......typeinfo of the instance slot
1670 : invokespecial....true if the method is invoked by INVOKESPECIAL
1671 :
1672 : RETURN VALUE:
1673 : resolveSucceeded....everything ok
1674 : resolveDeferred.....tests could not be done, have been deferred
1675 : resolveFailed.......exception has been thrown
1676 :
1677 : *******************************************************************************/
1678 :
1679 : #if defined(ENABLE_VERIFIER)
1680 181750 : resolve_result_t resolve_method_instance_type_checks(methodinfo *refmethod,
1681 : methodinfo *mi,
1682 : typeinfo_t *instanceti,
1683 : bool invokespecial)
1684 : {
1685 : typeinfo_t tinfo;
1686 : typeinfo_t *tip;
1687 : resolve_result_t result;
1688 :
1689 181750 : if (invokespecial && instanceti->is_newobject())
1690 : { /* XXX clean up */
1691 0 : instruction *ins = instanceti->newobject_instruction();
1692 0 : classref_or_classinfo initclass = (ins) ? ins[-1].sx.val.c : to_classref_or_classinfo(refmethod->clazz);
1693 0 : tip = &tinfo;
1694 0 : if (!tip->init_class(initclass))
1695 0 : return resolveFailed;
1696 : }
1697 : else {
1698 181750 : tip = instanceti;
1699 : }
1700 :
1701 : result = resolve_lazy_subtype_checks(refmethod,
1702 : tip,
1703 : to_classref_or_classinfo(mi->clazz),
1704 181750 : resolveLinkageError);
1705 181750 : if (result != resolveSucceeded)
1706 154 : return result;
1707 :
1708 : /* check protected access */
1709 :
1710 : /* XXX use other `declarer` than mi->clazz? */
1711 181596 : if (((mi->flags & ACC_PROTECTED) != 0)
1712 : && !SAME_PACKAGE(mi->clazz, refmethod->clazz))
1713 : {
1714 : result = resolve_lazy_subtype_checks(refmethod,
1715 : tip,
1716 : to_classref_or_classinfo(refmethod->clazz),
1717 3833 : resolveIllegalAccessError);
1718 3833 : if (result != resolveSucceeded)
1719 0 : return result;
1720 : }
1721 :
1722 : /* everything ok */
1723 :
1724 181596 : return resolveSucceeded;
1725 : }
1726 : #endif /* defined(ENABLE_VERIFIER) */
1727 :
1728 :
1729 : /* resolve_method_param_type_checks ********************************************
1730 :
1731 : Check non-instance parameter types of a method invocation.
1732 :
1733 : IN:
1734 : jd...............jitdata of the method doing the call
1735 : refmethod........the method containing the reference
1736 : iptr.............the invoke instruction
1737 : mi...............the methodinfo of the resolved method
1738 : invokestatic.....true if the method is invoked by INVOKESTATIC
1739 :
1740 : RETURN VALUE:
1741 : resolveSucceeded....everything ok
1742 : resolveDeferred.....tests could not be done, have been deferred
1743 : resolveFailed.......exception has been thrown
1744 :
1745 : *******************************************************************************/
1746 :
1747 : #if defined(ENABLE_VERIFIER)
1748 232413 : resolve_result_t resolve_method_param_type_checks(jitdata *jd,
1749 : methodinfo *refmethod,
1750 : instruction *iptr,
1751 : methodinfo *mi,
1752 : bool invokestatic)
1753 : {
1754 : varinfo *param;
1755 : resolve_result_t result;
1756 : methoddesc *md;
1757 : typedesc *paramtypes;
1758 : s4 type;
1759 : s4 instancecount;
1760 : s4 i;
1761 :
1762 232413 : assert(jd);
1763 :
1764 232413 : instancecount = (invokestatic) ? 0 : 1;
1765 :
1766 : /* check subtype constraints for TYPE_ADR parameters */
1767 :
1768 232413 : md = mi->parseddesc;
1769 232413 : paramtypes = md->paramtypes;
1770 :
1771 443926 : for (i = md->paramcount-1-instancecount; i>=0; --i) {
1772 220725 : param = VAR(iptr->sx.s23.s2.args[i+instancecount]);
1773 220725 : type = md->paramtypes[i+instancecount].type;
1774 :
1775 220725 : assert(param);
1776 220725 : assert(type == param->type);
1777 :
1778 220725 : if (type == TYPE_ADR) {
1779 : result = resolve_lazy_subtype_checks(refmethod,
1780 : &(param->typeinfo),
1781 148525 : to_classref_or_classinfo(paramtypes[i+instancecount].classref),
1782 148525 : resolveLinkageError);
1783 148525 : if (result != resolveSucceeded)
1784 9212 : return result;
1785 : }
1786 : }
1787 :
1788 : /* everything ok */
1789 :
1790 223201 : return resolveSucceeded;
1791 : }
1792 : #endif /* defined(ENABLE_VERIFIER) */
1793 :
1794 :
1795 : /* resolve_method_param_type_checks_stackbased *********************************
1796 :
1797 : Check non-instance parameter types of a method invocation.
1798 :
1799 : IN:
1800 : refmethod........the method containing the reference
1801 : mi...............the methodinfo of the resolved method
1802 : invokestatic.....true if the method is invoked by INVOKESTATIC
1803 : stack............TOS before the INVOKE instruction
1804 :
1805 : RETURN VALUE:
1806 : resolveSucceeded....everything ok
1807 : resolveDeferred.....tests could not be done, have been deferred
1808 : resolveFailed.......exception has been thrown
1809 :
1810 : *******************************************************************************/
1811 :
1812 : #if defined(ENABLE_VERIFIER)
1813 0 : resolve_result_t resolve_method_param_type_checks_stackbased(
1814 : methodinfo *refmethod,
1815 : methodinfo *mi,
1816 : bool invokestatic,
1817 : typedescriptor_t *stack)
1818 : {
1819 : typedescriptor_t *param;
1820 : resolve_result_t result;
1821 : methoddesc *md;
1822 : typedesc *paramtypes;
1823 : s4 type;
1824 : s4 instancecount;
1825 : s4 i;
1826 :
1827 0 : instancecount = (invokestatic) ? 0 : 1;
1828 :
1829 : /* check subtype constraints for TYPE_ADR parameters */
1830 :
1831 0 : md = mi->parseddesc;
1832 0 : paramtypes = md->paramtypes;
1833 :
1834 0 : param = stack - (md->paramslots - 1 - instancecount);
1835 :
1836 0 : for (i = instancecount; i < md->paramcount; ++i) {
1837 0 : type = md->paramtypes[i].type;
1838 :
1839 0 : assert(type == param->type);
1840 :
1841 0 : if (type == TYPE_ADR) {
1842 : result = resolve_lazy_subtype_checks(refmethod,
1843 : &(param->typeinfo),
1844 0 : to_classref_or_classinfo(paramtypes[i].classref),
1845 0 : resolveLinkageError);
1846 0 : if (result != resolveSucceeded)
1847 0 : return result;
1848 : }
1849 :
1850 0 : param += (IS_2_WORD_TYPE(type)) ? 2 : 1;
1851 : }
1852 :
1853 : /* everything ok */
1854 :
1855 0 : return resolveSucceeded;
1856 : }
1857 : #endif /* defined(ENABLE_VERIFIER) */
1858 :
1859 :
1860 : /* resolve_method_loading_constraints ******************************************
1861 :
1862 : Impose loading constraints on the parameters and return type of the
1863 : given method.
1864 :
1865 : IN:
1866 : referer..........the class refering to the method
1867 : mi...............the method
1868 :
1869 : RETURN VALUE:
1870 : true................everything ok
1871 : false...............an exception has been thrown
1872 :
1873 : *******************************************************************************/
1874 :
1875 : #if defined(ENABLE_VERIFIER)
1876 256528 : bool resolve_method_loading_constraints(classinfo *referer,
1877 : methodinfo *mi)
1878 : {
1879 : methoddesc *md;
1880 : typedesc *paramtypes;
1881 256528 : Utf8String name;
1882 : s4 i;
1883 : s4 instancecount;
1884 :
1885 : /* impose loading constraints on parameters (including instance) */
1886 :
1887 256528 : md = mi->parseddesc;
1888 256528 : paramtypes = md->paramtypes;
1889 256528 : instancecount = (mi->flags & ACC_STATIC) / ACC_STATIC;
1890 :
1891 699148 : for (i = 0; i < md->paramcount; i++) {
1892 442620 : if (i < instancecount || paramtypes[i].type == TYPE_ADR) {
1893 371394 : if (i < instancecount) {
1894 : /* The type of the 'this' pointer is the class containing */
1895 : /* the method definition. Since container is the same as, */
1896 : /* or a subclass of declarer, we also constrain declarer */
1897 : /* by transitivity of loading constraints. */
1898 47635 : name = mi->clazz->name;
1899 : }
1900 : else {
1901 323759 : name = paramtypes[i].classref->name;
1902 : }
1903 :
1904 : /* The caller (referer) and the callee (container) must agree */
1905 : /* on the types of the parameters. */
1906 371394 : if (!classcache_add_constraint(referer->classloader,
1907 : mi->clazz->classloader, name))
1908 0 : return false; /* exception */
1909 : }
1910 : }
1911 :
1912 : /* impose loading constraint onto return type */
1913 :
1914 256528 : if (md->returntype.type == TYPE_ADR) {
1915 : /* The caller (referer) and the callee (container) must agree */
1916 : /* on the return type. */
1917 117718 : if (!classcache_add_constraint(referer->classloader,
1918 : mi->clazz->classloader,
1919 : md->returntype.classref->name))
1920 0 : return false; /* exception */
1921 : }
1922 :
1923 : /* everything ok */
1924 :
1925 256528 : return true;
1926 : }
1927 : #endif /* defined(ENABLE_VERIFIER) */
1928 :
1929 :
1930 : /* resolve_method_lazy *********************************************************
1931 :
1932 : Resolve an unresolved method reference lazily
1933 :
1934 : NOTE: This function does NOT do any verification checks. In case of a
1935 : successful resolution, you must call resolve_method_verifier_checks
1936 : in order to perform the necessary checks!
1937 :
1938 : IN:
1939 : refmethod........the referer method
1940 : methodref........the method reference
1941 : invokespecial....true if this is an INVOKESPECIAL instruction
1942 :
1943 : RETURN VALUE:
1944 : resolveSucceeded.....the reference has been resolved
1945 : resolveDeferred......the resolving could not be performed lazily
1946 : resolveFailed........resolving failed, an exception has been thrown.
1947 :
1948 : *******************************************************************************/
1949 :
1950 289988 : resolve_result_t resolve_method_lazy(methodinfo *refmethod,
1951 : constant_FMIref *methodref,
1952 : bool invokespecial)
1953 : {
1954 : classinfo *referer;
1955 : classinfo *container;
1956 : methodinfo *mi;
1957 :
1958 289988 : assert(refmethod);
1959 :
1960 : #ifdef RESOLVE_VERBOSE
1961 : printf("resolve_method_lazy\n");
1962 : #endif
1963 :
1964 : /* the class containing the reference */
1965 :
1966 289988 : referer = refmethod->clazz;
1967 289988 : assert(referer);
1968 :
1969 : /* check if the method itself is already resolved */
1970 :
1971 289988 : if (methodref->is_resolved())
1972 104754 : return resolveSucceeded;
1973 :
1974 : /* first we must resolve the class containg the method */
1975 :
1976 185234 : if (!resolve_class_from_name(referer, refmethod,
1977 : methodref->p.classref->name, resolveLazy, true, true, &container))
1978 : {
1979 : /* the class reference could not be resolved */
1980 0 : return resolveFailed; /* exception */
1981 : }
1982 185234 : if (!container)
1983 57421 : return resolveDeferred; /* be lazy */
1984 :
1985 127813 : assert(container->state & CLASS_LINKED);
1986 :
1987 : /* now we must find the declaration of the method in `container`
1988 : * or one of its superclasses */
1989 :
1990 127813 : if (container->flags & ACC_INTERFACE) {
1991 : mi = class_resolveinterfacemethod(container,
1992 : methodref->name,
1993 : methodref->descriptor,
1994 5167 : referer, true);
1995 :
1996 : } else {
1997 : mi = class_resolveclassmethod(container,
1998 : methodref->name,
1999 : methodref->descriptor,
2000 122646 : referer, true);
2001 : }
2002 :
2003 127813 : if (!mi) {
2004 : /* The method does not exist. But since we were called lazily, */
2005 : /* this error must not be reported now. (It will be reported */
2006 : /* if eager resolving of this method is ever tried.) */
2007 :
2008 0 : exceptions_clear_exception();
2009 0 : return resolveDeferred; /* be lazy */
2010 : }
2011 :
2012 127813 : if (invokespecial) {
2013 41074 : mi = resolve_method_invokespecial_lookup(refmethod, mi);
2014 41074 : if (!mi)
2015 0 : return resolveFailed; /* exception */
2016 : }
2017 :
2018 : /* have the method params already been parsed? no, do it. */
2019 :
2020 127813 : mi->parseddesc->params_from_paramtypes(mi->flags);
2021 :
2022 : /* cache the result of the resolution */
2023 :
2024 127813 : methodref->p.method = mi;
2025 :
2026 : /* succeed */
2027 :
2028 127813 : return resolveSucceeded;
2029 : }
2030 :
2031 : /* resolve_method **************************************************************
2032 :
2033 : Resolve an unresolved method reference
2034 :
2035 : IN:
2036 : ref..............struct containing the reference
2037 : mode.............mode of resolution:
2038 : resolveLazy...only resolve if it does not
2039 : require loading classes
2040 : resolveEager..load classes if necessary
2041 :
2042 : OUT:
2043 : *result..........set to the result of resolution, or to NULL if
2044 : the reference has not been resolved
2045 : In the case of an exception, *result is
2046 : guaranteed to be set to NULL.
2047 :
2048 : RETURN VALUE:
2049 : true.............everything ok
2050 : (*result may still be NULL for resolveLazy)
2051 : false............an exception has been thrown
2052 :
2053 : *******************************************************************************/
2054 :
2055 33330 : bool resolve_method(unresolved_method *ref, resolve_mode_t mode, methodinfo **result)
2056 : {
2057 : classinfo *referer;
2058 : classinfo *container;
2059 : methodinfo *mi;
2060 :
2061 33330 : assert(ref);
2062 33330 : assert(result);
2063 33330 : assert(mode == resolveLazy || mode == resolveEager);
2064 :
2065 : #ifdef RESOLVE_VERBOSE
2066 : unresolved_method_debug_dump(ref,stdout);
2067 : #endif
2068 :
2069 33330 : *result = NULL;
2070 :
2071 : /* the class containing the reference */
2072 :
2073 33330 : referer = ref->referermethod->clazz;
2074 33330 : assert(referer);
2075 :
2076 : /* check if the method itself is already resolved */
2077 :
2078 33330 : if (ref->methodref->is_resolved()) {
2079 11212 : mi = ref->methodref->p.method;
2080 11212 : container = mi->clazz;
2081 11212 : goto resolved_the_method;
2082 : }
2083 :
2084 : /* first we must resolve the class containing the method */
2085 :
2086 22118 : if (!resolve_class_from_name(referer,ref->referermethod,
2087 : ref->methodref->p.classref->name,mode,true,true,&container))
2088 : {
2089 : /* the class reference could not be resolved */
2090 3 : return false; /* exception */
2091 : }
2092 22115 : if (!container)
2093 0 : return true; /* be lazy */
2094 :
2095 22115 : assert(container);
2096 22115 : assert(container->state & CLASS_LINKED);
2097 :
2098 : /* now we must find the declaration of the method in `container`
2099 : * or one of its superclasses */
2100 :
2101 22115 : if (container->flags & ACC_INTERFACE) {
2102 : mi = class_resolveinterfacemethod(container,
2103 : ref->methodref->name,
2104 : ref->methodref->descriptor,
2105 458 : referer, true);
2106 :
2107 : } else {
2108 : mi = class_resolveclassmethod(container,
2109 : ref->methodref->name,
2110 : ref->methodref->descriptor,
2111 21657 : referer, true);
2112 : }
2113 :
2114 22115 : if (!mi) {
2115 0 : if (mode == resolveLazy) {
2116 : /* The method does not exist. But since we were called lazily, */
2117 : /* this error must not be reported now. (It will be reported */
2118 : /* if eager resolving of this method is ever tried.) */
2119 :
2120 0 : exceptions_clear_exception();
2121 0 : return true; /* be lazy */
2122 : }
2123 :
2124 0 : return false; /* exception */ /* XXX set exceptionptr? */
2125 : }
2126 :
2127 : /* { the method reference has been resolved } */
2128 :
2129 22115 : if (ref->flags & RESOLVE_SPECIAL) {
2130 12222 : mi = resolve_method_invokespecial_lookup(ref->referermethod,mi);
2131 12222 : if (!mi)
2132 0 : return false; /* exception */
2133 : }
2134 :
2135 : /* have the method params already been parsed? no, do it. */
2136 :
2137 22115 : mi->parseddesc->params_from_paramtypes(mi->flags);
2138 :
2139 : /* cache the resolution */
2140 :
2141 22115 : ref->methodref->p.method = mi;
2142 :
2143 : resolved_the_method:
2144 :
2145 : #ifdef ENABLE_VERIFIER
2146 33327 : if (opt_verify) {
2147 : resolve_result_t checkresult = resolve_method_verifier_checks(
2148 : ref->referermethod,
2149 : ref->methodref,
2150 : mi,
2151 33327 : (ref->flags & RESOLVE_STATIC));
2152 :
2153 33327 : if (checkresult != resolveSucceeded)
2154 0 : return (bool) checkresult;
2155 :
2156 : /* impose loading constraints on params and return type */
2157 :
2158 33327 : if (!resolve_method_loading_constraints(referer, mi))
2159 0 : return false;
2160 :
2161 33327 : classinfo *declarer = mi->clazz;
2162 33327 : assert(declarer);
2163 33327 : assert(referer->state & CLASS_LINKED);
2164 :
2165 : /* for non-static methods we have to check the constraints on the */
2166 : /* instance type */
2167 :
2168 : int instancecount;
2169 :
2170 33327 : if (!(ref->flags & RESOLVE_STATIC)) {
2171 : checkresult = resolve_and_check_subtype_set(ref->referermethod,
2172 : &(ref->instancetypes),
2173 : to_classref_or_classinfo(container),
2174 : mode,
2175 27593 : resolveLinkageError);
2176 27593 : if (checkresult != resolveSucceeded)
2177 1 : return (bool) checkresult;
2178 27592 : instancecount = 1;
2179 : }
2180 : else {
2181 5734 : instancecount = 0;
2182 : }
2183 :
2184 : /* check subtype constraints for TYPE_ADR parameters */
2185 :
2186 33326 : assert(mi->parseddesc->paramcount == ref->methodref->parseddesc.md->paramcount);
2187 33326 : typedesc *paramtypes = mi->parseddesc->paramtypes;
2188 :
2189 64370 : for (int i = 0; i < mi->parseddesc->paramcount-instancecount; i++) {
2190 31045 : if (paramtypes[i+instancecount].type == TYPE_ADR) {
2191 26255 : if (ref->paramconstraints) {
2192 : checkresult = resolve_and_check_subtype_set(ref->referermethod,
2193 : ref->paramconstraints + i,
2194 26255 : to_classref_or_classinfo(paramtypes[i+instancecount].classref),
2195 : mode,
2196 26255 : resolveLinkageError);
2197 26255 : if (checkresult != resolveSucceeded)
2198 1 : return (bool) checkresult;
2199 : }
2200 : }
2201 : }
2202 :
2203 : /* check protected access */
2204 :
2205 33325 : if (((mi->flags & ACC_PROTECTED) != 0) && !SAME_PACKAGE(declarer,referer))
2206 : {
2207 : checkresult = resolve_and_check_subtype_set(ref->referermethod,
2208 : &(ref->instancetypes),
2209 : to_classref_or_classinfo(referer),
2210 : mode,
2211 0 : resolveIllegalAccessError);
2212 0 : if (checkresult != resolveSucceeded)
2213 0 : return (bool) checkresult;
2214 : }
2215 : }
2216 : #endif /* ENABLE_VERIFIER */
2217 :
2218 : /* succeed */
2219 33325 : *result = mi;
2220 33325 : return true;
2221 : }
2222 :
2223 : /* resolve_method_eager ********************************************************
2224 :
2225 : Resolve an unresolved method reference eagerly.
2226 :
2227 : IN:
2228 : ref..............struct containing the reference
2229 :
2230 : RETURN VALUE:
2231 : methodinfo * to the method, or
2232 : NULL if an exception has been thrown
2233 :
2234 : *******************************************************************************/
2235 :
2236 33330 : methodinfo * resolve_method_eager(unresolved_method *ref)
2237 : {
2238 : methodinfo *mi;
2239 :
2240 33330 : if (!resolve_method(ref,resolveEager,&mi))
2241 5 : return NULL;
2242 :
2243 33325 : return mi;
2244 : }
2245 :
2246 : /******************************************************************************/
2247 : /* CREATING THE DATA STRUCTURES */
2248 : /******************************************************************************/
2249 :
2250 : #ifdef ENABLE_VERIFIER
2251 131701 : static bool unresolved_subtype_set_from_typeinfo(classinfo *referer,
2252 : methodinfo *refmethod,
2253 : unresolved_subtype_set *stset,
2254 : typeinfo_t *tinfo,
2255 : Utf8String declaredclassname)
2256 : {
2257 : int count;
2258 : int i;
2259 :
2260 131701 : assert(stset);
2261 131701 : assert(tinfo);
2262 :
2263 : #ifdef RESOLVE_VERBOSE
2264 : printf("unresolved_subtype_set_from_typeinfo\n");
2265 : #ifdef TYPEINFO_DEBUG
2266 : typeinfo_print(stdout,tinfo,4);
2267 : #endif
2268 : printf(" declared classname:");utf_fprint_printable_ascii(stdout,declaredclassname);
2269 : printf("\n");
2270 : #endif
2271 :
2272 131701 : if (tinfo->is_primitive()) {
2273 : exceptions_throw_verifyerror(refmethod,
2274 0 : "Invalid use of returnAddress");
2275 0 : return false;
2276 : }
2277 :
2278 131701 : if (tinfo->is_newobject()) {
2279 : exceptions_throw_verifyerror(refmethod,
2280 0 : "Invalid use of uninitialized object");
2281 0 : return false;
2282 : }
2283 :
2284 : /* the nulltype is always assignable */
2285 131701 : if (tinfo->is_nulltype())
2286 2774 : goto empty_set;
2287 :
2288 : /* every type is assignable to (BOOTSTRAP)java.lang.Object */
2289 128927 : if (declaredclassname == utf8::java_lang_Object
2290 : && referer->classloader == NULL) /* XXX do loading constraints make the second check obsolete? */
2291 : {
2292 4487 : goto empty_set;
2293 : }
2294 :
2295 124440 : if (tinfo->merged) {
2296 715 : count = tinfo->merged->count;
2297 715 : stset->subtyperefs = MNEW(classref_or_classinfo,count + 1);
2298 5088 : for (i=0; i<count; ++i) {
2299 4373 : classref_or_classinfo c = tinfo->merged->list[i];
2300 4373 : if (tinfo->dimension > 0) {
2301 : /* a merge of array types */
2302 : /* the merged list contains the possible _element_ types, */
2303 : /* so we have to create array types with these elements. */
2304 0 : if (c.is_classref()) {
2305 0 : c.ref = class_get_classref_multiarray_of(tinfo->dimension,c.ref);
2306 : }
2307 : else {
2308 0 : c.cls = class_multiarray_of(tinfo->dimension,c.cls,false);
2309 : }
2310 : }
2311 4373 : stset->subtyperefs[i] = c;
2312 : }
2313 715 : stset->subtyperefs[count].any = NULL; /* terminate */
2314 : }
2315 : else {
2316 123725 : if (CLASSREF_OR_CLASSINFO_NAME(tinfo->typeclass) == declaredclassname)
2317 : {
2318 : /* the class names are the same */
2319 : /* equality is guaranteed by the loading constraints */
2320 88902 : goto empty_set;
2321 : }
2322 : else {
2323 34823 : stset->subtyperefs = MNEW(classref_or_classinfo,1 + 1);
2324 34823 : stset->subtyperefs[0] = tinfo->typeclass;
2325 34823 : stset->subtyperefs[1].any = NULL; /* terminate */
2326 : }
2327 : }
2328 :
2329 35538 : return true;
2330 :
2331 : empty_set:
2332 96163 : UNRESOLVED_SUBTYPE_SET_EMTPY(*stset);
2333 96163 : return true;
2334 : }
2335 : #endif /* ENABLE_VERIFIER */
2336 :
2337 : /* create_unresolved_class *****************************************************
2338 :
2339 : Create an unresolved_class struct for the given class reference
2340 :
2341 : IN:
2342 : refmethod........the method triggering the resolution (if any)
2343 : classref.........the class reference
2344 : valuetype........value type to check against the resolved class
2345 : may be NULL, if no typeinfo is available
2346 :
2347 : RETURN VALUE:
2348 : a pointer to a new unresolved_class struct, or
2349 : NULL if an exception has been thrown
2350 :
2351 : *******************************************************************************/
2352 :
2353 : #ifdef ENABLE_VERIFIER
2354 18633 : unresolved_class * create_unresolved_class(methodinfo *refmethod,
2355 : constant_classref *classref,
2356 : typeinfo_t *valuetype)
2357 : {
2358 : unresolved_class *ref;
2359 :
2360 : #ifdef RESOLVE_VERBOSE
2361 : printf("create_unresolved_class\n");
2362 : printf(" referer: ");utf_fprint_printable_ascii(stdout,classref->referer->name);fputc('\n',stdout);
2363 : if (refmethod) {
2364 : printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2365 : printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2366 : }
2367 : printf(" name : ");utf_fprint_printable_ascii(stdout,classref->name);fputc('\n',stdout);
2368 : #endif
2369 :
2370 18633 : ref = NEW(unresolved_class);
2371 18633 : ref->classref = classref;
2372 18633 : ref->referermethod = refmethod;
2373 :
2374 18633 : if (valuetype) {
2375 18633 : if (!unresolved_subtype_set_from_typeinfo(classref->referer,refmethod,
2376 : &(ref->subtypeconstraints),valuetype,classref->name))
2377 0 : return NULL;
2378 : }
2379 : else {
2380 0 : UNRESOLVED_SUBTYPE_SET_EMTPY(ref->subtypeconstraints);
2381 : }
2382 :
2383 18633 : return ref;
2384 : }
2385 : #endif /* ENABLE_VERIFIER */
2386 :
2387 : /* resolve_create_unresolved_field *********************************************
2388 :
2389 : Create an unresolved_field struct for the given field access instruction
2390 :
2391 : IN:
2392 : referer..........the class containing the reference
2393 : refmethod........the method triggering the resolution (if any)
2394 : iptr.............the {GET,PUT}{FIELD,STATIC}{,CONST} instruction
2395 :
2396 : RETURN VALUE:
2397 : a pointer to a new unresolved_field struct, or
2398 : NULL if an exception has been thrown
2399 :
2400 : *******************************************************************************/
2401 :
2402 20923 : unresolved_field * resolve_create_unresolved_field(classinfo *referer,
2403 : methodinfo *refmethod,
2404 : instruction *iptr)
2405 : {
2406 : unresolved_field *ref;
2407 20923 : constant_FMIref *fieldref = NULL;
2408 :
2409 : #ifdef RESOLVE_VERBOSE
2410 : printf("create_unresolved_field\n");
2411 : printf(" referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2412 : printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2413 : printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2414 : #endif
2415 :
2416 20923 : ref = NEW(unresolved_field);
2417 20923 : ref->flags = 0;
2418 20923 : ref->referermethod = refmethod;
2419 20923 : UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
2420 :
2421 20923 : switch (iptr->opc) {
2422 : case ICMD_PUTFIELD:
2423 614 : ref->flags |= RESOLVE_PUTFIELD;
2424 614 : break;
2425 :
2426 : case ICMD_PUTFIELDCONST:
2427 100 : ref->flags |= RESOLVE_PUTFIELD;
2428 100 : break;
2429 :
2430 : case ICMD_PUTSTATIC:
2431 1332 : ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
2432 1332 : break;
2433 :
2434 : case ICMD_PUTSTATICCONST:
2435 9 : ref->flags |= RESOLVE_PUTFIELD | RESOLVE_STATIC;
2436 9 : break;
2437 :
2438 : case ICMD_GETFIELD:
2439 677 : break;
2440 :
2441 : case ICMD_GETSTATIC:
2442 18191 : ref->flags |= RESOLVE_STATIC;
2443 18191 : break;
2444 :
2445 : default:
2446 0 : assert(false);
2447 : break;
2448 : }
2449 :
2450 20923 : fieldref = iptr->sx.s23.s3.fmiref;
2451 :
2452 20923 : assert(fieldref);
2453 :
2454 : #ifdef RESOLVE_VERBOSE
2455 : /* printf(" class : ");utf_fprint_printable_ascii(stdout,fieldref->p.classref->name);fputc('\n',stdout);*/
2456 : printf(" name : ");utf_fprint_printable_ascii(stdout,fieldref->name);fputc('\n',stdout);
2457 : printf(" desc : ");utf_fprint_printable_ascii(stdout,fieldref->descriptor);fputc('\n',stdout);
2458 : printf(" type : ");descriptor_debug_print_typedesc(stdout,fieldref->parseddesc.fd);
2459 : fputc('\n',stdout);
2460 : #endif
2461 :
2462 20923 : ref->fieldref = fieldref;
2463 :
2464 20923 : return ref;
2465 : }
2466 :
2467 : /* resolve_constrain_unresolved_field ******************************************
2468 :
2469 : Record subtype constraints for a field access.
2470 :
2471 : IN:
2472 : ref..............the unresolved_field structure of the access
2473 : referer..........the class containing the reference
2474 : refmethod........the method triggering the resolution (if any)
2475 : instanceti.......instance typeinfo, if available
2476 : valueti..........value typeinfo, if available
2477 :
2478 : RETURN VALUE:
2479 : true.............everything ok
2480 : false............an exception has been thrown
2481 :
2482 : *******************************************************************************/
2483 :
2484 : #if defined(ENABLE_VERIFIER)
2485 21596 : bool resolve_constrain_unresolved_field(unresolved_field *ref,
2486 : classinfo *referer,
2487 : methodinfo *refmethod,
2488 : typeinfo_t *instanceti,
2489 : typeinfo_t *valueti)
2490 : {
2491 : constant_FMIref *fieldref;
2492 : int type;
2493 : typeinfo_t tinfo;
2494 : typedesc *fd;
2495 :
2496 21596 : assert(ref);
2497 :
2498 21596 : fieldref = ref->fieldref;
2499 21596 : assert(fieldref);
2500 :
2501 : #ifdef RESOLVE_VERBOSE
2502 : printf("constrain_unresolved_field\n");
2503 : printf(" referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2504 : printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2505 : printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2506 : /* printf(" class : ");utf_fprint_printable_ascii(stdout,fieldref->p.classref->name);fputc('\n',stdout); */
2507 : printf(" name : ");utf_fprint_printable_ascii(stdout,fieldref->name);fputc('\n',stdout);
2508 : printf(" desc : ");utf_fprint_printable_ascii(stdout,fieldref->descriptor);fputc('\n',stdout);
2509 : printf(" type : ");descriptor_debug_print_typedesc(stdout,fieldref->parseddesc.fd);
2510 : fputc('\n',stdout);
2511 : #endif
2512 :
2513 21596 : assert(instanceti || ((ref->flags & RESOLVE_STATIC) != 0));
2514 21596 : fd = fieldref->parseddesc.fd;
2515 21596 : assert(fd);
2516 :
2517 : /* record subtype constraints for the instance type, if any */
2518 21596 : if (instanceti) {
2519 : typeinfo_t *insttip;
2520 :
2521 : /* The instanceslot must contain a reference to a non-array type */
2522 2061 : if (!instanceti->is_reference()) {
2523 0 : exceptions_throw_verifyerror(refmethod, "illegal instruction: field access on non-reference");
2524 0 : return false;
2525 : }
2526 2061 : if (instanceti->is_array()) {
2527 0 : exceptions_throw_verifyerror(refmethod, "illegal instruction: field access on array");
2528 0 : return false;
2529 : }
2530 :
2531 2061 : if (((ref->flags & RESOLVE_PUTFIELD) != 0) && instanceti->is_newobject())
2532 : {
2533 : /* The instruction writes a field in an uninitialized object. */
2534 : /* This is only allowed when a field of an uninitialized 'this' object is */
2535 : /* written inside an initialization method */
2536 :
2537 : classinfo *initclass;
2538 0 : instruction *ins = instanceti->newobject_instruction();
2539 :
2540 0 : if (ins != NULL) {
2541 : exceptions_throw_verifyerror(refmethod,
2542 0 : "accessing field of uninitialized object");
2543 0 : return false;
2544 : }
2545 : /* XXX check that class of field == refmethod->clazz */
2546 0 : initclass = refmethod->clazz; /* XXX classrefs */
2547 0 : assert(initclass->state & CLASS_LOADED);
2548 0 : assert(initclass->state & CLASS_LINKED);
2549 :
2550 0 : tinfo.init_class(initclass);
2551 0 : insttip = &tinfo;
2552 : }
2553 : else {
2554 2061 : insttip = instanceti;
2555 : }
2556 2061 : if (!unresolved_subtype_set_from_typeinfo(referer, refmethod,
2557 : &(ref->instancetypes), insttip,
2558 : FIELDREF_CLASSNAME(fieldref)))
2559 0 : return false;
2560 : }
2561 : else {
2562 19535 : UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
2563 : }
2564 :
2565 : /* record subtype constraints for the value type, if any */
2566 21596 : type = fd->type;
2567 23520 : if (type == TYPE_ADR && ((ref->flags & RESOLVE_PUTFIELD) != 0)) {
2568 1924 : assert(valueti);
2569 1924 : if (!unresolved_subtype_set_from_typeinfo(referer, refmethod,
2570 : &(ref->valueconstraints), valueti,
2571 : fieldref->parseddesc.fd->classref->name))
2572 0 : return false;
2573 : }
2574 : else {
2575 19672 : UNRESOLVED_SUBTYPE_SET_EMTPY(ref->valueconstraints);
2576 : }
2577 :
2578 21596 : return true;
2579 : }
2580 : #endif /* ENABLE_VERIFIER */
2581 :
2582 : /* resolve_create_unresolved_method ********************************************
2583 :
2584 : Create an unresolved_method struct for the given method invocation
2585 :
2586 : IN:
2587 : referer..........the class containing the reference
2588 : refmethod........the method triggering the resolution (if any)
2589 : iptr.............the INVOKE* instruction
2590 :
2591 : RETURN VALUE:
2592 : a pointer to a new unresolved_method struct
2593 :
2594 : *******************************************************************************/
2595 :
2596 64232 : unresolved_method * resolve_create_unresolved_method(classinfo *referer,
2597 : methodinfo *refmethod,
2598 : constant_FMIref *methodref,
2599 : bool invokestatic,
2600 : bool invokespecial)
2601 : {
2602 : unresolved_method *ref;
2603 :
2604 64232 : assert(methodref);
2605 :
2606 : #ifdef RESOLVE_VERBOSE
2607 : printf("create_unresolved_method\n");
2608 : printf(" referer: ");utf_fprint_printable_ascii(stdout,referer->name);fputc('\n',stdout);
2609 : printf(" rmethod: ");utf_fprint_printable_ascii(stdout,refmethod->name);fputc('\n',stdout);
2610 : printf(" rmdesc : ");utf_fprint_printable_ascii(stdout,refmethod->descriptor);fputc('\n',stdout);
2611 : printf(" name : ");utf_fprint_printable_ascii(stdout,methodref->name);fputc('\n',stdout);
2612 : printf(" desc : ");utf_fprint_printable_ascii(stdout,methodref->descriptor);fputc('\n',stdout);
2613 : #endif
2614 :
2615 : /* allocate params if necessary */
2616 64232 : methodref->parseddesc.md->params_from_paramtypes(invokestatic ? ACC_STATIC : ACC_NONE);
2617 :
2618 : /* create the data structure */
2619 64232 : ref = NEW(unresolved_method);
2620 : ref->flags = ((invokestatic) ? RESOLVE_STATIC : 0)
2621 64232 : | ((invokespecial) ? RESOLVE_SPECIAL : 0);
2622 64232 : ref->referermethod = refmethod;
2623 64232 : ref->methodref = methodref;
2624 64232 : ref->paramconstraints = NULL;
2625 64232 : UNRESOLVED_SUBTYPE_SET_EMTPY(ref->instancetypes);
2626 :
2627 64232 : return ref;
2628 : }
2629 :
2630 :
2631 : /* resolve_constrain_unresolved_method_instance ********************************
2632 :
2633 : Record subtype constraints for the instance argument of a method call.
2634 :
2635 : IN:
2636 : ref..............the unresolved_method structure of the call
2637 : referer..........the class containing the reference
2638 : refmethod........the method triggering the resolution (if any)
2639 : iptr.............the INVOKE* instruction
2640 :
2641 : RETURN VALUE:
2642 : true.............everything ok
2643 : false............an exception has been thrown
2644 :
2645 : *******************************************************************************/
2646 :
2647 : #if defined(ENABLE_VERIFIER)
2648 58818 : bool resolve_constrain_unresolved_method_instance(unresolved_method *ref,
2649 : methodinfo *refmethod,
2650 : typeinfo_t *instanceti,
2651 : bool invokespecial)
2652 : {
2653 : constant_FMIref *methodref;
2654 : constant_classref *instanceref;
2655 : typeinfo_t tinfo;
2656 : typeinfo_t *tip;
2657 :
2658 58818 : assert(ref);
2659 58818 : methodref = ref->methodref;
2660 58818 : assert(methodref);
2661 :
2662 : /* XXX clean this up */
2663 : instanceref = methodref->is_resolved()
2664 : ? class_get_self_classref(methodref->p.method->clazz)
2665 58818 : : methodref->p.classref;
2666 :
2667 : #ifdef RESOLVE_VERBOSE
2668 : printf("resolve_constrain_unresolved_method_instance\n");
2669 : printf(" rmethod: "); method_println(refmethod);
2670 : printf(" mref : "); method_methodref_println(methodref);
2671 : #endif
2672 :
2673 : /* record subtype constraints for the instance type, if any */
2674 :
2675 58818 : if (invokespecial && instanceti->is_newobject())
2676 : { /* XXX clean up */
2677 0 : instruction *ins = instanceti->newobject_instruction();
2678 0 : classref_or_classinfo initclass = (ins) ? ins[-1].sx.val.c : to_classref_or_classinfo(refmethod->clazz);
2679 0 : tip = &tinfo;
2680 0 : if (!tip->init_class(initclass))
2681 0 : return false;
2682 : }
2683 : else {
2684 58818 : tip = instanceti;
2685 : }
2686 :
2687 58818 : if (!unresolved_subtype_set_from_typeinfo(refmethod->clazz, refmethod,
2688 : &(ref->instancetypes),tip,instanceref->name))
2689 0 : return false;
2690 :
2691 58818 : return true;
2692 : }
2693 : #endif /* defined(ENABLE_VERIFIER) */
2694 :
2695 :
2696 : /* resolve_constrain_unresolved_method_params *********************************
2697 :
2698 : Record subtype constraints for the non-instance arguments of a method call.
2699 :
2700 : IN:
2701 : jd...............current jitdata (for looking up variables)
2702 : ref..............the unresolved_method structure of the call
2703 : refmethod........the method triggering the resolution (if any)
2704 : iptr.............the INVOKE* instruction
2705 :
2706 : RETURN VALUE:
2707 : true.............everything ok
2708 : false............an exception has been thrown
2709 :
2710 : *******************************************************************************/
2711 :
2712 : #if defined(ENABLE_VERIFIER)
2713 66787 : bool resolve_constrain_unresolved_method_params(jitdata *jd,
2714 : unresolved_method *ref,
2715 : methodinfo *refmethod,
2716 : instruction *iptr)
2717 : {
2718 : constant_FMIref *methodref;
2719 : varinfo *param;
2720 : methoddesc *md;
2721 : int i,j;
2722 : int type;
2723 : int instancecount;
2724 :
2725 66787 : assert(ref);
2726 66787 : methodref = ref->methodref;
2727 66787 : assert(methodref);
2728 66787 : md = methodref->parseddesc.md;
2729 66787 : assert(md);
2730 66787 : assert(md->params != NULL);
2731 :
2732 : #ifdef RESOLVE_VERBOSE
2733 : printf("resolve_constrain_unresolved_method_params\n");
2734 : printf(" rmethod: "); method_println(refmethod);
2735 : printf(" mref : "); method_methodref_println(methodref);
2736 : #endif
2737 :
2738 66787 : instancecount = (ref->flags & RESOLVE_STATIC) ? 0 : 1;
2739 :
2740 : /* record subtype constraints for the parameter types, if any */
2741 :
2742 127799 : for (i=md->paramcount-1-instancecount; i>=0; --i) {
2743 61012 : param = VAR(iptr->sx.s23.s2.args[i+instancecount]);
2744 61012 : type = md->paramtypes[i+instancecount].type;
2745 :
2746 61012 : assert(param);
2747 61012 : assert(type == param->type);
2748 :
2749 61012 : if (type == TYPE_ADR) {
2750 50265 : if (!ref->paramconstraints) {
2751 38753 : ref->paramconstraints = MNEW(unresolved_subtype_set,md->paramcount);
2752 42887 : for (j=md->paramcount-1-instancecount; j>i; --j)
2753 4134 : UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[j]);
2754 : }
2755 50265 : assert(ref->paramconstraints);
2756 50265 : if (!unresolved_subtype_set_from_typeinfo(refmethod->clazz, refmethod,
2757 : ref->paramconstraints + i,&(param->typeinfo),
2758 : md->paramtypes[i+instancecount].classref->name))
2759 0 : return false;
2760 : }
2761 : else {
2762 10747 : if (ref->paramconstraints)
2763 1055 : UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[i]);
2764 : }
2765 : }
2766 :
2767 66787 : return true;
2768 : }
2769 : #endif /* ENABLE_VERIFIER */
2770 :
2771 :
2772 : /* resolve_constrain_unresolved_method_params_stackbased ***********************
2773 :
2774 : Record subtype constraints for the non-instance arguments of a method call.
2775 :
2776 : IN:
2777 : ref..............the unresolved_method structure of the call
2778 : refmethod........the method triggering the resolution (if any)
2779 : stack............TOS before the INVOKE instruction
2780 :
2781 : RETURN VALUE:
2782 : true.............everything ok
2783 : false............an exception has been thrown
2784 :
2785 : *******************************************************************************/
2786 :
2787 : #if defined(ENABLE_VERIFIER)
2788 0 : bool resolve_constrain_unresolved_method_params_stackbased(
2789 : unresolved_method *ref,
2790 : methodinfo *refmethod,
2791 : typedescriptor_t *stack)
2792 : {
2793 : constant_FMIref *methodref;
2794 : typedescriptor_t *param;
2795 : methoddesc *md;
2796 : int i,j;
2797 : int type;
2798 : int instancecount;
2799 :
2800 0 : assert(ref);
2801 0 : methodref = ref->methodref;
2802 0 : assert(methodref);
2803 0 : md = methodref->parseddesc.md;
2804 0 : assert(md);
2805 0 : assert(md->params != NULL);
2806 :
2807 : #ifdef RESOLVE_VERBOSE
2808 : printf("resolve_constrain_unresolved_method_params_stackbased\n");
2809 : printf(" rmethod: "); method_println(refmethod);
2810 : printf(" mref : "); method_methodref_println(methodref);
2811 : #endif
2812 :
2813 0 : instancecount = (ref->flags & RESOLVE_STATIC) ? 0 : 1;
2814 :
2815 : /* record subtype constraints for the parameter types, if any */
2816 :
2817 0 : param = stack - (md->paramslots - 1 - instancecount);
2818 :
2819 0 : for (i = instancecount; i < md->paramcount; ++i) {
2820 0 : type = md->paramtypes[i].type;
2821 :
2822 0 : assert(type == param->type);
2823 :
2824 0 : if (type == TYPE_ADR) {
2825 0 : if (!ref->paramconstraints) {
2826 0 : ref->paramconstraints = MNEW(unresolved_subtype_set,md->paramcount);
2827 0 : for (j = 0; j < i - instancecount; ++j)
2828 0 : UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[j]);
2829 : }
2830 0 : assert(ref->paramconstraints);
2831 0 : if (!unresolved_subtype_set_from_typeinfo(refmethod->clazz, refmethod,
2832 : ref->paramconstraints + i - instancecount,&(param->typeinfo),
2833 : md->paramtypes[i].classref->name))
2834 0 : return false;
2835 : }
2836 : else {
2837 0 : if (ref->paramconstraints)
2838 0 : UNRESOLVED_SUBTYPE_SET_EMTPY(ref->paramconstraints[i]);
2839 : }
2840 :
2841 0 : param += (IS_2_WORD_TYPE(type)) ? 2 : 1;
2842 : }
2843 :
2844 0 : return true;
2845 : }
2846 : #endif /* ENABLE_VERIFIER */
2847 :
2848 :
2849 : /******************************************************************************/
2850 : /* FREEING MEMORY */
2851 : /******************************************************************************/
2852 :
2853 : #ifdef ENABLE_VERIFIER
2854 0 : inline static void unresolved_subtype_set_free_list(classref_or_classinfo *list)
2855 : {
2856 0 : if (list) {
2857 0 : classref_or_classinfo *p = list;
2858 :
2859 : /* this is silly. we *only* need to count the elements for MFREE */
2860 0 : while ((p++)->any)
2861 : ;
2862 0 : MFREE(list,classref_or_classinfo,(p - list));
2863 : }
2864 0 : }
2865 : #endif /* ENABLE_VERIFIER */
2866 :
2867 : /* unresolved_class_free *******************************************************
2868 :
2869 : Free the memory used by an unresolved_class
2870 :
2871 : IN:
2872 : ref..............the unresolved_class
2873 :
2874 : *******************************************************************************/
2875 :
2876 0 : void unresolved_class_free(unresolved_class *ref)
2877 : {
2878 0 : assert(ref);
2879 :
2880 : #ifdef ENABLE_VERIFIER
2881 0 : unresolved_subtype_set_free_list(ref->subtypeconstraints.subtyperefs);
2882 : #endif
2883 0 : FREE(ref,unresolved_class);
2884 0 : }
2885 :
2886 : /* unresolved_field_free *******************************************************
2887 :
2888 : Free the memory used by an unresolved_field
2889 :
2890 : IN:
2891 : ref..............the unresolved_field
2892 :
2893 : *******************************************************************************/
2894 :
2895 0 : void unresolved_field_free(unresolved_field *ref)
2896 : {
2897 0 : assert(ref);
2898 :
2899 : #ifdef ENABLE_VERIFIER
2900 0 : unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
2901 0 : unresolved_subtype_set_free_list(ref->valueconstraints.subtyperefs);
2902 : #endif
2903 0 : FREE(ref,unresolved_field);
2904 0 : }
2905 :
2906 : /* unresolved_method_free ******************************************************
2907 :
2908 : Free the memory used by an unresolved_method
2909 :
2910 : IN:
2911 : ref..............the unresolved_method
2912 :
2913 : *******************************************************************************/
2914 :
2915 0 : void unresolved_method_free(unresolved_method *ref)
2916 : {
2917 0 : assert(ref);
2918 :
2919 : #ifdef ENABLE_VERIFIER
2920 0 : unresolved_subtype_set_free_list(ref->instancetypes.subtyperefs);
2921 0 : if (ref->paramconstraints) {
2922 : int i;
2923 0 : int count = ref->methodref->parseddesc.md->paramcount;
2924 :
2925 0 : for (i=0; i<count; ++i)
2926 0 : unresolved_subtype_set_free_list(ref->paramconstraints[i].subtyperefs);
2927 0 : MFREE(ref->paramconstraints,unresolved_subtype_set,count);
2928 : }
2929 : #endif
2930 0 : FREE(ref,unresolved_method);
2931 0 : }
2932 :
2933 : /******************************************************************************/
2934 : /* DEBUG DUMPS */
2935 : /******************************************************************************/
2936 :
2937 : #if !defined(NDEBUG)
2938 :
2939 : /* unresolved_subtype_set_debug_dump *******************************************
2940 :
2941 : Print debug info for unresolved_subtype_set to stream
2942 :
2943 : IN:
2944 : stset............the unresolved_subtype_set
2945 : file.............the stream
2946 :
2947 : *******************************************************************************/
2948 :
2949 0 : void unresolved_subtype_set_debug_dump(unresolved_subtype_set *stset,FILE *file)
2950 : {
2951 : classref_or_classinfo *p;
2952 :
2953 0 : if (SUBTYPESET_IS_EMPTY(*stset)) {
2954 0 : fprintf(file," (empty)\n");
2955 : }
2956 : else {
2957 0 : p = stset->subtyperefs;
2958 0 : for (;p->any; ++p) {
2959 0 : if (p->is_classref()) {
2960 0 : fprintf(file," ref: ");
2961 0 : utf_fprint_printable_ascii(file,p->ref->name);
2962 : }
2963 : else {
2964 0 : fprintf(file," cls: ");
2965 0 : utf_fprint_printable_ascii(file,p->cls->name);
2966 : }
2967 0 : fputc('\n',file);
2968 : }
2969 : }
2970 0 : }
2971 :
2972 : /* unresolved_class_debug_dump *************************************************
2973 :
2974 : Print debug info for unresolved_class to stream
2975 :
2976 : IN:
2977 : ref..............the unresolved_class
2978 : file.............the stream
2979 :
2980 : *******************************************************************************/
2981 :
2982 0 : void unresolved_class_debug_dump(unresolved_class *ref,FILE *file)
2983 : {
2984 0 : fprintf(file,"unresolved_class(%p):\n",(void *)ref);
2985 0 : if (ref) {
2986 0 : fprintf(file," referer : ");
2987 0 : utf_fprint_printable_ascii(file,ref->classref->referer->name); fputc('\n',file);
2988 0 : fprintf(file," refmethod : ");
2989 0 : utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
2990 0 : fprintf(file," refmethodd: ");
2991 0 : utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
2992 0 : fprintf(file," classname : ");
2993 0 : utf_fprint_printable_ascii(file,ref->classref->name); fputc('\n',file);
2994 0 : fprintf(file," subtypeconstraints:\n");
2995 0 : unresolved_subtype_set_debug_dump(&(ref->subtypeconstraints),file);
2996 : }
2997 0 : }
2998 :
2999 : /* unresolved_field_debug_dump *************************************************
3000 :
3001 : Print debug info for unresolved_field to stream
3002 :
3003 : IN:
3004 : ref..............the unresolved_field
3005 : file.............the stream
3006 :
3007 : *******************************************************************************/
3008 :
3009 0 : void unresolved_field_debug_dump(unresolved_field *ref,FILE *file)
3010 : {
3011 0 : fprintf(file,"unresolved_field(%p):\n",(void *)ref);
3012 0 : if (ref) {
3013 0 : fprintf(file," referer : ");
3014 0 : utf_fprint_printable_ascii(file,ref->referermethod->clazz->name); fputc('\n',file);
3015 0 : fprintf(file," refmethod : ");
3016 0 : utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
3017 0 : fprintf(file," refmethodd: ");
3018 0 : utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
3019 0 : fprintf(file," classname : ");
3020 0 : utf_fprint_printable_ascii(file,FIELDREF_CLASSNAME(ref->fieldref)); fputc('\n',file);
3021 0 : fprintf(file," name : ");
3022 0 : utf_fprint_printable_ascii(file,ref->fieldref->name); fputc('\n',file);
3023 0 : fprintf(file," descriptor: ");
3024 0 : utf_fprint_printable_ascii(file,ref->fieldref->descriptor); fputc('\n',file);
3025 0 : fprintf(file," parseddesc: ");
3026 0 : descriptor_debug_print_typedesc(file,ref->fieldref->parseddesc.fd); fputc('\n',file);
3027 0 : fprintf(file," flags : %04x\n",ref->flags);
3028 0 : fprintf(file," instancetypes:\n");
3029 0 : unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
3030 0 : fprintf(file," valueconstraints:\n");
3031 0 : unresolved_subtype_set_debug_dump(&(ref->valueconstraints),file);
3032 : }
3033 0 : }
3034 :
3035 : /* unresolved_method_debug_dump ************************************************
3036 :
3037 : Print debug info for unresolved_method to stream
3038 :
3039 : IN:
3040 : ref..............the unresolved_method
3041 : file.............the stream
3042 :
3043 : *******************************************************************************/
3044 :
3045 0 : void unresolved_method_debug_dump(unresolved_method *ref,FILE *file)
3046 : {
3047 : int i;
3048 :
3049 0 : fprintf(file,"unresolved_method(%p):\n",(void *)ref);
3050 0 : if (ref) {
3051 0 : fprintf(file," referer : ");
3052 0 : utf_fprint_printable_ascii(file,ref->referermethod->clazz->name); fputc('\n',file);
3053 0 : fprintf(file," refmethod : ");
3054 0 : utf_fprint_printable_ascii(file,ref->referermethod->name); fputc('\n',file);
3055 0 : fprintf(file," refmethodd: ");
3056 0 : utf_fprint_printable_ascii(file,ref->referermethod->descriptor); fputc('\n',file);
3057 0 : fprintf(file," classname : ");
3058 0 : utf_fprint_printable_ascii(file,METHODREF_CLASSNAME(ref->methodref)); fputc('\n',file);
3059 0 : fprintf(file," name : ");
3060 0 : utf_fprint_printable_ascii(file,ref->methodref->name); fputc('\n',file);
3061 0 : fprintf(file," descriptor: ");
3062 0 : utf_fprint_printable_ascii(file,ref->methodref->descriptor); fputc('\n',file);
3063 0 : fprintf(file," parseddesc: ");
3064 0 : descriptor_debug_print_methoddesc(file,ref->methodref->parseddesc.md); fputc('\n',file);
3065 0 : fprintf(file," flags : %04x\n",ref->flags);
3066 0 : fprintf(file," instancetypes:\n");
3067 0 : unresolved_subtype_set_debug_dump(&(ref->instancetypes),file);
3068 0 : fprintf(file," paramconstraints:\n");
3069 0 : if (ref->paramconstraints) {
3070 0 : for (i=0; i<ref->methodref->parseddesc.md->paramcount; ++i) {
3071 0 : fprintf(file," param %d:\n",i);
3072 0 : unresolved_subtype_set_debug_dump(ref->paramconstraints + i,file);
3073 : }
3074 : }
3075 : else {
3076 0 : fprintf(file," (empty)\n");
3077 : }
3078 : }
3079 0 : }
3080 : #endif /* !defined(NDEBUG) */
3081 :
3082 :
3083 : /*
3084 : * These are local overrides for various environment variables in Emacs.
3085 : * Please do not remove this and leave it at the end of the file, where
3086 : * Emacs will automagically detect them.
3087 : * ---------------------------------------------------------------------
3088 : * Local variables:
3089 : * mode: c++
3090 : * indent-tabs-mode: t
3091 : * c-basic-offset: 4
3092 : * tab-width: 4
3093 : * End:
3094 : * vim:noexpandtab:sw=4:ts=4:
3095 : */
|