Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fuzzing #28

Merged
merged 67 commits into from
Jul 27, 2023
Merged
Show file tree
Hide file tree
Changes from 64 commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
541d444
Fuzzer in progress (design experiments)
epatrizio Apr 25, 2023
d385794
design a basic fuzzer
zapashcanon May 16, 2023
421bffa
Fuzzer in progress (design leo, first evols)
epatrizio May 19, 2023
2a6dba0
Fuzzer in progress (add itestop, irelop)
epatrizio May 19, 2023
9ba41ba
Fuzzer in progress (fix add_local)
epatrizio May 22, 2023
3bbc012
Fuzzer in progress (add 'extend' and more 'ibinop' instructions)
epatrizio May 22, 2023
4606426
Fuzzer in progress (init float support)
epatrizio May 22, 2023
4136919
Fuzzer in progress (float support)
epatrizio May 23, 2023
9fd9a30
specialise let+ to single element, add and+
zapashcanon May 23, 2023
c530521
tmp
epatrizio May 23, 2023
50e0e53
Fuzzer in progress (if_else instruction in progress)
epatrizio May 23, 2023
f260a11
remove global environment in fuzzer
zapashcanon May 24, 2023
c27cdbc
Fuzzer in progress (global_get instruction in progress)
epatrizio May 25, 2023
b2b9261
Fuzzer in progress (global_get instruction and interprets interface)
epatrizio May 29, 2023
15780c6
Fuzzer in progress (global_set, local_set tee)
epatrizio May 29, 2023
27beae2
Fuzzer in progress (Issue #32 : fix global_type pp)
epatrizio May 30, 2023
70c1572
Fuzzer in progress (init memory support)
epatrizio May 31, 2023
e1ce3c0
Fuzzer in progress (Issue #34 : fix data pp)
epatrizio Jun 1, 2023
37b47ff
Fuzzer in progress (init data support)
epatrizio Jun 1, 2023
3af4c8d
Fuzzer in progress (memory refacto in progress)
epatrizio Jun 2, 2023
07d7af8
Fuzzer in progress (memory data)
epatrizio Jun 6, 2023
fdb26b6
Fuzzer in progress (memory data - reviews)
epatrizio Jun 6, 2023
ab652ce
Fuzzer in progress (refacto draft)
epatrizio Jun 12, 2023
a590c80
Fuzzer in progress (bug fix memarg align Issue #42)
epatrizio Jun 13, 2023
a285f36
Fuzzer in progress (bug fix call func instr)
epatrizio Jun 14, 2023
2d0b747
Fuzzer in progress (bug fix memarg align Issue #42)
epatrizio Jun 14, 2023
6584033
Fuzzer in progress (bug fix optimize module Issue #43)
epatrizio Jun 16, 2023
64137c6
Fuzzer in progress (refactoring)
epatrizio Jun 16, 2023
d619c3a
Fuzzer in progress (if_then block instr in progress)
epatrizio Jun 16, 2023
958db3b
Fuzzer in progress (syntax removed, integrated into crowbar lib)
epatrizio Jun 19, 2023
c4b6ec8
Fuzzer in progress (bug fix optimize module Issue #43 - add tests)
epatrizio Jun 19, 2023
1282a6b
Fuzzer in progress
epatrizio Jun 19, 2023
f27c5b3
promote test
epatrizio Jun 19, 2023
9b10b8b
Fuzzer in progress (format)
epatrizio Jun 20, 2023
0f177a2
start blocks
epatrizio Jun 20, 2023
efd8895
update to latest refactor
epatrizio Jun 20, 2023
7a4ab9b
fix data pp again
epatrizio Jun 20, 2023
edac2bc
promote tests
epatrizio Jun 20, 2023
6020430
fix data mode pp again
epatrizio Jun 20, 2023
0b5645f
Fuzzer in progress
epatrizio Jun 20, 2023
f5cba98
fix block/if type gen
epatrizio Jun 20, 2023
d88de30
Fuzzer in progress (unreachable block_br instr)
epatrizio Jun 21, 2023
fb25bca
Fuzzer in progress (function calls improvement)
epatrizio Jun 22, 2023
5f2ba28
Fuzzer in progress (fix function calls improvement)
epatrizio Jun 22, 2023
73d9622
Fuzzer in progress (br_if instr)
epatrizio Jun 22, 2023
b40678d
Fuzzer in progress (br_if instr fix)
epatrizio Jun 22, 2023
79c099a
Fuzzer in progress (loops and timeout)
epatrizio Jun 23, 2023
5db3376
Fuzzer in progress (loops and timeout reviews)
epatrizio Jun 27, 2023
107db56
Fuzzer in progress (tmp)
epatrizio Jun 27, 2023
8f2e102
fix expr_br and expr_br_if
zapashcanon Jun 28, 2023
4800f04
Merge pull request #6 from OCamlPro/tmpfuzzing
epatrizio Jun 28, 2023
0b919a5
Fuzzer in progress (more reviews)
epatrizio Jun 28, 2023
b52f029
Fuzzer in progress (mini fix)
epatrizio Jun 29, 2023
bfffb12
improve fuzzer.ml output, factorize interprets
zapashcanon Jun 29, 2023
ecb1458
fix typecheck bug
zapashcanon Jun 30, 2023
84b77a2
Merge pull request #8 from OCamlPro/tmpfuzzing
epatrizio Jun 30, 2023
44769ad
fix parser+typecheck bug
zapashcanon Jul 1, 2023
41fd0c2
Merge pull request #9 from OCamlPro/tmpfuzzing
epatrizio Jul 3, 2023
dcd0d9a
improve interprets and timeout handling
zapashcanon Jul 1, 2023
e96ca9a
Merge pull request #10 from OCamlPro/tmpfuzzing
epatrizio Jul 4, 2023
4f71995
Fuzzer in progress (table type elem init)
epatrizio Jul 4, 2023
69f5014
Fuzzer in progress (table type elem in progress)
epatrizio Jul 6, 2023
a16afe7
Fuzzer in progress (table elem instr)
epatrizio Jul 6, 2023
1184cf5
Fuzzer in progress (table elem fix / reviews)
epatrizio Jul 10, 2023
c22f23b
Fuzzer in progress (add active elem_mode)
epatrizio Jul 11, 2023
4b296e6
Fuzzer in progress (refacto table_init table_copy)
epatrizio Jul 24, 2023
6fd966b
Add TODOs
epatrizio Jul 27, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 1 addition & 9 deletions src/dune
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,7 @@
types
value
wutf8)
(private_modules
convert
float32
float64
lexer
menhir_parser
spectest
stack
wutf8)
(private_modules convert lexer menhir_parser spectest stack wutf8)
(libraries integers menhirLib ocaml_intrinsics ppxlib sedlex uutf)
(preprocess
(pps sedlex.ppx))
Expand Down
2 changes: 1 addition & 1 deletion src/menhir_parser.mly
Original file line number Diff line number Diff line change
Expand Up @@ -660,7 +660,7 @@ let expr_aux ==
let bt = match pt, rt with
| [], [] -> bt
| pt, rt ->
let pt = List.rev_map (fun t -> None, t) pt in
let pt = List.map (fun t -> None, t) pt in
let raw = pt, rt in
begin match bt with
| Some (Arg.Bt_ind type_use) -> Some (bt_raw (Some type_use) raw)
Expand Down
172 changes: 94 additions & 78 deletions src/optimize.ml
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ let locals_func body_expr =
let rec aux_instr instr =
match instr with
| Local_get ind | Local_set ind | Local_tee ind ->
Hashtbl.add locals_hashtbl ind ()
Hashtbl.replace locals_hashtbl ind ()
| Block (_, _, e) -> aux_expr e
| Loop (_, _, e) -> aux_expr e
| If_else (_, _, e1, e2) ->
Expand Down Expand Up @@ -263,91 +263,107 @@ let locals_func body_expr =
aux_expr body_expr;
locals_hashtbl

let locals_used_in_func locals nb_args body_expr =
let loc_hashtbl = locals_func body_expr in
let remove_local idx body_expr =
let rec aux_instr instr =
match instr with
| Local_get ind when ind >= idx -> Local_get (ind - 1)
| Local_set ind when ind >= idx -> Local_set (ind - 1)
| Local_tee ind when ind >= idx -> Local_tee (ind - 1)
| Block (m, t, e) -> Block (m, t, aux_expr e)
| Loop (m, t, e) -> Loop (m, t, aux_expr e)
| If_else (m, t, e1, e2) -> If_else (m, t, aux_expr e1, aux_expr e2)
| I64_extend32_s | I32_wrap_i64 | F32_demote_f64 | F64_promote_f32
| Ref_is_null | Ref_as_non_null | Ref_eq | Drop | Memory_size
| Memory_grow | Memory_fill | Memory_copy | Nop | Unreachable | Return
| Array_len | I31_get_u | I31_get_s | I31_new | Extern_externalize
| Extern_internalize | I32_const _ | I64_const _ | F32_const _
| F64_const _
| I_unop (_, _)
| F_unop (_, _)
| I_binop (_, _)
| F_binop (_, _)
| I_testop (_, _)
| I_relop (_, _)
| F_relop (_, _)
| I_extend8_s _ | I_extend16_s _ | I64_extend_i32 _
| I_trunc_f (_, _, _)
| I_trunc_sat_f (_, _, _)
| F_convert_i (_, _, _)
| I_reinterpret_f (_, _)
| F_reinterpret_i (_, _)
| Ref_null _ | Ref_func _
| Ref_cast (_, _)
| Ref_test (_, _)
| Select _ | Local_get _ | Local_set _ | Local_tee _ | Global_get _
| Global_set _ | Table_get _ | Table_set _ | Table_size _ | Table_grow _
| Table_fill _
| Table_copy (_, _)
| Table_init (_, _)
| Elem_drop _
| I_load (_, _)
| F_load (_, _)
| I_store (_, _)
| F_store (_, _)
| I_load8 (_, _, _)
| I_load16 (_, _, _)
| I64_load32 (_, _)
| I_store8 (_, _)
| I_store16 (_, _)
| I64_store32 _ | Memory_init _ | Data_drop _ | Br _ | Br_if _
| Br_table (_, _)
| Br_on_cast (_, _, _)
| Br_on_cast_fail (_, _, _)
| Br_on_non_null _ | Br_on_null _ | Return_call _
| Return_call_indirect (_, _)
| Call _
| Call_indirect (_, _)
| Call_ref _ | Return_call_ref _ | Array_get _ | Array_get_u _
| Array_new _
| Array_new_data (_, _)
| Array_new_default _
| Array_new_elem (_, _)
| Array_new_fixed (_, _)
| Array_set _
| Struct_get (_, _)
| Struct_get_s (_, _)
| Struct_new _ | Struct_new_default _
| Struct_set (_, _) ->
instr
and aux_expr expr = List.map aux_instr expr in
aux_expr body_expr
let remove_local map body =
let new_x x = match Hashtbl.find_opt map x with None -> x | Some x -> x in
let rec aux_instr instr =
match instr with
| Local_get ind -> Local_get (new_x ind)
| Local_set ind -> Local_set (new_x ind)
| Local_tee ind -> Local_tee (new_x ind)
| Block (m, t, e) -> Block (m, t, aux_expr e)
| Loop (m, t, e) -> Loop (m, t, aux_expr e)
| If_else (m, t, e1, e2) -> If_else (m, t, aux_expr e1, aux_expr e2)
| I64_extend32_s | I32_wrap_i64 | F32_demote_f64 | F64_promote_f32
| Ref_is_null | Ref_as_non_null | Ref_eq | Drop | Memory_size | Memory_grow
| Memory_fill | Memory_copy | Nop | Unreachable | Return | Array_len
| I31_get_u | I31_get_s | I31_new | Extern_externalize | Extern_internalize
| I32_const _ | I64_const _ | F32_const _ | F64_const _
| I_unop (_, _)
| F_unop (_, _)
| I_binop (_, _)
| F_binop (_, _)
| I_testop (_, _)
| I_relop (_, _)
| F_relop (_, _)
| I_extend8_s _ | I_extend16_s _ | I64_extend_i32 _
| I_trunc_f (_, _, _)
| I_trunc_sat_f (_, _, _)
| F_convert_i (_, _, _)
| I_reinterpret_f (_, _)
| F_reinterpret_i (_, _)
| Ref_null _ | Ref_func _
| Ref_cast (_, _)
| Ref_test (_, _)
| Select _ | Global_get _ | Global_set _ | Table_get _ | Table_set _
| Table_size _ | Table_grow _ | Table_fill _
| Table_copy (_, _)
| Table_init (_, _)
| Elem_drop _
| I_load (_, _)
| F_load (_, _)
| I_store (_, _)
| F_store (_, _)
| I_load8 (_, _, _)
| I_load16 (_, _, _)
| I64_load32 (_, _)
| I_store8 (_, _)
| I_store16 (_, _)
| I64_store32 _ | Memory_init _ | Data_drop _ | Br _ | Br_if _
| Br_table (_, _)
| Br_on_cast (_, _, _)
| Br_on_cast_fail (_, _, _)
| Br_on_non_null _ | Br_on_null _ | Return_call _
| Return_call_indirect (_, _)
| Call _
| Call_indirect (_, _)
| Call_ref _ | Return_call_ref _ | Array_get _ | Array_get_u _ | Array_new _
| Array_new_data (_, _)
| Array_new_default _
| Array_new_elem (_, _)
| Array_new_fixed (_, _)
| Array_set _
| Struct_get (_, _)
| Struct_get_s (_, _)
| Struct_new _ | Struct_new_default _
| Struct_set (_, _) ->
instr
and aux_expr expr = List.map aux_instr expr in
aux_expr body

let remove_unused_locals locals nb_args body =
let unused_locals =
let used_locals = locals_func body in
let locals = List.mapi (fun i _x -> nb_args + i) locals in
List.filter (fun x -> not @@ Hashtbl.mem used_locals x) locals
in
let loop (idx, param_l, body_expr) param : int * param list * expr =
match Hashtbl.find_opt loc_hashtbl (idx + nb_args) with
| None -> (idx + 1, param_l, remove_local (idx + nb_args) body_expr)
| Some _ -> (idx + 1, List.append param_l [ param ], body_expr)
let rename_map = Hashtbl.create 16 in
List.iteri
(fun j x ->
let name, _ = x in
let _x = Option.value name ~default:"anon" in
let count = ref 0 in
for i = 0 to j do
if List.mem (nb_args + i) unused_locals then incr count
done;
if not @@ List.mem (nb_args + j) unused_locals then begin
Hashtbl.replace rename_map (nb_args + j) (nb_args + j - !count)
end )
locals;
let locals = List.mapi (fun i x -> (nb_args + i, x)) locals in
let locals =
List.filter_map
(fun (i, x) -> if List.mem i unused_locals then None else Some x)
locals
in
let _, l, b = List.fold_left loop (0, [], body_expr) locals in
(l, b)
let body = remove_local rename_map body in
(locals, body)

let optimize_func func =
let { type_f; locals; body; id } = func in
let body = optimize_expr body in
let pt, _ = type_f in
let nb_args = List.length pt in
let locals, body = locals_used_in_func locals nb_args body in
let locals, body = remove_unused_locals locals nb_args body in
{ type_f; locals; body; id }

let optimize_runtime_func f =
Expand Down
4 changes: 2 additions & 2 deletions src/symbolic.ml
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,10 @@ module Pp = struct
let data_mode fmt = function
| Data_passive -> ()
| Data_active (i, e) ->
Format.fprintf fmt "(%a %a)" symb_indice_opt i expr e
Format.fprintf fmt "(memory %a) (offset %a)" symb_indice_opt i expr e

let data fmt (d : data) =
Format.fprintf fmt {|(data %a %S)|} data_mode d.mode d.init
Format.fprintf fmt {|(data %a %a %S)|} id_opt d.id data_mode d.mode d.init

let elem fmt (e : elem) =
Format.fprintf fmt "@[<hov 2>(elem %a %a %a %a)@]" id_opt e.id elem_mode
Expand Down
10 changes: 5 additions & 5 deletions src/typecheck.ml
Original file line number Diff line number Diff line change
Expand Up @@ -284,9 +284,6 @@ let rec typecheck_instr (env : env) (stack : stack) (instr : instr) :
let t = Env.global_get i env in
Stack.pop [ typ_of_val_type t ] stack
| If_else (_id, block_type, e1, e2) ->
let block_type =
Option.map (fun (pt, rt) -> (List.rev pt, rt)) block_type
in
let* stack = Stack.pop [ i32 ] stack in
let* stack_e1 = typecheck_expr env e1 ~is_loop:false block_type ~stack in
let* _stack_e2 = typecheck_expr env e2 ~is_loop:false block_type ~stack in
Expand Down Expand Up @@ -441,7 +438,7 @@ let rec typecheck_instr (env : env) (stack : stack) (instr : instr) :
let* stack = Stack.pop [ i32 ] stack in
let jt = Env.block_type_get i env in
let* stack = Stack.pop jt stack in
Stack.push (List.rev jt) stack
Stack.push jt stack
| Br_table (branches, i) ->
let* stack = Stack.pop [ i32 ] stack in
let default_jt = Env.block_type_get i env in
Expand Down Expand Up @@ -499,7 +496,10 @@ and typecheck_expr env expr ~is_loop (block_type : func_type option)
error_s "type mismatch block %a" Stack.pp_error (rt, stack)
else
match Stack.match_prefix ~prefix:pt ~stack:previous_stack with
| None -> Error "type mismatch (param type)"
| None ->
error_s
"type mismatch (param type: prefix is %a and previous_stack is %a)"
Stack.pp pt Stack.pp previous_stack
| Some stack_to_push -> Stack.push rt stack_to_push

let typecheck_function (modul : modul) func refs =
Expand Down
16 changes: 12 additions & 4 deletions src/types.ml
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,10 @@ struct

let mut fmt = function Const -> () | Var -> Format.fprintf fmt "mut"

let global_type fmt (m, vt) = Format.fprintf fmt "(%a %a)" mut m val_type vt
let global_type fmt (m, vt) =
match m with
| Var -> Format.fprintf fmt "(mut %a)" val_type vt
| Const -> Format.fprintf fmt "%a" val_type vt

let local fmt (id, t) =
Format.fprintf fmt "(local %a %a)" id_opt id val_type t
Expand Down Expand Up @@ -528,10 +531,15 @@ struct
| S32 -> Format.fprintf fmt "32"
| S64 -> Format.fprintf fmt "64"

(* TODO: when offset is 0 then do not print anything, if offset is N (memargN) then print nothing ? *)
let memarg fmt { offset; align } =
if offset = 0 && align = 0 then ()
else Format.fprintf fmt "offset=%d align=%d" offset align
let pow_2 n =
assert (n >= 0);
1 lsl n
in
let off fmt offset =
if offset > 0 then Format.fprintf fmt "offset=%d" offset
in
epatrizio marked this conversation as resolved.
Show resolved Hide resolved
Format.fprintf fmt "%a align=%d" off offset (pow_2 align)

let rec instr fmt = function
| I32_const i -> Format.fprintf fmt "i32.const %ld" i
Expand Down
Loading