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