@@ -22,7 +22,7 @@ class_info_t *get_class_info(FILE *class_file)
22
22
}
23
23
24
24
/**
25
- * Get the number of integer parameters that a method takes.
25
+ * Get the number of parameters that a method takes.
26
26
* Use the descriptor string of the method to determine its signature.
27
27
*/
28
28
uint16_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)
175
175
return (char * ) name -> info ;
176
176
}
177
177
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
+
178
187
void read_field_attributes (FILE * class_file , field_info * info )
179
188
{
180
189
for (u2 i = 0 ; i < info -> attributes_count ; i ++ ) {
@@ -223,6 +232,54 @@ void read_method_attributes(FILE *class_file,
223
232
assert (found_code && "Missing method code" );
224
233
}
225
234
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
+
226
283
#define IS_STATIC 0x0008
227
284
228
285
field_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)
311
368
/* Read the list of static methods */
312
369
clazz .methods = get_methods (class_file , & clazz .constant_pool );
313
370
371
+ /* Read the list of attributes */
372
+ clazz .bootstrap =
373
+ read_bootstrap_attribute (class_file , & clazz .constant_pool );
374
+
314
375
clazz .initialized = false;
315
376
316
377
return clazz ;
0 commit comments