Java lambda code synthesis. More...
#include "lambda_synthesis.h"#include <util/message.h>#include <util/namespace.h>#include <util/symbol_table_base.h>#include "java_bytecode_convert_method.h"#include "java_bytecode_parse_tree.h"#include "java_static_initializers.h"#include "java_types.h"#include "java_utils.h"#include "synthetic_methods_map.h"#include <string.h>Go to the source code of this file.
maybe_boxed_type is a boxed primitive return its unboxing method; otherwise return empty. function_symbol depending on whether virtual dispatch could be required (i.e., if it is non-static and its 'this' parameter is a non-final type) expr needs (un)boxing to satisfy required_type, add the required symbols to symbol_table and code to code_block, then return an expression giving the adjusted expression. Java lambda code synthesis.
Definition in file lambda_synthesis.cpp.
Map from method, indexed by name and descriptor but not defining class, onto defined-ness (i.e.
true if defined with a default method, false if abstract)
Definition at line 125 of file lambda_synthesis.cpp.
Box or unbox expr as per box_or_unbox_type_if_necessary, then cast the result to required_type.
If the source is legal Java that should mean a pointer upcast or primitive widening conversion, but this is not checked.
Definition at line 743 of file lambda_synthesis.cpp.
If expr needs (un)boxing to satisfy required_type, add the required symbols to symbol_table and code to code_block, then return an expression giving the adjusted expression.
Otherwise return expr unchanged. role is a suggested name prefix for any temporary variable needed; function_id is the id of the function any created code it added to.
Regarding the apparent behaviour of the Java compiler / runtime with regard to adapting generic methods to/from primtitive types:
When unboxing, it appears to permit widening numeric conversions at the same time. For example, implementing Consumer<Short> by a function of type long -> void is possible, as the generated function will look like impl(Object o) { realfunc(((Number)o).longValue()); }
On the other hand when boxing to satisfy a generic interface type this is not permitted: in theory we should be able to implement Producer<Long> by a function of type () -> int, generating boxing code like impl() { return Long.valueOf(realfunc()); }
However it appears there is no way to convey to the lambda metafactory that a Long is really required rather than an Integer (the obvious conversion from int), so the compiler forbids this and requires that only simple boxing is performed.
Therefore when unboxing we cast to Number first, while when boxing and the target type is not a specific boxed type (i.e. the target is Object or Number etc) then we use the primitive type as our cue regarding the boxed type to produce.
Definition at line 684 of file lambda_synthesis.cpp.
Definition at line 298 of file lambda_synthesis.cpp.
Definition at line 541 of file lambda_synthesis.cpp.
Definition at line 395 of file lambda_synthesis.cpp.
Definition at line 27 of file lambda_synthesis.cpp.
Find all methods defined by this method and its parent types, returned as a map from const java_class_typet::methodt * onto a boolean value which is true if the method is defined (i.e.
has a default definition) as of this node in the class graph. If there are multiple name-and-descriptor-compatible methods, for example because both If1.f(int) and If2.f(int) are inherited here, only one is stored in the map, chosen arbitrarily.
Definition at line 135 of file lambda_synthesis.cpp.
Retrieves the symbol of the lambda method associated with the given lambda method handle (bootstrap method).
Definition at line 55 of file lambda_synthesis.cpp.
Definition at line 451 of file lambda_synthesis.cpp.
If maybe_boxed_type is a boxed primitive return its unboxing method; otherwise return empty.
Definition at line 613 of file lambda_synthesis.cpp.
Definition at line 337 of file lambda_synthesis.cpp.
Instantiates an object suitable for calling a given constructor (but does not actually call it).
Adds a local to symbol_table, and code implementing the required operation to result; returns a symbol carrying a reference to the newly instantiated object.
result falls within this parameter we should instantiate. Definition at line 572 of file lambda_synthesis.cpp.
Create invokedynamic synthetic constructor.
Definition at line 475 of file lambda_synthesis.cpp.
Create the body for the synthetic method implementing an invokedynamic method.
Create invokedynamic synthetic method.
For most lambdas this means creating a simple function body like TR new_synthetic_method(T1 param1, T2 param2, ...) { return target_method(capture1, capture2, ..., param1, param2, ...); }, where the first parameter might be a this parameter. For a constructor method, the generated code will be of the form TNew new_synthetic_method(T1 param1, T2 param2, ...) { return new TNew(capture1, capture2, ..., param1, param2, ...); } i.e. the TNew object will be both instantiated and constructed.
function_id Definition at line 773 of file lambda_synthesis.cpp.
Definition at line 77 of file lambda_synthesis.cpp.
Definition at line 37 of file lambda_synthesis.cpp.
Produce a class_method_descriptor_exprt or symbol_exprt for function_symbol depending on whether virtual dispatch could be required (i.e., if it is non-static and its 'this' parameter is a non-final type)
Definition at line 626 of file lambda_synthesis.cpp.
Definition at line 250 of file lambda_synthesis.cpp.
Definition at line 204 of file lambda_synthesis.cpp.