Skip to content

Commit 7e5f1ac

Browse files
committed
De-duplicate initialize_goto_model's code
lazy_goto_modelt used almost the same code. Refactor initialize_goto_model's implementation to enable re-use from lazy_goto_modelt.
1 parent 5ed1623 commit 7e5f1ac

File tree

5 files changed

+142
-153
lines changed

5 files changed

+142
-153
lines changed

jbmc/src/java_bytecode/lazy_goto_model.cpp

Lines changed: 15 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,17 @@
55

66
#include "lazy_goto_model.h"
77

8-
#include "java_bytecode_language.h"
8+
#include <util/config.h>
9+
#include <util/exception_utils.h>
10+
#include <util/journalling_symbol_table.h>
11+
#include <util/options.h>
912

13+
#include <goto-programs/initialize_goto_model.h>
1014
#include <goto-programs/read_goto_binary.h>
11-
#include <goto-programs/rebuild_goto_start_function.h>
1215

1316
#include <langapi/mode.h>
1417

15-
#include <util/config.h>
16-
#include <util/exception_utils.h>
17-
#include <util/journalling_symbol_table.h>
18-
#include <util/options.h>
18+
#include "java_bytecode_language.h"
1919

2020
#ifdef _MSC_VER
2121
# include <util/unicode.h>
@@ -164,93 +164,20 @@ void lazy_goto_modelt::initialize(
164164
}
165165
else
166166
{
167-
for(const auto &filename : sources)
168-
{
169-
#ifdef _MSC_VER
170-
std::ifstream infile(widen(filename));
171-
#else
172-
std::ifstream infile(filename);
173-
#endif
174-
175-
if(!infile)
176-
{
177-
throw system_exceptiont(
178-
"failed to open input file '" + filename + '\'');
179-
}
180-
181-
language_filet &lf = add_language_file(filename);
182-
lf.language = get_language_from_filename(filename);
183-
184-
if(lf.language == nullptr)
185-
{
186-
throw invalid_source_file_exceptiont(
187-
"failed to figure out type of file '" + filename + '\'');
188-
}
189-
190-
languaget &language = *lf.language;
191-
language.set_message_handler(message_handler);
192-
language.set_language_options(options);
193-
194-
msg.status() << "Parsing " << filename << messaget::eom;
195-
196-
if(language.parse(infile, filename))
197-
{
198-
throw invalid_source_file_exceptiont("PARSING ERROR");
199-
}
200-
201-
lf.get_modules();
202-
}
203-
204-
msg.status() << "Converting" << messaget::eom;
205-
206-
if(language_files.typecheck(symbol_table))
207-
{
208-
throw invalid_source_file_exceptiont("CONVERSION ERROR");
209-
}
167+
initialize_from_source_files(
168+
sources, options, language_files, symbol_table, message_handler);
210169
}
211170

212171
if(read_objects_and_link(binaries, *goto_model, message_handler))
213172
throw incorrect_goto_program_exceptiont{"failed to read/link goto model"};
214173

215-
bool binaries_provided_start =
216-
symbol_table.has_symbol(goto_functionst::entry_point());
217-
218-
bool entry_point_generation_failed = false;
219-
220-
if(binaries_provided_start && options.is_set("function"))
221-
{
222-
// The goto binaries provided already contain a __CPROVER_start
223-
// function that may be tied to a different entry point `function`.
224-
// Hence, we will rebuild the __CPROVER_start function.
225-
226-
// Get the language annotation of the existing __CPROVER_start function.
227-
std::unique_ptr<languaget> language =
228-
get_entry_point_language(symbol_table, options, message_handler);
229-
230-
// To create a new entry point we must first remove the old one
231-
remove_existing_entry_point(symbol_table);
232-
233-
// Create the new entry-point
234-
entry_point_generation_failed =
235-
language->generate_support_functions(symbol_table);
236-
237-
// Remove the function from the goto functions so it is copied back in
238-
// from the symbol table during goto_convert
239-
if(!entry_point_generation_failed)
240-
unload(goto_functionst::entry_point());
241-
}
242-
else if(!binaries_provided_start)
243-
{
244-
// Allow all language front-ends to try to provide the user-specified
245-
// (--function) entry-point, or some language-specific default:
246-
entry_point_generation_failed =
247-
language_files.generate_support_functions(symbol_table);
248-
}
249-
250-
if(entry_point_generation_failed)
251-
{
252-
throw invalid_source_file_exceptiont("SUPPORT FUNCTION GENERATION ERROR");
253-
}
174+
set_up_custom_entry_point(
175+
language_files,
176+
symbol_table,
177+
[this](const irep_idt &id) { goto_functions.unload(id); },
178+
options,
179+
false,
180+
message_handler);
254181

255182
// stupid hack
256183
config.set_object_bits_from_symbol_table(symbol_table);

jbmc/src/java_bytecode/lazy_goto_model.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -183,11 +183,6 @@ class lazy_goto_modelt : public abstract_goto_modelt
183183
/// Eagerly loads all functions from the symbol table.
184184
void load_all_functions() const;
185185

186-
void unload(const irep_idt &name) const
187-
{
188-
goto_functions.unload(name);
189-
}
190-
191186
language_filet &add_language_file(const std::string &filename)
192187
{
193188
return language_files.add_file(filename);

src/goto-programs/initialize_goto_model.cpp

Lines changed: 92 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,13 @@ Author: Daniel Kroening, [email protected]
3434
/// Generate an entry point that calls a function with the given name, based on
3535
/// the functions language mode in the symbol table
3636
static bool generate_entry_point_for_function(
37-
const irep_idt &entry_function_name,
3837
const optionst &options,
39-
goto_modelt &goto_model,
38+
symbol_tablet &symbol_table,
4039
message_handlert &message_handler)
4140
{
42-
auto const entry_function_sym =
43-
goto_model.symbol_table.lookup(entry_function_name);
41+
const irep_idt &entry_function_name = options.get_option("function");
42+
CHECK_RETURN(!entry_function_name.empty());
43+
auto const entry_function_sym = symbol_table.lookup(entry_function_name);
4444
if(entry_function_sym == nullptr)
4545
{
4646
throw invalid_command_line_argument_exceptiont{
@@ -54,42 +54,23 @@ static bool generate_entry_point_for_function(
5454
CHECK_RETURN(entry_language != nullptr);
5555
entry_language->set_message_handler(message_handler);
5656
entry_language->set_language_options(options);
57-
return entry_language->generate_support_functions(goto_model.symbol_table);
57+
return entry_language->generate_support_functions(symbol_table);
5858
}
5959

60-
goto_modelt initialize_goto_model(
61-
const std::vector<std::string> &files,
62-
message_handlert &message_handler,
63-
const optionst &options)
60+
void initialize_from_source_files(
61+
const std::list<std::string> &sources,
62+
const optionst &options,
63+
language_filest &language_files,
64+
symbol_tablet &symbol_table,
65+
message_handlert &message_handler)
6466
{
65-
messaget msg(message_handler);
66-
if(files.empty())
67-
{
68-
throw invalid_command_line_argument_exceptiont(
69-
"missing program argument",
70-
"filename",
71-
"one or more paths to program files");
72-
}
73-
74-
std::list<std::string> binaries, sources;
75-
76-
for(const auto &file : files)
77-
{
78-
if(is_goto_binary(file, message_handler))
79-
binaries.push_back(file);
80-
else
81-
sources.push_back(file);
82-
}
67+
if(sources.empty())
68+
return;
8369

84-
language_filest language_files;
85-
language_files.set_message_handler(message_handler);
86-
87-
goto_modelt goto_model;
70+
messaget msg(message_handler);
8871

89-
if(!sources.empty())
72+
for(const auto &filename : sources)
9073
{
91-
for(const auto &filename : sources)
92-
{
9374
#ifdef _MSC_VER
9475
std::ifstream infile(widen(filename));
9576
#else
@@ -107,8 +88,8 @@ goto_modelt initialize_goto_model(
10788

10889
if(lf.language==nullptr)
10990
{
110-
throw invalid_source_file_exceptiont(
111-
"Failed to figure out type of file '" + filename + '\'');
91+
throw invalid_command_line_argument_exceptiont{
92+
"Failed to figure out type of file", filename};
11293
}
11394

11495
languaget &language=*lf.language;
@@ -119,75 +100,127 @@ goto_modelt initialize_goto_model(
119100

120101
if(language.parse(infile, filename))
121102
{
122-
throw invalid_source_file_exceptiont("PARSING ERROR");
103+
throw invalid_input_exceptiont("PARSING ERROR");
123104
}
124105

125106
lf.get_modules();
126107
}
127108

128109
msg.status() << "Converting" << messaget::eom;
129110

130-
if(language_files.typecheck(goto_model.symbol_table))
111+
if(language_files.typecheck(symbol_table))
131112
{
132-
throw invalid_source_file_exceptiont("CONVERSION ERROR");
113+
throw invalid_input_exceptiont("CONVERSION ERROR");
133114
}
134-
}
135-
136-
if(read_objects_and_link(binaries, goto_model, message_handler))
137-
{
138-
throw invalid_source_file_exceptiont{
139-
"failed to read object or link in files"};
140-
}
115+
}
141116

142-
bool binaries_provided_start=
143-
goto_model.symbol_table.has_symbol(goto_functionst::entry_point());
117+
void set_up_custom_entry_point(
118+
language_filest &language_files,
119+
symbol_tablet &symbol_table,
120+
const std::function<void(const irep_idt &)> &unload,
121+
const optionst &options,
122+
bool try_mode_lookup,
123+
message_handlert &message_handler)
124+
{
125+
bool binaries_provided_start =
126+
symbol_table.has_symbol(goto_functionst::entry_point());
144127

145128
bool entry_point_generation_failed=false;
146129

147130
if(binaries_provided_start && options.is_set("function"))
148131
{
132+
// The goto binaries provided already contain a __CPROVER_start
133+
// function that may be tied to a different entry point `function`.
134+
// Hence, we will rebuild the __CPROVER_start function.
135+
149136
// Get the language annotation of the existing __CPROVER_start function.
150-
std::unique_ptr<languaget> language = get_entry_point_language(
151-
goto_model.symbol_table, options, message_handler);
137+
std::unique_ptr<languaget> language =
138+
get_entry_point_language(symbol_table, options, message_handler);
152139

153140
// To create a new entry point we must first remove the old one
154-
remove_existing_entry_point(goto_model.symbol_table);
141+
remove_existing_entry_point(symbol_table);
155142

156143
// Create the new entry-point
157144
entry_point_generation_failed =
158-
language->generate_support_functions(goto_model.symbol_table);
145+
language->generate_support_functions(symbol_table);
159146

160147
// Remove the function from the goto functions so it is copied back in
161148
// from the symbol table during goto_convert
162149
if(!entry_point_generation_failed)
163-
goto_model.unload(goto_functionst::entry_point());
150+
unload(goto_functionst::entry_point());
164151
}
165152
else if(!binaries_provided_start)
166153
{
167-
if(options.is_set("function"))
154+
if(try_mode_lookup && options.is_set("function"))
168155
{
169156
// no entry point is present; Use the mode of the specified entry function
170157
// to generate one
171158
entry_point_generation_failed = generate_entry_point_for_function(
172-
options.get_option("function"), options, goto_model, message_handler);
159+
options, symbol_table, message_handler);
173160
}
174-
if(entry_point_generation_failed || !options.is_set("function"))
161+
if(
162+
!try_mode_lookup || entry_point_generation_failed ||
163+
!options.is_set("function"))
175164
{
176165
// Allow all language front-ends to try to provide the user-specified
177166
// (--function) entry-point, or some language-specific default:
178167
entry_point_generation_failed =
179-
language_files.generate_support_functions(goto_model.symbol_table);
168+
language_files.generate_support_functions(symbol_table);
180169
}
181170
}
182171

183172
if(entry_point_generation_failed)
184173
{
185-
throw invalid_source_file_exceptiont("SUPPORT FUNCTION GENERATION ERROR");
174+
throw invalid_input_exceptiont("SUPPORT FUNCTION GENERATION ERROR");
175+
}
176+
}
177+
178+
goto_modelt initialize_goto_model(
179+
const std::vector<std::string> &files,
180+
message_handlert &message_handler,
181+
const optionst &options)
182+
{
183+
messaget msg(message_handler);
184+
if(files.empty())
185+
{
186+
throw invalid_command_line_argument_exceptiont(
187+
"missing program argument",
188+
"filename",
189+
"one or more paths to program files");
190+
}
191+
192+
std::list<std::string> binaries, sources;
193+
194+
for(const auto &file : files)
195+
{
196+
if(is_goto_binary(file, message_handler))
197+
binaries.push_back(file);
198+
else
199+
sources.push_back(file);
186200
}
187201

202+
language_filest language_files;
203+
language_files.set_message_handler(message_handler);
204+
205+
goto_modelt goto_model;
206+
207+
initialize_from_source_files(
208+
sources, options, language_files, goto_model.symbol_table, message_handler);
209+
210+
if(read_objects_and_link(binaries, goto_model, message_handler))
211+
throw incorrect_goto_program_exceptiont{"failed to read/link goto model"};
212+
213+
set_up_custom_entry_point(
214+
language_files,
215+
goto_model.symbol_table,
216+
[&goto_model](const irep_idt &id) { goto_model.goto_functions.unload(id); },
217+
options,
218+
true,
219+
message_handler);
220+
188221
if(language_files.final(goto_model.symbol_table))
189222
{
190-
throw invalid_source_file_exceptiont("FINAL STAGE CONVERSION ERROR");
223+
throw invalid_input_exceptiont("FINAL STAGE CONVERSION ERROR");
191224
}
192225

193226
msg.status() << "Generating GOTO Program" << messaget::eom;

0 commit comments

Comments
 (0)