Skip to content

Commit b1b853a

Browse files
authored
Add -main option to specify entrypoint function in interpreter mode (#374)
When running unit tests with the CompCert reference interpreter, it's nice to be able to start execution at a given test function instead of having to write a main function. This PR adds a -main command-line option to give the name of the entry point function. The default is still main. Frama-C has a similar option. The function specified with -main is called with no arguments. If its return type is int, its return value is the exit status of the program. Otherwise, its return value is ignored and the program exits with status 0.
1 parent 6aeb645 commit b1b853a

File tree

4 files changed

+42
-20
lines changed

4 files changed

+42
-20
lines changed

cfrontend/C2C.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1495,7 +1495,7 @@ let convertProgram p =
14951495
let p' =
14961496
{ prog_defs = gl2;
14971497
prog_public = public_globals gl2;
1498-
prog_main = intern_string "main";
1498+
prog_main = intern_string !Clflags.main_function_name;
14991499
prog_types = typs;
15001500
prog_comp_env = ce } in
15011501
Diagnostics.check_errors ();

driver/Clflags.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,4 @@ let option_small_const = ref (!option_small_data)
6767
let option_timings = ref false
6868
let stdlib_path = ref Configuration.stdlib_path
6969
let use_standard_headers = ref Configuration.has_standard_headers
70+
let main_function_name = ref "main"

driver/Driver.ml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,7 @@ Code generation options: (use -fno-<opt> to turn off -f<opt>)
233233
-trace Have the interpreter produce a detailed trace of reductions
234234
-random Randomize execution order
235235
-all Simulate all possible execution orders
236+
-main <name> Start executing at function <name> instead of main()
236237
|}
237238

238239
let print_usage_and_exit () =
@@ -355,7 +356,8 @@ let cmdline_actions =
355356
Exact "-quiet", Unit (fun () -> Interp.trace := 0);
356357
Exact "-trace", Unit (fun () -> Interp.trace := 2);
357358
Exact "-random", Unit (fun () -> Interp.mode := Interp.Random);
358-
Exact "-all", Unit (fun () -> Interp.mode := Interp.All)
359+
Exact "-all", Unit (fun () -> Interp.mode := Interp.All);
360+
Exact "-main", String (fun s -> main_function_name := s)
359361
]
360362
(* Optimization options *)
361363
(* -f options: come in -f and -fno- variants *)

driver/Interp.ml

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -587,41 +587,60 @@ let world_program prog =
587587

588588
(* Massaging the program to get a suitable "main" function *)
589589

590-
let change_main_function p old_main old_main_ty =
591-
let old_main = Evalof(Evar(old_main, old_main_ty), old_main_ty) in
590+
let change_main_function p new_main_fn =
591+
let new_main_id = intern_string "%main%" in
592+
{ p with
593+
Ctypes.prog_main = new_main_id;
594+
Ctypes.prog_defs =
595+
(new_main_id, Gfun(Internal new_main_fn)) :: p.Ctypes.prog_defs }
596+
597+
let call_main3_function main_id main_ty =
598+
let main_var = Evalof(Evar(main_id, main_ty), main_ty) in
592599
let arg1 = Eval(Vint(coqint_of_camlint 0l), type_int32s) in
593600
let arg2 = arg1 in
594601
let body =
595-
Sreturn(Some(Ecall(old_main, Econs(arg1, Econs(arg2, Enil)), type_int32s))) in
596-
let new_main_fn =
597-
{ fn_return = type_int32s; fn_callconv = cc_default;
598-
fn_params = []; fn_vars = []; fn_body = body } in
599-
let new_main_id = intern_string "___main" in
600-
{ prog_main = new_main_id;
601-
Ctypes.prog_defs = (new_main_id, Gfun(Ctypes.Internal new_main_fn)) :: p.Ctypes.prog_defs;
602-
Ctypes.prog_public = p.Ctypes.prog_public;
603-
prog_types = p.prog_types;
604-
prog_comp_env = p.prog_comp_env }
602+
Sreturn(Some(Ecall(main_var, Econs(arg1, Econs(arg2, Enil)), type_int32s)))
603+
in
604+
{ fn_return = type_int32s; fn_callconv = cc_default;
605+
fn_params = []; fn_vars = []; fn_body = body }
606+
607+
let call_other_main_function main_id main_ty main_ty_res =
608+
let main_var = Evalof(Evar(main_id, main_ty), main_ty) in
609+
let body =
610+
Ssequence(Sdo(Ecall(main_var, Enil, main_ty_res)),
611+
Sreturn(Some(Eval(Vint(coqint_of_camlint 0l), type_int32s)))) in
612+
{ fn_return = type_int32s; fn_callconv = cc_default;
613+
fn_params = []; fn_vars = []; fn_body = body }
605614

606615
let rec find_main_function name = function
607616
| [] -> None
608-
| (id, Gfun fd) :: gdl -> if id = name then Some fd else find_main_function name gdl
609-
| (id, Gvar v) :: gdl -> find_main_function name gdl
617+
| (id, Gfun fd) :: gdl ->
618+
if id = name then Some fd else find_main_function name gdl
619+
| (id, Gvar v) :: gdl ->
620+
find_main_function name gdl
610621

611622
let fixup_main p =
612623
match find_main_function p.Ctypes.prog_main p.Ctypes.prog_defs with
613624
| None ->
614-
fprintf err_formatter "ERROR: no main() function@.";
625+
fprintf err_formatter "ERROR: no entry function %s()@."
626+
(extern_atom p.Ctypes.prog_main);
615627
None
616628
| Some main_fd ->
617629
match type_of_fundef main_fd with
618630
| Tfunction(Tnil, Ctypes.Tint(I32, Signed, _), _) ->
619631
Some p
620-
| Tfunction(Tcons(Ctypes.Tint _, Tcons(Tpointer(Tpointer(Ctypes.Tint(I8,_,_),_),_), Tnil)),
632+
| Tfunction(Tcons(Ctypes.Tint _,
633+
Tcons(Tpointer(Tpointer(Ctypes.Tint(I8,_,_),_),_), Tnil)),
621634
Ctypes.Tint _, _) as ty ->
622-
Some (change_main_function p p.Ctypes.prog_main ty)
635+
Some (change_main_function p
636+
(call_main3_function p.Ctypes.prog_main ty))
637+
| Tfunction(Tnil, ty_res, _) as ty ->
638+
Some (change_main_function p
639+
(call_other_main_function p.Ctypes.prog_main ty ty_res))
623640
| _ ->
624-
fprintf err_formatter "ERROR: wrong type for main() function@.";
641+
fprintf err_formatter
642+
"ERROR: wrong type for entry function %s()@."
643+
(extern_atom p.Ctypes.prog_main);
625644
None
626645

627646
(* Execution of a whole program *)

0 commit comments

Comments
 (0)