bac879428e65b22908213d3db7b542d4d69227d8
[cacao.git] / src / vm / jit / verify / typecheck-fields.inc
1 /* src/vm/jit/verify/typecheck-fields.inc - type checking for field ICMDs
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: 
30
31    $Id$
32
33 */
34
35
36 {
37         unresolved_field *uf;
38         constant_FMIref *fieldref;
39         typeinfo *instanceti;
40         typeinfo *valueti;
41 #if !defined(TYPECHECK_TYPEINFERER)
42         resolve_result_t result;
43 #endif
44
45         TYPECHECK_COUNT(stat_ins_field);
46
47         instanceti = (instance) ? &(instance->typeinfo) : NULL;
48         valueti    = (value && value->type == TYPE_ADR) ? &(value->typeinfo) : NULL;
49
50         /* get the field reference from the instruction */
51
52         if (INSTRUCTION_IS_UNRESOLVED(state->iptr)) {
53                 uf = state->iptr->sx.s23.s3.uf;
54                 fieldref = uf->fieldref;
55         }
56         else {
57                 uf = NULL;
58                 fieldref = state->iptr->sx.s23.s3.fmiref;
59         }
60
61 #if !defined(TYPECHECK_TYPEINFERER)
62         /* check the basic value type for PUT instructions */
63
64         if (value && value->type != fieldref->parseddesc.fd->type)
65                 VERIFY_ERROR("Field type mismatch");
66
67         /* try to resolve the field reference lazily */
68
69         result = resolve_field_lazy(state->m, fieldref);
70
71         if (result == resolveSucceeded) {
72                 fieldinfo *fi;
73
74                 /* perform verification checks now */
75
76                 fi  = fieldref->p.field;
77
78                 result = resolve_field_verifier_checks(
79                                 state->m, fieldref, fi->class, fi,
80                                 instanceti, valueti,
81                                 (instance == NULL),
82                                 (value != NULL));
83         }
84
85         if (result == resolveFailed)
86                 EXCEPTION;
87
88         /* if not resolved, yet, create an unresolved field */
89
90         if (result != resolveSucceeded) {
91                 if (!uf) {
92                         uf = resolve_create_unresolved_field(state->m->class, 
93                                         state->m, state->iptr);
94                         if (!uf)
95                                 EXCEPTION;
96
97                         state->iptr->sx.s23.s3.uf = uf;
98                         state->iptr->flags.bits |= INS_FLAG_UNRESOLVED;
99                 }
100
101                 /* record the subtype constraints for this field access */
102
103                 if (!resolve_constrain_unresolved_field(
104                                         uf, state->m->class, state->m,
105                                         instanceti, valueti))
106                         EXCEPTION; /* XXX maybe wrap exception? */
107
108                 TYPECHECK_COUNTIF(INSTRUCTION_IS_UNRESOLVED(state->iptr),stat_ins_field_unresolved);
109                 TYPECHECK_COUNTIF(INSTRUCTION_IS_RESOLVED(state->iptr) && 
110                                 !state->iptr->sx.s23.s3.fmiref->p.field->class->initialized,
111                                 stat_ins_field_uninitialized);
112         }
113 #endif /* !defined(TYPECHECK_TYPEINFERER) */
114                 
115         /* write the result type */
116
117         if (value == NULL) {
118 #if defined(TYPECHECK_STACKBASED)
119                 typedescriptor *dv;
120
121                 if (IS_2_WORD_TYPE(fieldref->parseddesc.fd->type)) {
122                         CHECK_STACK_SPACE(2);
123                         stack += 2;
124                         dv = &(stack[-1]);
125                         stack[0].type = TYPE_VOID;
126                 }
127                 else {
128                         CHECK_STACK_SPACE(1);
129                         stack += 1;
130                         dv = stack;
131                 }
132 #define DST dv
133 #else
134 #define DST VAROP(state->iptr->dst)
135 #endif
136                 DST->type = fieldref->parseddesc.fd->type;
137                 if (DST->type == TYPE_ADR) {
138                         if (!typeinfo_init_from_typedesc(fieldref->parseddesc.fd,NULL,&(DST->typeinfo)))
139                                 EXCEPTION;
140                 }
141 #undef DST
142         }
143 }
144
145 /*
146  * These are local overrides for various environment variables in Emacs.
147  * Please do not remove this and leave it at the end of the file, where
148  * Emacs will automagically detect them.
149  * ---------------------------------------------------------------------
150  * Local variables:
151  * mode: c
152  * indent-tabs-mode: t
153  * c-basic-offset: 4
154  * tab-width: 4
155  * End:
156  * vim:noexpandtab:sw=4:ts=4:filetype=c:
157  */