Skip to content

Commit

Permalink
Unify topXXX.mli / opttopXXX.mli (ocaml#10061)
Browse files Browse the repository at this point in the history
This unifies both implementations of the toplevel under a common interface.

Similar Makefile hacks to those in place for dynlink are used: byte
and native implementations are in separate directories, while the
shared interface are in the parent and copied as needed by the build
rules.

This is a preliminary step to remove duplication as much as possible
in the two implementations, but should already be pretty useful for
libraries that use the `Toploop` interface.
  • Loading branch information
AltGr authored and dbuenzli committed Mar 25, 2021
1 parent e85bbdb commit 7680a9b
Show file tree
Hide file tree
Showing 19 changed files with 306 additions and 380 deletions.
294 changes: 159 additions & 135 deletions .depend

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,15 @@ _build
/tools/caml-tex
/tools/eventlog_metadata

/toplevel/byte/toploop.mli
/toplevel/byte/trace.mli
/toplevel/byte/topdirs.mli
/toplevel/byte/topmain.mli
/toplevel/native/toploop.mli
/toplevel/native/trace.mli
/toplevel/native/topdirs.mli
/toplevel/native/topmain.mli

/utils/config.ml
/utils/domainstate.ml
/utils/domainstate.mli
Expand Down
3 changes: 3 additions & 0 deletions Changes
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ Working version
to the implementation and the coercion.
(Leandro Ostera, review by Gabriel Scherer and Thomas Refis)

* #10061: remove modules `Opttoploop`, `Opttopstart`, which are replaced by
`Toploop` and `Topstart`, made available in native code.

### Build system:

### Bug fixes:
Expand Down
42 changes: 25 additions & 17 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,6 @@ OPTSTART=driver/optmain.cmo

TOPLEVELSTART=toplevel/topstart.cmo

OPTTOPLEVELSTART=toplevel/opttopstart.cmo

PERVASIVES=$(STDLIB_MODULES) outcometree topdirs toploop

LIBFILES=stdlib.cma std_exit.cmo *.cmi camlheader
Expand Down Expand Up @@ -373,6 +371,9 @@ endif
driver/*.cmi \
toplevel/*.cmi \
"$(INSTALL_COMPLIBDIR)"
$(INSTALL_DATA) \
toplevel/byte/*.cmi \
"$(INSTALL_COMPLIBDIR)"
ifeq "$(INSTALL_SOURCE_ARTIFACTS)" "true"
$(INSTALL_DATA) \
utils/*.cmt utils/*.cmti utils/*.mli \
Expand All @@ -384,6 +385,9 @@ ifeq "$(INSTALL_SOURCE_ARTIFACTS)" "true"
driver/*.cmt driver/*.cmti driver/*.mli \
toplevel/*.cmt toplevel/*.cmti toplevel/*.mli \
"$(INSTALL_COMPLIBDIR)"
$(INSTALL_DATA) \
toplevel/byte/*.cmt \
"$(INSTALL_COMPLIBDIR)"
endif
$(INSTALL_DATA) \
compilerlibs/*.cma \
Expand All @@ -397,8 +401,8 @@ endif
"$(INSTALL_LIBDIR)"
ifeq "$(INSTALL_SOURCE_ARTIFACTS)" "true"
$(INSTALL_DATA) \
toplevel/topdirs.cmt toplevel/topdirs.cmti \
toplevel/topdirs.mli \
toplevel/byte/topdirs.cmt \
toplevel/topdirs.cmti toplevel/byte/topdirs.mli \
"$(INSTALL_LIBDIR)"
endif
$(MAKE) -C tools install
Expand Down Expand Up @@ -538,10 +542,7 @@ installoptopt:
if test -f ocamlnat$(EXE) ; then \
$(INSTALL_PROG) ocamlnat$(EXE) "$(INSTALL_BINDIR)"; \
$(INSTALL_DATA) \
toplevel/opttopdirs.cmi \
"$(INSTALL_LIBDIR)"; \
$(INSTALL_DATA) \
$(OPTTOPLEVELSTART:.cmo=.cmx) $(OPTTOPLEVELSTART:.cmo=.$(O)) \
$(TOPLEVELSTART:.cmo=.cmx) $(TOPLEVELSTART:.cmo=.$(O)) \
"$(INSTALL_COMPLIBDIR)"; \
fi
cd "$(INSTALL_COMPLIBDIR)" && \
Expand All @@ -555,7 +556,8 @@ ifeq "$(INSTALL_SOURCE_ARTIFACTS)" "true"
utils/*.ml parsing/*.ml typing/*.ml bytecomp/*.ml driver/*.ml \
file_formats/*.ml \
lambda/*.ml \
toplevel/*.ml middle_end/*.ml middle_end/closure/*.ml \
toplevel/*.ml toplevel/byte/*.ml \
middle_end/*.ml middle_end/closure/*.ml \
middle_end/flambda/*.ml middle_end/flambda/base_types/*.ml \
asmcomp/*.ml \
asmcmp/debug/*.ml \
Expand Down Expand Up @@ -611,7 +613,7 @@ ocaml_dependencies := \

.INTERMEDIATE: ocaml.tmp
ocaml.tmp: $(ocaml_dependencies)
$(CAMLC) $(LINKFLAGS) -linkall -o $@ $^
$(CAMLC) $(LINKFLAGS) -I toplevel/byte -linkall -o $@ $^

ocaml$(EXE): $(expunge) ocaml.tmp
- $(CAMLRUN) $^ $@ $(PERVASIVES)
Expand Down Expand Up @@ -1007,8 +1009,12 @@ ocamlnat$(EXE): compilerlibs/ocamlcommon.cmxa compilerlibs/ocamloptcomp.cmxa \
compilerlibs/ocamlbytecomp.cmxa \
otherlibs/dynlink/dynlink.cmxa \
compilerlibs/ocamlopttoplevel.cmxa \
$(OPTTOPLEVELSTART:.cmo=.cmx)
$(CAMLOPT_CMD) $(LINKFLAGS) -linkall -o $@ $^
$(TOPLEVELSTART:.cmo=.cmx)
$(CAMLOPT_CMD) $(LINKFLAGS) -linkall -I toplevel/native -o $@ $^

$(TOPLEVELSTART:.cmo=.cmx): $(TOPLEVELSTART:.cmo=.ml) \
toplevel/native/topmain.cmx
$(CAMLOPT_CMD) $(COMPFLAGS) $(OPTCOMPFLAGS) -I toplevel/native -c $<

partialclean::
rm -f ocamlnat ocamlnat.exe
Expand Down Expand Up @@ -1043,19 +1049,19 @@ endif
.SUFFIXES: .ml .mli .cmo .cmi .cmx

.ml.cmo:
$(CAMLC) $(COMPFLAGS) -c $<
$(CAMLC) $(COMPFLAGS) -c $< -I $(@D)

.mli.cmi:
$(CAMLC) $(COMPFLAGS) -c $<

.ml.cmx:
$(CAMLOPT) $(COMPFLAGS) $(OPTCOMPFLAGS) -c $<
$(CAMLOPT) $(COMPFLAGS) $(OPTCOMPFLAGS) -c $< -I $(@D)

partialclean::
for d in utils parsing typing bytecomp asmcomp middle_end file_formats \
lambda middle_end/closure middle_end/flambda \
middle_end/flambda/base_types asmcomp/debug \
driver toplevel tools; do \
driver toplevel toplevel/byte toplevel/native tools; do \
rm -f $$d/*.cm[ioxt] $$d/*.cmti $$d/*.annot $$d/*.s $$d/*.asm \
$$d/*.o $$d/*.obj $$d/*.so $$d/*.dll; \
done
Expand All @@ -1065,8 +1071,10 @@ depend: beforedepend
(for d in utils parsing typing bytecomp asmcomp middle_end \
lambda file_formats middle_end/closure middle_end/flambda \
middle_end/flambda/base_types asmcomp/debug \
driver toplevel; \
do $(CAMLDEP) $(DEPFLAGS) $(DEPINCLUDES) $$d/*.mli $$d/*.ml || exit; \
driver toplevel toplevel/byte toplevel/native; \
do \
$(CAMLDEP) $(DEPFLAGS) -I $$d $(DEPINCLUDES) $$d/*.mli $$d/*.ml \
|| exit; \
done) > .depend

.PHONY: distclean
Expand Down
35 changes: 27 additions & 8 deletions compilerlibs/Makefile.compilerlibs
Original file line number Diff line number Diff line change
Expand Up @@ -261,14 +261,33 @@ MIDDLE_END_CMI=\
OPTCOMP=$(MIDDLE_END) $(ASMCOMP)
OPTCOMP_CMI=$(MIDDLE_END_CMI) $(ASMCOMP_CMI)

TOPLEVEL=toplevel/genprintval.cmo toplevel/toploop.cmo \
toplevel/trace.cmo toplevel/topdirs.cmo toplevel/topmain.cmo
TOPLEVEL_CMI=
TOPLEVEL=toplevel/genprintval.cmo toplevel/byte/toploop.cmo \
toplevel/byte/trace.cmo toplevel/byte/topdirs.cmo toplevel/byte/topmain.cmo
TOPLEVEL_CMI=toplevel/byte/toploop.cmi toplevel/byte/trace.cmi \
toplevel/byte/topdirs.cmi toplevel/byte/topmain.cmi

OPTTOPLEVEL=toplevel/genprintval.cmo toplevel/opttoploop.cmo \
toplevel/opttopdirs.cmo toplevel/opttopmain.cmo
OPTTOPLEVEL_CMI=
OPTTOPLEVEL=toplevel/genprintval.cmo toplevel/native/toploop.cmo \
toplevel/native/topdirs.cmo toplevel/native/topmain.cmo
OPTTOPLEVEL_CMI=toplevel/native/toploop.cmi toplevel/native/topdirs.cmi \
toplevel/native/topmain.cmi

TOPLEVEL_SHARED_MLIS = toploop.mli trace.mli topdirs.mli topmain.mli

toplevel/byte/%.mli toplevel/byte/%.cmi: toplevel/%.mli toplevel/%.cmi
cp toplevel/$*.mli toplevel/$*.cmi $(@D)

toplevel/native/%.mli toplevel/native/%.cmi: toplevel/%.mli toplevel/%.cmi
cp toplevel/$*.mli toplevel/$*.cmi $(@D)

beforedepend::
cp $(TOPLEVEL_SHARED_MLIS:%=toplevel/%) toplevel/byte
cp $(TOPLEVEL_SHARED_MLIS:%=toplevel/%) toplevel/native

partialclean::
rm -f $(TOPLEVEL_SHARED_MLIS:%.mli=\
toplevel/byte/%.mli toplevel/byte/%.cmi)
rm -f $(TOPLEVEL_SHARED_MLIS:%.mli=\
toplevel/native/%.mli toplevel/native/%.cmi)

$(COMMON:.cmo=.cmx) $(BYTECOMP:.cmo=.cmx) $(OPTCOMP:.cmo=.cmx): ocamlopt$(EXE)
$(OPTTOPLEVEL:.cmo=.cmx): ocamlopt$(EXE)
Expand Down Expand Up @@ -322,12 +341,12 @@ partialclean::


compilerlibs/ocamltoplevel.cma: $(TOPLEVEL_CMI) $(TOPLEVEL)
$(CAMLC) -a -o $@ $(TOPLEVEL)
$(CAMLC) -a -o $@ -I toplevel/byte $(TOPLEVEL)
partialclean::
rm -f compilerlibs/ocamltoplevel.cma

compilerlibs/ocamlopttoplevel.cmxa: $(OPTTOPLEVEL_CMI) $(OPTTOPLEVEL:.cmo=.cmx)
$(CAMLOPT) -a -o $@ $(OPTTOPLEVEL:.cmo=.cmx)
$(CAMLOPT) -a -o $@ -I toplevel/native $(OPTTOPLEVEL:.cmo=.cmx)
partialclean::
rm -f compilerlibs/ocamlopttoplevel.cmxa \
compilerlibs/ocamlopttoplevel.a compilerlibs/ocamlopttoplevel.lib
2 changes: 1 addition & 1 deletion testsuite/tests/tool-toplevel/pr6468.compilers.reference
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ Raised at f in file "//toplevel//", line 2, characters 11-26
Called from g in file "//toplevel//", line 1, characters 11-15
Called from Stdlib__fun.protect in file "fun.ml", line 33, characters 8-15
Re-raised at Stdlib__fun.protect in file "fun.ml", line 38, characters 6-52
Called from Toploop.load_lambda in file "toplevel/toploop.ml", line 212, characters 4-150
Called from Toploop.load_lambda in file "toplevel/byte/toploop.ml", line 212, characters 4-150

2 changes: 1 addition & 1 deletion tools/.depend
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ caml_tex.cmo : \
../parsing/ast_iterator.cmi \
../parsing/ast_helper.cmi
caml_tex.cmx : \
../toplevel/toploop.cmx \
../toplevel/toploop.cmi \
../parsing/syntaxerr.cmx \
../parsing/parsetree.cmi \
../parsing/parse.cmx \
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
12 changes: 9 additions & 3 deletions toplevel/opttopdirs.ml → toplevel/native/topdirs.ml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ open Format
open Misc
open Longident
open Types
open Opttoploop
open Toploop

(* The standard output formatter *)
let std_out = std_formatter
Expand Down Expand Up @@ -114,8 +114,8 @@ let _ = Hashtbl.add directive_table "load" (Directive_string (dir_load std_out))

(* Load commands from a file *)

let dir_use ppf name = ignore(Opttoploop.use_file ppf name)
let dir_use_output ppf name = ignore(Opttoploop.use_output ppf name)
let dir_use ppf name = ignore(Toploop.use_file ppf name)
let dir_use_output ppf name = ignore(Toploop.use_output ppf name)

let _ = Hashtbl.add directive_table "use" (Directive_string (dir_use std_out))
let _ = Hashtbl.add directive_table "use_output"
Expand Down Expand Up @@ -195,6 +195,12 @@ let parse_warnings ppf iserr s =
try Warnings.parse_options iserr s
with Arg.Bad err -> fprintf ppf "%s.@." err

let unavailable () = invalid_arg "Directive unavailable in the native toplevel."

let dir_trace _ _ = unavailable ()
let dir_untrace _ _ = unavailable ()
let dir_untrace_all _ _ = unavailable ()

let _ =
(* Control the printing of values *)

Expand Down
56 changes: 48 additions & 8 deletions toplevel/opttoploop.ml → toplevel/native/toploop.ml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ type directive_fun =
| Directive_ident of (Longident.t -> unit)
| Directive_bool of (bool -> unit)

type directive_info = {
section: string;
doc: string;
}

let remembered = ref Ident.empty

Expand Down Expand Up @@ -215,6 +219,14 @@ let run_hooks hook = List.iter (fun f -> f hook) !hooks

(* Load in-core and execute a lambda term *)

let may_trace = ref false (* Global lock on tracing *)

let backtrace = ref None

let record_backtrace () =
if Printexc.backtrace_status ()
then backtrace := Some (Printexc.get_backtrace ())

let phrase_seqid = ref 0
let phrase_name = ref "TOP"

Expand Down Expand Up @@ -271,12 +283,21 @@ let load_lambda ppf ~module_ident ~required_globals lam size =
if Filename.is_implicit dll
then Filename.concat (Sys.getcwd ()) dll
else dll in
let res = dll_run dll !phrase_name in
(try Sys.remove dll with Sys_error _ -> ());
(* note: under windows, cannot remove a loaded dll
(should remember the handles, close them in at_exit, and then remove
files) *)
res
match
may_trace := true;
Fun.protect
~finally:(fun () ->
may_trace := false;
(try Sys.remove dll with Sys_error _ -> ()))
(* note: under windows, cannot remove a loaded dll
(should remember the handles, close them in at_exit, and then
remove files) *)
(fun () -> dll_run dll !phrase_name)
with
| res -> res
| exception x ->
record_backtrace ();
Exception x

(* Print the outcome of an evaluation *)

Expand All @@ -300,12 +321,26 @@ let print_out_exception ppf exn outv =
let print_exception_outcome ppf exn =
if exn = Out_of_memory then Gc.full_major ();
let outv = outval_of_value !toplevel_env (Obj.repr exn) Predef.type_exn in
print_out_exception ppf exn outv
print_out_exception ppf exn outv;
if Printexc.backtrace_status ()
then
match !backtrace with
| None -> ()
| Some b ->
print_string b;
backtrace := None

(* The table of toplevel directives.
Filled by functions from module topdirs. *)

let directive_table = (Hashtbl.create 13 : (string, directive_fun) Hashtbl.t)
let directive_table = (Hashtbl.create 23 : (string, directive_fun) Hashtbl.t)

let directive_info_table =
(Hashtbl.create 23 : (string, directive_info) Hashtbl.t)

let add_directive name dir_fun dir_info =
Hashtbl.add directive_table name dir_fun;
Hashtbl.add directive_info_table name dir_info

(* Execute a toplevel phrase *)

Expand Down Expand Up @@ -682,3 +717,8 @@ let run_script ppf name args =
else name
in
use_silently ppf explicit_name

(* API compat *)

let getvalue _ = assert false
let setvalue _ _ = assert false
10 changes: 5 additions & 5 deletions toplevel/opttopmain.ml → toplevel/native/topmain.ml
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,12 @@ let expand_position pos len =


let prepare ppf =
Opttoploop.set_paths ();
Toploop.set_paths ();
try
let res =
List.for_all (Opttopdirs.load_file ppf) (List.rev !preload_objects)
List.for_all (Topdirs.load_file ppf) (List.rev !preload_objects)
in
Opttoploop.run_hooks Opttoploop.Startup;
Toploop.run_hooks Toploop.Startup;
res
with x ->
try Location.report_exception ppf x; false
Expand Down Expand Up @@ -73,7 +73,7 @@ let file_argument name =
(Array.length !argv - !Arg.current)
in
Compmisc.read_clflags_from_env ();
if prepare ppf && Opttoploop.run_script ppf name newargs
if prepare ppf && Toploop.run_script ppf name newargs
then raise (Exit_with_status 0)
else raise (Exit_with_status 2)
end
Expand Down Expand Up @@ -115,7 +115,7 @@ let main () =
Compmisc.read_clflags_from_env ();
if not (prepare Format.err_formatter) then raise (Exit_with_status 2);
Compmisc.init_path ();
Opttoploop.loop Format.std_formatter
Toploop.loop Format.std_formatter

let main () =
match main () with
Expand Down

0 comments on commit 7680a9b

Please sign in to comment.