Project

General

Profile

Download (6.87 KB) Statistics
| Branch: | Tag: | Revision:
1

    
2
let active = ref false
3
let tiny_debug = ref false
4
let tiny_help = ref false
5
let descending = ref 1
6
let unrolling = ref 0
7
let output = ref false
8
let reachtube = ref false (* used to produce a list of set iterates *)
9
              
10
let quiet () = Tiny.Report.verbosity := 0
11
let report = Tiny_utils.report
12
               
13
let print_tiny_help () =
14
  let open Format in
15
  Format.eprintf "@[Tiny verifier plugin produces a simple imperative code \
16
          output for the provided main node, inlining all calls. This \
17
          code can then be analyzed using tiny analyzer options.@]";
18
  Format.eprintf "@.@?";
19
  flush stdout
20

    
21
  
22
let tiny_run ~basename prog machines =
23
  if !tiny_help then (
24
    let _ = print_tiny_help () in
25
    exit 0
26
  );
27
  let node_name =
28
    match !Options.main_node with
29
    | "" -> (
30
      Format.eprintf "Tiny verifier requires a main node.@.";
31
      Format.eprintf "@[<v 2>Available ones are:@ %a@]@.@?"
32
        (Utils.fprintf_list ~sep:"@ "
33
           (fun fmt m ->
34
             Format.fprintf fmt "%s" m.Machine_code_types.mname.node_id
35
           )
36
        )
37
        machines; 
38
      exit 1
39
    )
40
    | s -> ( (* should have been addessed before *)
41
      match Machine_code_common.get_machine_opt machines s with
42
      | None -> begin
43
          Global.main_node := s;
44
          Format.eprintf "Code generation error: %a@." Error.pp_error_msg Error.Main_not_found;
45
          raise (Error.Error (Location.dummy_loc, Error.Main_not_found))
46
        end
47
      | Some _ -> s
48
    )
49
  in
50
  let m = Machine_code_common.get_machine machines node_name in
51
  let env = (* We add each variables of the node the Tiny env *)
52
    Tiny_utils.machine_to_env m in
53
  (*let nd = m.mname in*)
54
  (* Building preamble with some bounds on inputs *)
55
  (* TODO: deal woth contracts, asserts, ... *)
56
  let bounds_inputs = [] in
57
  let ast = Tiny_utils.machine_to_ast bounds_inputs m in
58
  (* let mems = m.mmemory in *)
59
  if !output then (
60
    let destname = !Options.dest_dir ^ "/" ^ basename ^ "_" ^ node_name ^ ".tiny" in
61
    report ~level:2 (fun fmt -> Format.fprintf fmt "Exporting resulting tiny source as %s@ " destname);
62
    let out = open_out destname in
63
    let fmt = Format.formatter_of_out_channel out in
64
    Format.fprintf fmt "%a@." Tiny.Ast.Var.Set.pp env; 
65
    Format.fprintf fmt "%a@." Tiny.Ast.fprint_stm ast; 
66
    close_out out;
67
    
68
    
69
  );
70
  report ~level:1 (fun fmt -> Format.fprintf fmt "%a@." Tiny.Ast.fprint_stm ast); 
71
  
72
  let dom =
73
    let open Tiny.Load_domains in
74
    prepare_domains (List.map get_domain !domains)
75
  in
76
  let results = Tiny.Analyze.analyze
77
                  dom
78
                  (not !reachtube) (* when this argument is false, a
79
                                      simulation is performed*)
80
                  !descending
81
                  !unrolling
82
                  env
83
                  ast
84
  in
85
  (* if !Tiny.Report.verbosity > 1 then *)
86
  if !reachtube then (
87
    (* Print preamble *)
88
    report ~level:1 (Tiny_tube.export_to_csv env ast results);
89
    (* We produce in a folder: the csv file, the tiny file *)
90
    let destname = !Options.dest_dir ^ "/" ^ basename ^ "_" ^ node_name ^ ".csv" in
91
    report ~level:1 (fun fmt -> Format.fprintf fmt "Exporting resulting tube as %s@ " destname);
92
    let out = open_out destname in
93
    let fmt = Format.formatter_of_out_channel out in
94
    Format.fprintf fmt "%t@." (Tiny_tube.export_to_csv env ast results); 
95
    close_out out;
96
    
97
  )
98
  else
99
    let module Results = (val results: Tiny.Analyze.Results) in
100
    let module Dom = Results.Dom in
101
    let module PrintResults = Tiny.PrintResults.Make (Dom) in
102
    let m = Results.results in
103
    report ~level:1 (PrintResults.print m env ast)
104
    (* no !output_file *);
105
    (* else PrintResults.print_invariants m ast !output_file *)
106

    
107
    ()
108
  
109
  
110
module Verifier =
111
  (struct
112
    include VerifierType.Default
113

    
114
    (* Enforce global inline from top node *)
115
    let get_normalization_params () =
116
      Options.global_inline := true;
117
      get_normalization_params ()
118
      
119
    let name = "tiny"
120
    let options =
121
      [
122
        "-debug", Arg.Set tiny_debug, "tiny debug";
123
        ("-abstract-domain", Arg.String Tiny.Load_domains.decl_domain,
124
         "<domain>  Use abstract domain <domain> " ^ Tiny.Domains.available_domains_str);
125
        (* ("-a", Arg.String Tiny.Load_domains.decl_domain,
126
         *  "<domain>  Use abstract domain <domain> " ^ Tiny.Domains.available_domains_str); *)
127
        ("-param", Arg.String Tiny.Load_domains.set_param,
128
         "<p>  Send <p> to the abstract domain, syntax <dom>:<p> can be used \
129
          to target the (sub)domain <dom>");
130
        (* ("-p", Arg.String Tiny.Load_domains.set_param,
131
         *  "<p>  Send <p> to the abstract domain, syntax <dom>:<p> can be used \
132
         *   to target the (sub)domain <dom>"); *)
133
        ("-help-domain", Arg.String Tiny.Load_domains.help_domain,
134
         "<domain>  Print params of <domain>");
135
        (* ("-h", Arg.String Tiny.Load_domains.help_domain, "<domain>  Print params of <domain>"); *)
136
        (* ("--compile", Arg.Set compile_mode, " Compilation mode: compile to C");
137
      ("-c", Arg.Set compile_mode,             " Compilation mode: compile to C");*)
138
        
139
        ("-quiet", Arg.Unit quiet, " Quiet mode");
140
        (* ("-q", Arg.Unit quiet, " Quiet mode"); *)
141
        ("-verbose", Arg.Set_int Tiny.Report.verbosity,
142
         "<n>  Verbosity level (default is 1)");
143
        (* ("-v", Arg.Set_int Tiny.Report.verbosity, "<n>  Verbosity level (default is 1)"); *)
144
  (*      ("--output", Arg.String set_output_file,
145
         "<filename> Output results to file <filename> (default is \
146
          standard ouput)");
147
        ("-o", Arg.String set_output_file,
148
         "<filename>  Output results to file <filename> (default is standard ouput)");
149
   *)
150
        ("-descending", Arg.Set_int descending,
151
         "<n>  Perform <n> descending iterations after fixpoint of a loop \
152
          is reached (default is 1)");
153
        (* ("-d", Arg.Set_int descending,
154
         *  "<n>  Perform <n> descending iterations after fixpoint of a loop \
155
         * is reached (default is 1)"); *)
156
      ("-unrolling", Arg.Set_int unrolling,
157
       "<n>  Unroll loops <n> times before computing fixpoint (default is 0)");
158
      ("-reachtube", Arg.Int (fun n -> unrolling :=n; reachtube:=true),
159
       "<n>  Unroll main loop <n> times to compute finite horizon analysis (default is invariant, with 0)");
160
      ("-output", Arg.Set output,
161
       "<n>  Export resulting tiny file as <name>_<mainnode>.tiny");
162
      (* (\* ("-u", Arg.Set_int unrolling,
163
       *  *  "<n>  Unroll loops <n> times before computing fixpoint (default is 0)"); *\) *)
164
       "-help", Arg.Set tiny_help, "tiny help and usage";
165
        
166
      
167
      ]
168
      
169
    let activate () =
170
      active := true;
171
      (* Options.global_inline := true;
172
       * Options.optimization := 0;
173
       * Options.const_unfold := true; *)
174
      ()
175
      
176
    let is_active () = !active
177
    let run = tiny_run
178
            
179
            
180
  end: VerifierType.S)
181
    
(3-3/3)