|
20 | 20 | #include <util/expr_util.h>
|
21 | 21 |
|
22 | 22 | #include <goto-programs/cfg.h>
|
| 23 | +#include <goto-programs/class_hierarchy.h> |
23 | 24 | #include <analyses/cfg_dominators.h>
|
24 | 25 |
|
25 | 26 | #include "java_bytecode_convert_method.h"
|
@@ -91,11 +92,15 @@ java_bytecode_convert_methodt::java_bytecode_convert_methodt(
|
91 | 92 | symbol_tablet &_symbol_table,
|
92 | 93 | message_handlert &_message_handler,
|
93 | 94 | const bool &_disable_runtime_checks,
|
94 |
| - int _max_array_length): |
| 95 | + int _max_array_length, |
| 96 | + std::vector<irep_idt>& _needed_methods, |
| 97 | + const class_hierarchyt& _ch) : |
95 | 98 | messaget(_message_handler),
|
96 | 99 | symbol_table(_symbol_table),
|
97 | 100 | disable_runtime_checks(_disable_runtime_checks),
|
98 |
| - max_array_length(_max_array_length) |
| 101 | + max_array_length(_max_array_length), |
| 102 | + needed_methods(_needed_methods), |
| 103 | + class_hierarchy(_ch) |
99 | 104 | {
|
100 | 105 | }
|
101 | 106 |
|
@@ -181,6 +186,35 @@ void java_bytecode_convert_methodt::push(const exprt::operandst &o)
|
181 | 186 | stack[stack.size()-o.size()+i]=o[i];
|
182 | 187 | }
|
183 | 188 |
|
| 189 | +void java_bytecode_convert_method_lazy( |
| 190 | + const symbolt& class_symbol, |
| 191 | + const irep_idt method_identifier, |
| 192 | + const java_bytecode_parse_treet::methodt &m, |
| 193 | + symbol_tablet& symbol_table) |
| 194 | +{ |
| 195 | + symbolt method_symbol; |
| 196 | + typet member_type=java_type_from_string(m.signature); |
| 197 | + |
| 198 | + method_symbol.name=method_identifier; |
| 199 | + method_symbol.base_name=m.base_name; |
| 200 | + method_symbol.mode=ID_java; |
| 201 | + method_symbol.location=m.source_location; |
| 202 | + method_symbol.location.set_function(method_identifier); |
| 203 | + |
| 204 | + if(method_symbol.base_name=="<init>") |
| 205 | + { |
| 206 | + method_symbol.pretty_name=id2string(class_symbol.pretty_name)+"."+ |
| 207 | + id2string(class_symbol.base_name)+"()"; |
| 208 | + member_type.set(ID_constructor,true); |
| 209 | + } |
| 210 | + else |
| 211 | + method_symbol.pretty_name=id2string(class_symbol.pretty_name)+"."+ |
| 212 | + id2string(m.base_name)+"()"; |
| 213 | + |
| 214 | + method_symbol.type=member_type; |
| 215 | + symbol_table.add(method_symbol); |
| 216 | +} |
| 217 | + |
184 | 218 | /*******************************************************************\
|
185 | 219 |
|
186 | 220 | Function: java_bytecode_convert_methodt::convert
|
@@ -346,9 +380,9 @@ void java_bytecode_convert_methodt::convert(
|
346 | 380 | if(!m.is_abstract)
|
347 | 381 | method_symbol.value=convert_instructions(m, code_type);
|
348 | 382 |
|
349 |
| - // do we have the method symbol already? |
| 383 | + // Replace the existing stub symbol with the real deal: |
350 | 384 | const auto s_it=symbol_table.symbols.find(method.get_name());
|
351 |
| - if(s_it!=symbol_table.symbols.end()) |
| 385 | + assert(s_it!=symbol_table.symbols.end()); |
352 | 386 | symbol_table.symbols.erase(s_it); // erase, we stubbed it
|
353 | 387 |
|
354 | 388 | symbol_table.add(method_symbol);
|
@@ -991,13 +1025,26 @@ codet java_bytecode_convert_methodt::convert_instructions(
|
991 | 1025 | id2string(fn_basename) + "()";
|
992 | 1026 | auto fn_type=arg0.type();
|
993 | 1027 | check_stub_function(id,fn_basename,fn_prettyname,fn_type);
|
| 1028 | + |
| 1029 | + needed_methods.push_back(arg0.get(ID_identifier)); |
994 | 1030 |
|
995 | 1031 | if(is_virtual)
|
996 | 1032 | {
|
997 | 1033 | // dynamic binding
|
998 | 1034 | assert(use_this);
|
999 | 1035 | assert(!call.arguments().empty());
|
1000 | 1036 | call.function()=arg0;
|
| 1037 | + const auto& call_class=arg0.get(ID_C_class); |
| 1038 | + assert(call_class!=irep_idt()); |
| 1039 | + const auto& call_basename=arg0.get(ID_component_name); |
| 1040 | + assert(call_basename!=irep_idt()); |
| 1041 | + auto child_classes=class_hierarchy.get_children_trans(call_class); |
| 1042 | + for(const auto& child_class : child_classes) |
| 1043 | + { |
| 1044 | + auto methodid=id2string(child_class)+"."+id2string(call_basename); |
| 1045 | + if(symbol_table.has_symbol(methodid)) |
| 1046 | + needed_methods.push_back(methodid); |
| 1047 | + } |
1001 | 1048 | }
|
1002 | 1049 | else
|
1003 | 1050 | {
|
@@ -1974,13 +2021,17 @@ void java_bytecode_convert_method(
|
1974 | 2021 | symbol_tablet &symbol_table,
|
1975 | 2022 | message_handlert &message_handler,
|
1976 | 2023 | const bool &disable_runtime_checks,
|
1977 |
| - int max_array_length) |
| 2024 | + int max_array_length, |
| 2025 | + std::vector<irep_idt>& needed_methods, |
| 2026 | + const class_hierarchyt& ch) |
1978 | 2027 | {
|
1979 | 2028 | java_bytecode_convert_methodt java_bytecode_convert_method(
|
1980 | 2029 | symbol_table,
|
1981 | 2030 | message_handler,
|
1982 | 2031 | disable_runtime_checks,
|
1983 |
| - max_array_length); |
| 2032 | + max_array_length, |
| 2033 | + needed_methods, |
| 2034 | + ch); |
1984 | 2035 |
|
1985 | 2036 | java_bytecode_convert_method(class_symbol, method);
|
1986 | 2037 | }
|
0 commit comments