1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
(* SPDX-License-Identifier: AGPL-3.0-or-later *)
(* Copyright © 2021-2026 OCamlPro *)
(* Written by the Owi programmers *)
open Syntax
let run_file ~entry_point ~symbolic_parameters ~source_file =
let { Symbolic_parameters.unsafe
; invoke_with_symbols
; exploration_strategy = _
; generate_abstract_invariant
; fail_mode
; timeout
; timeout_instr
; use_ite_for_select
; _
} =
symbolic_parameters
in
let* modul = Compile.Wasm.File.until_validate ~unsafe source_file in
(* TODO: enable this once the smart strategy is fully implemented
( match exploration_strategy with
| Smart -> Cmd_call_graph.compute_distances m entry_point
| _ -> () );
*)
let* modul =
Cmd_utils.set_entry_point entry_point invoke_with_symbols modul
in
let* abstract_invariant =
if generate_abstract_invariant then
let* env = Cmd_wasm_abs.env () in
let+ modul, env =
Compile.Wasm.Binary.until_abstract_link ~unsafe ~name:None env modul
in
try
let state = Abstract_interpreter_control_flow.modul ~env ~modul in
state.invariant
with Abstract_interpreter_control_flow.RecursiveFunctionCall ->
Abstract_invariant.empty ()
else Ok (Abstract_invariant.empty ())
in
let env = Env.Symbolic.empty ~context:() in
let* env =
Env.Symbolic.link_extern_module ~env ~name:"wasi_snapshot_preview1"
Symbolic_wasm_ffi.wasi_snapshot_preview1
in
let* env =
Env.Symbolic.link_extern_module ~env ~name:"owi" Symbolic_wasm_ffi.owi
in
let+ modul, env =
(* unsafe is set to true because the module was already validated before *)
Compile.Wasm.Binary.until_symbolic_link env ~unsafe:true ~name:None modul
in
let module Parameters = struct
let throw_away_trap =
match fail_mode with Assertion_only -> true | Both | Trap_only -> false
let timeout = timeout
let timeout_instr = timeout_instr
let use_ite_for_select = use_ite_for_select
let abstract_invariant = abstract_invariant
end in
let module I = Interpret.Symbolic (Parameters) in
Benchmark.with_utime @@ fun () -> I.modul ~env ~modul
(* NB: This function propagates potential errors (Result.err) occurring
during evaluation (OS, syntax error, etc.), except for Trap and Assert,
which are handled here. Most of the computations are done in the Result
monad, hence the let*. *)
let cmd ~entry_point ~source_file ~(symbolic_parameters : Symbolic_parameters.t)
~workspace =
(* deterministic_result_order implies no_stop_at_failure *)
let no_stop_at_failure =
(* TODO: move this somewhere else *)
symbolic_parameters.deterministic_result_order
|| symbolic_parameters.no_stop_at_failure
in
let* to_run, run_time =
run_file ~symbolic_parameters ~source_file ~entry_point
in
let { Symbolic_parameters.exploration_strategy
; fail_mode
; workers
; no_worker_isolation
; solver
; deterministic_result_order
; model_format
; no_value
; no_assert_failure_expression_printing
; model_out_file
; with_breadcrumbs
; seed
; _
} =
symbolic_parameters
in
Symbolic_driver.run ~exploration_strategy ~fail_mode ~workers
~no_worker_isolation ~solver ~deterministic_result_order ~model_format
~no_value ~no_assert_failure_expression_printing ~workspace
~no_stop_at_failure ~model_out_file ~with_breadcrumbs ~seed ~run_time to_run