|
1 | 1 | open Bap.Std
|
2 | 2 | open Core_kernel
|
3 |
| -include Self() |
4 | 3 |
|
| 4 | +include Self() |
5 | 5 |
|
6 | 6 | let get_direct_typ (e : exp) : Type.t = match e with
|
7 | 7 | | Bil.Var v -> Var.typ v
|
8 | 8 | | Bil.Unknown (_,t) -> t
|
9 | 9 | | Bil.Int w -> Type.Imm (Word.bitwidth w)
|
10 | 10 | | _ -> failwith "the expression is not flattened"
|
11 | 11 |
|
| 12 | +class substituter (x : var) (x' : var) = object |
| 13 | + inherit Exp.mapper as super |
| 14 | + |
| 15 | + method! map_var v = |
| 16 | + if Var.equal x v then Var x' else super#map_var v |
| 17 | + |
| 18 | + method! map_let v ~exp ~body = |
| 19 | + let exp = super#map_exp exp in |
| 20 | + let body = if Var.equal x v then body else super#map_exp body in |
| 21 | + Let (v, exp, body) |
| 22 | +end |
| 23 | + |
12 | 24 | let flatten_exp (exp : exp) (blk : blk term) (before : tid) : exp * blk term =
|
13 | 25 | let is_virtual = true in
|
14 | 26 | let fresh = true in
|
@@ -61,13 +73,15 @@ let flatten_exp (exp : exp) (blk : blk term) (before : tid) : exp * blk term =
|
61 | 73 | Term.prepend def_t ~before blk def
|
62 | 74 | | Bil.Let (v, x, y) ->
|
63 | 75 | let x, blk = aux x blk in
|
64 |
| - let y, blk = aux y blk in |
65 |
| - let vtype = Var.typ v in |
66 |
| - let var = Var.create ~is_virtual ~fresh "flt" vtype in |
67 |
| - let e = Bil.Let (v, x, y) in |
68 |
| - let def = Def.create var e in |
69 |
| - Bil.Var var, |
70 |
| - Term.prepend def_t ~before blk def |
| 76 | + let var, blk = match x with |
| 77 | + | Var v -> v, blk |
| 78 | + | _ -> |
| 79 | + let vtype = Var.typ v in |
| 80 | + let var = Var.create ~is_virtual ~fresh "flt" vtype in |
| 81 | + let def = Def.create var x in |
| 82 | + var, Term.prepend def_t ~before blk def in |
| 83 | + let y = (new substituter v var)#map_exp y in |
| 84 | + aux y blk |
71 | 85 | | Bil.Unknown (_, _) -> exp, blk
|
72 | 86 | | Bil.Ite (x, y, z) ->
|
73 | 87 | let x, blk = aux x blk in
|
|
0 commit comments