-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Allow partial function evaluation to be caught by bindings (#967)
This PR extends the backend's ability to recover from errors when partial functions are evaluated in the context of a bindings library. Rather then unconditionally crashing the entire host process, we throw an exception that the bindings code can catch and translate to a C-ABI error structure for the backend to deal with. Previously, we implemented this behaviour for hooks (#955); this PR does the same for general partial function evaluation. The changes are as follows: * Refactor (as discussed previously) the implementation of `finish_rewriting` from LLVM IR into C++. * Add a new code-generation flag to enable the new error behaviour. * Modify `llvm-kompile` to pass this flag when compiling a bindings library. * Read the flag to change behaviour in the appropriate places in the runtime library. * Add a test that the C bindings can safely try to evaluate undefined partial functions and catch an error when the evaluation fails. Fixes #925
- Loading branch information
Showing
12 changed files
with
2,251 additions
and
82 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
#include <runtime/header.h> | ||
|
||
#include <cstdint> | ||
#include <iostream> | ||
#include <memory> | ||
|
||
extern "C" { | ||
|
||
FILE *output_file = nullptr; | ||
bool statistics = false; | ||
bool binary_output = false; | ||
bool proof_output = false; | ||
|
||
extern int64_t steps; | ||
extern bool safe_partial; | ||
|
||
int32_t get_exit_code(block *); | ||
|
||
[[noreturn]] void finish_rewriting(block *subject, bool error) { | ||
// This function is responsible for closing output_file when rewriting | ||
// finishes; because it can exit in a few different ways (exceptions, | ||
// std::exit etc.) it's cleaner to set up a smart pointer to do this safely | ||
// for us. | ||
[[maybe_unused]] auto closer | ||
= std::unique_ptr<FILE, decltype(&fclose)>(output_file, fclose); | ||
|
||
if (error && safe_partial) { | ||
throw std::runtime_error( | ||
"Attempted to evaluate partial function at an undefined input"); | ||
} | ||
|
||
if (!output_file) { | ||
throw std::runtime_error( | ||
"Called finish_rewriting with no output file specified"); | ||
} | ||
|
||
if (statistics) { | ||
printStatistics(output_file, steps); | ||
} | ||
|
||
if (!proof_output) { | ||
if (binary_output) { | ||
serializeConfigurationToFile(output_file, subject, true); | ||
} else { | ||
printConfiguration(output_file, subject); | ||
} | ||
} | ||
|
||
auto exit_code = error ? 113 : get_exit_code(subject); | ||
std::exit(exit_code); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
#include "api.h" | ||
|
||
#include <assert.h> | ||
#include <stdio.h> | ||
|
||
void test_safe_eval(struct kllvm_c_api *api, char const *pattern) { | ||
kore_pattern *one = api->kore_pattern_parse(pattern); | ||
kore_sort *sort_int = api->kore_composite_sort_new("SortInt"); | ||
|
||
kore_error *err = api->kore_error_new(); | ||
|
||
char *data; | ||
size_t size; | ||
api->kore_simplify(err, one, sort_int, &data, &size); | ||
|
||
assert( | ||
!api->kore_error_is_success(err) | ||
&& "Shouldn't be able to evaluate pattern"); | ||
|
||
api->kore_pattern_free(one); | ||
api->kore_sort_free(sort_int); | ||
api->kore_error_free(err); | ||
} | ||
|
||
int main(int argc, char **argv) { | ||
if (argc <= 1) { | ||
return 1; | ||
} | ||
|
||
struct kllvm_c_api api = load_c_api(argv[1]); | ||
|
||
api.kllvm_init(); | ||
|
||
test_safe_eval(&api, "Lblfoo{}(\\dv{SortInt{}}(\"1\"))"); | ||
test_safe_eval(&api, "Lblbar{}()"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
module SAFE-PARTIAL | ||
imports INT | ||
|
||
syntax Int ::= foo(Int) [function, klabel(foo), symbol] | ||
| bar(Int) [function, klabel(bar), symbol] | ||
rule foo(0) => 0 | ||
endmodule |
Oops, something went wrong.