14
14
#include < util/suffix.h>
15
15
#include < util/config.h>
16
16
#include < util/cmdline.h>
17
+ #include < util/journalling_symbol_table.h>
17
18
#include < util/string2int.h>
18
19
#include < util/invariant.h>
19
20
#include < json/json_parser.h>
@@ -247,16 +248,20 @@ bool java_bytecode_languaget::typecheck(
247
248
}
248
249
else if (lazy_methods_mode==LAZY_METHODS_MODE_EAGER)
249
250
{
250
- // Simply elaborate all methods symbols now.
251
+ journalling_symbol_tablet journalling_symbol_table =
252
+ journalling_symbol_tablet::wrap (symbol_table);
253
+ // Convert all methods for which we have bytecode now
251
254
for (const auto &method_sig : method_bytecode)
252
255
{
253
- java_bytecode_convert_method (
254
- symbol_table.lookup_ref (method_sig.second .class_id ),
255
- method_sig.second .method ,
256
- symbol_table,
257
- get_message_handler (),
258
- max_user_array_length,
259
- string_preprocess);
256
+ convert_single_method (method_sig.first , journalling_symbol_table);
257
+ }
258
+ // Now convert all newly added string methods
259
+ id_sett string_methods;
260
+ string_preprocess.get_all_function_names (string_methods);
261
+ for (const auto &fn_name : journalling_symbol_table.get_inserted ())
262
+ {
263
+ if (string_methods.count (fn_name) != 0 )
264
+ convert_single_method (fn_name, symbol_table);
260
265
}
261
266
}
262
267
// Otherwise our caller is in charge of elaborating methods on demand.
@@ -310,19 +315,13 @@ bool java_bytecode_languaget::do_ci_lazy_method_conversion(
310
315
symbol_tablet &symbol_table,
311
316
method_bytecodet &method_bytecode)
312
317
{
313
- const auto method_converter = [&](
314
- const symbolt &symbol,
315
- const java_bytecode_parse_treet::methodt &method,
316
- ci_lazy_methods_neededt new_lazy_methods) {
317
- java_bytecode_convert_method (
318
- symbol,
319
- method,
320
- symbol_table,
321
- get_message_handler (),
322
- max_user_array_length,
323
- std::move (new_lazy_methods),
324
- string_preprocess);
325
- };
318
+ const method_convertert method_converter =
319
+ [this , &symbol_table]
320
+ (const irep_idt &function_id, ci_lazy_methods_neededt lazy_methods_needed)
321
+ {
322
+ return convert_single_method (
323
+ function_id, symbol_table, std::move (lazy_methods_needed));
324
+ };
326
325
327
326
ci_lazy_methodst method_gather (
328
327
symbol_table,
@@ -349,9 +348,11 @@ const select_pointer_typet &
349
348
// / \return Populates `methods` with the complete list of lazy methods that are
350
349
// / available to convert (those which are valid parameters for
351
350
// / `convert_lazy_method`)
352
- void java_bytecode_languaget::methods_provided (
353
- std::set<irep_idt> &methods) const
351
+ void java_bytecode_languaget::methods_provided (id_sett &methods) const
354
352
{
353
+ // Add all string solver methods to map
354
+ string_preprocess.get_all_function_names (methods);
355
+ // Add all concrete methods to map
355
356
for (const auto &kv : method_bytecode)
356
357
methods.insert (kv.first );
357
358
}
@@ -368,59 +369,60 @@ void java_bytecode_languaget::convert_lazy_method(
368
369
const irep_idt &function_id,
369
370
symbol_tablet &symbol_table)
370
371
{
371
- const method_bytecodet::class_method_and_bytecodet &cmb =
372
- *method_bytecode.get (function_id);
373
- java_bytecode_convert_method (
374
- symbol_table.lookup_ref (cmb.class_id ),
375
- cmb.method ,
376
- symbol_table,
377
- get_message_handler (),
378
- max_user_array_length,
379
- string_preprocess);
372
+ convert_single_method (function_id, symbol_table);
380
373
}
381
374
382
- // / Replace methods of the String library that are in the symbol table by code
383
- // / generated by string_preprocess.
384
- // / \param context: a symbol table
385
- void java_bytecode_languaget::replace_string_methods (
386
- symbol_table_baset &context)
375
+ // / \brief Convert a method (one whose type is known but whose body hasn't
376
+ // / been converted) but don't run typecheck, etc
377
+ // / \remarks Amends the symbol table entry for function `function_id`, which
378
+ // / should be a method provided by this instance of `java_bytecode_languaget`
379
+ // / to have a value representing the method body.
380
+ // / \param function_id: method ID to convert
381
+ // / \param symbol_table: global symbol table
382
+ // / \param needed_lazy_methods: optionally a collection of needed methods to
383
+ // / update with any methods touched during the conversion
384
+ bool java_bytecode_languaget::convert_single_method (
385
+ const irep_idt &function_id,
386
+ symbol_table_baset &symbol_table,
387
+ optionalt<ci_lazy_methods_neededt> needed_lazy_methods)
387
388
{
388
- // Symbols that have code type are potentialy to be replaced
389
- std::list<symbolt> code_symbols;
390
- forall_symbols (symbol, context.symbols )
389
+ const symbolt &symbol = symbol_table.lookup_ref (function_id);
390
+
391
+ // Nothing to do if body is already loaded
392
+ if (symbol.value .is_not_nil ())
393
+ return false ;
394
+
395
+ exprt generated_code =
396
+ string_preprocess.code_for_function (symbol, symbol_table);
397
+ if (generated_code.is_not_nil ())
391
398
{
392
- if (symbol->second .type .id ()==ID_code)
393
- code_symbols.push_back (symbol->second );
399
+ // Populate body of the function with code generated by string preprocess
400
+ symbol_table.get_writeable_ref (function_id).value = generated_code;
401
+ return false ;
394
402
}
395
403
396
- for (const auto &symbol : code_symbols)
404
+ // No string solver implementation, check if have bytecode for it
405
+ method_bytecodet::opt_reft cmb = method_bytecode.get (function_id);
406
+ if (cmb)
397
407
{
398
- const irep_idt &id=symbol.name ;
399
- exprt generated_code=string_preprocess.code_for_function (
400
- id, to_code_type (symbol.type ), symbol.location , context);
401
- if (generated_code.is_not_nil ())
402
- {
403
- // Replace body of the function by code generated by string preprocess
404
- symbolt &symbol=*context.get_writeable (id);
405
- symbol.value =generated_code;
406
- // Specifically instrument the new code, since this comes after the
407
- // blanket instrumentation pass called before typechecking.
408
- java_bytecode_instrument_symbol (
409
- context,
410
- symbol,
411
- throw_runtime_exceptions,
412
- get_message_handler ());
413
- }
408
+ java_bytecode_convert_method (
409
+ symbol_table.lookup_ref (cmb->get ().class_id ),
410
+ cmb->get ().method ,
411
+ symbol_table,
412
+ get_message_handler (),
413
+ max_user_array_length,
414
+ std::move (needed_lazy_methods),
415
+ string_preprocess);
416
+ return false ;
414
417
}
418
+
419
+ return true ;
415
420
}
416
421
417
422
bool java_bytecode_languaget::final (symbol_table_baset &symbol_table)
418
423
{
419
424
PRECONDITION (language_options_initialized);
420
425
421
- // replace code of String methods calls by code we generate
422
- replace_string_methods (symbol_table);
423
-
424
426
return false ;
425
427
}
426
428
0 commit comments