Skip to content

Commit 061a72c

Browse files
author
svorenova
committed
Pass lambda method handles to method instruction conversion
1 parent a29ca48 commit 061a72c

File tree

2 files changed

+47
-4
lines changed

2 files changed

+47
-4
lines changed

src/java_bytecode/java_bytecode_convert_method.cpp

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,27 @@ code_typet member_type_lazy(
303303
return to_code_type(member_type_from_descriptor);
304304
}
305305

306+
/// Retrieves the symbol of the lambda method associated with the given
307+
/// lambda method handle (bootstrap method).
308+
/// \param lambda_method_handles Vector of lambda method handles (bootstrap
309+
/// methods) of the class where the lambda is called
310+
/// \param index Index of the lambda method handle in the vector
311+
/// \return Symbol of the lambda method if the method handle does not have an
312+
/// unknown type
313+
optionalt<symbolt> java_bytecode_convert_methodt::get_lambda_method_symbol(
314+
const java_class_typet::java_lambda_method_handlest &lambda_method_handles,
315+
const irep_idt &index)
316+
{
317+
const symbol_exprt &lambda_method_handle =
318+
lambda_method_handles.at(std::stoi(id2string(index)));
319+
// If the lambda method handle has an unknown type, it does not refer to
320+
// any symbol (it is a symbol expression with empty identifier)
321+
if(!lambda_method_handle.get_identifier().empty())
322+
return symbol_table.lookup_ref(lambda_method_handle.get_identifier());
323+
else
324+
return {};
325+
}
326+
306327
/// This creates a method symbol in the symtab, but doesn't actually perform
307328
/// method conversion just yet. The caller should call
308329
/// java_bytecode_convert_method later to give the symbol/method a body.
@@ -552,7 +573,11 @@ void java_bytecode_convert_methodt::convert(
552573
current_method=method_symbol.name;
553574
method_has_this=code_type.has_this();
554575
if((!m.is_abstract) && (!m.is_native))
555-
method_symbol.value=convert_instructions(m, code_type, method_symbol.name);
576+
method_symbol.value = convert_instructions(
577+
m,
578+
code_type,
579+
method_symbol.name,
580+
to_java_class_type(class_symbol.type).lambda_method_handles());
556581
}
557582

558583
const bytecode_infot &java_bytecode_convert_methodt::get_bytecode_info(
@@ -923,7 +948,8 @@ static unsigned get_bytecode_type_width(const typet &ty)
923948
codet java_bytecode_convert_methodt::convert_instructions(
924949
const methodt &method,
925950
const code_typet &method_type,
926-
const irep_idt &method_name)
951+
const irep_idt &method_name,
952+
const java_class_typet::java_lambda_method_handlest &lambda_method_handles)
927953
{
928954
const instructionst &instructions=method.instructions;
929955

@@ -1208,7 +1234,19 @@ codet java_bytecode_convert_methodt::convert_instructions(
12081234
else if(statement=="invokedynamic")
12091235
{
12101236
// not used in Java
1211-
code_typet &code_type=to_code_type(arg0.type());
1237+
code_typet &code_type = to_code_type(arg0.type());
1238+
1239+
const optionalt<symbolt> &lambda_method_symbol = get_lambda_method_symbol(
1240+
lambda_method_handles,
1241+
code_type.get(ID_java_lambda_method_handle_index));
1242+
if(lambda_method_symbol.has_value())
1243+
debug() << "Converting invokedynamic for lambda: "
1244+
<< lambda_method_symbol.value().name << eom;
1245+
else
1246+
debug() << "Converting invokedynamic for lambda with unknown handle "
1247+
"type"
1248+
<< eom;
1249+
12121250
const code_typet::parameterst &parameters(code_type.parameters());
12131251

12141252
pop(parameters.size());

src/java_bytecode/java_bytecode_convert_method_class.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,13 +235,18 @@ class java_bytecode_convert_methodt:public messaget
235235
const address_mapt &amap,
236236
bool allow_merge=true);
237237

238+
optionalt<symbolt> get_lambda_method_symbol(
239+
const java_class_typet::java_lambda_method_handlest &lambda_method_handles,
240+
const irep_idt &index);
241+
238242
// conversion
239243
void convert(const symbolt &class_symbol, const methodt &);
240244

241245
codet convert_instructions(
242246
const methodt &,
243247
const code_typet &,
244-
const irep_idt &);
248+
const irep_idt &,
249+
const java_class_typet::java_lambda_method_handlest &);
245250

246251
const bytecode_infot &get_bytecode_info(const irep_idt &statement);
247252

0 commit comments

Comments
 (0)