@@ -22,7 +22,7 @@ class_info_t *get_class_info(FILE *class_file)
2222}
2323
2424/**
25- * Get the number of integer parameters that a method takes.
25+ * Get the number of parameters that a method takes.
2626 * Use the descriptor string of the method to determine its signature.
2727 */
2828uint16_t get_number_of_parameters (method_t * method )
@@ -175,6 +175,15 @@ char *find_class_name_from_index(uint16_t idx, class_file_t *clazz)
175175 return (char * ) name -> info ;
176176}
177177
178+ bootmethods_t * find_bootstrap_method (uint16_t idx , class_file_t * clazz )
179+ {
180+ const_pool_info * info = get_constant (& clazz -> constant_pool , idx );
181+ assert (info -> tag == CONSTANT_InvokeDynamic && "Expected a InvokeDynanmic" );
182+ return & clazz -> bootstrap
183+ -> bootstrap_methods [((CONSTANT_InvokeDynamic_info * ) info -> info )
184+ -> bootstrap_method_attr_index ];
185+ }
186+ 178187void read_field_attributes (FILE * class_file , field_info * info )
179188{
180189 for (u2 i = 0 ; i < info -> attributes_count ; i ++ ) {
@@ -223,6 +232,54 @@ void read_method_attributes(FILE *class_file,
223232 assert (found_code && "Missing method code" );
224233}
225234
235+ bootmethods_attr_t * read_bootstrap_attribute (FILE * class_file ,
236+ constant_pool_t * cp )
237+ {
238+ u2 attributes_count = read_u2 (class_file );
239+ for (u2 i = 0 ; i < attributes_count ; i ++ ) {
240+ attribute_info ainfo = {
241+ .attribute_name_index = read_u2 (class_file ),
242+ .attribute_length = read_u4 (class_file ),
243+ };
244+ long attribute_end = ftell (class_file ) + ainfo .attribute_length ;
245+ const_pool_info * type_constant =
246+ get_constant (cp , ainfo .attribute_name_index );
247+ assert (type_constant -> tag == CONSTANT_Utf8 && "Expected a UTF8" );
248+ if (!strcmp ((char * ) type_constant -> info , "BootstrapMethods" )) {
249+ bootmethods_attr_t * bootstrap = malloc (sizeof (* bootstrap ));
250+ 251+ bootstrap -> num_bootstrap_methods = read_u2 (class_file );
252+ bootstrap -> bootstrap_methods = malloc (
253+ sizeof (bootmethods_t ) * bootstrap -> num_bootstrap_methods );
254+ 255+ assert (bootstrap -> bootstrap_methods &&
256+ "Failed to allocate bootstrap method" );
257+ for (int j = 0 ; j < bootstrap -> num_bootstrap_methods ; ++ j ) {
258+ bootstrap -> bootstrap_methods [j ].bootstrap_method_ref =
259+ read_u2 (class_file );
260+ bootstrap -> bootstrap_methods [j ].num_bootstrap_arguments =
261+ read_u2 (class_file );
262+ bootstrap -> bootstrap_methods [j ].bootstrap_arguments = malloc (
263+ sizeof (u2 ) *
264+ bootstrap -> bootstrap_methods [j ].num_bootstrap_arguments );
265+ assert (bootstrap -> bootstrap_methods [j ].bootstrap_arguments &&
266+ "Failed to allocate bootstrap argument" );
267+ for (int k = 0 ;
268+ k <
269+ bootstrap -> bootstrap_methods [j ].num_bootstrap_arguments ;
270+ ++ k ) {
271+ bootstrap -> bootstrap_methods [j ].bootstrap_arguments [k ] =
272+ read_u2 (class_file );
273+ }
274+ }
275+ return bootstrap ;
276+ }
277+ /* Skip the rest of the attribute */
278+ fseek (class_file , attribute_end , SEEK_SET );
279+ }
280+ return NULL ;
281+ }
282+ 226283#define IS_STATIC 0x0008
227284
228285field_t * get_fields (FILE * class_file , constant_pool_t * cp , class_file_t * clazz )
@@ -311,6 +368,10 @@ class_file_t get_class(FILE *class_file)
311368 /* Read the list of static methods */
312369 clazz .methods = get_methods (class_file , & clazz .constant_pool );
313370
371+ /* Read the list of attributes */
372+ clazz .bootstrap =
373+ read_bootstrap_attribute (class_file , & clazz .constant_pool );
374+ 314375 clazz .initialized = false;
315376
316377 return clazz ;
0 commit comments