31 if(
c ==
'$' ||
c ==
':' ||
c ==
'.')
41 return "java::lambda_synthetic_class$" +
54static std::optional<java_class_typet::java_lambda_method_handlet>
64 if(index >= lambda_method_handles.size())
76static std::optional<java_class_typet::java_lambda_method_handlet>
88 const auto &lambda_method_handles =
class_type.lambda_method_handles();
111 return a->get_base_name() ==
b->get_base_name()
112 ? (
a->get_descriptor() ==
b->get_descriptor()
114 :
a->get_descriptor() <
b->get_descriptor())
115 :
a->get_base_name() <
b->get_base_name();
137 static const irep_idt jlo =
"java::java.lang.Object";
155 for(
const auto &base :
interface.bases())
176 for(
const auto &method :
interface.methods())
178 static const irep_idt equals =
"equals";
183 (method.get_base_name() == equals &&
185 (method.get_base_name() ==
hashCode &&
227 "produces a type with at least two unimplemented methods");
236 "produces a type with no unimplemented methods");
319 param.set_identifier(
363 param.set_identifier(
404 for(
const auto &instruction : instructions)
415 <<
" address " << instruction.address
430 <<
" address " << instruction.address <<
" for lambda: "
447#if defined(__GNUC__) && __GNUC__ >= 14
490 parameters.at(0).get_identifier(), parameters.at(0).type());
538 return std::move(result);
582 "REF_NewInvokeSpecial lambda must refer to a constructor");
598 "newinvokespecial_instance",
612static std::optional<irep_idt>
620 : std::optional<irep_idt>{};
646 const irep_idt mangled_method_name =
690 const std::string &
role)
708 "A Java non-pointer type involved in a type disagreement should"
749 const std::string &
role)
788 const auto ¶meters = function_type.parameters();
794 parameters.at(0).get_identifier(), parameters.at(0).type());
800 if(
field.get_name() ==
"@java.lang.Object")
859 "should have args for every parameter");
868 "param" + std::to_string(i));
878 function_type.return_type(),
897 return std::move(result);
struct bytecode_infot const bytecode_info[]
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Internally generated symbol table entryThis is a symbol generated as part of translation to or modifi...
An expression describing a method on a class.
A codet representing sequential composition of program statements.
void add(const codet &code)
A goto_instruction_codet representing the declaration of a local variable.
A codet representing an assignment in the program.
goto_instruction_codet representation of a function call statement.
exprt::operandst argumentst
goto_instruction_codet representation of a "return from a function" statement.
std::vector< parametert > parameterst
void set_is_constructor()
const parameterst & parameters() const
const typet & return_type() const
Data structure for representing an arbitrary statement in a program.
Operator to dereference a pointer.
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Base class for all expressions.
typet & type()
Return the type of the expression.
Represents a lambda call to a method.
std::vector< java_lambda_method_handlet > java_lambda_method_handlest
@ LAMBDA_VIRTUAL_METHOD_HANDLE
Virtual call to the given interface or method.
@ UNKNOWN_HANDLE
Can't be called.
@ LAMBDA_CONSTRUCTOR_HANDLE
Instantiate the needed type then call a constructor.
Extract member of struct or union.
Class that provides messages with a built-in verbosity 'level'.
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
bool lookup(const irep_idt &name, const symbolt *&symbol) const override
See documentation for namespace_baset::lookup().
const std::string message
no_unique_unimplemented_method_exceptiont(const std::string &s)
Symbol table entry of function parameterThis is a symbol generated as part of type checking.
The pointer type These are both 'bitvector_typet' (they have a width) and 'type_with_subtypet' (they ...
An expression containing a side effect.
A struct tag type, i.e., struct_typet with an identifier.
Expression to hold a symbol (variable)
The symbol table base class interface.
const symbolt * lookup(const irep_idt &name) const
Find a symbol in the symbol table for read-only access.
bool add(const symbolt &symbol)
Add a new symbol to the symbol table.
const symbolt & lookup_ref(const irep_idt &name) const
Find a symbol in the symbol table for read-only access.
Symbol table entry describing a data typeThis is a symbol generated as part of type checking.
static exprt conditional_cast(const exprt &expr, const typet &type)
The type of an expression, extends irept.
const std::string & id2string(const irep_idt &d)
void create_method_stub_symbol(const irep_idt &identifier, const irep_idt &base_name, const irep_idt &pretty_name, const typet &type, const irep_idt &declaring_class, symbol_table_baset &symbol_table, message_handlert &message_handler)
JAVA Bytecode Language Conversion.
irep_idt clinit_wrapper_name(const irep_idt &class_name)
Get the Java static initializer wrapper name for a given class (the wrapper checks if static initiali...
reference_typet java_reference_type(const typet &subtype)
const java_method_typet & to_java_method_type(const typet &type)
const java_reference_typet & to_java_reference_type(const typet &type)
const java_class_typet & to_java_class_type(const typet &type)
const java_primitive_type_infot * get_java_primitive_type_info(const typet &maybe_primitive_type)
If primitive_type is a Java primitive type, return information about it, otherwise return null.
const java_boxed_type_infot * get_boxed_type_info_by_name(const irep_idt &type_name)
If type_name is a Java boxed type tag, return information about it, otherwise return null.
std::optional< irep_idt > declaring_class(const symbolt &symbol)
Gets the identifier of the class which declared a given symbol.
void set_declaring_class(symbolt &symbol, const irep_idt &declaring_class)
Sets the identifier of the class which declared a given symbol to declaring_class.
irep_idt strip_java_namespace_prefix(const irep_idt &to_strip)
Strip java:: prefix from given identifier.
static symbolt implemented_method_symbol(synthetic_methods_mapt &synthetic_methods, const java_class_typet::methodt &method_to_implement, const irep_idt &synthetic_class_name)
symbolt synthetic_class_symbol(const irep_idt &synthetic_class_name, const java_class_typet::java_lambda_method_handlet &lambda_method_handle, const struct_tag_typet &functional_interface_tag, const java_method_typet &dynamic_method_type)
exprt make_function_expr(const symbolt &function_symbol, const symbol_table_baset &symbol_table)
Produce a class_method_descriptor_exprt or symbol_exprt for function_symbol depending on whether virt...
void create_invokedynamic_synthetic_classes(const irep_idt &method_identifier, const java_bytecode_parse_treet::methodt::instructionst &instructions, symbol_table_baset &symbol_table, synthetic_methods_mapt &synthetic_methods, message_handlert &message_handler)
static std::optional< java_class_typet::java_lambda_method_handlet > lambda_method_handle(const symbol_table_baset &symbol_table, const irep_idt &method_identifier, const java_method_typet &dynamic_method_type)
exprt box_or_unbox_type_if_necessary(exprt expr, const typet &required_type, code_blockt &code_block, symbol_table_baset &symbol_table, const irep_idt &function_id, const std::string &role)
If expr needs (un)boxing to satisfy required_type, add the required symbols to symbol_table and code ...
std::map< const java_class_typet::methodt *, bool, compare_base_name_and_descriptort > methods_by_name_and_descriptort
Map from method, indexed by name and descriptor but not defining class, onto defined-ness (i....
codet invokedynamic_synthetic_constructor(const irep_idt &function_id, symbol_table_baset &symbol_table, message_handlert &message_handler)
Create invokedynamic synthetic constructor.
static symbol_exprt instantiate_new_object(const irep_idt &function_id, const symbolt &lambda_method_symbol, symbol_table_baset &symbol_table, code_blockt &result)
Instantiates an object suitable for calling a given constructor (but does not actually call it).
static const java_class_typet::methodt * try_get_unique_unimplemented_method(const symbol_table_baset &symbol_table, const struct_tag_typet &functional_interface_tag, const irep_idt &method_identifier, const int instruction_address, const messaget &log)
static std::optional< irep_idt > get_unboxing_method(const pointer_typet &maybe_boxed_type)
If maybe_boxed_type is a boxed primitive return its unboxing method; otherwise return empty.
static symbol_exprt create_and_declare_local(const irep_idt &function_id, const irep_idt &basename, const typet &type, symbol_table_baset &symbol_table, code_blockt &method)
static std::string escape_symbol_special_chars(std::string input)
static const symbolt & get_or_create_method_symbol(const irep_idt &identifier, const irep_idt &base_name, const irep_idt &pretty_name, const typet &type, const irep_idt &declaring_class, symbol_table_baset &symbol_table, message_handlert &log)
exprt adjust_type_if_necessary(exprt expr, const typet &required_type, code_blockt &code_block, symbol_table_baset &symbol_table, const irep_idt &function_id, const std::string &role)
Box or unbox expr as per box_or_unbox_type_if_necessary, then cast the result to required_type.
codet invokedynamic_synthetic_method(const irep_idt &function_id, symbol_table_baset &symbol_table, message_handlert &message_handler)
Create the body for the synthetic method implementing an invokedynamic method.
static std::optional< java_class_typet::java_lambda_method_handlet > get_lambda_method_handle(const symbol_table_baset &symbol_table, const java_class_typet::java_lambda_method_handlest &lambda_method_handles, const size_t index)
Retrieves the symbol of the lambda method associated with the given lambda method handle (bootstrap m...
irep_idt lambda_synthetic_class_name(const irep_idt &method_identifier, std::size_t instruction_address)
static symbolt constructor_symbol(synthetic_methods_mapt &synthetic_methods, const irep_idt &synthetic_class_name, java_method_typet constructor_type)
static const methods_by_name_and_descriptort get_interface_methods(const irep_idt &interface_id, const namespacet &ns)
Find all methods defined by this method and its parent types, returned as a map from const java_class...
Java lambda code synthesis.
bool can_cast_type< pointer_typet >(const typet &type)
Check whether a reference to a typet is a pointer_typet.
const reference_typet & to_reference_type(const typet &type)
Cast a typet to a reference_typet.
const pointer_typet & to_pointer_type(const typet &type)
Cast a typet to a pointer_typet.
#define INVARIANT(CONDITION, REASON)
This macro uses the wrapper function 'invariant_violated_string'.
#define POSTCONDITION(CONDITION)
const code_typet & to_code_type(const typet &type)
Cast a typet to a code_typet.
const struct_tag_typet & to_struct_tag_type(const typet &type)
Cast a typet to a struct_tag_typet.
const class_typet & to_class_type(const typet &type)
Cast a typet to a class_typet.
int strcmp(const char *s1, const char *s2)
int operator()(const java_class_typet::methodt *a, const java_class_typet::methodt *b) const
Return type for get_boxed_type_info_by_name.
std::vector< instructiont > instructionst
Synthetic methods are particular methods internally generated by the Java frontend,...
std::unordered_map< irep_idt, synthetic_method_typet > synthetic_methods_mapt
Maps method names on to a synthetic method kind.
@ INVOKEDYNAMIC_METHOD
A generated method for a class capturing the parameters of an invokedynamic instruction.
@ INVOKEDYNAMIC_CAPTURE_CONSTRUCTOR
A generated constructor for a class capturing the parameters of an invokedynamic instruction.