Skip to content

Commit c61a4d0

Browse files
committed
fix: Fix segfault on graders using samplers returning newly defined exceptions
(or extensible variant cases)
1 parent e63359e commit c61a4d0

File tree

3 files changed

+42
-4
lines changed

3 files changed

+42
-4
lines changed

src/grader/introspection.ml

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,39 @@ let get_value lid ty =
167167
else
168168
failwith (Format.asprintf "Wrong type %a." Printtyp.type_sch val_type)
169169

170+
(* Replacement for [Toploop.print_value] that doesn't segfault on yet
171+
unregistered extension constructors.
172+
173+
Note: re-instanciating [Genprintval.Make] means we lose any previously
174+
defined printers through [Topdirs.dir_install_printer]. *)
175+
let base_print_value, install_printer =
176+
let module Printer = Genprintval.Make(Obj)(struct
177+
type valu = Obj.t
178+
exception Error
179+
let eval_address = function
180+
| Env.Aident id ->
181+
if Ident.persistent id || Ident.global id then
182+
Symtable.get_global_value id
183+
else begin
184+
let name = Translmod.toplevel_name id in
185+
try Toploop.getvalue name
186+
with _ -> raise Error
187+
end
188+
| Env.Adot(_, _) ->
189+
(* in this case we bail out because this may refer to a
190+
yet-unregistered extension constructor within the current module.
191+
The printer has a reasonable fallback. *)
192+
raise Error
193+
let same_value v1 v2 = (v1 == v2)
194+
end)
195+
in
196+
let print_value env obj ppf ty =
197+
!Oprint.out_value ppf @@
198+
Printer.outval_of_value 300 100 (fun _ _ _ -> None) env obj ty
199+
in
200+
let install_printer pr = Printer.install_printer pr in
201+
print_value, install_printer
202+
170203
let print_value ppf v ty =
171204
let { Typedtree.ctyp_type = ty; _ } =
172205
Typetexp.transl_type_scheme !Toploop.toplevel_env (Ty.obj ty) in
@@ -192,17 +225,17 @@ let print_value ppf v ty =
192225
done)
193226
(fun () -> ()) in
194227
begin try
195-
Toploop.print_value !Toploop.toplevel_env (Obj.repr v) tmp_ppf ty ;
228+
base_print_value !Toploop.toplevel_env (Obj.repr v) tmp_ppf ty ;
196229
Format.pp_print_flush tmp_ppf ()
197230
with Exit -> () end ;
198231
match !state with `Start | `Decided false | `Undecided -> false | `Decided true -> true in
199232
if needs_parentheses then begin
200233
Format.fprintf ppf "@[<hv 1>(" ;
201-
Toploop.print_value !Toploop.toplevel_env (Obj.repr v) ppf ty ;
234+
base_print_value !Toploop.toplevel_env (Obj.repr v) ppf ty ;
202235
Format.fprintf ppf ")@]"
203236
end else begin
204237
Format.fprintf ppf "@[<hv 0>" ;
205-
Toploop.print_value !Toploop.toplevel_env (Obj.repr v) ppf ty ;
238+
base_print_value !Toploop.toplevel_env (Obj.repr v) ppf ty ;
206239
Format.fprintf ppf "@]"
207240
end
208241

@@ -414,6 +447,7 @@ let allow_introspection ~divert =
414447
stderr_cb := bad_stderr_cb ;
415448
res
416449

450+
let install_printer pr = install_printer pr
417451
let get_printer ty = fun ppf v -> print_value ppf v ty
418452

419453
let register_sampler name f = register_sampler name f

src/grader/introspection_intf.mli

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ module type INTROSPECTION = sig
3636

3737
val register_sampler: string -> ('a -> 'b) -> unit
3838
val get_sampler: 'a Ty.ty -> (unit -> 'a)
39+
40+
val install_printer:
41+
Path.t -> Types.type_expr -> (Format.formatter -> Obj.t -> unit) -> unit
42+
3943
val get_printer: 'a Ty.ty -> (Format.formatter -> 'a -> unit)
4044

4145
val parse_lid: string -> Longident.t

src/grader/test_lib.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1351,7 +1351,7 @@ module Intro = Pre_test.Introspection
13511351
let () =
13521352
let path = Path.Pident (Ident.create_local "fun_printer") in
13531353
let ty = Typetexp.transl_type_scheme !Toploop.toplevel_env (Ty.obj [%ty: _ -> _ ]) in
1354-
Toploop.install_printer path ty.Typedtree.ctyp_type fun_printer
1354+
Intro.install_printer path ty.Typedtree.ctyp_type fun_printer
13551355
end
13561356
13571357
let (@@@) f g = fun x -> f x @ g x

0 commit comments

Comments
 (0)