@@ -18,8 +18,6 @@ class_info_t get_class_info(FILE *class_file)
18
18
};
19
19
u2 interfaces_count = read_u2 (class_file );
20
20
assert (!interfaces_count && "This VM does not support interfaces." );
21
- u2 fields_count = read_u2 (class_file );
22
- assert (!fields_count && "This VM does not support fields." );
23
21
return info ;
24
22
}
25
23
@@ -92,6 +90,75 @@ char *find_method_info_from_index(uint16_t idx,
92
90
return (char * ) class_name -> info ;
93
91
}
94
92
93
+ CONSTANT_FieldOrMethodRef_info * get_fieldref (constant_pool_t * cp , u2 idx )
94
+ {
95
+ const_pool_info * field = get_constant (cp , idx );
96
+ assert (field -> tag == CONSTANT_FieldRef && "Expected a FieldRef" );
97
+ return (CONSTANT_FieldOrMethodRef_info * ) field -> info ;
98
+ }
99
+
100
+ /**
101
+ * Find the field info corresponding to the given constant pool index.
102
+ *
103
+ * @param index the constant pool index of the Methodref to call
104
+ * @param clazz the parsed class file
105
+ * @param name_info the pointer that will contain method name on return
106
+ * @param descriptor_info the pointer that will contain method infomation on
107
+ * return
108
+ * @return the class name which has this field
109
+ */
110
+ char * find_field_info_from_index (uint16_t idx ,
111
+ class_file_t * clazz ,
112
+ char * * name_info ,
113
+ char * * descriptor_info )
114
+ {
115
+ CONSTANT_FieldOrMethodRef_info * field_ref =
116
+ get_fieldref (& clazz -> constant_pool , idx );
117
+ const_pool_info * name_and_type =
118
+ get_constant (& clazz -> constant_pool , field_ref -> name_and_type_index );
119
+ assert (name_and_type -> tag == CONSTANT_NameAndType &&
120
+ "Expected a NameAndType" );
121
+ const_pool_info * name = get_constant (
122
+ & clazz -> constant_pool ,
123
+ ((CONSTANT_NameAndType_info * ) name_and_type -> info )-> name_index );
124
+ assert (name -> tag == CONSTANT_Utf8 && "Expected a UTF8" );
125
+ const_pool_info * descriptor = get_constant (
126
+ & clazz -> constant_pool ,
127
+ ((CONSTANT_NameAndType_info * ) name_and_type -> info )-> descriptor_index );
128
+ assert (descriptor -> tag == CONSTANT_Utf8 && "Expected a UTF8" );
129
+ CONSTANT_Class_info * class_info =
130
+ get_class_name (& clazz -> constant_pool , field_ref -> class_index );
131
+ const_pool_info * class_name =
132
+ get_constant (& clazz -> constant_pool , class_info -> string_index );
133
+ * name_info = (char * ) name -> info ;
134
+ * descriptor_info = (char * ) descriptor -> info ;
135
+
136
+ return (char * ) class_name -> info ;
137
+ }
138
+
139
+ char * find_class_name_from_index (uint16_t idx , class_file_t * clazz )
140
+ {
141
+ CONSTANT_Class_info * class = get_class_name (& clazz -> constant_pool , idx );
142
+
143
+ const_pool_info * name =
144
+ get_constant (& clazz -> constant_pool , class -> string_index );
145
+ assert (name -> tag == CONSTANT_Utf8 && "Expected a UTF8" );
146
+ return (char * ) name -> info ;
147
+ }
148
+
149
+ void read_field_attributes (FILE * class_file , field_info * info )
150
+ {
151
+ for (u2 i = 0 ; i < info -> attributes_count ; i ++ ) {
152
+ attribute_info ainfo = {
153
+ .attribute_name_index = read_u2 (class_file ),
154
+ .attribute_length = read_u4 (class_file ),
155
+ };
156
+ long attribute_end = ftell (class_file ) + ainfo .attribute_length ;
157
+ /* Skip all the attribute */
158
+ fseek (class_file , attribute_end , SEEK_SET );
159
+ }
160
+ }
161
+
95
162
void read_method_attributes (FILE * class_file ,
96
163
method_info * info ,
97
164
code_t * code ,
@@ -129,6 +196,37 @@ void read_method_attributes(FILE *class_file,
129
196
130
197
#define IS_STATIC 0x0008
131
198
199
+ field_t * get_fields (FILE * class_file , constant_pool_t * cp , class_file_t * clazz )
200
+ {
201
+ u2 fields_count = read_u2 (class_file );
202
+ clazz -> fields_count = fields_count ;
203
+ field_t * fields = malloc (sizeof (* fields ) * (fields_count + 1 ));
204
+ assert (fields && "Failed to allocate methods" );
205
+
206
+ field_t * field = fields ;
207
+ for (u2 i = 0 ; i < fields_count ; i ++ , field ++ ) {
208
+ field_info info = {
209
+ .access_flags = read_u2 (class_file ),
210
+ .name_index = read_u2 (class_file ),
211
+ .descriptor_index = read_u2 (class_file ),
212
+ .attributes_count = read_u2 (class_file ),
213
+ };
214
+
215
+ const_pool_info * name = get_constant (cp , info .name_index );
216
+ assert (name -> tag == CONSTANT_Utf8 && "Expected a UTF8" );
217
+ field -> name = (char * ) name -> info ;
218
+ const_pool_info * descriptor = get_constant (cp , info .descriptor_index );
219
+ assert (descriptor -> tag == CONSTANT_Utf8 && "Expected a UTF8" );
220
+ field -> descriptor = (char * ) descriptor -> info ;
221
+
222
+ read_field_attributes (class_file , & info );
223
+ }
224
+
225
+ /* Mark end of array with NULL name */
226
+ field -> name = NULL ;
227
+ return fields ;
228
+ }
229
+
132
230
method_t * get_methods (FILE * class_file , constant_pool_t * cp )
133
231
{
134
232
u2 method_count = read_u2 (class_file );
@@ -184,6 +282,9 @@ class_file_t get_class(FILE *class_file)
184
282
/* Read information about the class that was compiled. */
185
283
get_class_info (class_file );
186
284
285
+ /* Read the list of fields */
286
+ clazz .fields = get_fields (class_file , & clazz .constant_pool , & clazz );
287
+
187
288
/* Read the list of static methods */
188
289
clazz .methods = get_methods (class_file , & clazz .constant_pool );
189
290
return clazz ;
0 commit comments