Line data Source code
1 : /* src/vm/descriptor.hpp - checking and parsing of field / method descriptors
2 :
3 : Copyright (C) 1996-2013
4 : CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5 :
6 : This file is part of CACAO.
7 :
8 : This program is free software; you can redistribute it and/or
9 : modify it under the terms of the GNU General Public License as
10 : published by the Free Software Foundation; either version 2, or (at
11 : your option) any later version.
12 :
13 : This program is distributed in the hope that it will be useful, but
14 : WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 : General Public License for more details.
17 :
18 : You should have received a copy of the GNU General Public License
19 : along with this program; if not, write to the Free Software
20 : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 : 02110-1301, USA.
22 :
23 : */
24 :
25 :
26 : #ifndef DESCRIPTOR_HPP_
27 : #define DESCRIPTOR_HPP_ 1
28 :
29 : #include "config.h"
30 :
31 : #include <cstddef> // for size_t
32 : #include <cstdio> // for FILE
33 : #include <stdint.h> // for uint32_t, uint8_t
34 : #include <sys/types.h> // for ssize_t
35 :
36 : #include "toolbox/hashtable.hpp" // for InsertOnlyStringEntry, etc
37 :
38 : #include "vm/global.hpp" // for Type, Type::TYPE_ADR, etc
39 : #include "vm/primitive.hpp" // for PrimitiveType
40 : #include "vm/types.hpp" // for s4, u2, s2, u1
41 : #include "vm/utf8.hpp" // for Utf8String
42 :
43 : class Mutex;
44 : struct classinfo;
45 : struct constant_classref;
46 : struct typedesc;
47 : struct paramdesc;
48 : struct methoddesc;
49 :
50 :
51 : /* data structures ************************************************************/
52 :
53 : /*----------------------------------------------------------------------------*/
54 : /* Descriptor Pools */
55 : /* */
56 : /* A descriptor_pool is a temporary data structure used during loading of */
57 : /* a class. The descriptor_pool is used to allocate the table of */
58 : /* constant_classrefs the class uses, and for parsing the field and method */
59 : /* descriptors which occurr within the class. The inner workings of */
60 : /* descriptor_pool are not important for outside code. */
61 : /* */
62 : /* You use a descriptor_pool as follows: */
63 : /* */
64 : /* 1. create one with descriptor_pool_new */
65 : /* 2. add all explicit class references with descriptor_pool_add_class */
66 : /* 3. add all field/method descriptors with descriptor_pool_add */
67 : /* 4. call descriptor_pool_create_classrefs */
68 : /* You can now lookup classrefs with descriptor_pool_lookup_classref */
69 : /* 5. call descriptor_pool_alloc_parsed_descriptors */
70 : /* 6. for each field descriptor call descriptor_pool_parse_field_descriptor */
71 : /* for each method descriptor call descriptor_pool_parse_method_descriptor */
72 : /* */
73 : /* IMPORTANT: The descriptor_pool functions use DNEW and DMNEW for allocating */
74 : /* memory which can be thrown away when the steps above have been */
75 : /* done. */
76 : /*----------------------------------------------------------------------------*/
77 :
78 : struct descriptor_pool;
79 :
80 : namespace cacao {
81 :
82 35953 : struct DescriptorPool {
83 : DescriptorPool(classinfo *referer);
84 :
85 : bool add_class(Utf8String name);
86 : bool add_field(Utf8String desc);
87 : ssize_t add_method(Utf8String desc); // returns number of paramslots method needs,
88 : // or -1 on error
89 :
90 : constant_classref *create_classrefs(s4 *count);
91 : constant_classref *lookup_classref(Utf8String classname);
92 :
93 : void alloc_parsed_descriptors();
94 :
95 : typedesc *parse_field_descriptor(Utf8String desc);
96 : methoddesc *parse_method_descriptor(Utf8String desc, s4 mflags, constant_classref *thisclass);
97 :
98 : classinfo *get_referer();
99 :
100 : void get_sizes(size_t *classrefsize, size_t *descsize);
101 : private:
102 : template<typename T>
103 : inline T *allocate(size_t size = sizeof(T));
104 :
105 : typedef HashTable<InsertOnlyNameValuePair<u2> > ClassrefHash;
106 : typedef HashTable<InsertOnlyNameValuePair<typedesc*> > FieldrefHash;
107 :
108 : ClassrefHash classrefhash;
109 : FieldrefHash fieldrefhash;
110 :
111 : classinfo *referer;
112 : size_t fieldcount;
113 : size_t methodcount;
114 : size_t paramcount;
115 : size_t descriptorsize;
116 : constant_classref *classrefs;
117 : Mutex *mutex;
118 :
119 : // we allocate all typedesc & methoddesc from a big chunk of memory
120 : // created in alloc_parsed_descriptors
121 : uint8_t *descriptors;
122 : uint8_t *descriptors_next;
123 : };
124 :
125 :
126 : } // end namespace cacao
127 :
128 :
129 : /* data structures for parsed field/method descriptors ************************/
130 :
131 : struct typedesc {
132 : // return the size in bytes needed for the given type.
133 : inline size_t typesize() const;
134 :
135 : constant_classref *classref; /* class reference for TYPE_ADR types */
136 : Type type : 8; /* TYPE_??? constant [1] */
137 : PrimitiveType primitivetype : 8; /* (PRIMITIVE)TYPE_??? constant [2] */
138 : u1 arraydim; /* array dimension (0 if no array) */
139 : };
140 :
141 : /* [1]...the type field contains the basic type used within the VM. So ints, */
142 : /* shorts, chars, bytes, booleans all have TYPE_INT. */
143 : /* [2]...the primitivetype field contains the declared type. */
144 : /* So short is PRIMITIVETYPE_SHORT, char is PRIMITIVETYPE_CHAR. */
145 : /* For non-primitive types primitivetype is TYPE_ADR. */
146 :
147 : struct paramdesc {
148 : #if defined(__MIPS__)
149 : Type type : 8; /* TYPE_??? of the register allocated */
150 : #endif
151 : bool inmemory; /* argument in register or on stack */
152 : uint32_t index; /* index into argument register array */
153 : uint32_t regoff; /* register index or stack offset */
154 : };
155 :
156 : struct methoddesc {
157 : void params_from_paramtypes(s4 mflags);
158 :
159 : s2 paramcount; /* number of parameters */
160 : s2 paramslots; /* like above but LONG,DOUBLE count twice */
161 : s4 argintreguse; /* number of used integer argument registers */
162 : s4 argfltreguse; /* number of used float argument registers */
163 : s4 memuse; /* number of stack slots used */
164 : paramdesc *params; /* allocated parameter descriptions [3] */
165 : Mutex *pool_lock; /* synchronizes access to params */
166 : typedesc returntype; /* parsed descriptor of the return type */
167 : typedesc paramtypes[1]; /* parameter types, variable length! */
168 : };
169 :
170 : /* [3]...If params is NULL, the parameter descriptions have not yet been */
171 : /* allocated. In this case ___the possible 'this' pointer of the method */
172 : /* is NOT counted in paramcount/paramslots and it is NOT included in */
173 : /* the paramtypes array___. */
174 : /* If params != NULL, the parameter descriptions have been */
175 : /* allocated, and the 'this' pointer of the method, if any, IS included.*/
176 : /* In case the method has no parameters at all, the special value */
177 : /* METHODDESC_NO_PARAMS is used (see below). */
178 :
179 : /* METHODDESC_NO_PARAMS is a special value for the methoddesc.params field */
180 : /* indicating that the method is a static method without any parameters. */
181 : /* This special value must be != NULL and it may only be set if */
182 : /* md->paramcount == 0. */
183 :
184 : #define METHODDESC_NOPARAMS ((paramdesc*)1)
185 :
186 : /* function prototypes ********************************************************/
187 :
188 : Type descriptor_to_basic_type(Utf8String desc);
189 :
190 : void descriptor_debug_print_typedesc(FILE*,typedesc*);
191 : void descriptor_debug_print_methoddesc(FILE*,methoddesc*);
192 :
193 : /* inline functions ********************************************************/
194 :
195 52174 : inline size_t typedesc::typesize() const {
196 52174 : switch (type) {
197 : case TYPE_INT:
198 : case TYPE_FLT:
199 15150 : return 4;
200 :
201 : case TYPE_LNG:
202 : case TYPE_DBL:
203 5908 : return 8;
204 :
205 : case TYPE_ADR:
206 31116 : return SIZEOF_VOID_P;
207 :
208 : default:
209 0 : assert(false && "Illegal Type");
210 : return 0;
211 : }
212 : }
213 :
214 :
215 : #endif // DESCRIPTOR_HPP_
216 :
217 :
218 : /*
219 : * These are local overrides for various environment variables in Emacs.
220 : * Please do not remove this and leave it at the end of the file, where
221 : * Emacs will automagically detect them.
222 : * ---------------------------------------------------------------------
223 : * Local variables:
224 : * mode: c++
225 : * indent-tabs-mode: t
226 : * c-basic-offset: 4
227 : * tab-width: 4
228 : * End:
229 : * vim:noexpandtab:sw=4:ts=4:
230 : */
|