@@ -18,8 +18,6 @@ class_info_t get_class_info(FILE *class_file)
1818 };
1919 u2 interfaces_count = read_u2 (class_file );
2020 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." );
2321 return info ;
2422}
2523
@@ -92,6 +90,75 @@ char *find_method_info_from_index(uint16_t idx,
9290 return (char * ) class_name -> info ;
9391}
9492
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+ 95162void read_method_attributes (FILE * class_file ,
96163 method_info * info ,
97164 code_t * code ,
@@ -129,6 +196,37 @@ void read_method_attributes(FILE *class_file,
129196
130197#define IS_STATIC 0x0008
131198
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+ 132230method_t * get_methods (FILE * class_file , constant_pool_t * cp )
133231{
134232 u2 method_count = read_u2 (class_file );
@@ -184,6 +282,9 @@ class_file_t get_class(FILE *class_file)
184282 /* Read information about the class that was compiled. */
185283 get_class_info (class_file );
186284
285+ /* Read the list of fields */
286+ clazz .fields = get_fields (class_file , & clazz .constant_pool , & clazz );
287+ 187288 /* Read the list of static methods */
188289 clazz .methods = get_methods (class_file , & clazz .constant_pool );
189290 return clazz ;
0 commit comments