-
Notifications
You must be signed in to change notification settings - Fork 273
[TG-2478] Make Bootstrap methods available in method/instruction conversion #1937
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Unit tests will follow in the next few days. |
|
||
const java_class_typet::java_lambda_method_handlet &lambda_method_handle = | ||
lambda_method_handles.at( | ||
std::stoi(id2string(code_type.get(ID_java_lambda_method_handle_id)))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
index
rather than id
since I think that more strongly suggests it is a zero indexed counter rather than some unique identifier.
src/java_bytecode/java_types.h
Outdated
@@ -30,6 +30,48 @@ class java_class_typet:public class_typet | |||
{ | |||
return set(ID_access, access); | |||
} | |||
|
|||
class java_lambda_method_handlet : public exprt |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Noting my reservations about inheriting from exprt
here (my preference would be irept
since it isn't a node in an AST but we still need irep functionality to store it in a class_typet
). However interested in seeing other perspectives on this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After an offline discussion, a reasonable solution seems to be holding the method handle as a symbol_exprt
(which only has an identifier of the referred method).
// now do lambda method handles (bootstrap methods) | ||
for(const auto &lambda_entry : c.lambda_method_handle_map) | ||
{ | ||
const reference_typet lambda_ref = java_reference_type( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now I think about it a bit more, seems odd that this is a reference_typet
, why not just directly store either:
symbol_typet
symbol_exprt
of type the type of the method (e.g. acode_typet
)- just an
irep_idt
as the identifier
Again interested in other opinions on this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason why I opted for a reference here is that method handles are defined as references to methods: https://docs.oracle.com/javase/8/docs/api/java/lang/invoke/MethodHandle.html
I'm happy to change it to any of the suggested types if that would make it semantically clearer or more fitting to the CBMC logic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting - I think you're right that my suggestions aren't quite right.
However, I think what you have might be a bit of a mismatch. It seems like the type of the method handle is a java_reference_type(code_typet{params and returns})
(e.g. kind of like Predicate<Integer>
and the value is a address_of_exprt(symbol_exprt{method_name}))
(e.g. Integer::equals
).
I don't think it will cause problems, but for example I would expect if I look up a symbol_typet
in the symbol table, then what I'd get back would have is_type
set to true, wheras in this case it will be is_function()
that returns true.
Not sure - thinking in comments - do you have any thoughts on this @mgudemann ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After an offline discussion with @thk123 the type of a method handle is now symbol_exprt
. Any further thoughts on this choice would be appreciated.
const java_class_typet::java_lambda_method_handlet &lambda_method_handle = | ||
lambda_method_handles.at( | ||
std::stoi(id2string(code_type.get(ID_java_lambda_method_handle_id)))); | ||
const symbolt &lambda_method_symbol = symbol_table.lookup_ref |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So I can build directly on this - could this be moved into a method on/taking lambda_method_handles
that gives me java_lambda_method_handlet
and lambda_method_symbol
for a given index (so for example I'm protected from changes in exactly how this works: type().subtype().get(ID_identifier)
)
df3085b
to
061a72c
Compare
This is now ready for (re)review. |
@thk123 @thomasspriggs @smowton Can I please get two reviews for this? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks very good, some suggestions but I don't think anything blocking or major.
src/util/irep_ids.def
Outdated
@@ -836,6 +836,7 @@ IREP_ID_TWO(C_java_generic_symbol, #java_generic_symbol) | |||
IREP_ID_TWO(generic_types, #generic_types) | |||
IREP_ID_TWO(implicit_generic_types, #implicit_generic_types) | |||
IREP_ID_TWO(type_variables, #type_variables) | |||
IREP_ID_TWO(java_lambda_method_handle_index, #lambda_method_handle_index) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comments by convention are called ID_C_...
, though I wonder if this really should be a comment, if two invokedynamic
s refer to two different method handles they probably should be not-equal
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This index is stored in the invoke dynamic instruction together with it's type which is of the form Execute:(<arguments>)<lambda's_interface_name>
which I think should be just as unique as the index. So there's probably no harm in putting the index in comment but I'm not entirely sure about it. What would be the benefit of having it as a comment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wasn't clear - it currently is a comment (since the name starts with a #
), I agree with you - it should not be a comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I see, will change it.
|
||
const optionalt<symbolt> &lambda_method_symbol = get_lambda_method_symbol( | ||
lambda_method_handles, | ||
code_type.get(ID_java_lambda_method_handle_index)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably better to use get_int
here and have get_lambda_method_symbol
take an int
as this handles the conversion for you.
|
||
REQUIRE(num_matches == 1); | ||
INFO("Entry found"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
INFO is only printed when a require fails so I don't know if this is actually useful since it will only appear when the wrong entry is found? (e.g. count_if > == 1
but find_if == false
)
const auto num_matches = std::count_if( | ||
parsed_class.lambda_method_handle_map.begin(), | ||
parsed_class.lambda_method_handle_map.end(), | ||
[&method_type, &lambda_method_ref](const lambda_method_entryt &entry) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps store this predicate as a is_match
or remove the second loop by using copy_if
and checking there is exactly one (bit clunky I know)
? "StaticLambdas.lambda$1:(ILjava/lang/Object;LDummyGeneric;)V" | ||
: "StaticLambdas.lambda$static$1:(ILjava/lang/" | ||
"Object;LDummyGeneric;)V"; | ||
const std::string method_type = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you pull the string up a line you can suffix it to both method name variants to reduce duplication/stop the lines wrapping making it harder to follow what is going on:
const std::string lambda_method_ref =
compiler == "eclipse"
? "StaticLambdas.lambda$1:" + method_type
: "StaticLambdas.lambda$static$1:" + method_type;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also why change from descriptor
to method_type
, is descriptor not more precise?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The names for both variables come from the names of the fields of lambda_method_handlet
which (mostly) come from the bytecode specification. The thing with using method_type
in declaration of lambda_method_ref
would only work if the lambda does not capture anything so it would only work for some of the examples in the tests. I would prefer to keep it consistent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is also the reason why I introduced the lambda_method_ref
as a field, because it is unambiguous unlike method_type
.
@@ -18,19 +18,11 @@ | |||
|
|||
#include <java_bytecode/java_bytecode_parse_tree.h> | |||
#include <java_bytecode/java_types.h> | |||
#include <testing-utils/run_test_with_compilers.h> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sweet one less thing for me to do for my PR 🎉
unit/testing-utils/require_type.cpp
Outdated
@@ -394,3 +394,29 @@ java_generic_symbol_typet require_type::require_java_generic_symbol_type( | |||
|
|||
return generic_base_type; | |||
} | |||
|
|||
/// |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing doc line
#include <testing-utils/run_test_with_compilers.h> | ||
#include <testing-utils/require_type.h> | ||
|
||
SCENARIO( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These cover checking that the method handle table ends up in the symbol table, it would be great to have tests that check the indexs for the instruction end up in the instruction, but maybe this is better covered by the next step when we've actually converted that instruction.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I think it will be easier in the next step. If you would prefer to have tests at this stage, let me know.
|
||
void add_lambda_method_handle(const irep_idt &identifier) | ||
{ | ||
lambda_method_handles().emplace_back(identifier); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't appear to be quite right, due to the mix an match of move semantics and const references. My understanding is that emplace_back
will move its parameter into the vector, leaving the original copy it was passed in, in an invalid/undefined state. However the type of identifier
is const reference, which means we are promising not to update it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
emplace_back
takes arguments to pass to the constructor of the vector type (in this case const irep_idt &identifier
as an input to symbol_exprt
constructor):
http://en.cppreference.com/w/cpp/container/vector/emplace_back
I don't think the identifier is left in an invalid/undefined state, maybe the original copy of symbol_exprt
that is moved to the vector? Although the above source says that the new element is constructed 'in-place at the location provided by the container'
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, thank you for explaining how this works, I was wondering where the conversion from irep_idt to symbol_exprt was happening. I had previously been reading about &&
as part of move semantics. Why is the type of the identifier
parameter not irep_idt &&identifier
to match the type needed by emplace_back
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
emplace_back
and std::move
are different things, with similar aims. emplace_back
just tries to avoid constructing a temporary object to pass as an argument, copy-constructing an object to go in the collection, and then destructing the original temporary. It can only be used to create a new object, but it does it directly in the place it's needed.
/// unknown type | ||
optionalt<symbolt> java_bytecode_convert_methodt::get_lambda_method_symbol( | ||
const java_class_typet::java_lambda_method_handlest &lambda_method_handles, | ||
const irep_idt &index) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should this rather be an integer (size_t)?
// any symbol (it is a symbol expression with empty identifier) | ||
if(!lambda_method_handle.get_identifier().empty()) | ||
return symbol_table.lookup_ref(lambda_method_handle.get_identifier()); | ||
else |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
else
could be omitted
/// \param descriptor: the descriptor the lambda method should have | ||
/// \param entry_index: the number to skip (i.e. if multiple entries with the | ||
/// same descriptor | ||
/// \param lambda_method_ref: the reference/descriptor of the lambda method |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Side comment: I think we need a coding guideline on whether there should be a colon after the param name or not (both versions co-exist in this PR). I see the advantage of using a colon to improve readability in the source code, however, doxygen lays it out as follows: http://cprover.diffblue.com/invariant_8h.html#a66872166e18e5b1c3a087f532078b803
Ie, it seems that the colon is part of the description, which may look a bit weird.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, I created a PR to propose this in our coding standard #1959
8ad281a
to
fab5952
Compare
@thk123 @peterschrammel Thank you, the changes according to reviews are in the commits with 'cont' at the end and they will be squashed into the commits with the name before 'cont.' before merging. I rebased on top of develop so all commits are shown after the reviews though. |
2e250fe
to
f7f7901
Compare
@@ -0,0 +1,262 @@ | |||
/*******************************************************************\ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file does not appear to be in the Makefiles
9144912
to
3d6854e
Compare
When parsing invokedynamic instructions in pool table, store the index of the corresponding lambda method handle (bootstrap method) in the bootstrap methods attribute table
The method ref can differ from the interface_type and method_type when, e.g., local variables are used in the lambda method.
To test for a new field lamba_method_ref for a lambda method handle
Keeping the data members const deletes the default copy assignment operator and causes the existing unit tests crash for Microsoft Visual Studio.
5e0f38a
to
212da75
Compare
@thk123 @peterschrammel Can I please get a re-review? CI should be passing now. |
REQUIRE(matching_lambda_entry != parsed_class.lambda_method_handle_map.end()); | ||
|
||
return matching_lambda_entry->second; | ||
INFO("Number of matching lambda method entries: " << matches.size()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Won't this already be printed if the matches.size() != 1
anyway?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that is true, but in a less readable way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lgtm
/// \param lambda_method_handles Vector of lambda method handles (bootstrap | ||
/// methods) of the class where the lambda is called | ||
/// \param index Index of the lambda method handle in the vector | ||
/// \return Symbol of the lambda method if the method handle does not have an |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"... does not have an unknown ..." maybe better "... have a known ..." ?
/// unknown type | ||
optionalt<symbolt> java_bytecode_convert_methodt::get_lambda_method_symbol( | ||
const java_class_typet::java_lambda_method_handlest &lambda_method_handles, | ||
const size_t &index) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
index
should be passed by value
@@ -1791,6 +1792,7 @@ java_bytecode_parsert::parse_method_handle(const method_handle_infot &entry) | |||
// "new" when it is a class variable, instantiated in <init> | |||
lambda_method_handle.lambda_method_name = | |||
name_and_type.get_name(pool_entry_lambda); | |||
lambda_method_handle.lambda_method_ref = method_ref; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could be a std::move
} | ||
void add_unknown_lambda_method_handle() | ||
{ | ||
lambda_method_handles().emplace_back(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could you please add a comment that explains why this works? I imagine it is because UNKNOWN
is the default
Merging to avoid CI round trips, @svorenova has agreed to apply these non-blocking changes in a separate commit. |
7202003 Merge branch 'develop' of github.com:diffblue/cbmc into CBMC_subtree_2018-04-10 768e8a6 Merge pull request diffblue#2009 from romainbrenguier/solvers/sparse-arrays-in-get 69f6e7b Merge pull request diffblue#2032 from tautschnig/replace-rename-performance ec43b00 Merge pull request diffblue#2026 from tautschnig/sat-clean 64b336a Refactor interval_sparse_array::concretize 5392645 Reserve size of array in concretize 8277e92 Stop using concretize_array_expr in unit tests 1a08772 Tests where model involves long strings a6c4010 Stop using concretize_arrays_in_expression 6d87233 Use concretize instead of fill_in_array 052d503 Use get_array in get_char_array_and_concretize 8ed138b Remove unused header c58ac60 Avoid copy in ranged for loops over expressions beff419 Use sparse arrays in get_array 9b286d9 Use sparse arrays in string_refinement::get 037f631 Refactor string_refinementt::get dfc584a Add concretize function for interval_sparse_array cb10550 Use sparse arrays in substitute_array_access ce4c008 Remove plus_exprt_with_overflow_check 4779b25 Get rid of calls to plus_exprt_with_overflow c40b836 Truncate string concatenations in case of overflow c52c813 Add a sum_overflows function 0d03591 Add an `at` function for access in sparse arrays 848dd95 Add an interval_sparse_array::of_expr function 5f07bf0 Initialization of sparse array from array-list 5b4d618 Reduce number of constraints in format ede2fa1 Clear string_dependencies in calls to dec_solve d483c81 Initialize sparse array from array_exprt a914153 Use map instead of vector for sparse array entries 20d2445 Remove unused rename(expr, old_id, new_id) 430d402 Use exprt::depth_iterator in rename_symbolt 54e5b85 Use a const expr to avoid unnecessary detach 6f71ff6 replace_symbolt: stop early if there is nothing to replace with 1dbb162 Clean locally built SAT solver objects 28c076b Merge pull request diffblue#2013 from LAJW/lajw/java-no-load-class e6a9127 Merge pull request diffblue#2020 from tautschnig/sat-cleanup 70741ff Remove support for Precosat 2aa81eb Remove support for SMVSAT a0fd3f7 Remove support for Limmat as a SAT solver 28cca9c Remove unused DIMACS parser 1d81306 Merge pull request diffblue#2015 from tautschnig/fix-smt2_solver-clean 392144d Makefiles: Place .d suffix used for dependencies in DEPEXT variable 839d32a smt2_solver.{o,d} should be removed by "make clean" 48e427a Merge pull request diffblue#1979 from romainbrenguier/regression/fix-indexOf-test c2f3726 Merge pull request diffblue#1976 from romainbrenguier/regression/activate-dependency-tests 42ecfa2 Add --java-no-load-class option 69fb74a Merge pull request diffblue#1995 from tautschnig/byte-update-soundness aa766ae Set string-max-length in indexOf test 988b818 Merge pull request diffblue#1990 from tautschnig/missing-header 8300147 Abort on byte_update(pointer) 4a8d9b4 Include missing header a695814 Merge pull request diffblue#1986 from thk123/revert/1816/overlay-classes 9933b58 Revert "Merge pull request diffblue#1816 from NathanJPhillips/feature/overlay-methods" cd9b839 Revert "Merge pull request diffblue#1982 from NathanJPhillips/bugfix/load-object-once" 58beeb4 Merge pull request diffblue#1978 from svorenova/lambda_tg2478_cont 1e3a9cd Merge pull request diffblue#1980 from NathanJPhillips/tests/irept 772b603 Merge pull request diffblue#1982 from NathanJPhillips/bugfix/load-object-once 0902ae7 Tests to demonstrate expected sharing behaviour of irept 2239ec1 Unit test of irept's public API 81ac259 Prevent test running on symex-driven lazy loading eae194f Allow incorrect paths for jar files on the classpath without crashing 6749fd0 Tests to ensure invalid values in the classpath are ignored 3c95aa1 Prevent attempting to load any class more than once c520331 Unit test to show java.lang.Object can be loaded from an explicit model 05a7b4a Merge pull request diffblue#1981 from smowton/smowton/cleanup/missing-docstring e4dc2aa Merge pull request diffblue#1946 from thk123/feature/TG-1811/unit-tests-for-invokedynamic-static-lambda 2b53d3b Merge pull request diffblue#1983 from svorenova/lambda_tg2478_fix f428247 Tidying up for lambdas f3b1379 Merge pull request diffblue#1975 from romainbrenguier/bugfix/literal-length-TG2878 7d4441d Regression test for lambda in a package 7366fda Format class name for lambda method handles 7db42c0 Add missing Doxygen parameter description 31fa0fe Addressing review comments 2a0927c Merge pull request diffblue#1643 from NathanJPhillips/bugfix/string-solver-function-type-mistake 229d1ee Merge pull request diffblue#1977 from romainbrenguier/bugfix/string-equals-TG-2179 97a6713 Merge pull request diffblue#1816 from NathanJPhillips/feature/overlay-methods e2d4b09 Updates for merge 674c9f0 Activate tests for StringBuffer concat in loops a997ffb Add verification test for String.equals 1ab596d Merge commit '3b8120f3a8c9ed3a343493a44ac454ae265946c1' into develop f7602af Merge commit 'bb88574aaa4043f0ebf0ad6881ccaaeb1f0413ff' into merge-develop-20180327 55d36b5 Fix code for String.equals baf33f8 Added regression tests 9984fc1 Add ability to overlay classes with new definitions of existing methods 66c529c Tidied up java_class_loader_limitt 397c14e Correcting typos and adding documentation to unit tests 54f1c54 Adding checks for the super class of the generated class df895d3 Temp checkin for checking components 44a5dcb Adding check for inheritance 28bfc37 Amending path to reflect new location e27151b Correcting typo in the scenario name d7356be Modified behaviour to find function calls ac33761 Use raw strings to avoid unnecessary escaping 4201db9 Adding tests for static lambdas f9adaa6 Adding tests for member methods 5f5994b Pull out the logic for getting the inital assignment 7f843a7 Add natural language explanation of the test's checks fa27117 Introduce tests for lambdas that are member variables 8999cf6 Added utiltity for getting this member components 3e0e12e Adding tests for the other two returning lambdas that don't capture f3ddee6 Adding tests to verify the return of the lambda wrapper method db6756e Adding checks for parameters of the called function d2ed92b Adding test for lambda taking array parameters d171f64 Swap finding variable values to use regex 99c21ed Extended find pointer assignment to take a regex 5610aca Added unit test for lambda assigned 7b0cee1 Refactored test method to allow reuse bea730d Adding utility for verifying a set of statements contains a function call ee2179c Introduce checks the the function body for Execute calls the correct lambda 2348d10 Adding unit test for checking local lambda conversion 46fa176 Extending require utilities to be used in test 6df8d6b Extended require_goto_statements to provide meaningful errors 39282a6 Add debug information for working directory 770eb2a Remove methods without a implementation or usage 5cbb758 Merge pull request diffblue#1937 from svorenova/lambda_tg2711 8cfd9bf Merge pull request diffblue#1968 from smowton/smowton/cleanup/remove-exceptions-clarity 6ca3272 Merge pull request diffblue#1973 from karkhaz/kk-c++2a-fixes 212da75 Making members of a test utility class non-const d57fe53 Renaming the folder with lambda unit tests 823f2a7 Adding a unit test for lambda method handles in class symbol 8b172b4 Adding a utility function for lambda method handles in struct 844bb20 Pulling out a utility function to a separate file 3585f73 Updating unit tests for parsing lambda method table 078dc0f Updating a utility function a8ac3d4 Pass lambda method handles to method instruction conversion bf04c93 Add lambda method handles during class conversion a518393 Introduce lambda method handles in java class type 37afd9a Store the full method reference of lambda method handles 0a49697 Store bootstrap method index for invokedynamic instructions 56c9c02 Add test for string literals length af958f0 Correct length field of string literals a190534 Remove-exceptions: make lambda types explicit b052a4d Fix warnings emitted by C++2a compiler 20eaf21 Fix type of call to forName git-subtree-dir: cbmc git-subtree-split: 7202003985a99fb6563cf4d0fb8e7f2c727cc040
This passes the parsed bootstrap methods information to a class symbol and subsequently to method conversion. As a result, when
invokedynamic
instruction is to be converted, we have all necessary information to look up the corresponding lambda method.