@@ -1822,131 +1822,127 @@ void java_bytecode_parsert::read_bootstrapmethods_entry(classt &parsed_class)
1822
1822
u2_values[i] = read_u2 ();
1823
1823
1824
1824
// try parsing bootstrap method handle
1825
- if (num_bootstrap_arguments >= 3 )
1825
+ if (num_bootstrap_arguments < 3 )
1826
1826
{
1827
- // each entry contains a MethodHandle structure
1828
- // u2 tag
1829
- // u2 reference kind which must be in the range from 1 to 9
1830
- // u2 reference index into the constant pool
1831
- //
1832
- // reference kinds use the following
1833
- // 1 to 4 must point to a CONSTANT_Fieldref structure
1834
- // 5 or 8 must point to a CONSTANT_Methodref structure
1835
- // 6 or 7 must point to a CONSTANT_Methodref or
1836
- // CONSTANT_InterfaceMethodref structure, if the class file version
1837
- // number is 52.0 or above, to a CONSTANT_Methodref only in the case
1838
- // of less than 52.0
1839
- // 9 must point to a CONSTANT_InterfaceMethodref structure
1840
-
1841
- // the index must point to a CONSTANT_String
1842
- // CONSTANT_Class
1843
- // CONSTANT_Integer
1844
- // CONSTANT_Long
1845
- // CONSTANT_Float
1846
- // CONSTANT_Double
1847
- // CONSTANT_MethodHandle
1848
- // CONSTANT_MethodType
1849
-
1850
- // We read the three arguments here to see whether they correspond to
1851
- // our hypotheses for this being a lambda function entry.
1852
-
1853
- u2 argument_index1 = u2_values[0 ];
1854
- u2 argument_index2 = u2_values[1 ];
1855
- u2 argument_index3 = u2_values[2 ];
1856
-
1857
- // The additional arguments for the altmetafactory call are skipped,
1858
- // as they are currently not used. We verify though that they are of
1859
- // CONSTANT_Integer type, cases where this does not hold will be
1860
- // analyzed further.
1861
- bool recognized = true ;
1862
- for (size_t i = 3 ; i < num_bootstrap_arguments; i++)
1863
- {
1864
- u2 skipped_argument = u2_values[i];
1865
- recognized &= pool_entry (skipped_argument).tag == CONSTANT_Integer;
1866
- }
1867
- if (!recognized)
1868
- {
1869
- debug () << " format of BootstrapMethods entry not recognized" << eom;
1870
- lambda_method_handlet lambda_method_handle;
1871
- lambda_method_handle.handle_type = method_handle_typet::UNKNOWN_HANDLE;
1872
- lambda_method_handle.u2_values = std::move (u2_values);
1873
- parsed_class.lambda_method_handle_map [{parsed_class.name , bootstrap_method_index}] =
1874
- lambda_method_handle;
1875
- }
1876
- else
1877
- {
1878
- const pool_entryt &interface_type_argument =
1879
- pool_entry (argument_index1);
1880
- const pool_entryt &method_handle_argument = pool_entry (argument_index2);
1881
- const pool_entryt &method_type_argument = pool_entry (argument_index3);
1882
-
1883
- if (
1884
- !(interface_type_argument.tag == CONSTANT_MethodType &&
1885
- method_handle_argument.tag == CONSTANT_MethodHandle &&
1886
- method_type_argument.tag == CONSTANT_MethodType))
1887
- {
1888
- lambda_method_handlet lambda_method_handle;
1889
- lambda_method_handle.handle_type =
1890
- method_handle_typet::UNKNOWN_HANDLE;
1891
- lambda_method_handle.u2_values = std::move (u2_values);
1892
- parsed_class.lambda_method_handle_map [{parsed_class.name , bootstrap_method_index}] =
1893
- lambda_method_handle;
1894
- }
1895
- else
1896
- {
1897
- debug () << " INFO: parse lambda handle" << eom;
1898
- optionalt<lambda_method_handlet> lambda_method_handle =
1899
- parse_method_handle (method_handle_infot{method_handle_argument});
1900
-
1901
- if (!lambda_method_handle.has_value ())
1902
- {
1903
- lambda_method_handlet lambda_method_handle;
1904
- lambda_method_handle.handle_type =
1905
- method_handle_typet::UNKNOWN_HANDLE;
1906
- lambda_method_handle.u2_values = std::move (u2_values);
1907
- parsed_class.lambda_method_handle_map [{parsed_class.name , bootstrap_method_index}] =
1908
- lambda_method_handle;
1909
- }
1910
- else
1911
- {
1912
- if (
1913
- lambda_method_handle->handle_type !=
1914
- method_handle_typet::LAMBDA_METHOD_HANDLE)
1915
- {
1916
- lambda_method_handle->u2_values = std::move (u2_values);
1917
- error () << " ERROR: could not parse lambda function method handle"
1918
- << eom;
1919
- }
1920
- else
1921
- {
1922
- lambda_method_handle->interface_type =
1923
- pool_entry (interface_type_argument.ref1 ).s ;
1924
- lambda_method_handle->method_type =
1925
- pool_entry (method_type_argument.ref1 ).s ;
1926
- lambda_method_handle->u2_values = std::move (u2_values);
1927
- debug () << " lambda function reference "
1928
- << id2string (lambda_method_handle->lambda_method_name )
1929
- << " in class \" " << parsed_class.name << " \" "
1930
- << " \n interface type is "
1931
- << id2string (pool_entry (interface_type_argument.ref1 ).s )
1932
- << " \n method type is "
1933
- << id2string (pool_entry (method_type_argument.ref1 ).s )
1934
- << eom;
1935
- }
1936
- parsed_class.lambda_method_handle_map [{parsed_class.name , bootstrap_method_index}] =
1937
- *lambda_method_handle;
1938
- }
1939
- }
1940
- }
1827
+ lambda_method_handlet lambda_method_handle;
1828
+ lambda_method_handle.handle_type = method_handle_typet::UNKNOWN_HANDLE;
1829
+ lambda_method_handle.u2_values = std::move (u2_values);
1830
+ parsed_class.lambda_method_handle_map [{parsed_class.name ,
1831
+ bootstrap_method_index}] =
1832
+ lambda_method_handle;
1833
+ error () << " ERROR: num_bootstrap_arguments must be at least 3" << eom;
1834
+ continue ;
1941
1835
}
1942
- else
1836
+ // each entry contains a MethodHandle structure
1837
+ // u2 tag
1838
+ // u2 reference kind which must be in the range from 1 to 9
1839
+ // u2 reference index into the constant pool
1840
+ //
1841
+ // reference kinds use the following
1842
+ // 1 to 4 must point to a CONSTANT_Fieldref structure
1843
+ // 5 or 8 must point to a CONSTANT_Methodref structure
1844
+ // 6 or 7 must point to a CONSTANT_Methodref or
1845
+ // CONSTANT_InterfaceMethodref structure, if the class file version
1846
+ // number is 52.0 or above, to a CONSTANT_Methodref only in the case
1847
+ // of less than 52.0
1848
+ // 9 must point to a CONSTANT_InterfaceMethodref structure
1849
+
1850
+ // the index must point to a CONSTANT_String
1851
+ // CONSTANT_Class
1852
+ // CONSTANT_Integer
1853
+ // CONSTANT_Long
1854
+ // CONSTANT_Float
1855
+ // CONSTANT_Double
1856
+ // CONSTANT_MethodHandle
1857
+ // CONSTANT_MethodType
1858
+
1859
+ // We read the three arguments here to see whether they correspond to
1860
+ // our hypotheses for this being a lambda function entry.
1861
+
1862
+ u2 argument_index1 = u2_values[0 ];
1863
+ u2 argument_index2 = u2_values[1 ];
1864
+ u2 argument_index3 = u2_values[2 ];
1865
+
1866
+ // The additional arguments for the altmetafactory call are skipped,
1867
+ // as they are currently not used. We verify though that they are of
1868
+ // CONSTANT_Integer type, cases where this does not hold will be
1869
+ // analyzed further.
1870
+ bool recognized = true ;
1871
+ for (size_t i = 3 ; i < num_bootstrap_arguments; i++)
1872
+ {
1873
+ u2 skipped_argument = u2_values[i];
1874
+ recognized &= pool_entry (skipped_argument).tag == CONSTANT_Integer;
1875
+ }
1876
+ if (!recognized)
1943
1877
{
1878
+ debug () << " format of BootstrapMethods entry not recognized" << eom;
1944
1879
lambda_method_handlet lambda_method_handle;
1945
1880
lambda_method_handle.handle_type = method_handle_typet::UNKNOWN_HANDLE;
1946
1881
lambda_method_handle.u2_values = std::move (u2_values);
1947
1882
parsed_class.lambda_method_handle_map [{parsed_class.name , bootstrap_method_index}] =
1948
1883
lambda_method_handle;
1949
- error () << " ERROR: num_bootstrap_arguments must be at least 3" << eom;
1884
+ continue ;
1885
+ }
1886
+
1887
+ const pool_entryt &interface_type_argument =
1888
+ pool_entry (argument_index1);
1889
+ const pool_entryt &method_handle_argument = pool_entry (argument_index2);
1890
+ const pool_entryt &method_type_argument = pool_entry (argument_index3);
1891
+
1892
+ if (
1893
+ !(interface_type_argument.tag == CONSTANT_MethodType &&
1894
+ method_handle_argument.tag == CONSTANT_MethodHandle &&
1895
+ method_type_argument.tag == CONSTANT_MethodType))
1896
+ {
1897
+ lambda_method_handlet lambda_method_handle;
1898
+ lambda_method_handle.handle_type =
1899
+ method_handle_typet::UNKNOWN_HANDLE;
1900
+ lambda_method_handle.u2_values = std::move (u2_values);
1901
+ parsed_class.lambda_method_handle_map [{parsed_class.name , bootstrap_method_index}] =
1902
+ lambda_method_handle;
1903
+ continue ;
1904
+ }
1905
+
1906
+ debug () << " INFO: parse lambda handle" << eom;
1907
+ optionalt<lambda_method_handlet> lambda_method_handle =
1908
+ parse_method_handle (method_handle_infot{method_handle_argument});
1909
+
1910
+ if (!lambda_method_handle.has_value ())
1911
+ {
1912
+ lambda_method_handlet lambda_method_handle;
1913
+ lambda_method_handle.handle_type =
1914
+ method_handle_typet::UNKNOWN_HANDLE;
1915
+ lambda_method_handle.u2_values = std::move (u2_values);
1916
+ parsed_class.lambda_method_handle_map [{parsed_class.name , bootstrap_method_index}] =
1917
+ lambda_method_handle;
1918
+ continue ;
1919
+ }
1920
+
1921
+ if (
1922
+ lambda_method_handle->handle_type !=
1923
+ method_handle_typet::LAMBDA_METHOD_HANDLE)
1924
+ {
1925
+ lambda_method_handle->u2_values = std::move (u2_values);
1926
+ error () << " ERROR: could not parse lambda function method handle"
1927
+ << eom;
1928
+ continue ;
1950
1929
}
1930
+
1931
+ lambda_method_handle->interface_type =
1932
+ pool_entry (interface_type_argument.ref1 ).s ;
1933
+ lambda_method_handle->method_type =
1934
+ pool_entry (method_type_argument.ref1 ).s ;
1935
+ lambda_method_handle->u2_values = std::move (u2_values);
1936
+ debug () << " lambda function reference "
1937
+ << id2string (lambda_method_handle->lambda_method_name )
1938
+ << " in class \" " << parsed_class.name << " \" "
1939
+ << " \n interface type is "
1940
+ << id2string (pool_entry (interface_type_argument.ref1 ).s )
1941
+ << " \n method type is "
1942
+ << id2string (pool_entry (method_type_argument.ref1 ).s )
1943
+ << eom;
1944
+ parsed_class.lambda_method_handle_map [{parsed_class.name , bootstrap_method_index}] =
1945
+ *lambda_method_handle;
1946
+
1951
1947
}
1952
1948
}
0 commit comments