Skip to content

Commit 5dc0093

Browse files
committed
Lazy goto model: hook for driver program to replace or stub functions
This provides a hook for the driver program to either replace a method outright, or to provide a stub implementation when a function body cannot be provided by the language frontend (language_filest).
1 parent 10d0042 commit 5dc0093

File tree

6 files changed

+100
-9
lines changed

6 files changed

+100
-9
lines changed

src/goto-programs/lazy_goto_functions_map.h

+45-9
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,15 @@ class lazy_goto_functions_mapt final
5454
goto_functionst::goto_functiont &function,
5555
journalling_symbol_tablet &function_symbols)>
5656
post_process_functiont;
57+
typedef std::function<bool(const irep_idt &name)>
58+
can_generate_function_bodyt;
59+
typedef std::function<
60+
bool(
61+
symbolt &symbol,
62+
symbol_table_baset &symbol_table,
63+
goto_functiont &function,
64+
bool body_available)>
65+
generate_function_bodyt;
5766

5867
private:
5968
typedef std::map<key_type, goto_functiont> underlying_mapt;
@@ -66,6 +75,8 @@ class lazy_goto_functions_mapt final
6675
language_filest &language_files;
6776
symbol_tablet &symbol_table;
6877
const post_process_functiont post_process_function;
78+
const can_generate_function_bodyt driver_program_can_generate_function_body;
79+
const generate_function_bodyt driver_program_generate_function_body;
6980
message_handlert &message_handler;
7081

7182
public:
@@ -75,11 +86,17 @@ class lazy_goto_functions_mapt final
7586
language_filest &language_files,
7687
symbol_tablet &symbol_table,
7788
post_process_functiont post_process_function,
89+
can_generate_function_bodyt driver_program_can_generate_function_body,
90+
generate_function_bodyt driver_program_generate_function_body,
7891
message_handlert &message_handler)
7992
: goto_functions(goto_functions),
8093
language_files(language_files),
8194
symbol_table(symbol_table),
8295
post_process_function(std::move(post_process_function)),
96+
driver_program_can_generate_function_body(
97+
std::move(driver_program_can_generate_function_body)),
98+
driver_program_generate_function_body(
99+
std::move(driver_program_generate_function_body)),
83100
message_handler(message_handler)
84101
{
85102
}
@@ -107,7 +124,9 @@ class lazy_goto_functions_mapt final
107124
/// it a bodyless stub.
108125
bool can_produce_function(const key_type &name) const
109126
{
110-
return language_files.can_convert_lazy_method(name);
127+
return
128+
language_files.can_convert_lazy_method(name) ||
129+
driver_program_can_generate_function_body(name);
111130
}
112131

113132
void unload(const key_type &name) const { goto_functions.erase(name); }
@@ -153,14 +172,31 @@ class lazy_goto_functions_mapt final
153172
underlying_mapt::iterator it=goto_functions.find(name);
154173
if(it!=goto_functions.end())
155174
return *it;
156-
// Fill in symbol table entry body if not already done
157-
// If this returns false then it's a stub
158-
language_files.convert_lazy_method(name, function_symbol_table);
159-
// Create goto_functiont
160-
goto_functionst::goto_functiont function;
161-
goto_convert_functionst convert_functions(
162-
function_symbol_table, message_handler);
163-
convert_functions.convert_function(name, function);
175+
176+
symbolt &function_symbol = function_symbol_table.get_writeable_ref(name);
177+
goto_functiont function;
178+
179+
// First chance: see if the driver program wants to provide a replacement:
180+
bool body_provided =
181+
driver_program_generate_function_body(
182+
function_symbol,
183+
function_symbol_table,
184+
function,
185+
language_files.can_convert_lazy_method(name));
186+
187+
// Second chance: see if language_filest can provide a body:
188+
if(!body_provided)
189+
{
190+
// Fill in symbol table entry body if not already done
191+
language_files.convert_lazy_method(name, function_symbol_table);
192+
body_provided = function_symbol.value.is_not_nil();
193+
194+
// Create goto_functiont
195+
goto_convert_functionst convert_functions(
196+
function_symbol_table, message_handler);
197+
convert_functions.convert_function(name, function);
198+
}
199+
164200
// Add to map
165201
return *goto_functions.emplace(name, std::move(function)).first;
166202
}

src/goto-programs/lazy_goto_model.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
lazy_goto_modelt::lazy_goto_modelt(
2323
post_process_functiont post_process_function,
2424
post_process_functionst post_process_functions,
25+
can_generate_function_bodyt driver_program_can_generate_function_body,
26+
generate_function_bodyt driver_program_generate_function_body,
2527
message_handlert &message_handler)
2628
: goto_model(new goto_modelt()),
2729
symbol_table(goto_model->symbol_table),
@@ -41,9 +43,15 @@ lazy_goto_modelt::lazy_goto_modelt(
4143
function);
4244
this->post_process_function(model_function, *this);
4345
},
46+
std::move(driver_program_can_generate_function_body),
47+
std::move(driver_program_generate_function_body),
4448
message_handler),
4549
post_process_function(std::move(post_process_function)),
4650
post_process_functions(std::move(post_process_functions)),
51+
driver_program_can_generate_function_body(
52+
std::move(driver_program_can_generate_function_body)),
53+
driver_program_generate_function_body(
54+
std::move(driver_program_generate_function_body)),
4755
message_handler(message_handler)
4856
{
4957
language_files.set_message_handler(message_handler);
@@ -68,6 +76,8 @@ lazy_goto_modelt::lazy_goto_modelt(lazy_goto_modelt &&other)
6876
function);
6977
this->post_process_function(model_function, *this);
7078
},
79+
other.driver_program_can_generate_function_body,
80+
other.driver_program_generate_function_body,
7181
other.message_handler),
7282
language_files(std::move(other.language_files)),
7383
post_process_function(std::move(other.post_process_function)),

src/goto-programs/lazy_goto_model.h

+21
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,16 @@ class lazy_goto_modelt : public abstract_goto_modelt
2424
void(goto_model_functiont &function, const abstract_goto_modelt &)>
2525
post_process_functiont;
2626
typedef std::function<bool(goto_modelt &goto_model)> post_process_functionst;
27+
typedef lazy_goto_functions_mapt::can_generate_function_bodyt
28+
can_generate_function_bodyt;
29+
typedef lazy_goto_functions_mapt::generate_function_bodyt
30+
generate_function_bodyt;
2731

2832
explicit lazy_goto_modelt(
2933
post_process_functiont post_process_function,
3034
post_process_functionst post_process_functions,
35+
can_generate_function_bodyt driver_program_can_generate_function_body,
36+
generate_function_bodyt driver_program_generate_function_body,
3137
message_handlert &message_handler);
3238

3339
lazy_goto_modelt(lazy_goto_modelt &&other);
@@ -60,6 +66,19 @@ class lazy_goto_modelt : public abstract_goto_modelt
6066
[&handler, &options](goto_modelt &goto_model) -> bool {
6167
return handler.process_goto_functions(goto_model, options);
6268
},
69+
[&handler](const irep_idt &name) -> bool {
70+
return handler.can_generate_function_body(name);
71+
},
72+
[&handler]
73+
(symbolt &symbol,
74+
symbol_table_baset &symbol_table,
75+
goto_functiont &function,
76+
bool is_first_chance)
77+
{
78+
return
79+
handler.generate_function_body(
80+
symbol, symbol_table, function, is_first_chance);
81+
},
6382
message_handler);
6483
}
6584

@@ -127,6 +146,8 @@ class lazy_goto_modelt : public abstract_goto_modelt
127146
// Function/module processing functions
128147
const post_process_functiont post_process_function;
129148
const post_process_functionst post_process_functions;
149+
const can_generate_function_bodyt driver_program_can_generate_function_body;
150+
const generate_function_bodyt driver_program_generate_function_body;
130151

131152
/// Logging helper field
132153
message_handlert &message_handler;

src/jbmc/jbmc_parse_options.cpp

+14
Original file line numberDiff line numberDiff line change
@@ -994,6 +994,20 @@ bool jbmc_parse_optionst::process_goto_functions(
994994
return false;
995995
}
996996

997+
bool jbmc_parse_optionst::can_generate_function_body(const irep_idt &name)
998+
{
999+
return false;
1000+
}
1001+
1002+
bool jbmc_parse_optionst::generate_function_body(
1003+
symbolt &symbol,
1004+
symbol_table_baset &symbol_table,
1005+
goto_functiont &function,
1006+
bool body_available)
1007+
{
1008+
return false;
1009+
}
1010+
9971011
/// display command line help
9981012
void jbmc_parse_optionst::help()
9991013
{

src/jbmc/jbmc_parse_options.h

+8
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,14 @@ class jbmc_parse_optionst:
9898
const optionst &);
9999
bool process_goto_functions(goto_modelt &goto_model, const optionst &options);
100100

101+
bool can_generate_function_body(const irep_idt &name);
102+
103+
bool generate_function_body(
104+
symbolt &symbol,
105+
symbol_table_baset &symbol_table,
106+
goto_functiont &function,
107+
bool body_available);
108+
101109
protected:
102110
ui_message_handlert ui_message_handler;
103111
std::unique_ptr<cover_configt> cover_config;

unit/testing-utils/load_java_class.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ symbol_tablet load_java_class(
9797
lazy_goto_modelt lazy_goto_model(
9898
[] (goto_model_functiont &function, const abstract_goto_modelt &model) { }, // NOLINT (*)
9999
[] (goto_modelt &goto_model) { return false; }, // NOLINT (*)
100+
[] (const irep_idt &name) { return false; },
101+
[] (symbolt &symbol, symbol_table_baset &symbol_table, goto_functiont &function, bool body_available) { return false; }, // NOLINT (*)
100102
message_handler);
101103

102104
// Configure the path loading

0 commit comments

Comments
 (0)