* return true if the invocation is valid (not violating fixed facts), false other wise * * side effects: update input facts and FactMgr in cg_context if the invocation is found valid */
| 317 | * side effects: update input facts and FactMgr in cg_context if the invocation is found valid |
| 318 | */ |
| 319 | bool |
| 320 | FunctionInvocationUser::revisit(std::vector<const Fact*>& inputs, CGContext& cg_context) const |
| 321 | { |
| 322 | FactMgr* fm = get_fact_mgr_for_func(func); |
| 323 | fm->clear_map_visited(); |
| 324 | if (func->visited_cnt++ == 0) { |
| 325 | fm->setup_in_out_maps(true); |
| 326 | } |
| 327 | // for debugging |
| 328 | if (func->name=="func_10" && func->visited_cnt==19) { |
| 329 | //cout << func->visited_cnt << endl; |
| 330 | //func->Output(cout); |
| 331 | //cout << endl; |
| 332 | } |
| 333 | |
| 334 | // make copies so we can back up if fail |
| 335 | vector<const Fact*> inputs_copy = inputs; |
| 336 | |
| 337 | // add facts related to pass parameters |
| 338 | fm->caller_to_callee_handover(this, inputs); |
| 339 | |
| 340 | map<const Statement*, FactVec> facts_in_copy = fm->map_facts_in; |
| 341 | map<const Statement*, FactVec> facts_out_copy = fm->map_facts_out; |
| 342 | map<const Statement*, Effect> stm_effect_copy = fm->map_stm_effect; |
| 343 | map<const Statement*, Effect> accum_effect_copy = fm->map_accum_effect; |
| 344 | // TODO: revisit only if "contingent variable" has been changed? |
| 345 | if (!func->body->visit_facts(inputs, cg_context)) { |
| 346 | // restore facts and effect |
| 347 | fm->map_facts_in = facts_in_copy; |
| 348 | fm->map_facts_out = facts_out_copy; |
| 349 | fm->map_stm_effect = stm_effect_copy; |
| 350 | fm->map_accum_effect = accum_effect_copy; |
| 351 | inputs = inputs_copy; |
| 352 | return false; |
| 353 | } |
| 354 | cg_context.add_effect(fm->map_stm_effect[func->body]); |
| 355 | FactVec ret_facts; |
| 356 | func->body->add_back_return_facts(fm, ret_facts); |
| 357 | save_return_fact(ret_facts); |
| 358 | // incorporate early return facts |
| 359 | merge_facts(inputs, ret_facts); |
| 360 | |
| 361 | // remove facts related to passing parameters |
| 362 | FactMgr::update_facts_for_oos_vars(func->param, inputs); |
| 363 | |
| 364 | fm->setup_in_out_maps(false); |
| 365 | // remember the effect context during this visit to this function |
| 366 | func->accum_eff_context.add_external_effect(cg_context.get_effect_context()); |
| 367 | // update the original facts with new facts changed by function call |
| 368 | renew_facts(inputs_copy, inputs); |
| 369 | inputs = inputs_copy; |
| 370 | return true; |
| 371 | } |
| 372 | |
| 373 | /* |
| 374 | * save the return fact for later use |
no test coverage detected