@@ -306,6 +306,25 @@ code_typet member_type_lazy(
306306 return to_code_type (member_type_from_descriptor);
307307}
308308
309+ // / Retrieves the symbol of the lambda method associated with the given
310+ // / lambda method handle (bootstrap method).
311+ // / \param lambda_method_handles Vector of lambda method handles (bootstrap
312+ // / methods) of the class where the lambda is called
313+ // / \param index Index of the lambda method handle in the vector
314+ // / \return Symbol of the lambda method if the method handle does not have an
315+ // / unknown type
316+ optionalt<symbolt> java_bytecode_convert_methodt::get_lambda_method_symbol (
317+ const java_class_typet::java_lambda_method_handlest &lambda_method_handles,
318+ const size_t &index)
319+ {
320+ const symbol_exprt &lambda_method_handle = lambda_method_handles.at (index);
321+ // If the lambda method handle has an unknown type, it does not refer to
322+ // any symbol (it is a symbol expression with empty identifier)
323+ if (!lambda_method_handle.get_identifier ().empty ())
324+ return symbol_table.lookup_ref (lambda_method_handle.get_identifier ());
325+ return {};
326+ }
327+
309328// / This creates a method symbol in the symtab, but doesn't actually perform
310329// / method conversion just yet. The caller should call
311330// / java_bytecode_convert_method later to give the symbol/method a body.
@@ -555,7 +574,11 @@ void java_bytecode_convert_methodt::convert(
555574 current_method=method_symbol.name ;
556575 method_has_this=code_type.has_this ();
557576 if ((!m.is_abstract ) && (!m.is_native ))
558- method_symbol.value =convert_instructions (m, code_type, method_symbol.name );
577+ method_symbol.value = convert_instructions (
578+ m,
579+ code_type,
580+ method_symbol.name ,
581+ to_java_class_type (class_symbol.type ).lambda_method_handles ());
559582}
560583
561584const bytecode_infot &java_bytecode_convert_methodt::get_bytecode_info (
@@ -926,7 +949,8 @@ static unsigned get_bytecode_type_width(const typet &ty)
926949codet java_bytecode_convert_methodt::convert_instructions (
927950 const methodt &method,
928951 const code_typet &method_type,
929- const irep_idt &method_name)
952+ const irep_idt &method_name,
953+ const java_class_typet::java_lambda_method_handlest &lambda_method_handles)
930954{
931955 const instructionst &instructions=method.instructions ;
932956
@@ -1211,7 +1235,19 @@ codet java_bytecode_convert_methodt::convert_instructions(
12111235 else if (statement==" invokedynamic" )
12121236 {
12131237 // not used in Java
1214- code_typet &code_type=to_code_type (arg0.type ());
1238+ code_typet &code_type = to_code_type (arg0.type ());
1239+
1240+ const optionalt<symbolt> &lambda_method_symbol = get_lambda_method_symbol (
1241+ lambda_method_handles,
1242+ code_type.get_int (ID_java_lambda_method_handle_index));
1243+ if (lambda_method_symbol.has_value ())
1244+ debug () << " Converting invokedynamic for lambda: "
1245+ << lambda_method_symbol.value ().name << eom;
1246+ else
1247+ debug () << " Converting invokedynamic for lambda with unknown handle "
1248+ " type"
1249+ << eom;
1250+
12151251 const code_typet::parameterst ¶meters (code_type.parameters ());
12161252
12171253 pop (parameters.size ());
0 commit comments