@@ -115,6 +115,23 @@ static prefix_filtert get_context(const optionst &options)
115
115
return prefix_filtert (std::move (context_include), std::move (context_exclude));
116
116
}
117
117
118
+ std::unordered_multimap<irep_idt, symbolt> &
119
+ lazy_class_to_declared_symbols_mapt::get (const symbol_tablet &symbol_table)
120
+ {
121
+ if (!initialized)
122
+ {
123
+ map = class_to_declared_symbols (symbol_table);
124
+ initialized = true ;
125
+ }
126
+ return map;
127
+ }
128
+
129
+ void lazy_class_to_declared_symbols_mapt::reinitialize ()
130
+ {
131
+ initialized = false ;
132
+ map.clear ();
133
+ }
134
+
118
135
// / Consume options that are java bytecode specific.
119
136
void java_bytecode_languaget::set_language_options (const optionst &options)
120
137
{
@@ -203,7 +220,26 @@ void java_bytecode_languaget::set_language_options(const optionst &options)
203
220
java_cp_include_files=" .*" ;
204
221
205
222
nondet_static = options.get_bool_option (" nondet-static" );
206
- static_values_file = options.get_option (" static-values" );
223
+ if (options.is_set (" static-values" ))
224
+ {
225
+ const std::string filename = options.get_option (" static-values" );
226
+ jsont tmp_json;
227
+ if (parse_json (filename, *message_handler, tmp_json))
228
+ {
229
+ warning () << " Provided JSON file for static-values cannot be parsed; it"
230
+ << " will be ignored." << messaget::eom;
231
+ }
232
+ else
233
+ {
234
+ if (!tmp_json.is_object ())
235
+ {
236
+ warning () << " Provided JSON file for static-values is not a JSON "
237
+ << " object; it will be ignored." << messaget::eom;
238
+ }
239
+ else
240
+ static_values_json = std::move (to_json_object (tmp_json));
241
+ }
242
+ }
207
243
208
244
ignore_manifest_main_class =
209
245
options.get_bool_option (" ignore-manifest-main-class" );
@@ -853,7 +889,9 @@ bool java_bytecode_languaget::typecheck(
853
889
symbol_table,
854
890
synthetic_methods,
855
891
threading_support,
856
- !static_values_file.empty ());
892
+ static_values_json.has_value ());
893
+
894
+ lazy_class_to_declared_symbols_mapt class_to_declared_symbols;
857
895
858
896
// Now incrementally elaborate methods
859
897
// that are reachable from this entry point.
@@ -876,18 +914,21 @@ bool java_bytecode_languaget::typecheck(
876
914
for (const auto &function_id_and_type : synthetic_methods)
877
915
{
878
916
convert_single_method (
879
- function_id_and_type.first , journalling_symbol_table);
917
+ function_id_and_type.first ,
918
+ journalling_symbol_table,
919
+ class_to_declared_symbols);
880
920
}
881
921
// Convert all methods for which we have bytecode now
882
922
for (const auto &method_sig : method_bytecode)
883
923
{
884
- convert_single_method (method_sig.first , journalling_symbol_table);
924
+ convert_single_method (
925
+ method_sig.first , journalling_symbol_table, class_to_declared_symbols);
885
926
}
886
927
// Now convert all newly added string methods
887
928
for (const auto &fn_name : journalling_symbol_table.get_inserted ())
888
929
{
889
930
if (string_preprocess.implements_function (fn_name))
890
- convert_single_method (fn_name, symbol_table);
931
+ convert_single_method (fn_name, symbol_table, class_to_declared_symbols );
891
932
}
892
933
}
893
934
break ;
@@ -982,12 +1023,17 @@ bool java_bytecode_languaget::do_ci_lazy_method_conversion(
982
1023
symbol_table_buildert symbol_table_builder =
983
1024
symbol_table_buildert::wrap (symbol_table);
984
1025
1026
+ lazy_class_to_declared_symbols_mapt class_to_declared_symbols;
1027
+
985
1028
const method_convertert method_converter =
986
- [this , &symbol_table_builder](
1029
+ [this , &symbol_table_builder, &class_to_declared_symbols ](
987
1030
const irep_idt &function_id,
988
1031
ci_lazy_methods_neededt lazy_methods_needed) {
989
1032
return convert_single_method (
990
- function_id, symbol_table_builder, std::move (lazy_methods_needed));
1033
+ function_id,
1034
+ symbol_table_builder,
1035
+ std::move (lazy_methods_needed),
1036
+ class_to_declared_symbols);
991
1037
};
992
1038
993
1039
ci_lazy_methodst method_gather (
@@ -1050,7 +1096,8 @@ void java_bytecode_languaget::convert_lazy_method(
1050
1096
journalling_symbol_tablet symbol_table=
1051
1097
journalling_symbol_tablet::wrap (symtab);
1052
1098
1053
- convert_single_method (function_id, symbol_table);
1099
+ lazy_class_to_declared_symbols_mapt class_to_declared_symbols;
1100
+ convert_single_method (function_id, symbol_table, class_to_declared_symbols);
1054
1101
1055
1102
// Instrument runtime exceptions (unless symbol is a stub)
1056
1103
if (symbol.value .is_not_nil ())
@@ -1118,10 +1165,13 @@ static void notify_static_method_calls(
1118
1165
// / \param symbol_table: global symbol table
1119
1166
// / \param needed_lazy_methods: optionally a collection of needed methods to
1120
1167
// / update with any methods touched during the conversion
1168
+ // / \param class_to_declared_symbols: maps classes to the symbols that
1169
+ // / they declare.
1121
1170
bool java_bytecode_languaget::convert_single_method (
1122
1171
const irep_idt &function_id,
1123
1172
symbol_table_baset &symbol_table,
1124
- optionalt<ci_lazy_methods_neededt> needed_lazy_methods)
1173
+ optionalt<ci_lazy_methods_neededt> needed_lazy_methods,
1174
+ lazy_class_to_declared_symbols_mapt &class_to_declared_symbols)
1125
1175
{
1126
1176
// Do not convert if method is not in context
1127
1177
if (method_in_context && !(*method_in_context)(id2string (function_id)))
@@ -1177,7 +1227,7 @@ bool java_bytecode_languaget::convert_single_method(
1177
1227
function_id,
1178
1228
symbol_table,
1179
1229
nondet_static,
1180
- !static_values_file. empty (),
1230
+ static_values_json. has_value (),
1181
1231
object_factory_parameters,
1182
1232
get_pointer_type_selector (),
1183
1233
get_message_handler ());
@@ -1186,7 +1236,7 @@ bool java_bytecode_languaget::convert_single_method(
1186
1236
function_id,
1187
1237
symbol_table,
1188
1238
nondet_static,
1189
- !static_values_file. empty (),
1239
+ static_values_json. has_value (),
1190
1240
object_factory_parameters,
1191
1241
get_pointer_type_selector (),
1192
1242
get_message_handler ());
@@ -1197,14 +1247,16 @@ bool java_bytecode_languaget::convert_single_method(
1197
1247
declaring_class (symbol_table.lookup_ref (function_id));
1198
1248
INVARIANT (
1199
1249
class_name, " user_specified_clinit must be declared by a class." );
1250
+ INVARIANT (
1251
+ static_values_json.has_value (), " static-values JSON must be available" );
1200
1252
writable_symbol.value = get_user_specified_clinit_body (
1201
1253
*class_name,
1202
- static_values_file ,
1254
+ *static_values_json ,
1203
1255
symbol_table,
1204
- get_message_handler (),
1205
1256
needed_lazy_methods,
1206
1257
max_user_array_length,
1207
- references);
1258
+ references,
1259
+ class_to_declared_symbols.get (symbol_table));
1208
1260
break ;
1209
1261
}
1210
1262
case synthetic_method_typet::STUB_CLASS_STATIC_INITIALIZER:
0 commit comments